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 /* look in server.c for some explanation of these variables */
30 extern enum protocol_types Protocol;
32 extern uint32 global_client_caps;
34 extern bool global_encrypted_passwords_negotiated;
36 /****************************************************************************
37 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
38 path or anything including wildcards.
39 We're assuming here that '/' is not the second byte in any multibyte char
40 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
42 ****************************************************************************/
44 /* Custom version for processing POSIX paths. */
45 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
47 static NTSTATUS check_path_syntax_internal(char *path,
49 bool *p_last_component_contains_wcard)
53 NTSTATUS ret = NT_STATUS_OK;
54 bool start_of_name_component = True;
56 *p_last_component_contains_wcard = False;
59 if (IS_PATH_SEP(*s,posix_path)) {
61 * Safe to assume is not the second part of a mb char
62 * as this is handled below.
64 /* Eat multiple '/' or '\\' */
65 while (IS_PATH_SEP(*s,posix_path)) {
68 if ((d != path) && (*s != '\0')) {
69 /* We only care about non-leading or trailing '/' or '\\' */
73 start_of_name_component = True;
75 *p_last_component_contains_wcard = False;
79 if (start_of_name_component) {
80 if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
81 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
84 * No mb char starts with '.' so we're safe checking the directory separator here.
87 /* If we just added a '/' - delete it */
88 if ((d > path) && (*(d-1) == '/')) {
93 /* Are we at the start ? Can't go back further if so. */
95 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
98 /* Go back one level... */
99 /* We know this is safe as '/' cannot be part of a mb sequence. */
100 /* NOTE - if this assumption is invalid we are not in good shape... */
101 /* Decrement d first as d points to the *next* char to write into. */
102 for (d--; d > path; d--) {
106 s += 2; /* Else go past the .. */
107 /* We're still at the start of a name component, just the previous one. */
110 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
123 return NT_STATUS_OBJECT_NAME_INVALID;
131 *p_last_component_contains_wcard = True;
140 /* Get the size of the next MB character. */
141 next_codepoint(s,&siz);
159 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
161 return NT_STATUS_INVALID_PARAMETER;
164 start_of_name_component = False;
172 /****************************************************************************
173 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
174 No wildcards allowed.
175 ****************************************************************************/
177 NTSTATUS check_path_syntax(char *path)
180 return check_path_syntax_internal(path, False, &ignore);
183 /****************************************************************************
184 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
185 Wildcards allowed - p_contains_wcard returns true if the last component contained
187 ****************************************************************************/
189 NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
191 return check_path_syntax_internal(path, False, p_contains_wcard);
194 /****************************************************************************
195 Check the path for a POSIX client.
196 We're assuming here that '/' is not the second byte in any multibyte char
197 set (a safe assumption).
198 ****************************************************************************/
200 NTSTATUS check_path_syntax_posix(char *path)
203 return check_path_syntax_internal(path, True, &ignore);
206 /****************************************************************************
207 Pull a string and check the path allowing a wilcard - provide for error return.
208 ****************************************************************************/
210 size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
218 bool *contains_wcard)
225 ret = srvstr_pull_buf_talloc(ctx,
232 ret = srvstr_pull_talloc(ctx,
242 *err = NT_STATUS_INVALID_PARAMETER;
246 *contains_wcard = False;
248 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
250 * For a DFS path the function parse_dfs_path()
251 * will do the path processing, just make a copy.
257 if (lp_posix_pathnames()) {
258 *err = check_path_syntax_posix(*pp_dest);
260 *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
266 /****************************************************************************
267 Pull a string and check the path - provide for error return.
268 ****************************************************************************/
270 size_t srvstr_get_path(TALLOC_CTX *ctx,
284 ret = srvstr_pull_buf_talloc(ctx,
291 ret = srvstr_pull_talloc(ctx,
301 *err = NT_STATUS_INVALID_PARAMETER;
305 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
307 * For a DFS path the function parse_dfs_path()
308 * will do the path processing, just make a copy.
314 if (lp_posix_pathnames()) {
315 *err = check_path_syntax_posix(*pp_dest);
317 *err = check_path_syntax(*pp_dest);
323 /****************************************************************************
324 Check if we have a correct fsp pointing to a file. Basic check for open fsp.
325 ****************************************************************************/
327 bool check_fsp_open(connection_struct *conn, struct smb_request *req,
330 if (!(fsp) || !(conn)) {
331 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
334 if (((conn) != (fsp)->conn) || req->vuid != (fsp)->vuid) {
335 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
341 /****************************************************************************
342 Check if we have a correct fsp pointing to a file.
343 ****************************************************************************/
345 bool check_fsp(connection_struct *conn, struct smb_request *req,
348 if (!check_fsp_open(conn, req, fsp)) {
351 if ((fsp)->is_directory) {
352 reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
355 if ((fsp)->fh->fd == -1) {
356 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
359 (fsp)->num_smb_operations++;
363 /****************************************************************************
364 Check if we have a correct fsp pointing to a quota fake file. Replacement for
365 the CHECK_NTQUOTA_HANDLE_OK macro.
366 ****************************************************************************/
368 bool check_fsp_ntquota_handle(connection_struct *conn, struct smb_request *req,
371 if (!check_fsp_open(conn, req, fsp)) {
375 if (fsp->is_directory) {
379 if (fsp->fake_file_handle == NULL) {
383 if (fsp->fake_file_handle->type != FAKE_FILE_TYPE_QUOTA) {
387 if (fsp->fake_file_handle->private_data == NULL) {
394 /****************************************************************************
395 Check if we have a correct fsp. Replacement for the FSP_BELONGS_CONN macro
396 ****************************************************************************/
398 bool fsp_belongs_conn(connection_struct *conn, struct smb_request *req,
401 if ((fsp) && (conn) && ((conn)==(fsp)->conn)
402 && (req->vuid == (fsp)->vuid)) {
406 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
410 /****************************************************************************
411 Reply to a (netbios-level) special message.
412 ****************************************************************************/
414 void reply_special(char *inbuf)
416 int msg_type = CVAL(inbuf,0);
417 int msg_flags = CVAL(inbuf,1);
422 * We only really use 4 bytes of the outbuf, but for the smb_setlen
423 * calculation & friends (srv_send_smb uses that) we need the full smb
426 char outbuf[smb_size];
428 static bool already_got_session = False;
432 memset(outbuf, '\0', sizeof(outbuf));
434 smb_setlen(outbuf,0);
437 case 0x81: /* session request */
439 if (already_got_session) {
440 exit_server_cleanly("multiple session request not permitted");
443 SCVAL(outbuf,0,0x82);
445 if (name_len(inbuf+4) > 50 ||
446 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
447 DEBUG(0,("Invalid name length in session request\n"));
450 name_extract(inbuf,4,name1);
451 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
452 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
455 set_local_machine_name(name1, True);
456 set_remote_machine_name(name2, True);
458 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
459 get_local_machine_name(), get_remote_machine_name(),
462 if (name_type == 'R') {
463 /* We are being asked for a pathworks session ---
465 SCVAL(outbuf, 0,0x83);
469 /* only add the client's machine name to the list
470 of possibly valid usernames if we are operating
471 in share mode security */
472 if (lp_security() == SEC_SHARE) {
473 add_session_user(get_remote_machine_name());
476 reload_services(True);
479 already_got_session = True;
482 case 0x89: /* session keepalive request
483 (some old clients produce this?) */
484 SCVAL(outbuf,0,SMBkeepalive);
488 case 0x82: /* positive session response */
489 case 0x83: /* negative session response */
490 case 0x84: /* retarget session response */
491 DEBUG(0,("Unexpected session response\n"));
494 case SMBkeepalive: /* session keepalive */
499 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
500 msg_type, msg_flags));
502 srv_send_smb(smbd_server_fd(), outbuf, false);
506 /****************************************************************************
508 conn POINTER CAN BE NULL HERE !
509 ****************************************************************************/
511 void reply_tcon(struct smb_request *req)
513 connection_struct *conn = req->conn;
515 char *service_buf = NULL;
516 char *password = NULL;
521 DATA_BLOB password_blob;
522 TALLOC_CTX *ctx = talloc_tos();
524 START_PROFILE(SMBtcon);
526 if (smb_buflen(req->inbuf) < 4) {
527 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
528 END_PROFILE(SMBtcon);
532 p = smb_buf(req->inbuf)+1;
533 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
534 &service_buf, p, STR_TERMINATE) + 1;
535 pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
536 &password, p, STR_TERMINATE) + 1;
538 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
539 &dev, p, STR_TERMINATE) + 1;
541 if (service_buf == NULL || password == NULL || dev == NULL) {
542 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
543 END_PROFILE(SMBtcon);
546 p = strrchr_m(service_buf,'\\');
550 service = service_buf;
553 password_blob = data_blob(password, pwlen+1);
555 conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
558 data_blob_clear_free(&password_blob);
561 reply_nterror(req, nt_status);
562 END_PROFILE(SMBtcon);
566 reply_outbuf(req, 2, 0);
567 SSVAL(req->outbuf,smb_vwv0,max_recv);
568 SSVAL(req->outbuf,smb_vwv1,conn->cnum);
569 SSVAL(req->outbuf,smb_tid,conn->cnum);
571 DEBUG(3,("tcon service=%s cnum=%d\n",
572 service, conn->cnum));
574 END_PROFILE(SMBtcon);
578 /****************************************************************************
579 Reply to a tcon and X.
580 conn POINTER CAN BE NULL HERE !
581 ****************************************************************************/
583 void reply_tcon_and_X(struct smb_request *req)
585 connection_struct *conn = req->conn;
586 char *service = NULL;
588 TALLOC_CTX *ctx = talloc_tos();
589 /* what the cleint thinks the device is */
590 char *client_devicetype = NULL;
591 /* what the server tells the client the share represents */
592 const char *server_devicetype;
599 START_PROFILE(SMBtconX);
602 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
603 END_PROFILE(SMBtconX);
607 passlen = SVAL(req->inbuf,smb_vwv3);
608 tcon_flags = SVAL(req->inbuf,smb_vwv2);
610 /* we might have to close an old one */
611 if ((tcon_flags & 0x1) && conn) {
612 close_cnum(conn,req->vuid);
617 if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
618 reply_doserror(req, ERRDOS, ERRbuftoosmall);
619 END_PROFILE(SMBtconX);
623 if (global_encrypted_passwords_negotiated) {
624 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
626 if (lp_security() == SEC_SHARE) {
628 * Security = share always has a pad byte
629 * after the password.
631 p = smb_buf(req->inbuf) + passlen + 1;
633 p = smb_buf(req->inbuf) + passlen;
636 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
638 /* Ensure correct termination */
639 password.data[passlen]=0;
640 p = smb_buf(req->inbuf) + passlen + 1;
643 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
647 data_blob_clear_free(&password);
648 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
649 END_PROFILE(SMBtconX);
654 * the service name can be either: \\server\share
655 * or share directly like on the DELL PowerVault 705
658 q = strchr_m(path+2,'\\');
660 data_blob_clear_free(&password);
661 reply_doserror(req, ERRDOS, ERRnosuchshare);
662 END_PROFILE(SMBtconX);
670 p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
671 &client_devicetype, p,
672 MIN(6,smb_bufrem(req->inbuf, p)), STR_ASCII);
674 if (client_devicetype == NULL) {
675 data_blob_clear_free(&password);
676 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
677 END_PROFILE(SMBtconX);
681 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
683 conn = make_connection(service, password, client_devicetype,
684 req->vuid, &nt_status);
687 data_blob_clear_free(&password);
690 reply_nterror(req, nt_status);
691 END_PROFILE(SMBtconX);
696 server_devicetype = "IPC";
697 else if ( IS_PRINT(conn) )
698 server_devicetype = "LPT1:";
700 server_devicetype = "A:";
702 if (Protocol < PROTOCOL_NT1) {
703 reply_outbuf(req, 2, 0);
704 if (message_push_string(&req->outbuf, server_devicetype,
705 STR_TERMINATE|STR_ASCII) == -1) {
706 reply_nterror(req, NT_STATUS_NO_MEMORY);
707 END_PROFILE(SMBtconX);
711 /* NT sets the fstype of IPC$ to the null string */
712 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
714 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
715 /* Return permissions. */
719 reply_outbuf(req, 7, 0);
722 perm1 = FILE_ALL_ACCESS;
723 perm2 = FILE_ALL_ACCESS;
725 perm1 = CAN_WRITE(conn) ?
730 SIVAL(req->outbuf, smb_vwv3, perm1);
731 SIVAL(req->outbuf, smb_vwv5, perm2);
733 reply_outbuf(req, 3, 0);
736 if ((message_push_string(&req->outbuf, server_devicetype,
737 STR_TERMINATE|STR_ASCII) == -1)
738 || (message_push_string(&req->outbuf, fstype,
739 STR_TERMINATE) == -1)) {
740 reply_nterror(req, NT_STATUS_NO_MEMORY);
741 END_PROFILE(SMBtconX);
745 /* what does setting this bit do? It is set by NT4 and
746 may affect the ability to autorun mounted cdroms */
747 SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
748 (lp_csc_policy(SNUM(conn)) << 2));
750 if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) {
751 DEBUG(2,("Serving %s as a Dfs root\n",
752 lp_servicename(SNUM(conn)) ));
753 SSVAL(req->outbuf, smb_vwv2,
754 SMB_SHARE_IN_DFS | SVAL(req->outbuf, smb_vwv2));
759 DEBUG(3,("tconX service=%s \n",
762 /* set the incoming and outgoing tid to the just created one */
763 SSVAL(req->inbuf,smb_tid,conn->cnum);
764 SSVAL(req->outbuf,smb_tid,conn->cnum);
766 END_PROFILE(SMBtconX);
772 /****************************************************************************
773 Reply to an unknown type.
774 ****************************************************************************/
776 void reply_unknown_new(struct smb_request *req, uint8 type)
778 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
779 smb_fn_name(type), type, type));
780 reply_doserror(req, ERRSRV, ERRunknownsmb);
784 /****************************************************************************
786 conn POINTER CAN BE NULL HERE !
787 ****************************************************************************/
789 void reply_ioctl(struct smb_request *req)
791 connection_struct *conn = req->conn;
798 START_PROFILE(SMBioctl);
801 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
802 END_PROFILE(SMBioctl);
806 device = SVAL(req->inbuf,smb_vwv1);
807 function = SVAL(req->inbuf,smb_vwv2);
808 ioctl_code = (device << 16) + function;
810 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
812 switch (ioctl_code) {
813 case IOCTL_QUERY_JOB_INFO:
817 reply_doserror(req, ERRSRV, ERRnosupport);
818 END_PROFILE(SMBioctl);
822 reply_outbuf(req, 8, replysize+1);
823 SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
824 SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
825 SSVAL(req->outbuf,smb_vwv6,52); /* Offset to data */
826 p = smb_buf(req->outbuf);
827 memset(p, '\0', replysize+1); /* valgrind-safe. */
828 p += 1; /* Allow for alignment */
830 switch (ioctl_code) {
831 case IOCTL_QUERY_JOB_INFO:
833 files_struct *fsp = file_fsp(
834 req, SVAL(req->inbuf, smb_vwv0));
836 reply_doserror(req, ERRDOS, ERRbadfid);
837 END_PROFILE(SMBioctl);
840 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
841 srvstr_push((char *)req->outbuf, req->flags2, p+2,
843 STR_TERMINATE|STR_ASCII);
845 srvstr_push((char *)req->outbuf, req->flags2,
846 p+18, lp_servicename(SNUM(conn)),
847 13, STR_TERMINATE|STR_ASCII);
855 END_PROFILE(SMBioctl);
859 /****************************************************************************
860 Strange checkpath NTSTATUS mapping.
861 ****************************************************************************/
863 static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
865 /* Strange DOS error code semantics only for checkpath... */
866 if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
867 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
868 /* We need to map to ERRbadpath */
869 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
875 /****************************************************************************
876 Reply to a checkpath.
877 ****************************************************************************/
879 void reply_checkpath(struct smb_request *req)
881 connection_struct *conn = req->conn;
883 SMB_STRUCT_STAT sbuf;
885 TALLOC_CTX *ctx = talloc_tos();
887 START_PROFILE(SMBcheckpath);
889 srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
890 smb_buf(req->inbuf) + 1, 0,
891 STR_TERMINATE, &status);
892 if (!NT_STATUS_IS_OK(status)) {
893 status = map_checkpath_error((char *)req->inbuf, status);
894 reply_nterror(req, status);
895 END_PROFILE(SMBcheckpath);
899 status = resolve_dfspath(ctx, conn,
900 req->flags2 & FLAGS2_DFS_PATHNAMES,
903 if (!NT_STATUS_IS_OK(status)) {
904 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
905 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
907 END_PROFILE(SMBcheckpath);
913 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
915 status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
916 if (!NT_STATUS_IS_OK(status)) {
920 status = check_name(conn, name);
921 if (!NT_STATUS_IS_OK(status)) {
922 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status)));
926 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
927 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
928 status = map_nt_error_from_unix(errno);
932 if (!S_ISDIR(sbuf.st_mode)) {
933 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
935 END_PROFILE(SMBcheckpath);
939 reply_outbuf(req, 0, 0);
941 END_PROFILE(SMBcheckpath);
946 END_PROFILE(SMBcheckpath);
948 /* We special case this - as when a Windows machine
949 is parsing a path is steps through the components
950 one at a time - if a component fails it expects
951 ERRbadpath, not ERRbadfile.
953 status = map_checkpath_error((char *)req->inbuf, status);
954 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
956 * Windows returns different error codes if
957 * the parent directory is valid but not the
958 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
959 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
960 * if the path is invalid.
962 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
967 reply_nterror(req, status);
970 /****************************************************************************
972 ****************************************************************************/
974 void reply_getatr(struct smb_request *req)
976 connection_struct *conn = req->conn;
978 SMB_STRUCT_STAT sbuf;
984 TALLOC_CTX *ctx = talloc_tos();
986 START_PROFILE(SMBgetatr);
988 p = smb_buf(req->inbuf) + 1;
989 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
990 0, STR_TERMINATE, &status);
991 if (!NT_STATUS_IS_OK(status)) {
992 reply_nterror(req, status);
993 END_PROFILE(SMBgetatr);
997 status = resolve_dfspath(ctx, conn,
998 req->flags2 & FLAGS2_DFS_PATHNAMES,
1001 if (!NT_STATUS_IS_OK(status)) {
1002 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1003 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1004 ERRSRV, ERRbadpath);
1005 END_PROFILE(SMBgetatr);
1008 reply_nterror(req, status);
1009 END_PROFILE(SMBgetatr);
1013 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1014 under WfWg - weird! */
1015 if (*fname == '\0') {
1016 mode = aHIDDEN | aDIR;
1017 if (!CAN_WRITE(conn)) {
1023 status = unix_convert(ctx, conn, fname, False, &fname, NULL,&sbuf);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 reply_nterror(req, status);
1026 END_PROFILE(SMBgetatr);
1029 status = check_name(conn, fname);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
1032 reply_nterror(req, status);
1033 END_PROFILE(SMBgetatr);
1036 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
1037 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
1038 reply_unixerror(req, ERRDOS,ERRbadfile);
1039 END_PROFILE(SMBgetatr);
1043 mode = dos_mode(conn,fname,&sbuf);
1044 size = sbuf.st_size;
1045 mtime = sbuf.st_mtime;
1051 reply_outbuf(req, 10, 0);
1053 SSVAL(req->outbuf,smb_vwv0,mode);
1054 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1055 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1057 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1059 SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1061 if (Protocol >= PROTOCOL_NT1) {
1062 SSVAL(req->outbuf, smb_flg2,
1063 SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1066 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
1068 END_PROFILE(SMBgetatr);
1072 /****************************************************************************
1074 ****************************************************************************/
1076 void reply_setatr(struct smb_request *req)
1078 struct timespec ts[2];
1079 connection_struct *conn = req->conn;
1083 SMB_STRUCT_STAT sbuf;
1086 TALLOC_CTX *ctx = talloc_tos();
1088 START_PROFILE(SMBsetatr);
1093 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1097 p = smb_buf(req->inbuf) + 1;
1098 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
1099 0, STR_TERMINATE, &status);
1100 if (!NT_STATUS_IS_OK(status)) {
1101 reply_nterror(req, status);
1102 END_PROFILE(SMBsetatr);
1106 status = resolve_dfspath(ctx, conn,
1107 req->flags2 & FLAGS2_DFS_PATHNAMES,
1110 if (!NT_STATUS_IS_OK(status)) {
1111 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1112 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1113 ERRSRV, ERRbadpath);
1114 END_PROFILE(SMBsetatr);
1117 reply_nterror(req, status);
1118 END_PROFILE(SMBsetatr);
1122 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
1123 if (!NT_STATUS_IS_OK(status)) {
1124 reply_nterror(req, status);
1125 END_PROFILE(SMBsetatr);
1129 status = check_name(conn, fname);
1130 if (!NT_STATUS_IS_OK(status)) {
1131 reply_nterror(req, status);
1132 END_PROFILE(SMBsetatr);
1136 if (fname[0] == '.' && fname[1] == '\0') {
1138 * Not sure here is the right place to catch this
1139 * condition. Might be moved to somewhere else later -- vl
1141 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1142 END_PROFILE(SMBsetatr);
1146 mode = SVAL(req->inbuf,smb_vwv0);
1147 mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
1149 ts[1] = convert_time_t_to_timespec(mtime);
1150 status = smb_set_file_time(conn, NULL, fname,
1152 if (!NT_STATUS_IS_OK(status)) {
1153 reply_unixerror(req, ERRDOS, ERRnoaccess);
1154 END_PROFILE(SMBsetatr);
1158 if (mode != FILE_ATTRIBUTE_NORMAL) {
1159 if (VALID_STAT_OF_DIR(sbuf))
1164 if (file_set_dosmode(conn,fname,mode,&sbuf,NULL,false) != 0) {
1165 reply_unixerror(req, ERRDOS, ERRnoaccess);
1166 END_PROFILE(SMBsetatr);
1171 reply_outbuf(req, 0, 0);
1173 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1175 END_PROFILE(SMBsetatr);
1179 /****************************************************************************
1181 ****************************************************************************/
1183 void reply_dskattr(struct smb_request *req)
1185 connection_struct *conn = req->conn;
1186 uint64_t dfree,dsize,bsize;
1187 START_PROFILE(SMBdskattr);
1189 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
1190 reply_unixerror(req, ERRHRD, ERRgeneral);
1191 END_PROFILE(SMBdskattr);
1195 reply_outbuf(req, 5, 0);
1197 if (Protocol <= PROTOCOL_LANMAN2) {
1198 double total_space, free_space;
1199 /* we need to scale this to a number that DOS6 can handle. We
1200 use floating point so we can handle large drives on systems
1201 that don't have 64 bit integers
1203 we end up displaying a maximum of 2G to DOS systems
1205 total_space = dsize * (double)bsize;
1206 free_space = dfree * (double)bsize;
1208 dsize = (uint64_t)((total_space+63*512) / (64*512));
1209 dfree = (uint64_t)((free_space+63*512) / (64*512));
1211 if (dsize > 0xFFFF) dsize = 0xFFFF;
1212 if (dfree > 0xFFFF) dfree = 0xFFFF;
1214 SSVAL(req->outbuf,smb_vwv0,dsize);
1215 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1216 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1217 SSVAL(req->outbuf,smb_vwv3,dfree);
1219 SSVAL(req->outbuf,smb_vwv0,dsize);
1220 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1221 SSVAL(req->outbuf,smb_vwv2,512);
1222 SSVAL(req->outbuf,smb_vwv3,dfree);
1225 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1227 END_PROFILE(SMBdskattr);
1231 /****************************************************************************
1233 Can be called from SMBsearch, SMBffirst or SMBfunique.
1234 ****************************************************************************/
1236 void reply_search(struct smb_request *req)
1238 connection_struct *conn = req->conn;
1240 char *directory = NULL;
1246 unsigned int numentries = 0;
1247 unsigned int maxentries = 0;
1248 bool finished = False;
1254 bool check_descend = False;
1255 bool expect_close = False;
1257 bool mask_contains_wcard = False;
1258 bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1259 TALLOC_CTX *ctx = talloc_tos();
1260 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1262 START_PROFILE(SMBsearch);
1265 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1266 END_PROFILE(SMBsearch);
1270 if (lp_posix_pathnames()) {
1271 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1272 END_PROFILE(SMBsearch);
1276 /* If we were called as SMBffirst then we must expect close. */
1277 if(CVAL(req->inbuf,smb_com) == SMBffirst) {
1278 expect_close = True;
1281 reply_outbuf(req, 1, 3);
1282 maxentries = SVAL(req->inbuf,smb_vwv0);
1283 dirtype = SVAL(req->inbuf,smb_vwv1);
1284 p = smb_buf(req->inbuf) + 1;
1285 p += srvstr_get_path_wcard(ctx,
1293 &mask_contains_wcard);
1294 if (!NT_STATUS_IS_OK(nt_status)) {
1295 reply_nterror(req, nt_status);
1296 END_PROFILE(SMBsearch);
1300 nt_status = resolve_dfspath_wcard(ctx, conn,
1301 req->flags2 & FLAGS2_DFS_PATHNAMES,
1304 &mask_contains_wcard);
1305 if (!NT_STATUS_IS_OK(nt_status)) {
1306 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1307 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1308 ERRSRV, ERRbadpath);
1309 END_PROFILE(SMBsearch);
1312 reply_nterror(req, nt_status);
1313 END_PROFILE(SMBsearch);
1318 status_len = SVAL(p, 0);
1321 /* dirtype &= ~aDIR; */
1323 if (status_len == 0) {
1324 SMB_STRUCT_STAT sbuf;
1326 nt_status = unix_convert(ctx, conn, path, True,
1327 &directory, NULL, &sbuf);
1328 if (!NT_STATUS_IS_OK(nt_status)) {
1329 reply_nterror(req, nt_status);
1330 END_PROFILE(SMBsearch);
1334 nt_status = check_name(conn, directory);
1335 if (!NT_STATUS_IS_OK(nt_status)) {
1336 reply_nterror(req, nt_status);
1337 END_PROFILE(SMBsearch);
1341 p = strrchr_m(directory,'/');
1344 directory = talloc_strdup(ctx,".");
1346 reply_nterror(req, NT_STATUS_NO_MEMORY);
1347 END_PROFILE(SMBsearch);
1355 if (*directory == '\0') {
1356 directory = talloc_strdup(ctx,".");
1358 reply_nterror(req, NT_STATUS_NO_MEMORY);
1359 END_PROFILE(SMBsearch);
1363 memset((char *)status,'\0',21);
1364 SCVAL(status,0,(dirtype & 0x1F));
1366 nt_status = dptr_create(conn,
1372 mask_contains_wcard,
1375 if (!NT_STATUS_IS_OK(nt_status)) {
1376 reply_nterror(req, nt_status);
1377 END_PROFILE(SMBsearch);
1380 dptr_num = dptr_dnum(conn->dirptr);
1384 memcpy(status,p,21);
1385 status_dirtype = CVAL(status,0) & 0x1F;
1386 if (status_dirtype != (dirtype & 0x1F)) {
1387 dirtype = status_dirtype;
1390 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1391 if (!conn->dirptr) {
1394 string_set(&conn->dirpath,dptr_path(dptr_num));
1395 mask = dptr_wcard(dptr_num);
1400 * For a 'continue' search we have no string. So
1401 * check from the initial saved string.
1403 mask_contains_wcard = ms_has_wild(mask);
1404 dirtype = dptr_attr(dptr_num);
1407 DEBUG(4,("dptr_num is %d\n",dptr_num));
1409 if ((dirtype&0x1F) == aVOLID) {
1410 char buf[DIR_STRUCT_SIZE];
1411 memcpy(buf,status,21);
1412 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1413 0,aVOLID,0,!allow_long_path_components)) {
1414 reply_nterror(req, NT_STATUS_NO_MEMORY);
1415 END_PROFILE(SMBsearch);
1418 dptr_fill(buf+12,dptr_num);
1419 if (dptr_zero(buf+12) && (status_len==0)) {
1424 if (message_push_blob(&req->outbuf,
1425 data_blob_const(buf, sizeof(buf)))
1427 reply_nterror(req, NT_STATUS_NO_MEMORY);
1428 END_PROFILE(SMBsearch);
1436 ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1439 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1440 conn->dirpath,lp_dontdescend(SNUM(conn))));
1441 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) {
1442 check_descend = True;
1445 for (i=numentries;(i<maxentries) && !finished;i++) {
1446 finished = !get_dir_entry(ctx,
1457 char buf[DIR_STRUCT_SIZE];
1458 memcpy(buf,status,21);
1459 if (!make_dir_struct(ctx,
1466 !allow_long_path_components)) {
1467 reply_nterror(req, NT_STATUS_NO_MEMORY);
1468 END_PROFILE(SMBsearch);
1471 if (!dptr_fill(buf+12,dptr_num)) {
1474 if (message_push_blob(&req->outbuf,
1475 data_blob_const(buf, sizeof(buf)))
1477 reply_nterror(req, NT_STATUS_NO_MEMORY);
1478 END_PROFILE(SMBsearch);
1488 /* If we were called as SMBffirst with smb_search_id == NULL
1489 and no entries were found then return error and close dirptr
1492 if (numentries == 0) {
1493 dptr_close(&dptr_num);
1494 } else if(expect_close && status_len == 0) {
1495 /* Close the dptr - we know it's gone */
1496 dptr_close(&dptr_num);
1499 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1500 if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
1501 dptr_close(&dptr_num);
1504 if ((numentries == 0) && !mask_contains_wcard) {
1505 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1506 END_PROFILE(SMBsearch);
1510 SSVAL(req->outbuf,smb_vwv0,numentries);
1511 SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1512 SCVAL(smb_buf(req->outbuf),0,5);
1513 SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1515 /* The replies here are never long name. */
1516 SSVAL(req->outbuf, smb_flg2,
1517 SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1518 if (!allow_long_path_components) {
1519 SSVAL(req->outbuf, smb_flg2,
1520 SVAL(req->outbuf, smb_flg2)
1521 & (~FLAGS2_LONG_PATH_COMPONENTS));
1524 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1525 SSVAL(req->outbuf, smb_flg2,
1526 (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1529 directory = dptr_path(dptr_num);
1532 DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1533 smb_fn_name(CVAL(req->inbuf,smb_com)),
1535 directory ? directory : "./",
1540 END_PROFILE(SMBsearch);
1544 /****************************************************************************
1545 Reply to a fclose (stop directory search).
1546 ****************************************************************************/
1548 void reply_fclose(struct smb_request *req)
1556 bool path_contains_wcard = False;
1557 TALLOC_CTX *ctx = talloc_tos();
1559 START_PROFILE(SMBfclose);
1561 if (lp_posix_pathnames()) {
1562 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1563 END_PROFILE(SMBfclose);
1567 p = smb_buf(req->inbuf) + 1;
1568 p += srvstr_get_path_wcard(ctx,
1576 &path_contains_wcard);
1577 if (!NT_STATUS_IS_OK(err)) {
1578 reply_nterror(req, err);
1579 END_PROFILE(SMBfclose);
1583 status_len = SVAL(p,0);
1586 if (status_len == 0) {
1587 reply_doserror(req, ERRSRV, ERRsrverror);
1588 END_PROFILE(SMBfclose);
1592 memcpy(status,p,21);
1594 if(dptr_fetch(status+12,&dptr_num)) {
1595 /* Close the dptr - we know it's gone */
1596 dptr_close(&dptr_num);
1599 reply_outbuf(req, 1, 0);
1600 SSVAL(req->outbuf,smb_vwv0,0);
1602 DEBUG(3,("search close\n"));
1604 END_PROFILE(SMBfclose);
1608 /****************************************************************************
1610 ****************************************************************************/
1612 void reply_open(struct smb_request *req)
1614 connection_struct *conn = req->conn;
1620 SMB_STRUCT_STAT sbuf;
1627 uint32 create_disposition;
1628 uint32 create_options = 0;
1630 TALLOC_CTX *ctx = talloc_tos();
1632 START_PROFILE(SMBopen);
1635 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1636 END_PROFILE(SMBopen);
1640 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1641 deny_mode = SVAL(req->inbuf,smb_vwv0);
1642 dos_attr = SVAL(req->inbuf,smb_vwv1);
1644 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1645 smb_buf(req->inbuf)+1, 0,
1646 STR_TERMINATE, &status);
1647 if (!NT_STATUS_IS_OK(status)) {
1648 reply_nterror(req, status);
1649 END_PROFILE(SMBopen);
1653 if (!map_open_params_to_ntcreate(
1654 fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
1655 &share_mode, &create_disposition, &create_options)) {
1656 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1657 END_PROFILE(SMBopen);
1661 status = create_file(conn, /* conn */
1663 0, /* root_dir_fid */
1665 access_mask, /* access_mask */
1666 share_mode, /* share_access */
1667 create_disposition, /* create_disposition*/
1668 create_options, /* create_options */
1669 dos_attr, /* file_attributes */
1670 oplock_request, /* oplock_request */
1671 0, /* allocation_size */
1678 if (!NT_STATUS_IS_OK(status)) {
1679 if (open_was_deferred(req->mid)) {
1680 /* We have re-scheduled this call. */
1681 END_PROFILE(SMBopen);
1684 reply_openerror(req, status);
1685 END_PROFILE(SMBopen);
1689 size = sbuf.st_size;
1690 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1691 mtime = sbuf.st_mtime;
1694 DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
1695 close_file(req, fsp, ERROR_CLOSE);
1696 reply_doserror(req, ERRDOS,ERRnoaccess);
1697 END_PROFILE(SMBopen);
1701 reply_outbuf(req, 7, 0);
1702 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1703 SSVAL(req->outbuf,smb_vwv1,fattr);
1704 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1705 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1707 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1709 SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1710 SSVAL(req->outbuf,smb_vwv6,deny_mode);
1712 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1713 SCVAL(req->outbuf,smb_flg,
1714 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1717 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1718 SCVAL(req->outbuf,smb_flg,
1719 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1721 END_PROFILE(SMBopen);
1725 /****************************************************************************
1726 Reply to an open and X.
1727 ****************************************************************************/
1729 void reply_open_and_X(struct smb_request *req)
1731 connection_struct *conn = req->conn;
1736 /* Breakout the oplock request bits so we can set the
1737 reply bits separately. */
1738 int ex_oplock_request;
1739 int core_oplock_request;
1742 int smb_sattr = SVAL(req->inbuf,smb_vwv4);
1743 uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6);
1748 SMB_STRUCT_STAT sbuf;
1752 uint64_t allocation_size;
1753 ssize_t retval = -1;
1756 uint32 create_disposition;
1757 uint32 create_options = 0;
1758 TALLOC_CTX *ctx = talloc_tos();
1760 START_PROFILE(SMBopenX);
1762 if (req->wct < 15) {
1763 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1764 END_PROFILE(SMBopenX);
1768 open_flags = SVAL(req->inbuf,smb_vwv2);
1769 deny_mode = SVAL(req->inbuf,smb_vwv3);
1770 smb_attr = SVAL(req->inbuf,smb_vwv5);
1771 ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1772 core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1773 oplock_request = ex_oplock_request | core_oplock_request;
1774 smb_ofun = SVAL(req->inbuf,smb_vwv8);
1775 allocation_size = (uint64_t)IVAL(req->inbuf,smb_vwv9);
1777 /* If it's an IPC, pass off the pipe handler. */
1779 if (lp_nt_pipe_support()) {
1780 reply_open_pipe_and_X(conn, req);
1782 reply_doserror(req, ERRSRV, ERRaccess);
1784 END_PROFILE(SMBopenX);
1788 /* XXXX we need to handle passed times, sattr and flags */
1789 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1790 smb_buf(req->inbuf), 0, STR_TERMINATE,
1792 if (!NT_STATUS_IS_OK(status)) {
1793 reply_nterror(req, status);
1794 END_PROFILE(SMBopenX);
1798 if (!map_open_params_to_ntcreate(
1799 fname, deny_mode, smb_ofun, &access_mask,
1800 &share_mode, &create_disposition, &create_options)) {
1801 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1802 END_PROFILE(SMBopenX);
1806 status = create_file(conn, /* conn */
1808 0, /* root_dir_fid */
1810 access_mask, /* access_mask */
1811 share_mode, /* share_access */
1812 create_disposition, /* create_disposition*/
1813 create_options, /* create_options */
1814 smb_attr, /* file_attributes */
1815 oplock_request, /* oplock_request */
1816 0, /* allocation_size */
1820 &smb_action, /* pinfo */
1823 if (!NT_STATUS_IS_OK(status)) {
1824 END_PROFILE(SMBopenX);
1825 if (open_was_deferred(req->mid)) {
1826 /* We have re-scheduled this call. */
1829 reply_openerror(req, status);
1833 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1834 if the file is truncated or created. */
1835 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1836 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1837 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1838 close_file(req, fsp, ERROR_CLOSE);
1839 reply_nterror(req, NT_STATUS_DISK_FULL);
1840 END_PROFILE(SMBopenX);
1843 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1845 close_file(req, fsp, ERROR_CLOSE);
1846 reply_nterror(req, NT_STATUS_DISK_FULL);
1847 END_PROFILE(SMBopenX);
1850 sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
1853 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1854 mtime = sbuf.st_mtime;
1856 close_file(req, fsp, ERROR_CLOSE);
1857 reply_doserror(req, ERRDOS, ERRnoaccess);
1858 END_PROFILE(SMBopenX);
1862 /* If the caller set the extended oplock request bit
1863 and we granted one (by whatever means) - set the
1864 correct bit for extended oplock reply.
1867 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1868 smb_action |= EXTENDED_OPLOCK_GRANTED;
1871 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1872 smb_action |= EXTENDED_OPLOCK_GRANTED;
1875 /* If the caller set the core oplock request bit
1876 and we granted one (by whatever means) - set the
1877 correct bit for core oplock reply.
1880 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1881 reply_outbuf(req, 19, 0);
1883 reply_outbuf(req, 15, 0);
1886 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1887 SCVAL(req->outbuf, smb_flg,
1888 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1891 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1892 SCVAL(req->outbuf, smb_flg,
1893 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1896 SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
1897 SSVAL(req->outbuf,smb_vwv3,fattr);
1898 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1899 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
1901 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
1903 SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size);
1904 SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
1905 SSVAL(req->outbuf,smb_vwv11,smb_action);
1907 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1908 SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
1911 END_PROFILE(SMBopenX);
1916 /****************************************************************************
1917 Reply to a SMBulogoffX.
1918 ****************************************************************************/
1920 void reply_ulogoffX(struct smb_request *req)
1924 START_PROFILE(SMBulogoffX);
1926 vuser = get_valid_user_struct(req->vuid);
1929 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
1933 /* in user level security we are supposed to close any files
1934 open by this user */
1935 if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
1936 file_close_user(req->vuid);
1939 invalidate_vuid(req->vuid);
1941 reply_outbuf(req, 2, 0);
1943 DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
1945 END_PROFILE(SMBulogoffX);
1949 /****************************************************************************
1950 Reply to a mknew or a create.
1951 ****************************************************************************/
1953 void reply_mknew(struct smb_request *req)
1955 connection_struct *conn = req->conn;
1959 struct timespec ts[2];
1961 int oplock_request = 0;
1962 SMB_STRUCT_STAT sbuf;
1964 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
1965 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1966 uint32 create_disposition;
1967 uint32 create_options = 0;
1968 TALLOC_CTX *ctx = talloc_tos();
1970 START_PROFILE(SMBcreate);
1973 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1974 END_PROFILE(SMBcreate);
1978 fattr = SVAL(req->inbuf,smb_vwv0);
1979 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1980 com = SVAL(req->inbuf,smb_com);
1982 ts[1] =convert_time_t_to_timespec(
1983 srv_make_unix_date3(req->inbuf + smb_vwv1));
1986 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1987 smb_buf(req->inbuf) + 1, 0,
1988 STR_TERMINATE, &status);
1989 if (!NT_STATUS_IS_OK(status)) {
1990 reply_nterror(req, status);
1991 END_PROFILE(SMBcreate);
1995 if (fattr & aVOLID) {
1996 DEBUG(0,("Attempt to create file (%s) with volid set - "
1997 "please report this\n", fname));
2000 if(com == SMBmknew) {
2001 /* We should fail if file exists. */
2002 create_disposition = FILE_CREATE;
2004 /* Create if file doesn't exist, truncate if it does. */
2005 create_disposition = FILE_OVERWRITE_IF;
2008 status = create_file(conn, /* conn */
2010 0, /* root_dir_fid */
2012 access_mask, /* access_mask */
2013 share_mode, /* share_access */
2014 create_disposition, /* create_disposition*/
2015 create_options, /* create_options */
2016 fattr, /* file_attributes */
2017 oplock_request, /* oplock_request */
2018 0, /* allocation_size */
2025 if (!NT_STATUS_IS_OK(status)) {
2026 END_PROFILE(SMBcreate);
2027 if (open_was_deferred(req->mid)) {
2028 /* We have re-scheduled this call. */
2031 reply_openerror(req, status);
2035 ts[0] = get_atimespec(&sbuf); /* atime. */
2036 status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true);
2037 if (!NT_STATUS_IS_OK(status)) {
2038 END_PROFILE(SMBcreate);
2039 reply_openerror(req, status);
2043 reply_outbuf(req, 1, 0);
2044 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2046 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2047 SCVAL(req->outbuf,smb_flg,
2048 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2051 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2052 SCVAL(req->outbuf,smb_flg,
2053 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2056 DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) );
2057 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
2058 fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
2060 END_PROFILE(SMBcreate);
2064 /****************************************************************************
2065 Reply to a create temporary file.
2066 ****************************************************************************/
2068 void reply_ctemp(struct smb_request *req)
2070 connection_struct *conn = req->conn;
2076 SMB_STRUCT_STAT sbuf;
2079 TALLOC_CTX *ctx = talloc_tos();
2081 START_PROFILE(SMBctemp);
2084 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2085 END_PROFILE(SMBctemp);
2089 fattr = SVAL(req->inbuf,smb_vwv0);
2090 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2092 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
2093 smb_buf(req->inbuf)+1, 0, STR_TERMINATE,
2095 if (!NT_STATUS_IS_OK(status)) {
2096 reply_nterror(req, status);
2097 END_PROFILE(SMBctemp);
2101 fname = talloc_asprintf(ctx,
2105 fname = talloc_strdup(ctx, "TMXXXXXX");
2109 reply_nterror(req, NT_STATUS_NO_MEMORY);
2110 END_PROFILE(SMBctemp);
2114 status = resolve_dfspath(ctx, conn,
2115 req->flags2 & FLAGS2_DFS_PATHNAMES,
2118 if (!NT_STATUS_IS_OK(status)) {
2119 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2120 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2121 ERRSRV, ERRbadpath);
2122 END_PROFILE(SMBctemp);
2125 reply_nterror(req, status);
2126 END_PROFILE(SMBctemp);
2130 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
2131 if (!NT_STATUS_IS_OK(status)) {
2132 reply_nterror(req, status);
2133 END_PROFILE(SMBctemp);
2137 status = check_name(conn, fname);
2138 if (!NT_STATUS_IS_OK(status)) {
2139 reply_nterror(req, status);
2140 END_PROFILE(SMBctemp);
2144 tmpfd = smb_mkstemp(fname);
2146 reply_unixerror(req, ERRDOS, ERRnoaccess);
2147 END_PROFILE(SMBctemp);
2151 SMB_VFS_STAT(conn,fname,&sbuf);
2153 /* We should fail if file does not exist. */
2154 status = open_file_ntcreate(conn, req, fname, &sbuf,
2155 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
2156 FILE_SHARE_READ|FILE_SHARE_WRITE,
2163 /* close fd from smb_mkstemp() */
2166 if (!NT_STATUS_IS_OK(status)) {
2167 if (open_was_deferred(req->mid)) {
2168 /* We have re-scheduled this call. */
2169 END_PROFILE(SMBctemp);
2172 reply_openerror(req, status);
2173 END_PROFILE(SMBctemp);
2177 reply_outbuf(req, 1, 0);
2178 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2180 /* the returned filename is relative to the directory */
2181 s = strrchr_m(fsp->fsp_name, '/');
2189 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2190 thing in the byte section. JRA */
2191 SSVALS(p, 0, -1); /* what is this? not in spec */
2193 if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2195 reply_nterror(req, NT_STATUS_NO_MEMORY);
2196 END_PROFILE(SMBctemp);
2200 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2201 SCVAL(req->outbuf, smb_flg,
2202 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2205 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2206 SCVAL(req->outbuf, smb_flg,
2207 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2210 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
2211 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
2212 fsp->fh->fd, (unsigned int)sbuf.st_mode ) );
2214 END_PROFILE(SMBctemp);
2218 /*******************************************************************
2219 Check if a user is allowed to rename a file.
2220 ********************************************************************/
2222 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2223 uint16 dirtype, SMB_STRUCT_STAT *pst)
2227 if (!CAN_WRITE(conn)) {
2228 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2231 fmode = dos_mode(conn, fsp->fsp_name, pst);
2232 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
2233 return NT_STATUS_NO_SUCH_FILE;
2236 if (S_ISDIR(pst->st_mode)) {
2237 return NT_STATUS_OK;
2240 if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
2241 return NT_STATUS_OK;
2244 return NT_STATUS_ACCESS_DENIED;
2247 /*******************************************************************
2248 * unlink a file with all relevant access checks
2249 *******************************************************************/
2251 static NTSTATUS do_unlink(connection_struct *conn,
2252 struct smb_request *req,
2256 SMB_STRUCT_STAT sbuf;
2259 uint32 dirtype_orig = dirtype;
2262 DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
2264 if (!CAN_WRITE(conn)) {
2265 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2268 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
2269 return map_nt_error_from_unix(errno);
2272 fattr = dos_mode(conn,fname,&sbuf);
2274 if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2275 dirtype = aDIR|aARCH|aRONLY;
2278 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
2280 return NT_STATUS_NO_SUCH_FILE;
2283 if (!dir_check_ftype(conn, fattr, dirtype)) {
2285 return NT_STATUS_FILE_IS_A_DIRECTORY;
2287 return NT_STATUS_NO_SUCH_FILE;
2290 if (dirtype_orig & 0x8000) {
2291 /* These will never be set for POSIX. */
2292 return NT_STATUS_NO_SUCH_FILE;
2296 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2297 return NT_STATUS_FILE_IS_A_DIRECTORY;
2300 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2301 return NT_STATUS_NO_SUCH_FILE;
2304 if (dirtype & 0xFF00) {
2305 /* These will never be set for POSIX. */
2306 return NT_STATUS_NO_SUCH_FILE;
2311 return NT_STATUS_NO_SUCH_FILE;
2314 /* Can't delete a directory. */
2316 return NT_STATUS_FILE_IS_A_DIRECTORY;
2321 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
2322 return NT_STATUS_OBJECT_NAME_INVALID;
2323 #endif /* JRATEST */
2325 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
2327 On a Windows share, a file with read-only dosmode can be opened with
2328 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
2329 fails with NT_STATUS_CANNOT_DELETE error.
2331 This semantic causes a problem that a user can not
2332 rename a file with read-only dosmode on a Samba share
2333 from a Windows command prompt (i.e. cmd.exe, but can rename
2334 from Windows Explorer).
2337 if (!lp_delete_readonly(SNUM(conn))) {
2338 if (fattr & aRONLY) {
2339 return NT_STATUS_CANNOT_DELETE;
2343 /* On open checks the open itself will check the share mode, so
2344 don't do it here as we'll get it wrong. */
2346 status = create_file_unixpath
2350 DELETE_ACCESS, /* access_mask */
2351 FILE_SHARE_NONE, /* share_access */
2352 FILE_OPEN, /* create_disposition*/
2353 FILE_NON_DIRECTORY_FILE, /* create_options */
2354 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2355 0, /* oplock_request */
2356 0, /* allocation_size */
2363 if (!NT_STATUS_IS_OK(status)) {
2364 DEBUG(10, ("create_file_unixpath failed: %s\n",
2365 nt_errstr(status)));
2369 /* The set is across all open files on this dev/inode pair. */
2370 if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) {
2371 close_file(req, fsp, NORMAL_CLOSE);
2372 return NT_STATUS_ACCESS_DENIED;
2375 return close_file(req, fsp, NORMAL_CLOSE);
2378 /****************************************************************************
2379 The guts of the unlink command, split out so it may be called by the NT SMB
2381 ****************************************************************************/
2383 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2384 uint32 dirtype, const char *name_in, bool has_wild)
2386 const char *directory = NULL;
2391 NTSTATUS status = NT_STATUS_OK;
2392 SMB_STRUCT_STAT sbuf;
2393 TALLOC_CTX *ctx = talloc_tos();
2395 status = unix_convert(ctx, conn, name_in, has_wild, &name, NULL, &sbuf);
2396 if (!NT_STATUS_IS_OK(status)) {
2400 p = strrchr_m(name,'/');
2402 directory = talloc_strdup(ctx, ".");
2404 return NT_STATUS_NO_MEMORY;
2414 * We should only check the mangled cache
2415 * here if unix_convert failed. This means
2416 * that the path in 'mask' doesn't exist
2417 * on the file system and so we need to look
2418 * for a possible mangle. This patch from
2419 * Tine Smukavec <valentin.smukavec@hermes.si>.
2422 if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) {
2423 char *new_mask = NULL;
2424 mangle_lookup_name_from_8_3(ctx,
2434 directory = talloc_asprintf(ctx,
2439 return NT_STATUS_NO_MEMORY;
2442 dirtype = FILE_ATTRIBUTE_NORMAL;
2445 status = check_name(conn, directory);
2446 if (!NT_STATUS_IS_OK(status)) {
2450 status = do_unlink(conn, req, directory, dirtype);
2451 if (!NT_STATUS_IS_OK(status)) {
2457 struct smb_Dir *dir_hnd = NULL;
2461 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2462 return NT_STATUS_OBJECT_NAME_INVALID;
2465 if (strequal(mask,"????????.???")) {
2470 status = check_name(conn, directory);
2471 if (!NT_STATUS_IS_OK(status)) {
2475 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask,
2477 if (dir_hnd == NULL) {
2478 return map_nt_error_from_unix(errno);
2481 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2482 the pattern matches against the long name, otherwise the short name
2483 We don't implement this yet XXXX
2486 status = NT_STATUS_NO_SUCH_FILE;
2488 while ((dname = ReadDirName(dir_hnd, &offset))) {
2492 if (!is_visible_file(conn, directory, dname, &st, True)) {
2496 /* Quick check for "." and ".." */
2497 if (ISDOT(dname) || ISDOTDOT(dname)) {
2501 if(!mask_match(dname, mask, conn->case_sensitive)) {
2505 fname = talloc_asprintf(ctx, "%s/%s",
2509 return NT_STATUS_NO_MEMORY;
2512 status = check_name(conn, fname);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 TALLOC_FREE(dir_hnd);
2518 status = do_unlink(conn, req, fname, dirtype);
2519 if (!NT_STATUS_IS_OK(status)) {
2525 DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2530 TALLOC_FREE(dir_hnd);
2533 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
2534 status = map_nt_error_from_unix(errno);
2540 /****************************************************************************
2542 ****************************************************************************/
2544 void reply_unlink(struct smb_request *req)
2546 connection_struct *conn = req->conn;
2550 bool path_contains_wcard = False;
2551 TALLOC_CTX *ctx = talloc_tos();
2553 START_PROFILE(SMBunlink);
2556 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2557 END_PROFILE(SMBunlink);
2561 dirtype = SVAL(req->inbuf,smb_vwv0);
2563 srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
2564 smb_buf(req->inbuf) + 1, 0,
2565 STR_TERMINATE, &status, &path_contains_wcard);
2566 if (!NT_STATUS_IS_OK(status)) {
2567 reply_nterror(req, status);
2568 END_PROFILE(SMBunlink);
2572 status = resolve_dfspath_wcard(ctx, conn,
2573 req->flags2 & FLAGS2_DFS_PATHNAMES,
2576 &path_contains_wcard);
2577 if (!NT_STATUS_IS_OK(status)) {
2578 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2579 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2580 ERRSRV, ERRbadpath);
2581 END_PROFILE(SMBunlink);
2584 reply_nterror(req, status);
2585 END_PROFILE(SMBunlink);
2589 DEBUG(3,("reply_unlink : %s\n",name));
2591 status = unlink_internals(conn, req, dirtype, name,
2592 path_contains_wcard);
2593 if (!NT_STATUS_IS_OK(status)) {
2594 if (open_was_deferred(req->mid)) {
2595 /* We have re-scheduled this call. */
2596 END_PROFILE(SMBunlink);
2599 reply_nterror(req, status);
2600 END_PROFILE(SMBunlink);
2604 reply_outbuf(req, 0, 0);
2605 END_PROFILE(SMBunlink);
2610 /****************************************************************************
2612 ****************************************************************************/
2614 static void fail_readraw(void)
2616 const char *errstr = talloc_asprintf(talloc_tos(),
2617 "FAIL ! reply_readbraw: socket write fail (%s)",
2622 exit_server_cleanly(errstr);
2625 /****************************************************************************
2626 Fake (read/write) sendfile. Returns -1 on read or write fail.
2627 ****************************************************************************/
2629 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
2633 size_t tosend = nread;
2640 bufsize = MIN(nread, 65536);
2642 if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2646 while (tosend > 0) {
2650 if (tosend > bufsize) {
2655 ret = read_file(fsp,buf,startpos,cur_read);
2661 /* If we had a short read, fill with zeros. */
2662 if (ret < cur_read) {
2663 memset(buf, '\0', cur_read - ret);
2666 if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
2671 startpos += cur_read;
2675 return (ssize_t)nread;
2678 /****************************************************************************
2679 Return a readbraw error (4 bytes of zero).
2680 ****************************************************************************/
2682 static void reply_readbraw_error(void)
2686 if (write_data(smbd_server_fd(),header,4) != 4) {
2691 /****************************************************************************
2692 Use sendfile in readbraw.
2693 ****************************************************************************/
2695 void send_file_readbraw(connection_struct *conn,
2701 char *outbuf = NULL;
2704 #if defined(WITH_SENDFILE)
2706 * We can only use sendfile on a non-chained packet
2707 * but we can use on a non-oplocked file. tridge proved this
2708 * on a train in Germany :-). JRA.
2709 * reply_readbraw has already checked the length.
2712 if ( (chain_size == 0) && (nread > 0) && (fsp->base_fsp == NULL) &&
2713 (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
2715 DATA_BLOB header_blob;
2717 _smb_setlen(header,nread);
2718 header_blob = data_blob_const(header, 4);
2720 if (SMB_VFS_SENDFILE(smbd_server_fd(), fsp,
2721 &header_blob, startpos, nread) == -1) {
2722 /* Returning ENOSYS means no data at all was sent.
2723 * Do this as a normal read. */
2724 if (errno == ENOSYS) {
2725 goto normal_readbraw;
2729 * Special hack for broken Linux with no working sendfile. If we
2730 * return EINTR we sent the header but not the rest of the data.
2731 * Fake this up by doing read/write calls.
2733 if (errno == EINTR) {
2734 /* Ensure we don't do this again. */
2735 set_use_sendfile(SNUM(conn), False);
2736 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2738 if (fake_sendfile(fsp, startpos, nread) == -1) {
2739 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2740 fsp->fsp_name, strerror(errno) ));
2741 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2746 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2747 fsp->fsp_name, strerror(errno) ));
2748 exit_server_cleanly("send_file_readbraw sendfile failed");
2757 outbuf = TALLOC_ARRAY(NULL, char, nread+4);
2759 DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
2760 (unsigned)(nread+4)));
2761 reply_readbraw_error();
2766 ret = read_file(fsp,outbuf+4,startpos,nread);
2767 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2776 _smb_setlen(outbuf,ret);
2777 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2780 TALLOC_FREE(outbuf);
2783 /****************************************************************************
2784 Reply to a readbraw (core+ protocol).
2785 ****************************************************************************/
2787 void reply_readbraw(struct smb_request *req)
2789 connection_struct *conn = req->conn;
2790 ssize_t maxcount,mincount;
2797 START_PROFILE(SMBreadbraw);
2799 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
2800 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
2801 "raw reads/writes are disallowed.");
2805 reply_readbraw_error();
2806 END_PROFILE(SMBreadbraw);
2811 * Special check if an oplock break has been issued
2812 * and the readraw request croses on the wire, we must
2813 * return a zero length response here.
2816 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
2819 * We have to do a check_fsp by hand here, as
2820 * we must always return 4 zero bytes on error,
2824 if (!fsp || !conn || conn != fsp->conn ||
2825 req->vuid != fsp->vuid ||
2826 fsp->is_directory || fsp->fh->fd == -1) {
2828 * fsp could be NULL here so use the value from the packet. JRA.
2830 DEBUG(3,("reply_readbraw: fnum %d not valid "
2832 (int)SVAL(req->inbuf,smb_vwv0)));
2833 reply_readbraw_error();
2834 END_PROFILE(SMBreadbraw);
2838 /* Do a "by hand" version of CHECK_READ. */
2839 if (!(fsp->can_read ||
2840 ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
2841 (fsp->access_mask & FILE_EXECUTE)))) {
2842 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
2843 (int)SVAL(req->inbuf,smb_vwv0)));
2844 reply_readbraw_error();
2845 END_PROFILE(SMBreadbraw);
2849 flush_write_cache(fsp, READRAW_FLUSH);
2851 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
2852 if(req->wct == 10) {
2854 * This is a large offset (64 bit) read.
2856 #ifdef LARGE_SMB_OFF_T
2858 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
2860 #else /* !LARGE_SMB_OFF_T */
2863 * Ensure we haven't been sent a >32 bit offset.
2866 if(IVAL(req->inbuf,smb_vwv8) != 0) {
2867 DEBUG(0,("reply_readbraw: large offset "
2868 "(%x << 32) used and we don't support "
2869 "64 bit offsets.\n",
2870 (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
2871 reply_readbraw_error();
2872 END_PROFILE(SMBreadbraw);
2876 #endif /* LARGE_SMB_OFF_T */
2879 DEBUG(0,("reply_readbraw: negative 64 bit "
2880 "readraw offset (%.0f) !\n",
2881 (double)startpos ));
2882 reply_readbraw_error();
2883 END_PROFILE(SMBreadbraw);
2888 maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
2889 mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
2891 /* ensure we don't overrun the packet size */
2892 maxcount = MIN(65535,maxcount);
2894 if (is_locked(fsp,(uint32)req->smbpid,
2898 reply_readbraw_error();
2899 END_PROFILE(SMBreadbraw);
2903 if (SMB_VFS_FSTAT(fsp, &st) == 0) {
2907 if (startpos >= size) {
2910 nread = MIN(maxcount,(size - startpos));
2913 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2914 if (nread < mincount)
2918 DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
2919 "min=%lu nread=%lu\n",
2920 fsp->fnum, (double)startpos,
2921 (unsigned long)maxcount,
2922 (unsigned long)mincount,
2923 (unsigned long)nread ) );
2925 send_file_readbraw(conn, fsp, startpos, nread, mincount);
2927 DEBUG(5,("reply_readbraw finished\n"));
2928 END_PROFILE(SMBreadbraw);
2932 #define DBGC_CLASS DBGC_LOCKING
2934 /****************************************************************************
2935 Reply to a lockread (core+ protocol).
2936 ****************************************************************************/
2938 void reply_lockread(struct smb_request *req)
2940 connection_struct *conn = req->conn;
2947 struct byte_range_lock *br_lck = NULL;
2950 START_PROFILE(SMBlockread);
2953 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2954 END_PROFILE(SMBlockread);
2958 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
2960 if (!check_fsp(conn, req, fsp)) {
2961 END_PROFILE(SMBlockread);
2965 if (!CHECK_READ(fsp,req->inbuf)) {
2966 reply_doserror(req, ERRDOS, ERRbadaccess);
2967 END_PROFILE(SMBlockread);
2971 release_level_2_oplocks_on_change(fsp);
2973 numtoread = SVAL(req->inbuf,smb_vwv1);
2974 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
2976 numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
2978 reply_outbuf(req, 5, numtoread + 3);
2980 data = smb_buf(req->outbuf) + 3;
2983 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2984 * protocol request that predates the read/write lock concept.
2985 * Thus instead of asking for a read lock here we need to ask
2986 * for a write lock. JRA.
2987 * Note that the requested lock size is unaffected by max_recv.
2990 br_lck = do_lock(smbd_messaging_context(),
2993 (uint64_t)numtoread,
2997 False, /* Non-blocking lock. */
3000 TALLOC_FREE(br_lck);
3002 if (NT_STATUS_V(status)) {
3003 reply_nterror(req, status);
3004 END_PROFILE(SMBlockread);
3009 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
3012 if (numtoread > max_recv) {
3013 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
3014 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3015 (unsigned int)numtoread, (unsigned int)max_recv ));
3016 numtoread = MIN(numtoread,max_recv);
3018 nread = read_file(fsp,data,startpos,numtoread);
3021 reply_unixerror(req, ERRDOS, ERRnoaccess);
3022 END_PROFILE(SMBlockread);
3026 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3028 SSVAL(req->outbuf,smb_vwv0,nread);
3029 SSVAL(req->outbuf,smb_vwv5,nread+3);
3030 p = smb_buf(req->outbuf);
3031 SCVAL(p,0,0); /* pad byte. */
3034 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
3035 fsp->fnum, (int)numtoread, (int)nread));
3037 END_PROFILE(SMBlockread);
3042 #define DBGC_CLASS DBGC_ALL
3044 /****************************************************************************
3046 ****************************************************************************/
3048 void reply_read(struct smb_request *req)
3050 connection_struct *conn = req->conn;
3058 START_PROFILE(SMBread);
3061 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3062 END_PROFILE(SMBread);
3066 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
3068 if (!check_fsp(conn, req, fsp)) {
3069 END_PROFILE(SMBread);
3073 if (!CHECK_READ(fsp,req->inbuf)) {
3074 reply_doserror(req, ERRDOS, ERRbadaccess);
3075 END_PROFILE(SMBread);
3079 numtoread = SVAL(req->inbuf,smb_vwv1);
3080 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3082 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
3085 * The requested read size cannot be greater than max_recv. JRA.
3087 if (numtoread > max_recv) {
3088 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
3089 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3090 (unsigned int)numtoread, (unsigned int)max_recv ));
3091 numtoread = MIN(numtoread,max_recv);
3094 reply_outbuf(req, 5, numtoread+3);
3096 data = smb_buf(req->outbuf) + 3;
3098 if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtoread,
3099 (uint64_t)startpos, READ_LOCK)) {
3100 reply_doserror(req, ERRDOS,ERRlock);
3101 END_PROFILE(SMBread);
3106 nread = read_file(fsp,data,startpos,numtoread);
3109 reply_unixerror(req, ERRDOS,ERRnoaccess);
3110 END_PROFILE(SMBread);
3114 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3116 SSVAL(req->outbuf,smb_vwv0,nread);
3117 SSVAL(req->outbuf,smb_vwv5,nread+3);
3118 SCVAL(smb_buf(req->outbuf),0,1);
3119 SSVAL(smb_buf(req->outbuf),1,nread);
3121 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
3122 fsp->fnum, (int)numtoread, (int)nread ) );
3124 END_PROFILE(SMBread);
3128 /****************************************************************************
3130 ****************************************************************************/
3132 static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
3137 outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
3138 data = smb_buf(outbuf);
3140 memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
3142 SCVAL(outbuf,smb_vwv0,0xFF);
3143 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
3144 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
3145 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
3146 SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
3147 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
3148 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
3149 _smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
3153 /****************************************************************************
3154 Reply to a read and X - possibly using sendfile.
3155 ****************************************************************************/
3157 static void send_file_readX(connection_struct *conn, struct smb_request *req,
3158 files_struct *fsp, SMB_OFF_T startpos,
3161 SMB_STRUCT_STAT sbuf;
3164 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
3165 reply_unixerror(req, ERRDOS, ERRnoaccess);
3169 if (startpos > sbuf.st_size) {
3171 } else if (smb_maxcnt > (sbuf.st_size - startpos)) {
3172 smb_maxcnt = (sbuf.st_size - startpos);
3175 if (smb_maxcnt == 0) {
3179 #if defined(WITH_SENDFILE)
3181 * We can only use sendfile on a non-chained packet
3182 * but we can use on a non-oplocked file. tridge proved this
3183 * on a train in Germany :-). JRA.
3186 if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
3187 !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
3188 lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
3189 uint8 headerbuf[smb_size + 12 * 2];
3193 * Set up the packet header before send. We
3194 * assume here the sendfile will work (get the
3195 * correct amount of data).
3198 header = data_blob_const(headerbuf, sizeof(headerbuf));
3200 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3201 setup_readX_header((char *)headerbuf, smb_maxcnt);
3203 if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
3204 /* Returning ENOSYS or EINVAL means no data at all was sent.
3205 Do this as a normal read. */
3206 if (errno == ENOSYS || errno == EINVAL) {
3211 * Special hack for broken Linux with no working sendfile. If we
3212 * return EINTR we sent the header but not the rest of the data.
3213 * Fake this up by doing read/write calls.
3216 if (errno == EINTR) {
3217 /* Ensure we don't do this again. */
3218 set_use_sendfile(SNUM(conn), False);
3219 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
3220 nread = fake_sendfile(fsp, startpos,
3223 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3224 fsp->fsp_name, strerror(errno) ));
3225 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3227 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
3228 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3229 /* No outbuf here means successful sendfile. */
3230 TALLOC_FREE(req->outbuf);
3234 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
3235 fsp->fsp_name, strerror(errno) ));
3236 exit_server_cleanly("send_file_readX sendfile failed");
3239 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
3240 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3241 /* No outbuf here means successful sendfile. */
3242 TALLOC_FREE(req->outbuf);
3249 if ((smb_maxcnt & 0xFF0000) > 0x10000) {
3250 uint8 headerbuf[smb_size + 2*12];
3252 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3253 setup_readX_header((char *)headerbuf, smb_maxcnt);
3255 /* Send out the header. */
3256 if (write_data(smbd_server_fd(), (char *)headerbuf,
3257 sizeof(headerbuf)) != sizeof(headerbuf)) {
3258 DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
3259 fsp->fsp_name, strerror(errno) ));
3260 exit_server_cleanly("send_file_readX sendfile failed");
3262 nread = fake_sendfile(fsp, startpos, smb_maxcnt);
3264 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3265 fsp->fsp_name, strerror(errno) ));
3266 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3268 TALLOC_FREE(req->outbuf);
3272 reply_outbuf(req, 12, smb_maxcnt);
3274 nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
3276 reply_unixerror(req, ERRDOS, ERRnoaccess);
3280 setup_readX_header((char *)req->outbuf, nread);
3282 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
3283 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3288 /****************************************************************************
3289 Reply to a read and X.
3290 ****************************************************************************/
3292 void reply_read_and_X(struct smb_request *req)
3294 connection_struct *conn = req->conn;
3298 bool big_readX = False;
3300 size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
3303 START_PROFILE(SMBreadX);
3305 if ((req->wct != 10) && (req->wct != 12)) {
3306 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3310 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
3311 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3312 smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
3314 /* If it's an IPC, pass off the pipe handler. */
3316 reply_pipe_read_and_X(req);
3317 END_PROFILE(SMBreadX);
3321 if (!check_fsp(conn, req, fsp)) {
3322 END_PROFILE(SMBreadX);
3326 if (!CHECK_READ(fsp,req->inbuf)) {
3327 reply_doserror(req, ERRDOS,ERRbadaccess);
3328 END_PROFILE(SMBreadX);
3332 if (global_client_caps & CAP_LARGE_READX) {
3333 size_t upper_size = SVAL(req->inbuf,smb_vwv7);
3334 smb_maxcnt |= (upper_size<<16);
3335 if (upper_size > 1) {
3336 /* Can't do this on a chained packet. */
3337 if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) {
3338 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3339 END_PROFILE(SMBreadX);
3342 /* We currently don't do this on signed or sealed data. */
3343 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
3344 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3345 END_PROFILE(SMBreadX);
3348 /* Is there room in the reply for this data ? */
3349 if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
3351 NT_STATUS_INVALID_PARAMETER);
3352 END_PROFILE(SMBreadX);
3359 if (req->wct == 12) {
3360 #ifdef LARGE_SMB_OFF_T
3362 * This is a large offset (64 bit) read.
3364 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32);
3366 #else /* !LARGE_SMB_OFF_T */
3369 * Ensure we haven't been sent a >32 bit offset.
3372 if(IVAL(req->inbuf,smb_vwv10) != 0) {
3373 DEBUG(0,("reply_read_and_X - large offset (%x << 32) "
3374 "used and we don't support 64 bit offsets.\n",
3375 (unsigned int)IVAL(req->inbuf,smb_vwv10) ));
3376 END_PROFILE(SMBreadX);
3377 reply_doserror(req, ERRDOS, ERRbadaccess);
3381 #endif /* LARGE_SMB_OFF_T */
3385 if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)smb_maxcnt,
3386 (uint64_t)startpos, READ_LOCK)) {
3387 END_PROFILE(SMBreadX);
3388 reply_doserror(req, ERRDOS, ERRlock);
3393 schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
3394 END_PROFILE(SMBreadX);
3398 send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
3400 END_PROFILE(SMBreadX);
3404 /****************************************************************************
3405 Error replies to writebraw must have smb_wct == 1. Fix this up.
3406 ****************************************************************************/
3408 void error_to_writebrawerr(struct smb_request *req)
3410 uint8 *old_outbuf = req->outbuf;
3412 reply_outbuf(req, 1, 0);
3414 memcpy(req->outbuf, old_outbuf, smb_size);
3415 TALLOC_FREE(old_outbuf);
3418 /****************************************************************************
3419 Reply to a writebraw (core+ or LANMAN1.0 protocol).
3420 ****************************************************************************/
3422 void reply_writebraw(struct smb_request *req)
3424 connection_struct *conn = req->conn;
3427 ssize_t total_written=0;
3428 size_t numtowrite=0;
3436 START_PROFILE(SMBwritebraw);
3439 * If we ever reply with an error, it must have the SMB command
3440 * type of SMBwritec, not SMBwriteBraw, as this tells the client
3443 SCVAL(req->inbuf,smb_com,SMBwritec);
3445 if (srv_is_signing_active()) {
3446 END_PROFILE(SMBwritebraw);
3447 exit_server_cleanly("reply_writebraw: SMB signing is active - "
3448 "raw reads/writes are disallowed.");
3451 if (req->wct < 12) {
3452 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3453 error_to_writebrawerr(req);
3454 END_PROFILE(SMBwritebraw);
3458 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
3459 if (!check_fsp(conn, req, fsp)) {
3460 error_to_writebrawerr(req);
3461 END_PROFILE(SMBwritebraw);
3465 if (!CHECK_WRITE(fsp)) {
3466 reply_doserror(req, ERRDOS, ERRbadaccess);
3467 error_to_writebrawerr(req);
3468 END_PROFILE(SMBwritebraw);
3472 tcount = IVAL(req->inbuf,smb_vwv1);
3473 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3474 write_through = BITSETW(req->inbuf+smb_vwv7,0);
3476 /* We have to deal with slightly different formats depending
3477 on whether we are using the core+ or lanman1.0 protocol */
3479 if(Protocol <= PROTOCOL_COREPLUS) {
3480 numtowrite = SVAL(smb_buf(req->inbuf),-2);
3481 data = smb_buf(req->inbuf);
3483 numtowrite = SVAL(req->inbuf,smb_vwv10);
3484 data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11);
3487 /* Ensure we don't write bytes past the end of this packet. */
3488 if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) {
3489 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3490 error_to_writebrawerr(req);
3491 END_PROFILE(SMBwritebraw);
3495 if (is_locked(fsp,(uint32)req->smbpid,(uint64_t)tcount,
3496 (uint64_t)startpos, WRITE_LOCK)) {
3497 reply_doserror(req, ERRDOS, ERRlock);
3498 error_to_writebrawerr(req);
3499 END_PROFILE(SMBwritebraw);
3504 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3507 DEBUG(3,("reply_writebraw: initial write fnum=%d start=%.0f num=%d "
3508 "wrote=%d sync=%d\n",
3509 fsp->fnum, (double)startpos, (int)numtowrite,
3510 (int)nwritten, (int)write_through));
3512 if (nwritten < (ssize_t)numtowrite) {
3513 reply_unixerror(req, ERRHRD, ERRdiskfull);
3514 error_to_writebrawerr(req);
3515 END_PROFILE(SMBwritebraw);
3519 total_written = nwritten;
3521 /* Allocate a buffer of 64k + length. */
3522 buf = TALLOC_ARRAY(NULL, char, 65540);
3524 reply_doserror(req, ERRDOS, ERRnomem);
3525 error_to_writebrawerr(req);
3526 END_PROFILE(SMBwritebraw);
3530 /* Return a SMBwritebraw message to the redirector to tell
3531 * it to send more bytes */
3533 memcpy(buf, req->inbuf, smb_size);
3534 srv_set_message(buf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
3535 SCVAL(buf,smb_com,SMBwritebraw);
3536 SSVALS(buf,smb_vwv0,0xFFFF);
3538 if (!srv_send_smb(smbd_server_fd(),
3540 IS_CONN_ENCRYPTED(conn))) {
3541 exit_server_cleanly("reply_writebraw: srv_send_smb "
3545 /* Now read the raw data into the buffer and write it */
3546 status = read_smb_length(smbd_server_fd(), buf, SMB_SECONDARY_WAIT,
3548 if (!NT_STATUS_IS_OK(status)) {
3549 exit_server_cleanly("secondary writebraw failed");
3552 /* Set up outbuf to return the correct size */
3553 reply_outbuf(req, 1, 0);
3555 if (numtowrite != 0) {
3557 if (numtowrite > 0xFFFF) {
3558 DEBUG(0,("reply_writebraw: Oversize secondary write "
3559 "raw requested (%u). Terminating\n",
3560 (unsigned int)numtowrite ));
3561 exit_server_cleanly("secondary writebraw failed");
3564 if (tcount > nwritten+numtowrite) {
3565 DEBUG(3,("reply_writebraw: Client overestimated the "
3567 (int)tcount,(int)nwritten,(int)numtowrite));
3570 status = read_data(smbd_server_fd(), buf+4, numtowrite);
3572 if (!NT_STATUS_IS_OK(status)) {
3573 DEBUG(0,("reply_writebraw: Oversize secondary write "
3574 "raw read failed (%s). Terminating\n",
3575 nt_errstr(status)));
3576 exit_server_cleanly("secondary writebraw failed");
3579 nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
3580 if (nwritten == -1) {
3582 reply_unixerror(req, ERRHRD, ERRdiskfull);
3583 error_to_writebrawerr(req);
3584 END_PROFILE(SMBwritebraw);
3588 if (nwritten < (ssize_t)numtowrite) {
3589 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3590 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3594 total_written += nwritten;
3599 SSVAL(req->outbuf,smb_vwv0,total_written);
3601 status = sync_file(conn, fsp, write_through);
3602 if (!NT_STATUS_IS_OK(status)) {
3603 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
3604 fsp->fsp_name, nt_errstr(status) ));
3605 reply_nterror(req, status);
3606 error_to_writebrawerr(req);
3607 END_PROFILE(SMBwritebraw);
3611 DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
3613 fsp->fnum, (double)startpos, (int)numtowrite,
3614 (int)total_written));
3616 /* We won't return a status if write through is not selected - this
3617 * follows what WfWg does */
3618 END_PROFILE(SMBwritebraw);
3620 if (!write_through && total_written==tcount) {
3622 #if RABBIT_PELLET_FIX
3624 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
3625 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this.
3628 if (!send_keepalive(smbd_server_fd())) {
3629 exit_server_cleanly("reply_writebraw: send of "
3630 "keepalive failed");
3633 TALLOC_FREE(req->outbuf);
3639 #define DBGC_CLASS DBGC_LOCKING
3641 /****************************************************************************
3642 Reply to a writeunlock (core+).
3643 ****************************************************************************/
3645 void reply_writeunlock(struct smb_request *req)
3647 connection_struct *conn = req->conn;
3648 ssize_t nwritten = -1;
3652 NTSTATUS status = NT_STATUS_OK;
3655 START_PROFILE(SMBwriteunlock);
3658 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3659 END_PROFILE(SMBwriteunlock);
3663 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
3665 if (!check_fsp(conn, req, fsp)) {
3666 END_PROFILE(SMBwriteunlock);
3670 if (!CHECK_WRITE(fsp)) {
3671 reply_doserror(req, ERRDOS,ERRbadaccess);
3672 END_PROFILE(SMBwriteunlock);
3676 numtowrite = SVAL(req->inbuf,smb_vwv1);
3677 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3678 data = smb_buf(req->inbuf) + 3;
3681 && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
3682 (uint64_t)startpos, WRITE_LOCK)) {
3683 reply_doserror(req, ERRDOS, ERRlock);
3684 END_PROFILE(SMBwriteunlock);
3688 /* The special X/Open SMB protocol handling of
3689 zero length writes is *NOT* done for
3691 if(numtowrite == 0) {
3694 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3697 status = sync_file(conn, fsp, False /* write through */);
3698 if (!NT_STATUS_IS_OK(status)) {
3699 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
3700 fsp->fsp_name, nt_errstr(status) ));
3701 reply_nterror(req, status);
3702 END_PROFILE(SMBwriteunlock);
3706 if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
3707 reply_unixerror(req, ERRHRD, ERRdiskfull);
3708 END_PROFILE(SMBwriteunlock);
3713 status = do_unlock(smbd_messaging_context(),
3716 (uint64_t)numtowrite,
3720 if (NT_STATUS_V(status)) {
3721 reply_nterror(req, status);
3722 END_PROFILE(SMBwriteunlock);
3727 reply_outbuf(req, 1, 0);
3729 SSVAL(req->outbuf,smb_vwv0,nwritten);
3731 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
3732 fsp->fnum, (int)numtowrite, (int)nwritten));
3734 END_PROFILE(SMBwriteunlock);
3739 #define DBGC_CLASS DBGC_ALL
3741 /****************************************************************************
3743 ****************************************************************************/
3745 void reply_write(struct smb_request *req)
3747 connection_struct *conn = req->conn;
3749 ssize_t nwritten = -1;
3755 START_PROFILE(SMBwrite);
3758 END_PROFILE(SMBwrite);
3759 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3763 /* If it's an IPC, pass off the pipe handler. */
3765 reply_pipe_write(req);
3766 END_PROFILE(SMBwrite);
3770 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
3772 if (!check_fsp(conn, req, fsp)) {
3773 END_PROFILE(SMBwrite);
3777 if (!CHECK_WRITE(fsp)) {
3778 reply_doserror(req, ERRDOS, ERRbadaccess);
3779 END_PROFILE(SMBwrite);
3783 numtowrite = SVAL(req->inbuf,smb_vwv1);
3784 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3785 data = smb_buf(req->inbuf) + 3;
3787 if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
3788 (uint64_t)startpos, WRITE_LOCK)) {
3789 reply_doserror(req, ERRDOS, ERRlock);
3790 END_PROFILE(SMBwrite);
3795 * X/Open SMB protocol says that if smb_vwv1 is
3796 * zero then the file size should be extended or
3797 * truncated to the size given in smb_vwv[2-3].
3800 if(numtowrite == 0) {
3802 * This is actually an allocate call, and set EOF. JRA.
3804 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
3806 reply_nterror(req, NT_STATUS_DISK_FULL);
3807 END_PROFILE(SMBwrite);
3810 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
3812 reply_nterror(req, NT_STATUS_DISK_FULL);
3813 END_PROFILE(SMBwrite);
3816 trigger_write_time_update_immediate(fsp);
3818 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3821 status = sync_file(conn, fsp, False);
3822 if (!NT_STATUS_IS_OK(status)) {
3823 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
3824 fsp->fsp_name, nt_errstr(status) ));
3825 reply_nterror(req, status);
3826 END_PROFILE(SMBwrite);
3830 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3831 reply_unixerror(req, ERRHRD, ERRdiskfull);
3832 END_PROFILE(SMBwrite);
3836 reply_outbuf(req, 1, 0);
3838 SSVAL(req->outbuf,smb_vwv0,nwritten);
3840 if (nwritten < (ssize_t)numtowrite) {
3841 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3842 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3845 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
3847 END_PROFILE(SMBwrite);
3851 /****************************************************************************
3852 Ensure a buffer is a valid writeX for recvfile purposes.
3853 ****************************************************************************/
3855 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
3856 (2*14) + /* word count (including bcc) */ \
3859 bool is_valid_writeX_buffer(const uint8_t *inbuf)
3862 connection_struct *conn = NULL;
3863 unsigned int doff = 0;
3864 size_t len = smb_len_large(inbuf);
3866 if (is_encrypted_packet(inbuf)) {
3867 /* Can't do this on encrypted
3872 if (CVAL(inbuf,smb_com) != SMBwriteX) {
3876 if (CVAL(inbuf,smb_vwv0) != 0xFF ||
3877 CVAL(inbuf,smb_wct) != 14) {
3878 DEBUG(10,("is_valid_writeX_buffer: chained or "
3879 "invalid word length.\n"));
3883 conn = conn_find(SVAL(inbuf, smb_tid));
3885 DEBUG(10,("is_valid_writeX_buffer: bad tid\n"));
3889 DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
3892 doff = SVAL(inbuf,smb_vwv11);
3894 numtowrite = SVAL(inbuf,smb_vwv10);
3896 if (len > doff && len - doff > 0xFFFF) {
3897 numtowrite |= (((size_t)SVAL(inbuf,smb_vwv9))<<16);
3900 if (numtowrite == 0) {
3901 DEBUG(10,("is_valid_writeX_buffer: zero write\n"));
3905 /* Ensure the sizes match up. */
3906 if (doff < STANDARD_WRITE_AND_X_HEADER_SIZE) {
3907 /* no pad byte...old smbclient :-( */
3908 DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n",
3910 (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE));
3914 if (len - doff != numtowrite) {
3915 DEBUG(10,("is_valid_writeX_buffer: doff mismatch "
3916 "len = %u, doff = %u, numtowrite = %u\n",
3919 (unsigned int)numtowrite ));
3923 DEBUG(10,("is_valid_writeX_buffer: true "
3924 "len = %u, doff = %u, numtowrite = %u\n",
3927 (unsigned int)numtowrite ));
3932 /****************************************************************************
3933 Reply to a write and X.
3934 ****************************************************************************/
3936 void reply_write_and_X(struct smb_request *req)
3938 connection_struct *conn = req->conn;
3944 unsigned int smb_doff;
3945 unsigned int smblen;
3949 START_PROFILE(SMBwriteX);
3951 if ((req->wct != 12) && (req->wct != 14)) {
3952 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3953 END_PROFILE(SMBwriteX);
3957 numtowrite = SVAL(req->inbuf,smb_vwv10);
3958 smb_doff = SVAL(req->inbuf,smb_vwv11);
3959 smblen = smb_len(req->inbuf);
3961 if (req->unread_bytes > 0xFFFF ||
3962 (smblen > smb_doff &&
3963 smblen - smb_doff > 0xFFFF)) {
3964 numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
3967 if (req->unread_bytes) {
3968 /* Can't do a recvfile write on IPC$ */
3970 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3971 END_PROFILE(SMBwriteX);
3974 if (numtowrite != req->unread_bytes) {
3975 reply_doserror(req, ERRDOS, ERRbadmem);
3976 END_PROFILE(SMBwriteX);
3980 if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
3981 smb_doff + numtowrite > smblen) {
3982 reply_doserror(req, ERRDOS, ERRbadmem);
3983 END_PROFILE(SMBwriteX);
3988 /* If it's an IPC, pass off the pipe handler. */
3990 if (req->unread_bytes) {
3991 reply_doserror(req, ERRDOS, ERRbadmem);
3992 END_PROFILE(SMBwriteX);
3995 reply_pipe_write_and_X(req);
3996 END_PROFILE(SMBwriteX);
4000 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
4001 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
4002 write_through = BITSETW(req->inbuf+smb_vwv7,0);
4004 if (!check_fsp(conn, req, fsp)) {
4005 END_PROFILE(SMBwriteX);
4009 if (!CHECK_WRITE(fsp)) {
4010 reply_doserror(req, ERRDOS, ERRbadaccess);
4011 END_PROFILE(SMBwriteX);
4015 data = smb_base(req->inbuf) + smb_doff;
4017 if(req->wct == 14) {
4018 #ifdef LARGE_SMB_OFF_T
4020 * This is a large offset (64 bit) write.
4022 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32);
4024 #else /* !LARGE_SMB_OFF_T */
4027 * Ensure we haven't been sent a >32 bit offset.
4030 if(IVAL(req->inbuf,smb_vwv12) != 0) {
4031 DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
4032 "used and we don't support 64 bit offsets.\n",
4033 (unsigned int)IVAL(req->inbuf,smb_vwv12) ));
4034 reply_doserror(req, ERRDOS, ERRbadaccess);
4035 END_PROFILE(SMBwriteX);
4039 #endif /* LARGE_SMB_OFF_T */
4042 if (is_locked(fsp,(uint32)req->smbpid,
4043 (uint64_t)numtowrite,
4044 (uint64_t)startpos, WRITE_LOCK)) {
4045 reply_doserror(req, ERRDOS, ERRlock);
4046 END_PROFILE(SMBwriteX);
4050 /* X/Open SMB protocol says that, unlike SMBwrite
4051 if the length is zero then NO truncation is
4052 done, just a write of zero. To truncate a file,
4055 if(numtowrite == 0) {
4059 if ((req->unread_bytes == 0) &&
4060 schedule_aio_write_and_X(conn, req, fsp, data, startpos,
4062 END_PROFILE(SMBwriteX);
4066 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4069 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4070 reply_unixerror(req, ERRHRD, ERRdiskfull);
4071 END_PROFILE(SMBwriteX);
4075 reply_outbuf(req, 6, 0);
4076 SSVAL(req->outbuf,smb_vwv2,nwritten);
4077 SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
4079 if (nwritten < (ssize_t)numtowrite) {
4080 SCVAL(req->outbuf,smb_rcls,ERRHRD);
4081 SSVAL(req->outbuf,smb_err,ERRdiskfull);
4084 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
4085 fsp->fnum, (int)numtowrite, (int)nwritten));
4087 status = sync_file(conn, fsp, write_through);
4088 if (!NT_STATUS_IS_OK(status)) {
4089 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
4090 fsp->fsp_name, nt_errstr(status) ));
4091 reply_nterror(req, status);
4092 END_PROFILE(SMBwriteX);
4096 END_PROFILE(SMBwriteX);
4101 /****************************************************************************
4103 ****************************************************************************/
4105 void reply_lseek(struct smb_request *req)
4107 connection_struct *conn = req->conn;
4113 START_PROFILE(SMBlseek);
4116 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4117 END_PROFILE(SMBlseek);
4121 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4123 if (!check_fsp(conn, req, fsp)) {
4127 flush_write_cache(fsp, SEEK_FLUSH);
4129 mode = SVAL(req->inbuf,smb_vwv1) & 3;
4130 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
4131 startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2);
4140 res = fsp->fh->pos + startpos;
4151 if (umode == SEEK_END) {
4152 if((res = SMB_VFS_LSEEK(fsp,startpos,umode)) == -1) {
4153 if(errno == EINVAL) {
4154 SMB_OFF_T current_pos = startpos;
4155 SMB_STRUCT_STAT sbuf;
4157 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
4158 reply_unixerror(req, ERRDOS,
4160 END_PROFILE(SMBlseek);
4164 current_pos += sbuf.st_size;
4166 res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
4171 reply_unixerror(req, ERRDOS, ERRnoaccess);
4172 END_PROFILE(SMBlseek);
4179 reply_outbuf(req, 2, 0);
4180 SIVAL(req->outbuf,smb_vwv0,res);
4182 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
4183 fsp->fnum, (double)startpos, (double)res, mode));
4185 END_PROFILE(SMBlseek);
4189 /****************************************************************************
4191 ****************************************************************************/
4193 void reply_flush(struct smb_request *req)
4195 connection_struct *conn = req->conn;
4199 START_PROFILE(SMBflush);
4202 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4206 fnum = SVAL(req->inbuf,smb_vwv0);
4207 fsp = file_fsp(req, fnum);
4209 if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) {
4214 file_sync_all(conn);
4216 NTSTATUS status = sync_file(conn, fsp, True);
4217 if (!NT_STATUS_IS_OK(status)) {
4218 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
4219 fsp->fsp_name, nt_errstr(status) ));
4220 reply_nterror(req, status);
4221 END_PROFILE(SMBflush);
4226 reply_outbuf(req, 0, 0);
4228 DEBUG(3,("flush\n"));
4229 END_PROFILE(SMBflush);
4233 /****************************************************************************
4235 conn POINTER CAN BE NULL HERE !
4236 ****************************************************************************/
4238 void reply_exit(struct smb_request *req)
4240 START_PROFILE(SMBexit);
4242 file_close_pid(req->smbpid, req->vuid);
4244 reply_outbuf(req, 0, 0);
4246 DEBUG(3,("exit\n"));
4248 END_PROFILE(SMBexit);
4252 /****************************************************************************
4253 Reply to a close - has to deal with closing a directory opened by NT SMB's.
4254 ****************************************************************************/
4256 void reply_close(struct smb_request *req)
4258 connection_struct *conn = req->conn;
4259 NTSTATUS status = NT_STATUS_OK;
4260 files_struct *fsp = NULL;
4261 START_PROFILE(SMBclose);
4264 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4265 END_PROFILE(SMBclose);
4269 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4272 * We can only use check_fsp if we know it's not a directory.
4275 if(!fsp || (fsp->conn != conn) || (fsp->vuid != req->vuid)) {
4276 reply_doserror(req, ERRDOS, ERRbadfid);
4277 END_PROFILE(SMBclose);
4281 if(fsp->is_directory) {
4283 * Special case - close NT SMB directory handle.
4285 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
4286 status = close_file(req, fsp, NORMAL_CLOSE);
4290 * Close ordinary file.
4293 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
4294 fsp->fh->fd, fsp->fnum,
4295 conn->num_files_open));
4298 * Take care of any time sent in the close.
4301 t = srv_make_unix_date3(req->inbuf+smb_vwv1);
4302 set_close_write_time(fsp, convert_time_t_to_timespec(t));
4305 * close_file() returns the unix errno if an error
4306 * was detected on close - normally this is due to
4307 * a disk full error. If not then it was probably an I/O error.
4310 status = close_file(req, fsp, NORMAL_CLOSE);
4313 if (!NT_STATUS_IS_OK(status)) {
4314 reply_nterror(req, status);
4315 END_PROFILE(SMBclose);
4319 reply_outbuf(req, 0, 0);
4320 END_PROFILE(SMBclose);
4324 /****************************************************************************
4325 Reply to a writeclose (Core+ protocol).
4326 ****************************************************************************/
4328 void reply_writeclose(struct smb_request *req)
4330 connection_struct *conn = req->conn;
4332 ssize_t nwritten = -1;
4333 NTSTATUS close_status = NT_STATUS_OK;
4336 struct timespec mtime;
4339 START_PROFILE(SMBwriteclose);
4342 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4343 END_PROFILE(SMBwriteclose);
4347 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4349 if (!check_fsp(conn, req, fsp)) {
4350 END_PROFILE(SMBwriteclose);
4353 if (!CHECK_WRITE(fsp)) {
4354 reply_doserror(req, ERRDOS,ERRbadaccess);
4355 END_PROFILE(SMBwriteclose);
4359 numtowrite = SVAL(req->inbuf,smb_vwv1);
4360 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
4361 mtime = convert_time_t_to_timespec(srv_make_unix_date3(
4362 req->inbuf+smb_vwv4));
4363 data = smb_buf(req->inbuf) + 1;
4366 && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
4367 (uint64_t)startpos, WRITE_LOCK)) {
4368 reply_doserror(req, ERRDOS,ERRlock);
4369 END_PROFILE(SMBwriteclose);
4373 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4375 set_close_write_time(fsp, mtime);
4378 * More insanity. W2K only closes the file if writelen > 0.
4383 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
4385 close_status = close_file(req, fsp, NORMAL_CLOSE);
4388 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
4389 fsp->fnum, (int)numtowrite, (int)nwritten,
4390 conn->num_files_open));
4392 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4393 reply_doserror(req, ERRHRD, ERRdiskfull);
4394 END_PROFILE(SMBwriteclose);
4398 if(!NT_STATUS_IS_OK(close_status)) {
4399 reply_nterror(req, close_status);
4400 END_PROFILE(SMBwriteclose);
4404 reply_outbuf(req, 1, 0);
4406 SSVAL(req->outbuf,smb_vwv0,nwritten);
4407 END_PROFILE(SMBwriteclose);
4412 #define DBGC_CLASS DBGC_LOCKING
4414 /****************************************************************************
4416 ****************************************************************************/
4418 void reply_lock(struct smb_request *req)
4420 connection_struct *conn = req->conn;
4421 uint64_t count,offset;
4424 struct byte_range_lock *br_lck = NULL;
4426 START_PROFILE(SMBlock);
4429 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4430 END_PROFILE(SMBlock);
4434 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4436 if (!check_fsp(conn, req, fsp)) {
4437 END_PROFILE(SMBlock);
4441 release_level_2_oplocks_on_change(fsp);
4443 count = (uint64_t)IVAL(req->inbuf,smb_vwv1);
4444 offset = (uint64_t)IVAL(req->inbuf,smb_vwv3);
4446 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4447 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
4449 br_lck = do_lock(smbd_messaging_context(),
4456 False, /* Non-blocking lock. */
4460 TALLOC_FREE(br_lck);
4462 if (NT_STATUS_V(status)) {
4463 reply_nterror(req, status);
4464 END_PROFILE(SMBlock);
4468 reply_outbuf(req, 0, 0);
4470 END_PROFILE(SMBlock);
4474 /****************************************************************************
4476 ****************************************************************************/
4478 void reply_unlock(struct smb_request *req)
4480 connection_struct *conn = req->conn;
4481 uint64_t count,offset;
4485 START_PROFILE(SMBunlock);
4488 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4489 END_PROFILE(SMBunlock);
4493 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4495 if (!check_fsp(conn, req, fsp)) {
4496 END_PROFILE(SMBunlock);
4500 count = (uint64_t)IVAL(req->inbuf,smb_vwv1);
4501 offset = (uint64_t)IVAL(req->inbuf,smb_vwv3);
4503 status = do_unlock(smbd_messaging_context(),
4510 if (NT_STATUS_V(status)) {
4511 reply_nterror(req, status);
4512 END_PROFILE(SMBunlock);
4516 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4517 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
4519 reply_outbuf(req, 0, 0);
4521 END_PROFILE(SMBunlock);
4526 #define DBGC_CLASS DBGC_ALL
4528 /****************************************************************************
4530 conn POINTER CAN BE NULL HERE !
4531 ****************************************************************************/
4533 void reply_tdis(struct smb_request *req)
4535 connection_struct *conn = req->conn;
4536 START_PROFILE(SMBtdis);
4539 DEBUG(4,("Invalid connection in tdis\n"));
4540 reply_doserror(req, ERRSRV, ERRinvnid);
4541 END_PROFILE(SMBtdis);
4547 close_cnum(conn,req->vuid);
4550 reply_outbuf(req, 0, 0);
4551 END_PROFILE(SMBtdis);
4555 /****************************************************************************
4557 conn POINTER CAN BE NULL HERE !
4558 ****************************************************************************/
4560 void reply_echo(struct smb_request *req)
4562 connection_struct *conn = req->conn;
4565 unsigned int data_len = smb_buflen(req->inbuf);
4567 START_PROFILE(SMBecho);
4570 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4571 END_PROFILE(SMBecho);
4575 if (data_len > BUFFER_SIZE) {
4576 DEBUG(0,("reply_echo: data_len too large.\n"));
4577 reply_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
4578 END_PROFILE(SMBecho);
4582 smb_reverb = SVAL(req->inbuf,smb_vwv0);
4584 reply_outbuf(req, 1, data_len);
4586 /* copy any incoming data back out */
4588 memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len);
4591 if (smb_reverb > 100) {
4592 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
4596 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
4597 SSVAL(req->outbuf,smb_vwv0,seq_num);
4599 show_msg((char *)req->outbuf);
4600 if (!srv_send_smb(smbd_server_fd(),
4601 (char *)req->outbuf,
4602 IS_CONN_ENCRYPTED(conn)||req->encrypted))
4603 exit_server_cleanly("reply_echo: srv_send_smb failed.");
4606 DEBUG(3,("echo %d times\n", smb_reverb));
4608 TALLOC_FREE(req->outbuf);
4610 END_PROFILE(SMBecho);
4614 /****************************************************************************
4615 Reply to a printopen.
4616 ****************************************************************************/
4618 void reply_printopen(struct smb_request *req)
4620 connection_struct *conn = req->conn;
4624 START_PROFILE(SMBsplopen);
4627 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4628 END_PROFILE(SMBsplopen);
4632 if (!CAN_PRINT(conn)) {
4633 reply_doserror(req, ERRDOS, ERRnoaccess);
4634 END_PROFILE(SMBsplopen);
4638 /* Open for exclusive use, write only. */
4639 status = print_fsp_open(req, conn, NULL, req->vuid, &fsp);
4641 if (!NT_STATUS_IS_OK(status)) {
4642 reply_nterror(req, status);
4643 END_PROFILE(SMBsplopen);
4647 reply_outbuf(req, 1, 0);
4648 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
4650 DEBUG(3,("openprint fd=%d fnum=%d\n",
4651 fsp->fh->fd, fsp->fnum));
4653 END_PROFILE(SMBsplopen);
4657 /****************************************************************************
4658 Reply to a printclose.
4659 ****************************************************************************/
4661 void reply_printclose(struct smb_request *req)
4663 connection_struct *conn = req->conn;
4667 START_PROFILE(SMBsplclose);
4670 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4671 END_PROFILE(SMBsplclose);
4675 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4677 if (!check_fsp(conn, req, fsp)) {
4678 END_PROFILE(SMBsplclose);
4682 if (!CAN_PRINT(conn)) {
4683 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
4684 END_PROFILE(SMBsplclose);
4688 DEBUG(3,("printclose fd=%d fnum=%d\n",
4689 fsp->fh->fd,fsp->fnum));
4691 status = close_file(req, fsp, NORMAL_CLOSE);
4693 if(!NT_STATUS_IS_OK(status)) {
4694 reply_nterror(req, status);
4695 END_PROFILE(SMBsplclose);
4699 reply_outbuf(req, 0, 0);
4701 END_PROFILE(SMBsplclose);
4705 /****************************************************************************
4706 Reply to a printqueue.
4707 ****************************************************************************/
4709 void reply_printqueue(struct smb_request *req)
4711 connection_struct *conn = req->conn;
4715 START_PROFILE(SMBsplretq);
4718 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4719 END_PROFILE(SMBsplretq);
4723 max_count = SVAL(req->inbuf,smb_vwv0);
4724 start_index = SVAL(req->inbuf,smb_vwv1);
4726 /* we used to allow the client to get the cnum wrong, but that
4727 is really quite gross and only worked when there was only
4728 one printer - I think we should now only accept it if they
4729 get it right (tridge) */
4730 if (!CAN_PRINT(conn)) {
4731 reply_doserror(req, ERRDOS, ERRnoaccess);
4732 END_PROFILE(SMBsplretq);
4736 reply_outbuf(req, 2, 3);
4737 SSVAL(req->outbuf,smb_vwv0,0);
4738 SSVAL(req->outbuf,smb_vwv1,0);
4739 SCVAL(smb_buf(req->outbuf),0,1);
4740 SSVAL(smb_buf(req->outbuf),1,0);
4742 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
4743 start_index, max_count));
4746 print_queue_struct *queue = NULL;
4747 print_status_struct status;
4748 int count = print_queue_status(SNUM(conn), &queue, &status);
4749 int num_to_get = ABS(max_count);
4750 int first = (max_count>0?start_index:start_index+max_count+1);
4756 num_to_get = MIN(num_to_get,count-first);
4759 for (i=first;i<first+num_to_get;i++) {
4763 srv_put_dos_date2(p,0,queue[i].time);
4764 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
4765 SSVAL(p,5, queue[i].job);
4766 SIVAL(p,7,queue[i].size);
4768 srvstr_push(blob, req->flags2, p+12,
4769 queue[i].fs_user, 16, STR_ASCII);
4771 if (message_push_blob(
4774 blob, sizeof(blob))) == -1) {
4775 reply_nterror(req, NT_STATUS_NO_MEMORY);
4776 END_PROFILE(SMBsplretq);
4782 SSVAL(req->outbuf,smb_vwv0,count);
4783 SSVAL(req->outbuf,smb_vwv1,
4784 (max_count>0?first+count:first-1));
4785 SCVAL(smb_buf(req->outbuf),0,1);
4786 SSVAL(smb_buf(req->outbuf),1,28*count);
4791 DEBUG(3,("%d entries returned in queue\n",count));
4794 END_PROFILE(SMBsplretq);
4798 /****************************************************************************
4799 Reply to a printwrite.
4800 ****************************************************************************/
4802 void reply_printwrite(struct smb_request *req)
4804 connection_struct *conn = req->conn;
4809 START_PROFILE(SMBsplwr);
4812 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4813 END_PROFILE(SMBsplwr);
4817 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4819 if (!check_fsp(conn, req, fsp)) {
4820 END_PROFILE(SMBsplwr);
4824 if (!CAN_PRINT(conn)) {
4825 reply_doserror(req, ERRDOS, ERRnoaccess);
4826 END_PROFILE(SMBsplwr);
4830 if (!CHECK_WRITE(fsp)) {
4831 reply_doserror(req, ERRDOS, ERRbadaccess);
4832 END_PROFILE(SMBsplwr);
4836 numtowrite = SVAL(smb_buf(req->inbuf),1);
4838 if (smb_buflen(req->inbuf) < numtowrite + 3) {
4839 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4840 END_PROFILE(SMBsplwr);
4844 data = smb_buf(req->inbuf) + 3;
4846 if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
4847 reply_unixerror(req, ERRHRD, ERRdiskfull);
4848 END_PROFILE(SMBsplwr);
4852 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
4854 END_PROFILE(SMBsplwr);
4858 /****************************************************************************
4860 ****************************************************************************/
4862 void reply_mkdir(struct smb_request *req)
4864 connection_struct *conn = req->conn;
4865 char *directory = NULL;
4867 SMB_STRUCT_STAT sbuf;
4868 TALLOC_CTX *ctx = talloc_tos();
4870 START_PROFILE(SMBmkdir);
4872 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
4873 smb_buf(req->inbuf) + 1, 0,
4874 STR_TERMINATE, &status);
4875 if (!NT_STATUS_IS_OK(status)) {
4876 reply_nterror(req, status);
4877 END_PROFILE(SMBmkdir);
4881 status = resolve_dfspath(ctx, conn,
4882 req->flags2 & FLAGS2_DFS_PATHNAMES,
4885 if (!NT_STATUS_IS_OK(status)) {
4886 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4887 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
4888 ERRSRV, ERRbadpath);
4889 END_PROFILE(SMBmkdir);
4892 reply_nterror(req, status);
4893 END_PROFILE(SMBmkdir);
4897 status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
4898 if (!NT_STATUS_IS_OK(status)) {
4899 reply_nterror(req, status);
4900 END_PROFILE(SMBmkdir);
4904 status = check_name(conn, directory);
4905 if (!NT_STATUS_IS_OK(status)) {
4906 reply_nterror(req, status);
4907 END_PROFILE(SMBmkdir);
4911 status = create_directory(conn, req, directory);
4913 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
4915 if (!NT_STATUS_IS_OK(status)) {
4917 if (!use_nt_status()
4918 && NT_STATUS_EQUAL(status,
4919 NT_STATUS_OBJECT_NAME_COLLISION)) {
4921 * Yes, in the DOS error code case we get a
4922 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
4923 * samba4 torture test.
4925 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
4928 reply_nterror(req, status);
4929 END_PROFILE(SMBmkdir);
4933 reply_outbuf(req, 0, 0);
4935 DEBUG( 3, ( "mkdir %s\n", directory ) );
4937 END_PROFILE(SMBmkdir);
4941 /****************************************************************************
4942 Static function used by reply_rmdir to delete an entire directory
4943 tree recursively. Return True on ok, False on fail.
4944 ****************************************************************************/
4946 static bool recursive_rmdir(TALLOC_CTX *ctx,
4947 connection_struct *conn,
4950 const char *dname = NULL;
4953 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, directory,
4959 while((dname = ReadDirName(dir_hnd, &offset))) {
4960 char *fullname = NULL;
4963 if (ISDOT(dname) || ISDOTDOT(dname)) {
4967 if (!is_visible_file(conn, directory, dname, &st, False)) {
4971 /* Construct the full name. */
4972 fullname = talloc_asprintf(ctx,
4982 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
4987 if(st.st_mode & S_IFDIR) {
4988 if(!recursive_rmdir(ctx, conn, fullname)) {
4992 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
4996 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
5000 TALLOC_FREE(fullname);
5002 TALLOC_FREE(dir_hnd);
5006 /****************************************************************************
5007 The internals of the rmdir code - called elsewhere.
5008 ****************************************************************************/
5010 NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
5011 connection_struct *conn,
5012 const char *directory)
5017 /* Might be a symlink. */
5018 if(SMB_VFS_LSTAT(conn, directory, &st) != 0) {
5019 return map_nt_error_from_unix(errno);
5022 if (S_ISLNK(st.st_mode)) {
5023 /* Is what it points to a directory ? */
5024 if(SMB_VFS_STAT(conn, directory, &st) != 0) {
5025 return map_nt_error_from_unix(errno);
5027 if (!(S_ISDIR(st.st_mode))) {
5028 return NT_STATUS_NOT_A_DIRECTORY;
5030 ret = SMB_VFS_UNLINK(conn,directory);
5032 ret = SMB_VFS_RMDIR(conn,directory);
5035 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5036 FILE_NOTIFY_CHANGE_DIR_NAME,
5038 return NT_STATUS_OK;
5041 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
5043 * Check to see if the only thing in this directory are
5044 * vetoed files/directories. If so then delete them and
5045 * retry. If we fail to delete any of them (and we *don't*
5046 * do a recursive delete) then fail the rmdir.
5050 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
5051 directory, NULL, 0);
5053 if(dir_hnd == NULL) {
5058 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5059 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
5061 if (!is_visible_file(conn, directory, dname, &st, False))
5063 if(!IS_VETO_PATH(conn, dname)) {
5064 TALLOC_FREE(dir_hnd);
5070 /* We only have veto files/directories. Recursive delete. */
5072 RewindDir(dir_hnd,&dirpos);
5073 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5074 char *fullname = NULL;
5076 if (ISDOT(dname) || ISDOTDOT(dname)) {
5079 if (!is_visible_file(conn, directory, dname, &st, False)) {
5083 fullname = talloc_asprintf(ctx,
5093 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
5096 if(st.st_mode & S_IFDIR) {
5097 if(lp_recursive_veto_delete(SNUM(conn))) {
5098 if(!recursive_rmdir(ctx, conn, fullname))
5101 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
5104 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
5107 TALLOC_FREE(fullname);
5109 TALLOC_FREE(dir_hnd);
5110 /* Retry the rmdir */
5111 ret = SMB_VFS_RMDIR(conn,directory);
5117 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
5118 "%s\n", directory,strerror(errno)));
5119 return map_nt_error_from_unix(errno);
5122 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5123 FILE_NOTIFY_CHANGE_DIR_NAME,
5126 return NT_STATUS_OK;
5129 /****************************************************************************
5131 ****************************************************************************/
5133 void reply_rmdir(struct smb_request *req)
5135 connection_struct *conn = req->conn;
5136 char *directory = NULL;
5137 SMB_STRUCT_STAT sbuf;
5139 TALLOC_CTX *ctx = talloc_tos();
5141 START_PROFILE(SMBrmdir);
5143 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
5144 smb_buf(req->inbuf) + 1, 0,
5145 STR_TERMINATE, &status);
5146 if (!NT_STATUS_IS_OK(status)) {
5147 reply_nterror(req, status);
5148 END_PROFILE(SMBrmdir);
5152 status = resolve_dfspath(ctx, conn,
5153 req->flags2 & FLAGS2_DFS_PATHNAMES,
5156 if (!NT_STATUS_IS_OK(status)) {
5157 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5158 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5159 ERRSRV, ERRbadpath);
5160 END_PROFILE(SMBrmdir);
5163 reply_nterror(req, status);
5164 END_PROFILE(SMBrmdir);
5168 status = unix_convert(ctx, conn, directory, False, &directory,
5170 if (!NT_STATUS_IS_OK(status)) {
5171 reply_nterror(req, status);
5172 END_PROFILE(SMBrmdir);
5176 status = check_name(conn, directory);
5177 if (!NT_STATUS_IS_OK(status)) {
5178 reply_nterror(req, status);
5179 END_PROFILE(SMBrmdir);
5183 dptr_closepath(directory, req->smbpid);
5184 status = rmdir_internals(ctx, conn, directory);
5185 if (!NT_STATUS_IS_OK(status)) {
5186 reply_nterror(req, status);
5187 END_PROFILE(SMBrmdir);
5191 reply_outbuf(req, 0, 0);
5193 DEBUG( 3, ( "rmdir %s\n", directory ) );
5195 END_PROFILE(SMBrmdir);
5199 /*******************************************************************
5200 Resolve wildcards in a filename rename.
5201 ********************************************************************/
5203 static bool resolve_wildcards(TALLOC_CTX *ctx,
5208 char *name2_copy = NULL;
5213 char *p,*p2, *pname1, *pname2;
5215 name2_copy = talloc_strdup(ctx, name2);
5220 pname1 = strrchr_m(name1,'/');
5221 pname2 = strrchr_m(name2_copy,'/');
5223 if (!pname1 || !pname2) {
5227 /* Truncate the copy of name2 at the last '/' */
5230 /* Now go past the '/' */
5234 root1 = talloc_strdup(ctx, pname1);
5235 root2 = talloc_strdup(ctx, pname2);
5237 if (!root1 || !root2) {
5241 p = strrchr_m(root1,'.');
5244 ext1 = talloc_strdup(ctx, p+1);
5246 ext1 = talloc_strdup(ctx, "");
5248 p = strrchr_m(root2,'.');
5251 ext2 = talloc_strdup(ctx, p+1);
5253 ext2 = talloc_strdup(ctx, "");
5256 if (!ext1 || !ext2) {
5264 /* Hmmm. Should this be mb-aware ? */
5267 } else if (*p2 == '*') {
5269 root2 = talloc_asprintf(ctx, "%s%s",
5288 /* Hmmm. Should this be mb-aware ? */
5291 } else if (*p2 == '*') {
5293 ext2 = talloc_asprintf(ctx, "%s%s",
5309 *pp_newname = talloc_asprintf(ctx, "%s/%s.%s",
5314 *pp_newname = talloc_asprintf(ctx, "%s/%s",
5326 /****************************************************************************
5327 Ensure open files have their names updated. Updated to notify other smbd's
5329 ****************************************************************************/
5331 static void rename_open_files(connection_struct *conn,
5332 struct share_mode_lock *lck,
5333 const char *newname)
5336 bool did_rename = False;
5338 for(fsp = file_find_di_first(lck->id); fsp;
5339 fsp = file_find_di_next(fsp)) {
5340 /* fsp_name is a relative path under the fsp. To change this for other
5341 sharepaths we need to manipulate relative paths. */
5342 /* TODO - create the absolute path and manipulate the newname
5343 relative to the sharepath. */
5344 if (!strequal(fsp->conn->connectpath, conn->connectpath)) {
5347 DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
5348 fsp->fnum, file_id_string_tos(&fsp->file_id),
5349 fsp->fsp_name, newname ));
5350 string_set(&fsp->fsp_name, newname);
5355 DEBUG(10,("rename_open_files: no open files on file_id %s for %s\n",
5356 file_id_string_tos(&lck->id), newname ));
5359 /* Send messages to all smbd's (not ourself) that the name has changed. */
5360 rename_share_filename(smbd_messaging_context(), lck, conn->connectpath,
5364 /****************************************************************************
5365 We need to check if the source path is a parent directory of the destination
5366 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
5367 refuse the rename with a sharing violation. Under UNIX the above call can
5368 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
5369 probably need to check that the client is a Windows one before disallowing
5370 this as a UNIX client (one with UNIX extensions) can know the source is a
5371 symlink and make this decision intelligently. Found by an excellent bug
5372 report from <AndyLiebman@aol.com>.
5373 ****************************************************************************/
5375 static bool rename_path_prefix_equal(const char *src, const char *dest)
5377 const char *psrc = src;
5378 const char *pdst = dest;
5381 if (psrc[0] == '.' && psrc[1] == '/') {
5384 if (pdst[0] == '.' && pdst[1] == '/') {
5387 if ((slen = strlen(psrc)) > strlen(pdst)) {
5390 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
5394 * Do the notify calls from a rename
5397 static void notify_rename(connection_struct *conn, bool is_dir,
5398 const char *oldpath, const char *newpath)
5400 char *olddir, *newdir;
5401 const char *oldname, *newname;
5404 mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
5405 : FILE_NOTIFY_CHANGE_FILE_NAME;
5407 if (!parent_dirname_talloc(NULL, oldpath, &olddir, &oldname)
5408 || !parent_dirname_talloc(NULL, newpath, &newdir, &newname)) {
5409 TALLOC_FREE(olddir);
5413 if (strcmp(olddir, newdir) == 0) {
5414 notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, oldpath);
5415 notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, newpath);
5418 notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, oldpath);
5419 notify_fname(conn, NOTIFY_ACTION_ADDED, mask, newpath);
5421 TALLOC_FREE(olddir);
5422 TALLOC_FREE(newdir);
5424 /* this is a strange one. w2k3 gives an additional event for
5425 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
5426 files, but not directories */
5428 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
5429 FILE_NOTIFY_CHANGE_ATTRIBUTES
5430 |FILE_NOTIFY_CHANGE_CREATION,
5435 /****************************************************************************
5436 Rename an open file - given an fsp.
5437 ****************************************************************************/
5439 NTSTATUS rename_internals_fsp(connection_struct *conn,
5442 const char *newname_last_component,
5444 bool replace_if_exists)
5446 TALLOC_CTX *ctx = talloc_tos();
5447 SMB_STRUCT_STAT sbuf, sbuf1;
5448 NTSTATUS status = NT_STATUS_OK;
5449 struct share_mode_lock *lck = NULL;
5454 status = check_name(conn, newname);
5455 if (!NT_STATUS_IS_OK(status)) {
5459 /* Ensure newname contains a '/' */
5460 if(strrchr_m(newname,'/') == 0) {
5461 newname = talloc_asprintf(ctx,
5465 return NT_STATUS_NO_MEMORY;
5470 * Check for special case with case preserving and not
5471 * case sensitive. If the old last component differs from the original
5472 * last component only by case, then we should allow
5473 * the rename (user is trying to change the case of the
5477 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
5478 strequal(newname, fsp->fsp_name)) {
5480 char *newname_modified_last_component = NULL;
5483 * Get the last component of the modified name.
5484 * Note that we guarantee that newname contains a '/'
5487 p = strrchr_m(newname,'/');
5488 newname_modified_last_component = talloc_strdup(ctx,
5490 if (!newname_modified_last_component) {
5491 return NT_STATUS_NO_MEMORY;
5494 if(strcsequal(newname_modified_last_component,
5495 newname_last_component) == False) {
5497 * Replace the modified last component with
5500 *p = '\0'; /* Truncate at the '/' */
5501 newname = talloc_asprintf(ctx,
5504 newname_last_component);
5509 * If the src and dest names are identical - including case,
5510 * don't do the rename, just return success.
5513 if (strcsequal(fsp->fsp_name, newname)) {
5514 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
5516 return NT_STATUS_OK;
5520 * Have vfs_object_exist also fill sbuf1
5522 dst_exists = vfs_object_exist(conn, newname, &sbuf1);
5524 if(!replace_if_exists && dst_exists) {
5525 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
5526 fsp->fsp_name,newname));
5527 return NT_STATUS_OBJECT_NAME_COLLISION;
5531 struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
5532 files_struct *dst_fsp = file_find_di_first(fileid);
5534 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
5535 return NT_STATUS_ACCESS_DENIED;
5539 /* Ensure we have a valid stat struct for the source. */
5540 if (fsp->fh->fd != -1) {
5541 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
5542 return map_nt_error_from_unix(errno);
5545 if (SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) == -1) {
5546 return map_nt_error_from_unix(errno);
5550 status = can_rename(conn, fsp, attrs, &sbuf);
5552 if (!NT_STATUS_IS_OK(status)) {
5553 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5554 nt_errstr(status), fsp->fsp_name,newname));
5555 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION))
5556 status = NT_STATUS_ACCESS_DENIED;
5560 if (rename_path_prefix_equal(fsp->fsp_name, newname)) {
5561 return NT_STATUS_ACCESS_DENIED;
5564 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
5568 * We have the file open ourselves, so not being able to get the
5569 * corresponding share mode lock is a fatal error.
5572 SMB_ASSERT(lck != NULL);
5574 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
5575 uint32 create_options = fsp->fh->private_options;
5577 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
5578 fsp->fsp_name,newname));
5580 notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname);
5582 rename_open_files(conn, lck, newname);
5585 * A rename acts as a new file create w.r.t. allowing an initial delete
5586 * on close, probably because in Windows there is a new handle to the
5587 * new file. If initial delete on close was requested but not
5588 * originally set, we need to set it here. This is probably not 100% correct,
5589 * but will work for the CIFSFS client which in non-posix mode
5590 * depends on these semantics. JRA.
5593 set_allow_initial_delete_on_close(lck, fsp, True);
5595 if (create_options & FILE_DELETE_ON_CLOSE) {
5596 status = can_set_delete_on_close(fsp, True, 0);
5598 if (NT_STATUS_IS_OK(status)) {
5599 /* Note that here we set the *inital* delete on close flag,
5600 * not the regular one. The magic gets handled in close. */
5601 fsp->initial_delete_on_close = True;
5605 return NT_STATUS_OK;
5610 if (errno == ENOTDIR || errno == EISDIR) {
5611 status = NT_STATUS_OBJECT_NAME_COLLISION;
5613 status = map_nt_error_from_unix(errno);
5616 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5617 nt_errstr(status), fsp->fsp_name,newname));
5622 /****************************************************************************
5623 The guts of the rename command, split out so it may be called by the NT SMB
5625 ****************************************************************************/
5627 NTSTATUS rename_internals(TALLOC_CTX *ctx,
5628 connection_struct *conn,
5629 struct smb_request *req,
5630 const char *name_in,
5631 const char *newname_in,
5633 bool replace_if_exists,
5636 uint32_t access_mask)
5638 char *directory = NULL;
5640 char *last_component_src = NULL;
5641 char *last_component_dest = NULL;
5643 char *newname = NULL;
5646 NTSTATUS status = NT_STATUS_OK;
5647 SMB_STRUCT_STAT sbuf1, sbuf2;
5648 struct smb_Dir *dir_hnd = NULL;
5655 status = unix_convert(ctx, conn, name_in, src_has_wild, &name,
5656 &last_component_src, &sbuf1);
5657 if (!NT_STATUS_IS_OK(status)) {
5661 status = unix_convert(ctx, conn, newname_in, dest_has_wild, &newname,
5662 &last_component_dest, &sbuf2);
5663 if (!NT_STATUS_IS_OK(status)) {
5668 * Split the old name into directory and last component
5669 * strings. Note that unix_convert may have stripped off a
5670 * leading ./ from both name and newname if the rename is
5671 * at the root of the share. We need to make sure either both
5672 * name and newname contain a / character or neither of them do
5673 * as this is checked in resolve_wildcards().
5676 p = strrchr_m(name,'/');
5678 directory = talloc_strdup(ctx, ".");
5680 return NT_STATUS_NO_MEMORY;
5685 directory = talloc_strdup(ctx, name);
5687 return NT_STATUS_NO_MEMORY;
5690 *p = '/'; /* Replace needed for exceptional test below. */
5694 * We should only check the mangled cache
5695 * here if unix_convert failed. This means
5696 * that the path in 'mask' doesn't exist
5697 * on the file system and so we need to look
5698 * for a possible mangle. This patch from
5699 * Tine Smukavec <valentin.smukavec@hermes.si>.
5702 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
5703 char *new_mask = NULL;
5704 mangle_lookup_name_from_8_3(ctx,
5713 if (!src_has_wild) {
5717 * No wildcards - just process the one file.
5719 bool is_short_name = mangle_is_8_3(name, True, conn->params);
5721 /* Add a terminating '/' to the directory name. */
5722 directory = talloc_asprintf_append(directory,
5726 return NT_STATUS_NO_MEMORY;
5729 /* Ensure newname contains a '/' also */
5730 if(strrchr_m(newname,'/') == 0) {
5731 newname = talloc_asprintf(ctx,
5735 return NT_STATUS_NO_MEMORY;
5739 DEBUG(3, ("rename_internals: case_sensitive = %d, "
5740 "case_preserve = %d, short case preserve = %d, "
5741 "directory = %s, newname = %s, "
5742 "last_component_dest = %s, is_8_3 = %d\n",
5743 conn->case_sensitive, conn->case_preserve,
5744 conn->short_case_preserve, directory,
5745 newname, last_component_dest, is_short_name));
5747 /* The dest name still may have wildcards. */
5748 if (dest_has_wild) {
5749 char *mod_newname = NULL;
5750 if (!resolve_wildcards(ctx,
5751 directory,newname,&mod_newname)) {
5752 DEBUG(6, ("rename_internals: resolve_wildcards "
5756 return NT_STATUS_NO_MEMORY;
5758 newname = mod_newname;
5762 SMB_VFS_STAT(conn, directory, &sbuf1);
5764 status = S_ISDIR(sbuf1.st_mode) ?
5765 open_directory(conn, req, directory, &sbuf1,
5767 FILE_SHARE_READ|FILE_SHARE_WRITE,
5768 FILE_OPEN, 0, 0, NULL,
5770 : open_file_ntcreate(conn, req, directory, &sbuf1,
5772 FILE_SHARE_READ|FILE_SHARE_WRITE,
5773 FILE_OPEN, 0, 0, 0, NULL,
5776 if (!NT_STATUS_IS_OK(status)) {
5777 DEBUG(3, ("Could not open rename source %s: %s\n",
5778 directory, nt_errstr(status)));
5782 status = rename_internals_fsp(conn, fsp, newname,
5783 last_component_dest,
5784 attrs, replace_if_exists);
5786 close_file(req, fsp, NORMAL_CLOSE);
5788 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
5789 nt_errstr(status), directory,newname));
5795 * Wildcards - process each file that matches.
5797 if (strequal(mask,"????????.???")) {
5802 status = check_name(conn, directory);
5803 if (!NT_STATUS_IS_OK(status)) {
5807 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, attrs);
5808 if (dir_hnd == NULL) {
5809 return map_nt_error_from_unix(errno);
5812 status = NT_STATUS_NO_SUCH_FILE;
5814 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5815 * - gentest fix. JRA
5818 while ((dname = ReadDirName(dir_hnd, &offset))) {
5819 files_struct *fsp = NULL;
5821 char *destname = NULL;
5822 bool sysdir_entry = False;
5824 /* Quick check for "." and ".." */
5825 if (ISDOT(dname) || ISDOTDOT(dname)) {
5827 sysdir_entry = True;
5833 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
5837 if(!mask_match(dname, mask, conn->case_sensitive)) {
5842 status = NT_STATUS_OBJECT_NAME_INVALID;
5846 fname = talloc_asprintf(ctx,
5851 return NT_STATUS_NO_MEMORY;
5854 if (!resolve_wildcards(ctx,
5855 fname,newname,&destname)) {
5856 DEBUG(6, ("resolve_wildcards %s %s failed\n",
5862 return NT_STATUS_NO_MEMORY;
5866 SMB_VFS_STAT(conn, fname, &sbuf1);
5868 status = S_ISDIR(sbuf1.st_mode) ?
5869 open_directory(conn, req, fname, &sbuf1,
5871 FILE_SHARE_READ|FILE_SHARE_WRITE,
5872 FILE_OPEN, 0, 0, NULL,
5874 : open_file_ntcreate(conn, req, fname, &sbuf1,
5876 FILE_SHARE_READ|FILE_SHARE_WRITE,
5877 FILE_OPEN, 0, 0, 0, NULL,
5880 if (!NT_STATUS_IS_OK(status)) {
5881 DEBUG(3,("rename_internals: open_file_ntcreate "
5882 "returned %s rename %s -> %s\n",
5883 nt_errstr(status), directory, newname));
5887 status = rename_internals_fsp(conn, fsp, destname, dname,
5888 attrs, replace_if_exists);
5890 close_file(req, fsp, NORMAL_CLOSE);
5892 if (!NT_STATUS_IS_OK(status)) {
5893 DEBUG(3, ("rename_internals_fsp returned %s for "
5894 "rename %s -> %s\n", nt_errstr(status),
5895 directory, newname));
5901 DEBUG(3,("rename_internals: doing rename on %s -> "
5902 "%s\n",fname,destname));
5905 TALLOC_FREE(destname);
5907 TALLOC_FREE(dir_hnd);
5909 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
5910 status = map_nt_error_from_unix(errno);
5916 /****************************************************************************
5918 ****************************************************************************/
5920 void reply_mv(struct smb_request *req)
5922 connection_struct *conn = req->conn;
5924 char *newname = NULL;
5928 bool src_has_wcard = False;
5929 bool dest_has_wcard = False;
5930 TALLOC_CTX *ctx = talloc_tos();
5932 START_PROFILE(SMBmv);
5935 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5940 attrs = SVAL(req->inbuf,smb_vwv0);
5942 p = smb_buf(req->inbuf) + 1;
5943 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
5944 0, STR_TERMINATE, &status,
5946 if (!NT_STATUS_IS_OK(status)) {
5947 reply_nterror(req, status);
5952 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
5953 0, STR_TERMINATE, &status,
5955 if (!NT_STATUS_IS_OK(status)) {
5956 reply_nterror(req, status);
5961 status = resolve_dfspath_wcard(ctx, conn,
5962 req->flags2 & FLAGS2_DFS_PATHNAMES,
5966 if (!NT_STATUS_IS_OK(status)) {
5967 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5968 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5969 ERRSRV, ERRbadpath);
5973 reply_nterror(req, status);
5978 status = resolve_dfspath_wcard(ctx, conn,
5979 req->flags2 & FLAGS2_DFS_PATHNAMES,
5983 if (!NT_STATUS_IS_OK(status)) {
5984 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5985 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5986 ERRSRV, ERRbadpath);
5990 reply_nterror(req, status);
5995 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
5997 status = rename_internals(ctx, conn, req, name, newname, attrs, False,
5998 src_has_wcard, dest_has_wcard, DELETE_ACCESS);
5999 if (!NT_STATUS_IS_OK(status)) {
6000 if (open_was_deferred(req->mid)) {
6001 /* We have re-scheduled this call. */
6005 reply_nterror(req, status);
6010 reply_outbuf(req, 0, 0);
6016 /*******************************************************************
6017 Copy a file as part of a reply_copy.
6018 ******************************************************************/
6021 * TODO: check error codes on all callers
6024 NTSTATUS copy_file(TALLOC_CTX *ctx,
6025 connection_struct *conn,
6030 bool target_is_directory)
6032 SMB_STRUCT_STAT src_sbuf, sbuf2;
6034 files_struct *fsp1,*fsp2;
6037 uint32 new_create_disposition;
6040 dest = talloc_strdup(ctx, dest1);
6042 return NT_STATUS_NO_MEMORY;
6044 if (target_is_directory) {
6045 const char *p = strrchr_m(src,'/');
6051 dest = talloc_asprintf_append(dest,
6055 return NT_STATUS_NO_MEMORY;
6059 if (!vfs_file_exist(conn,src,&src_sbuf)) {
6061 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6064 if (!target_is_directory && count) {
6065 new_create_disposition = FILE_OPEN;
6067 if (!map_open_params_to_ntcreate(dest1,0,ofun,
6068 NULL, NULL, &new_create_disposition, NULL)) {
6070 return NT_STATUS_INVALID_PARAMETER;
6074 status = open_file_ntcreate(conn, NULL, src, &src_sbuf,
6076 FILE_SHARE_READ|FILE_SHARE_WRITE,
6079 FILE_ATTRIBUTE_NORMAL,
6083 if (!NT_STATUS_IS_OK(status)) {
6088 dosattrs = dos_mode(conn, src, &src_sbuf);
6089 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) {
6090 ZERO_STRUCTP(&sbuf2);
6093 status = open_file_ntcreate(conn, NULL, dest, &sbuf2,
6095 FILE_SHARE_READ|FILE_SHARE_WRITE,
6096 new_create_disposition,
6104 if (!NT_STATUS_IS_OK(status)) {
6105 close_file(NULL, fsp1, ERROR_CLOSE);
6109 if ((ofun&3) == 1) {
6110 if(SMB_VFS_LSEEK(fsp2,0,SEEK_END) == -1) {
6111 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
6113 * Stop the copy from occurring.
6116 src_sbuf.st_size = 0;
6120 if (src_sbuf.st_size) {
6121 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
6124 close_file(NULL, fsp1, NORMAL_CLOSE);
6126 /* Ensure the modtime is set correctly on the destination file. */
6127 set_close_write_time(fsp2, get_mtimespec(&src_sbuf));
6130 * As we are opening fsp1 read-only we only expect
6131 * an error on close on fsp2 if we are out of space.
6132 * Thus we don't look at the error return from the
6135 status = close_file(NULL, fsp2, NORMAL_CLOSE);
6137 if (!NT_STATUS_IS_OK(status)) {
6141 if (ret != (SMB_OFF_T)src_sbuf.st_size) {
6142 return NT_STATUS_DISK_FULL;
6145 return NT_STATUS_OK;
6148 /****************************************************************************
6149 Reply to a file copy.
6150 ****************************************************************************/
6152 void reply_copy(struct smb_request *req)
6154 connection_struct *conn = req->conn;
6156 char *newname = NULL;
6157 char *directory = NULL;
6161 int error = ERRnoaccess;
6166 bool target_is_directory=False;
6167 bool source_has_wild = False;
6168 bool dest_has_wild = False;
6169 SMB_STRUCT_STAT sbuf1, sbuf2;
6171 TALLOC_CTX *ctx = talloc_tos();
6173 START_PROFILE(SMBcopy);
6176 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6177 END_PROFILE(SMBcopy);
6181 tid2 = SVAL(req->inbuf,smb_vwv0);
6182 ofun = SVAL(req->inbuf,smb_vwv1);
6183 flags = SVAL(req->inbuf,smb_vwv2);
6185 p = smb_buf(req->inbuf);
6186 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
6187 0, STR_TERMINATE, &status,
6189 if (!NT_STATUS_IS_OK(status)) {
6190 reply_nterror(req, status);
6191 END_PROFILE(SMBcopy);
6194 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
6195 0, STR_TERMINATE, &status,
6197 if (!NT_STATUS_IS_OK(status)) {
6198 reply_nterror(req, status);
6199 END_PROFILE(SMBcopy);
6203 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
6205 if (tid2 != conn->cnum) {
6206 /* can't currently handle inter share copies XXXX */
6207 DEBUG(3,("Rejecting inter-share copy\n"));
6208 reply_doserror(req, ERRSRV, ERRinvdevice);
6209 END_PROFILE(SMBcopy);
6213 status = resolve_dfspath_wcard(ctx, conn,
6214 req->flags2 & FLAGS2_DFS_PATHNAMES,
6218 if (!NT_STATUS_IS_OK(status)) {
6219 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6220 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6221 ERRSRV, ERRbadpath);
6222 END_PROFILE(SMBcopy);
6225 reply_nterror(req, status);
6226 END_PROFILE(SMBcopy);
6230 status = resolve_dfspath_wcard(ctx, conn,
6231 req->flags2 & FLAGS2_DFS_PATHNAMES,
6235 if (!NT_STATUS_IS_OK(status)) {
6236 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6237 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6238 ERRSRV, ERRbadpath);
6239 END_PROFILE(SMBcopy);
6242 reply_nterror(req, status);
6243 END_PROFILE(SMBcopy);
6247 status = unix_convert(ctx, conn, name, source_has_wild,
6248 &name, NULL, &sbuf1);
6249 if (!NT_STATUS_IS_OK(status)) {
6250 reply_nterror(req, status);
6251 END_PROFILE(SMBcopy);
6255 status = unix_convert(ctx, conn, newname, dest_has_wild,
6256 &newname, NULL, &sbuf2);
6257 if (!NT_STATUS_IS_OK(status)) {
6258 reply_nterror(req, status);
6259 END_PROFILE(SMBcopy);
6263 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
6265 if ((flags&1) && target_is_directory) {
6266 reply_doserror(req, ERRDOS, ERRbadfile);
6267 END_PROFILE(SMBcopy);
6271 if ((flags&2) && !target_is_directory) {
6272 reply_doserror(req, ERRDOS, ERRbadpath);
6273 END_PROFILE(SMBcopy);
6277 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
6278 /* wants a tree copy! XXXX */
6279 DEBUG(3,("Rejecting tree copy\n"));
6280 reply_doserror(req, ERRSRV, ERRerror);
6281 END_PROFILE(SMBcopy);
6285 p = strrchr_m(name,'/');
6287 directory = talloc_strdup(ctx, "./");
6289 reply_nterror(req, NT_STATUS_NO_MEMORY);
6290 END_PROFILE(SMBcopy);
6296 directory = talloc_strdup(ctx, name);
6298 reply_nterror(req, NT_STATUS_NO_MEMORY);
6299 END_PROFILE(SMBcopy);
6306 * We should only check the mangled cache
6307 * here if unix_convert failed. This means
6308 * that the path in 'mask' doesn't exist
6309 * on the file system and so we need to look
6310 * for a possible mangle. This patch from
6311 * Tine Smukavec <valentin.smukavec@hermes.si>.
6314 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
6315 char *new_mask = NULL;
6316 mangle_lookup_name_from_8_3(ctx,
6325 if (!source_has_wild) {
6326 directory = talloc_asprintf_append(directory,
6329 if (dest_has_wild) {
6330 char *mod_newname = NULL;
6331 if (!resolve_wildcards(ctx,
6332 directory,newname,&mod_newname)) {
6333 reply_nterror(req, NT_STATUS_NO_MEMORY);
6334 END_PROFILE(SMBcopy);
6337 newname = mod_newname;
6340 status = check_name(conn, directory);
6341 if (!NT_STATUS_IS_OK(status)) {
6342 reply_nterror(req, status);
6343 END_PROFILE(SMBcopy);
6347 status = check_name(conn, newname);
6348 if (!NT_STATUS_IS_OK(status)) {
6349 reply_nterror(req, status);
6350 END_PROFILE(SMBcopy);
6354 status = copy_file(ctx,conn,directory,newname,ofun,
6355 count,target_is_directory);
6357 if(!NT_STATUS_IS_OK(status)) {
6358 reply_nterror(req, status);
6359 END_PROFILE(SMBcopy);
6365 struct smb_Dir *dir_hnd = NULL;
6366 const char *dname = NULL;
6369 if (strequal(mask,"????????.???")) {
6374 status = check_name(conn, directory);
6375 if (!NT_STATUS_IS_OK(status)) {
6376 reply_nterror(req, status);
6377 END_PROFILE(SMBcopy);
6381 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, 0);
6382 if (dir_hnd == NULL) {
6383 status = map_nt_error_from_unix(errno);
6384 reply_nterror(req, status);
6385 END_PROFILE(SMBcopy);
6391 while ((dname = ReadDirName(dir_hnd, &offset))) {
6392 char *destname = NULL;
6395 if (ISDOT(dname) || ISDOTDOT(dname)) {
6399 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
6403 if(!mask_match(dname, mask, conn->case_sensitive)) {
6407 error = ERRnoaccess;
6408 fname = talloc_asprintf(ctx,
6413 TALLOC_FREE(dir_hnd);
6414 reply_nterror(req, NT_STATUS_NO_MEMORY);
6415 END_PROFILE(SMBcopy);
6419 if (!resolve_wildcards(ctx,
6420 fname,newname,&destname)) {
6424 TALLOC_FREE(dir_hnd);
6425 reply_nterror(req, NT_STATUS_NO_MEMORY);
6426 END_PROFILE(SMBcopy);
6430 status = check_name(conn, fname);
6431 if (!NT_STATUS_IS_OK(status)) {
6432 TALLOC_FREE(dir_hnd);
6433 reply_nterror(req, status);
6434 END_PROFILE(SMBcopy);
6438 status = check_name(conn, destname);
6439 if (!NT_STATUS_IS_OK(status)) {
6440 TALLOC_FREE(dir_hnd);
6441 reply_nterror(req, status);
6442 END_PROFILE(SMBcopy);
6446 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
6448 status = copy_file(ctx,conn,fname,destname,ofun,
6449 count,target_is_directory);
6450 if (NT_STATUS_IS_OK(status)) {
6454 TALLOC_FREE(destname);
6456 TALLOC_FREE(dir_hnd);
6461 /* Error on close... */
6463 reply_unixerror(req, ERRHRD, ERRgeneral);
6464 END_PROFILE(SMBcopy);
6468 reply_doserror(req, ERRDOS, error);
6469 END_PROFILE(SMBcopy);
6473 reply_outbuf(req, 1, 0);
6474 SSVAL(req->outbuf,smb_vwv0,count);
6476 END_PROFILE(SMBcopy);
6481 #define DBGC_CLASS DBGC_LOCKING
6483 /****************************************************************************
6484 Get a lock pid, dealing with large count requests.
6485 ****************************************************************************/
6487 uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
6489 if(!large_file_format)
6490 return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
6492 return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
6495 /****************************************************************************
6496 Get a lock count, dealing with large count requests.
6497 ****************************************************************************/
6499 uint64_t get_lock_count( char *data, int data_offset, bool large_file_format)
6503 if(!large_file_format) {
6504 count = (uint64_t)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
6507 #if defined(HAVE_LONGLONG)
6508 count = (((uint64_t) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
6509 ((uint64_t) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
6510 #else /* HAVE_LONGLONG */
6513 * NT4.x seems to be broken in that it sends large file (64 bit)
6514 * lockingX calls even if the CAP_LARGE_FILES was *not*
6515 * negotiated. For boxes without large unsigned ints truncate the
6516 * lock count by dropping the top 32 bits.
6519 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
6520 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
6521 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
6522 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
6523 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
6526 count = (uint64_t)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
6527 #endif /* HAVE_LONGLONG */
6533 #if !defined(HAVE_LONGLONG)
6534 /****************************************************************************
6535 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
6536 ****************************************************************************/
6538 static uint32 map_lock_offset(uint32 high, uint32 low)
6542 uint32 highcopy = high;
6545 * Try and find out how many significant bits there are in high.
6548 for(i = 0; highcopy; i++)
6552 * We use 31 bits not 32 here as POSIX
6553 * lock offsets may not be negative.
6556 mask = (~0) << (31 - i);
6559 return 0; /* Fail. */
6565 #endif /* !defined(HAVE_LONGLONG) */
6567 /****************************************************************************
6568 Get a lock offset, dealing with large offset requests.
6569 ****************************************************************************/
6571 uint64_t get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err)
6573 uint64_t offset = 0;
6577 if(!large_file_format) {
6578 offset = (uint64_t)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
6581 #if defined(HAVE_LONGLONG)
6582 offset = (((uint64_t) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
6583 ((uint64_t) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
6584 #else /* HAVE_LONGLONG */
6587 * NT4.x seems to be broken in that it sends large file (64 bit)
6588 * lockingX calls even if the CAP_LARGE_FILES was *not*
6589 * negotiated. For boxes without large unsigned ints mangle the
6590 * lock offset by mapping the top 32 bits onto the lower 32.
6593 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
6594 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6595 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
6598 if((new_low = map_lock_offset(high, low)) == 0) {
6600 return (uint64_t)-1;
6603 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
6604 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
6605 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
6606 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
6609 offset = (uint64_t)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6610 #endif /* HAVE_LONGLONG */
6616 /****************************************************************************
6617 Reply to a lockingX request.
6618 ****************************************************************************/
6620 void reply_lockingX(struct smb_request *req)
6622 connection_struct *conn = req->conn;
6624 unsigned char locktype;
6625 unsigned char oplocklevel;
6628 uint64_t count = 0, offset = 0;
6633 bool large_file_format;
6635 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
6637 START_PROFILE(SMBlockingX);
6640 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6641 END_PROFILE(SMBlockingX);
6645 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
6646 locktype = CVAL(req->inbuf,smb_vwv3);
6647 oplocklevel = CVAL(req->inbuf,smb_vwv3+1);
6648 num_ulocks = SVAL(req->inbuf,smb_vwv6);
6649 num_locks = SVAL(req->inbuf,smb_vwv7);
6650 lock_timeout = IVAL(req->inbuf,smb_vwv4);
6651 large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
6653 if (!check_fsp(conn, req, fsp)) {
6654 END_PROFILE(SMBlockingX);
6658 data = smb_buf(req->inbuf);
6660 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
6661 /* we don't support these - and CANCEL_LOCK makes w2k
6662 and XP reboot so I don't really want to be
6663 compatible! (tridge) */
6664 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
6665 END_PROFILE(SMBlockingX);
6669 /* Check if this is an oplock break on a file
6670 we have granted an oplock on.
6672 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
6673 /* Client can insist on breaking to none. */
6674 bool break_to_none = (oplocklevel == 0);
6677 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
6678 "for fnum = %d\n", (unsigned int)oplocklevel,
6682 * Make sure we have granted an exclusive or batch oplock on
6686 if (fsp->oplock_type == 0) {
6688 /* The Samba4 nbench simulator doesn't understand
6689 the difference between break to level2 and break
6690 to none from level2 - it sends oplock break
6691 replies in both cases. Don't keep logging an error
6692 message here - just ignore it. JRA. */
6694 DEBUG(5,("reply_lockingX: Error : oplock break from "
6695 "client for fnum = %d (oplock=%d) and no "
6696 "oplock granted on this file (%s).\n",
6697 fsp->fnum, fsp->oplock_type, fsp->fsp_name));
6699 /* if this is a pure oplock break request then don't
6701 if (num_locks == 0 && num_ulocks == 0) {
6702 END_PROFILE(SMBlockingX);
6705 END_PROFILE(SMBlockingX);
6706 reply_doserror(req, ERRDOS, ERRlock);
6711 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
6713 result = remove_oplock(fsp);
6715 result = downgrade_oplock(fsp);
6719 DEBUG(0, ("reply_lockingX: error in removing "
6720 "oplock on file %s\n", fsp->fsp_name));
6721 /* Hmmm. Is this panic justified? */
6722 smb_panic("internal tdb error");
6725 reply_to_oplock_break_requests(fsp);
6727 /* if this is a pure oplock break request then don't send a
6729 if (num_locks == 0 && num_ulocks == 0) {
6730 /* Sanity check - ensure a pure oplock break is not a
6732 if(CVAL(req->inbuf,smb_vwv0) != 0xff)
6733 DEBUG(0,("reply_lockingX: Error : pure oplock "
6734 "break is a chained %d request !\n",
6735 (unsigned int)CVAL(req->inbuf,
6737 END_PROFILE(SMBlockingX);
6743 * We do this check *after* we have checked this is not a oplock break
6744 * response message. JRA.
6747 release_level_2_oplocks_on_change(fsp);
6749 if (smb_buflen(req->inbuf) <
6750 (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
6751 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6752 END_PROFILE(SMBlockingX);
6756 /* Data now points at the beginning of the list
6757 of smb_unlkrng structs */
6758 for(i = 0; i < (int)num_ulocks; i++) {
6759 lock_pid = get_lock_pid( data, i, large_file_format);
6760 count = get_lock_count( data, i, large_file_format);
6761 offset = get_lock_offset( data, i, large_file_format, &err);
6764 * There is no error code marked "stupid client bug".... :-).
6767 END_PROFILE(SMBlockingX);
6768 reply_doserror(req, ERRDOS, ERRnoaccess);
6772 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
6773 "pid %u, file %s\n", (double)offset, (double)count,
6774 (unsigned int)lock_pid, fsp->fsp_name ));
6776 status = do_unlock(smbd_messaging_context(),
6783 if (NT_STATUS_V(status)) {
6784 END_PROFILE(SMBlockingX);
6785 reply_nterror(req, status);
6790 /* Setup the timeout in seconds. */
6792 if (!lp_blocking_locks(SNUM(conn))) {
6796 /* Now do any requested locks */
6797 data += ((large_file_format ? 20 : 10)*num_ulocks);
6799 /* Data now points at the beginning of the list
6800 of smb_lkrng structs */
6802 for(i = 0; i < (int)num_locks; i++) {
6803 enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
6804 READ_LOCK:WRITE_LOCK);
6805 lock_pid = get_lock_pid( data, i, large_file_format);
6806 count = get_lock_count( data, i, large_file_format);
6807 offset = get_lock_offset( data, i, large_file_format, &err);
6810 * There is no error code marked "stupid client bug".... :-).
6813 END_PROFILE(SMBlockingX);
6814 reply_doserror(req, ERRDOS, ERRnoaccess);
6818 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
6819 "%u, file %s timeout = %d\n", (double)offset,
6820 (double)count, (unsigned int)lock_pid,
6821 fsp->fsp_name, (int)lock_timeout ));
6823 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
6824 if (lp_blocking_locks(SNUM(conn))) {
6826 /* Schedule a message to ourselves to
6827 remove the blocking lock record and
6828 return the right error. */
6830 if (!blocking_lock_cancel(fsp,
6836 NT_STATUS_FILE_LOCK_CONFLICT)) {
6837 END_PROFILE(SMBlockingX);
6842 ERRcancelviolation));
6846 /* Remove a matching pending lock. */
6847 status = do_lock_cancel(fsp,
6853 bool blocking_lock = lock_timeout ? True : False;
6854 bool defer_lock = False;
6855 struct byte_range_lock *br_lck;
6856 uint32 block_smbpid;
6858 br_lck = do_lock(smbd_messaging_context(),
6869 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6870 /* Windows internal resolution for blocking locks seems
6871 to be about 200ms... Don't wait for less than that. JRA. */
6872 if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
6873 lock_timeout = lp_lock_spin_time();
6878 /* This heuristic seems to match W2K3 very well. If a
6879 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
6880 it pretends we asked for a timeout of between 150 - 300 milliseconds as
6881 far as I can tell. Replacement for do_lock_spin(). JRA. */
6883 if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
6884 NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
6886 lock_timeout = lp_lock_spin_time();
6889 if (br_lck && defer_lock) {
6891 * A blocking lock was requested. Package up
6892 * this smb into a queued request and push it
6893 * onto the blocking lock queue.
6895 if(push_blocking_lock_request(br_lck,
6906 TALLOC_FREE(br_lck);
6907 END_PROFILE(SMBlockingX);
6912 TALLOC_FREE(br_lck);
6915 if (NT_STATUS_V(status)) {
6916 END_PROFILE(SMBlockingX);
6917 reply_nterror(req, status);
6922 /* If any of the above locks failed, then we must unlock
6923 all of the previous locks (X/Open spec). */
6925 if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) &&
6929 * Ensure we don't do a remove on the lock that just failed,
6930 * as under POSIX rules, if we have a lock already there, we
6931 * will delete it (and we shouldn't) .....
6933 for(i--; i >= 0; i--) {
6934 lock_pid = get_lock_pid( data, i, large_file_format);
6935 count = get_lock_count( data, i, large_file_format);
6936 offset = get_lock_offset( data, i, large_file_format,
6940 * There is no error code marked "stupid client
6944 END_PROFILE(SMBlockingX);
6945 reply_doserror(req, ERRDOS, ERRnoaccess);
6949 do_unlock(smbd_messaging_context(),
6956 END_PROFILE(SMBlockingX);
6957 reply_nterror(req, status);
6961 reply_outbuf(req, 2, 0);
6963 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
6964 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
6966 END_PROFILE(SMBlockingX);
6971 #define DBGC_CLASS DBGC_ALL
6973 /****************************************************************************
6974 Reply to a SMBreadbmpx (read block multiplex) request.
6975 Always reply with an error, if someone has a platform really needs this,
6976 please contact vl@samba.org
6977 ****************************************************************************/
6979 void reply_readbmpx(struct smb_request *req)
6981 START_PROFILE(SMBreadBmpx);
6982 reply_doserror(req, ERRSRV, ERRuseSTD);
6983 END_PROFILE(SMBreadBmpx);
6987 /****************************************************************************
6988 Reply to a SMBreadbs (read block multiplex secondary) request.
6989 Always reply with an error, if someone has a platform really needs this,
6990 please contact vl@samba.org
6991 ****************************************************************************/
6993 void reply_readbs(struct smb_request *req)
6995 START_PROFILE(SMBreadBs);
6996 reply_doserror(req, ERRSRV, ERRuseSTD);
6997 END_PROFILE(SMBreadBs);
7001 /****************************************************************************
7002 Reply to a SMBsetattrE.
7003 ****************************************************************************/
7005 void reply_setattrE(struct smb_request *req)
7007 connection_struct *conn = req->conn;
7008 struct timespec ts[2];
7010 SMB_STRUCT_STAT sbuf;
7013 START_PROFILE(SMBsetattrE);
7016 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7017 END_PROFILE(SMBsetattrE);
7021 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
7023 if(!fsp || (fsp->conn != conn)) {
7024 reply_doserror(req, ERRDOS, ERRbadfid);
7025 END_PROFILE(SMBsetattrE);
7031 * Convert the DOS times into unix times. Ignore create
7032 * time as UNIX can't set this.
7035 ts[0] = convert_time_t_to_timespec(
7036 srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */
7037 ts[1] = convert_time_t_to_timespec(
7038 srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */
7040 reply_outbuf(req, 0, 0);
7043 * Patch from Ray Frush <frush@engr.colostate.edu>
7044 * Sometimes times are sent as zero - ignore them.
7047 /* Ensure we have a valid stat struct for the source. */
7048 if (fsp->fh->fd != -1) {
7049 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
7050 status = map_nt_error_from_unix(errno);
7051 reply_nterror(req, status);
7052 END_PROFILE(SMBsetattrE);
7056 if (SMB_VFS_STAT(conn, fsp->fsp_name, &sbuf) == -1) {
7057 status = map_nt_error_from_unix(errno);
7058 reply_nterror(req, status);
7059 END_PROFILE(SMBsetattrE);
7064 status = smb_set_file_time(conn, fsp, fsp->fsp_name,
7066 if (!NT_STATUS_IS_OK(status)) {
7067 reply_doserror(req, ERRDOS, ERRnoaccess);
7068 END_PROFILE(SMBsetattrE);
7072 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
7074 (unsigned int)ts[0].tv_sec,
7075 (unsigned int)ts[1].tv_sec));
7077 END_PROFILE(SMBsetattrE);
7082 /* Back from the dead for OS/2..... JRA. */
7084 /****************************************************************************
7085 Reply to a SMBwritebmpx (write block multiplex primary) request.
7086 Always reply with an error, if someone has a platform really needs this,
7087 please contact vl@samba.org
7088 ****************************************************************************/
7090 void reply_writebmpx(struct smb_request *req)
7092 START_PROFILE(SMBwriteBmpx);
7093 reply_doserror(req, ERRSRV, ERRuseSTD);
7094 END_PROFILE(SMBwriteBmpx);
7098 /****************************************************************************
7099 Reply to a SMBwritebs (write block multiplex secondary) request.
7100 Always reply with an error, if someone has a platform really needs this,
7101 please contact vl@samba.org
7102 ****************************************************************************/
7104 void reply_writebs(struct smb_request *req)
7106 START_PROFILE(SMBwriteBs);
7107 reply_doserror(req, ERRSRV, ERRuseSTD);
7108 END_PROFILE(SMBwriteBs);
7112 /****************************************************************************
7113 Reply to a SMBgetattrE.
7114 ****************************************************************************/
7116 void reply_getattrE(struct smb_request *req)
7118 connection_struct *conn = req->conn;
7119 SMB_STRUCT_STAT sbuf;
7122 struct timespec create_ts;
7124 START_PROFILE(SMBgetattrE);
7127 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7128 END_PROFILE(SMBgetattrE);
7132 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
7134 if(!fsp || (fsp->conn != conn)) {
7135 reply_doserror(req, ERRDOS, ERRbadfid);
7136 END_PROFILE(SMBgetattrE);
7140 /* Do an fstat on this file */
7141 if(fsp_stat(fsp, &sbuf)) {
7142 reply_unixerror(req, ERRDOS, ERRnoaccess);
7143 END_PROFILE(SMBgetattrE);
7147 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
7150 * Convert the times into dos times. Set create
7151 * date to be last modify date as UNIX doesn't save
7155 reply_outbuf(req, 11, 0);
7157 create_ts = get_create_timespec(&sbuf,
7158 lp_fake_dir_create_times(SNUM(conn)));
7159 srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec);
7160 srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime);
7161 /* Should we check pending modtime here ? JRA */
7162 srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime);
7165 SIVAL(req->outbuf, smb_vwv6, 0);
7166 SIVAL(req->outbuf, smb_vwv8, 0);
7168 uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
7169 SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
7170 SIVAL(req->outbuf, smb_vwv8, allocation_size);
7172 SSVAL(req->outbuf,smb_vwv10, mode);
7174 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
7176 END_PROFILE(SMBgetattrE);