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 init_dfsroot(conn, req->inbuf, req->outbuf);
754 DEBUG(3,("tconX service=%s \n",
757 /* set the incoming and outgoing tid to the just created one */
758 SSVAL(req->inbuf,smb_tid,conn->cnum);
759 SSVAL(req->outbuf,smb_tid,conn->cnum);
761 END_PROFILE(SMBtconX);
767 /****************************************************************************
768 Reply to an unknown type.
769 ****************************************************************************/
771 void reply_unknown_new(struct smb_request *req, uint8 type)
773 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
774 smb_fn_name(type), type, type));
775 reply_doserror(req, ERRSRV, ERRunknownsmb);
779 /****************************************************************************
781 conn POINTER CAN BE NULL HERE !
782 ****************************************************************************/
784 void reply_ioctl(struct smb_request *req)
786 connection_struct *conn = req->conn;
793 START_PROFILE(SMBioctl);
796 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
797 END_PROFILE(SMBioctl);
801 device = SVAL(req->inbuf,smb_vwv1);
802 function = SVAL(req->inbuf,smb_vwv2);
803 ioctl_code = (device << 16) + function;
805 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
807 switch (ioctl_code) {
808 case IOCTL_QUERY_JOB_INFO:
812 reply_doserror(req, ERRSRV, ERRnosupport);
813 END_PROFILE(SMBioctl);
817 reply_outbuf(req, 8, replysize+1);
818 SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
819 SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
820 SSVAL(req->outbuf,smb_vwv6,52); /* Offset to data */
821 p = smb_buf(req->outbuf);
822 memset(p, '\0', replysize+1); /* valgrind-safe. */
823 p += 1; /* Allow for alignment */
825 switch (ioctl_code) {
826 case IOCTL_QUERY_JOB_INFO:
828 files_struct *fsp = file_fsp(SVAL(req->inbuf,
831 reply_doserror(req, ERRDOS, ERRbadfid);
832 END_PROFILE(SMBioctl);
835 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
836 srvstr_push((char *)req->outbuf, req->flags2, p+2,
838 STR_TERMINATE|STR_ASCII);
840 srvstr_push((char *)req->outbuf, req->flags2,
841 p+18, lp_servicename(SNUM(conn)),
842 13, STR_TERMINATE|STR_ASCII);
850 END_PROFILE(SMBioctl);
854 /****************************************************************************
855 Strange checkpath NTSTATUS mapping.
856 ****************************************************************************/
858 static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
860 /* Strange DOS error code semantics only for checkpath... */
861 if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
862 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
863 /* We need to map to ERRbadpath */
864 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
870 /****************************************************************************
871 Reply to a checkpath.
872 ****************************************************************************/
874 void reply_checkpath(struct smb_request *req)
876 connection_struct *conn = req->conn;
878 SMB_STRUCT_STAT sbuf;
880 TALLOC_CTX *ctx = talloc_tos();
882 START_PROFILE(SMBcheckpath);
884 srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
885 smb_buf(req->inbuf) + 1, 0,
886 STR_TERMINATE, &status);
887 if (!NT_STATUS_IS_OK(status)) {
888 status = map_checkpath_error((char *)req->inbuf, status);
889 reply_nterror(req, status);
890 END_PROFILE(SMBcheckpath);
894 status = resolve_dfspath(ctx, conn,
895 req->flags2 & FLAGS2_DFS_PATHNAMES,
898 if (!NT_STATUS_IS_OK(status)) {
899 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
900 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
902 END_PROFILE(SMBcheckpath);
908 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
910 status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
911 if (!NT_STATUS_IS_OK(status)) {
915 status = check_name(conn, name);
916 if (!NT_STATUS_IS_OK(status)) {
917 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status)));
921 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
922 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
923 status = map_nt_error_from_unix(errno);
927 if (!S_ISDIR(sbuf.st_mode)) {
928 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
930 END_PROFILE(SMBcheckpath);
934 reply_outbuf(req, 0, 0);
936 END_PROFILE(SMBcheckpath);
941 END_PROFILE(SMBcheckpath);
943 /* We special case this - as when a Windows machine
944 is parsing a path is steps through the components
945 one at a time - if a component fails it expects
946 ERRbadpath, not ERRbadfile.
948 status = map_checkpath_error((char *)req->inbuf, status);
949 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
951 * Windows returns different error codes if
952 * the parent directory is valid but not the
953 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
954 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
955 * if the path is invalid.
957 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
962 reply_nterror(req, status);
965 /****************************************************************************
967 ****************************************************************************/
969 void reply_getatr(struct smb_request *req)
971 connection_struct *conn = req->conn;
973 SMB_STRUCT_STAT sbuf;
979 TALLOC_CTX *ctx = talloc_tos();
981 START_PROFILE(SMBgetatr);
983 p = smb_buf(req->inbuf) + 1;
984 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
985 0, STR_TERMINATE, &status);
986 if (!NT_STATUS_IS_OK(status)) {
987 reply_nterror(req, status);
988 END_PROFILE(SMBgetatr);
992 status = resolve_dfspath(ctx, conn,
993 req->flags2 & FLAGS2_DFS_PATHNAMES,
996 if (!NT_STATUS_IS_OK(status)) {
997 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
998 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1000 END_PROFILE(SMBgetatr);
1003 reply_nterror(req, status);
1004 END_PROFILE(SMBgetatr);
1008 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1009 under WfWg - weird! */
1010 if (*fname == '\0') {
1011 mode = aHIDDEN | aDIR;
1012 if (!CAN_WRITE(conn)) {
1018 status = unix_convert(ctx, conn, fname, False, &fname, NULL,&sbuf);
1019 if (!NT_STATUS_IS_OK(status)) {
1020 reply_nterror(req, status);
1021 END_PROFILE(SMBgetatr);
1024 status = check_name(conn, fname);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
1027 reply_nterror(req, status);
1028 END_PROFILE(SMBgetatr);
1031 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
1032 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
1033 reply_unixerror(req, ERRDOS,ERRbadfile);
1034 END_PROFILE(SMBgetatr);
1038 mode = dos_mode(conn,fname,&sbuf);
1039 size = sbuf.st_size;
1040 mtime = sbuf.st_mtime;
1046 reply_outbuf(req, 10, 0);
1048 SSVAL(req->outbuf,smb_vwv0,mode);
1049 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1050 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1052 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1054 SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1056 if (Protocol >= PROTOCOL_NT1) {
1057 SSVAL(req->outbuf, smb_flg2,
1058 SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1061 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
1063 END_PROFILE(SMBgetatr);
1067 /****************************************************************************
1069 ****************************************************************************/
1071 void reply_setatr(struct smb_request *req)
1073 struct timespec ts[2];
1074 connection_struct *conn = req->conn;
1078 SMB_STRUCT_STAT sbuf;
1081 TALLOC_CTX *ctx = talloc_tos();
1083 START_PROFILE(SMBsetatr);
1088 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1092 p = smb_buf(req->inbuf) + 1;
1093 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
1094 0, STR_TERMINATE, &status);
1095 if (!NT_STATUS_IS_OK(status)) {
1096 reply_nterror(req, status);
1097 END_PROFILE(SMBsetatr);
1101 status = resolve_dfspath(ctx, conn,
1102 req->flags2 & FLAGS2_DFS_PATHNAMES,
1105 if (!NT_STATUS_IS_OK(status)) {
1106 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1107 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1108 ERRSRV, ERRbadpath);
1109 END_PROFILE(SMBsetatr);
1112 reply_nterror(req, status);
1113 END_PROFILE(SMBsetatr);
1117 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 reply_nterror(req, status);
1120 END_PROFILE(SMBsetatr);
1124 status = check_name(conn, fname);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 reply_nterror(req, status);
1127 END_PROFILE(SMBsetatr);
1131 if (fname[0] == '.' && fname[1] == '\0') {
1133 * Not sure here is the right place to catch this
1134 * condition. Might be moved to somewhere else later -- vl
1136 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1137 END_PROFILE(SMBsetatr);
1141 mode = SVAL(req->inbuf,smb_vwv0);
1142 mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
1144 ts[1] = convert_time_t_to_timespec(mtime);
1145 status = smb_set_file_time(conn, NULL, fname,
1147 if (!NT_STATUS_IS_OK(status)) {
1148 reply_unixerror(req, ERRDOS, ERRnoaccess);
1149 END_PROFILE(SMBsetatr);
1153 if (mode != FILE_ATTRIBUTE_NORMAL) {
1154 if (VALID_STAT_OF_DIR(sbuf))
1159 if (file_set_dosmode(conn,fname,mode,&sbuf,NULL,false) != 0) {
1160 reply_unixerror(req, ERRDOS, ERRnoaccess);
1161 END_PROFILE(SMBsetatr);
1166 reply_outbuf(req, 0, 0);
1168 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1170 END_PROFILE(SMBsetatr);
1174 /****************************************************************************
1176 ****************************************************************************/
1178 void reply_dskattr(struct smb_request *req)
1180 connection_struct *conn = req->conn;
1181 SMB_BIG_UINT dfree,dsize,bsize;
1182 START_PROFILE(SMBdskattr);
1184 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
1185 reply_unixerror(req, ERRHRD, ERRgeneral);
1186 END_PROFILE(SMBdskattr);
1190 reply_outbuf(req, 5, 0);
1192 if (Protocol <= PROTOCOL_LANMAN2) {
1193 double total_space, free_space;
1194 /* we need to scale this to a number that DOS6 can handle. We
1195 use floating point so we can handle large drives on systems
1196 that don't have 64 bit integers
1198 we end up displaying a maximum of 2G to DOS systems
1200 total_space = dsize * (double)bsize;
1201 free_space = dfree * (double)bsize;
1203 dsize = (SMB_BIG_UINT)((total_space+63*512) / (64*512));
1204 dfree = (SMB_BIG_UINT)((free_space+63*512) / (64*512));
1206 if (dsize > 0xFFFF) dsize = 0xFFFF;
1207 if (dfree > 0xFFFF) dfree = 0xFFFF;
1209 SSVAL(req->outbuf,smb_vwv0,dsize);
1210 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1211 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1212 SSVAL(req->outbuf,smb_vwv3,dfree);
1214 SSVAL(req->outbuf,smb_vwv0,dsize);
1215 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1216 SSVAL(req->outbuf,smb_vwv2,512);
1217 SSVAL(req->outbuf,smb_vwv3,dfree);
1220 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1222 END_PROFILE(SMBdskattr);
1226 /****************************************************************************
1228 Can be called from SMBsearch, SMBffirst or SMBfunique.
1229 ****************************************************************************/
1231 void reply_search(struct smb_request *req)
1233 connection_struct *conn = req->conn;
1235 char *directory = NULL;
1241 unsigned int numentries = 0;
1242 unsigned int maxentries = 0;
1243 bool finished = False;
1249 bool check_descend = False;
1250 bool expect_close = False;
1252 bool mask_contains_wcard = False;
1253 bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1254 TALLOC_CTX *ctx = talloc_tos();
1255 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1257 START_PROFILE(SMBsearch);
1260 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1261 END_PROFILE(SMBsearch);
1265 if (lp_posix_pathnames()) {
1266 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1267 END_PROFILE(SMBsearch);
1271 /* If we were called as SMBffirst then we must expect close. */
1272 if(CVAL(req->inbuf,smb_com) == SMBffirst) {
1273 expect_close = True;
1276 reply_outbuf(req, 1, 3);
1277 maxentries = SVAL(req->inbuf,smb_vwv0);
1278 dirtype = SVAL(req->inbuf,smb_vwv1);
1279 p = smb_buf(req->inbuf) + 1;
1280 p += srvstr_get_path_wcard(ctx,
1288 &mask_contains_wcard);
1289 if (!NT_STATUS_IS_OK(nt_status)) {
1290 reply_nterror(req, nt_status);
1291 END_PROFILE(SMBsearch);
1295 nt_status = resolve_dfspath_wcard(ctx, conn,
1296 req->flags2 & FLAGS2_DFS_PATHNAMES,
1299 &mask_contains_wcard);
1300 if (!NT_STATUS_IS_OK(nt_status)) {
1301 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1302 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1303 ERRSRV, ERRbadpath);
1304 END_PROFILE(SMBsearch);
1307 reply_nterror(req, nt_status);
1308 END_PROFILE(SMBsearch);
1313 status_len = SVAL(p, 0);
1316 /* dirtype &= ~aDIR; */
1318 if (status_len == 0) {
1319 SMB_STRUCT_STAT sbuf;
1321 nt_status = unix_convert(ctx, conn, path, True,
1322 &directory, NULL, &sbuf);
1323 if (!NT_STATUS_IS_OK(nt_status)) {
1324 reply_nterror(req, nt_status);
1325 END_PROFILE(SMBsearch);
1329 nt_status = check_name(conn, directory);
1330 if (!NT_STATUS_IS_OK(nt_status)) {
1331 reply_nterror(req, nt_status);
1332 END_PROFILE(SMBsearch);
1336 p = strrchr_m(directory,'/');
1339 directory = talloc_strdup(ctx,".");
1341 reply_nterror(req, NT_STATUS_NO_MEMORY);
1342 END_PROFILE(SMBsearch);
1350 if (*directory == '\0') {
1351 directory = talloc_strdup(ctx,".");
1353 reply_nterror(req, NT_STATUS_NO_MEMORY);
1354 END_PROFILE(SMBsearch);
1358 memset((char *)status,'\0',21);
1359 SCVAL(status,0,(dirtype & 0x1F));
1361 nt_status = dptr_create(conn,
1367 mask_contains_wcard,
1370 if (!NT_STATUS_IS_OK(nt_status)) {
1371 reply_nterror(req, nt_status);
1372 END_PROFILE(SMBsearch);
1375 dptr_num = dptr_dnum(conn->dirptr);
1379 memcpy(status,p,21);
1380 status_dirtype = CVAL(status,0) & 0x1F;
1381 if (status_dirtype != (dirtype & 0x1F)) {
1382 dirtype = status_dirtype;
1385 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1386 if (!conn->dirptr) {
1389 string_set(&conn->dirpath,dptr_path(dptr_num));
1390 mask = dptr_wcard(dptr_num);
1395 * For a 'continue' search we have no string. So
1396 * check from the initial saved string.
1398 mask_contains_wcard = ms_has_wild(mask);
1399 dirtype = dptr_attr(dptr_num);
1402 DEBUG(4,("dptr_num is %d\n",dptr_num));
1404 if ((dirtype&0x1F) == aVOLID) {
1405 char buf[DIR_STRUCT_SIZE];
1406 memcpy(buf,status,21);
1407 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1408 0,aVOLID,0,!allow_long_path_components)) {
1409 reply_nterror(req, NT_STATUS_NO_MEMORY);
1410 END_PROFILE(SMBsearch);
1413 dptr_fill(buf+12,dptr_num);
1414 if (dptr_zero(buf+12) && (status_len==0)) {
1419 if (message_push_blob(&req->outbuf,
1420 data_blob_const(buf, sizeof(buf)))
1422 reply_nterror(req, NT_STATUS_NO_MEMORY);
1423 END_PROFILE(SMBsearch);
1431 ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1434 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1435 conn->dirpath,lp_dontdescend(SNUM(conn))));
1436 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) {
1437 check_descend = True;
1440 for (i=numentries;(i<maxentries) && !finished;i++) {
1441 finished = !get_dir_entry(ctx,
1452 char buf[DIR_STRUCT_SIZE];
1453 memcpy(buf,status,21);
1454 if (!make_dir_struct(ctx,
1461 !allow_long_path_components)) {
1462 reply_nterror(req, NT_STATUS_NO_MEMORY);
1463 END_PROFILE(SMBsearch);
1466 if (!dptr_fill(buf+12,dptr_num)) {
1469 if (message_push_blob(&req->outbuf,
1470 data_blob_const(buf, sizeof(buf)))
1472 reply_nterror(req, NT_STATUS_NO_MEMORY);
1473 END_PROFILE(SMBsearch);
1483 /* If we were called as SMBffirst with smb_search_id == NULL
1484 and no entries were found then return error and close dirptr
1487 if (numentries == 0) {
1488 dptr_close(&dptr_num);
1489 } else if(expect_close && status_len == 0) {
1490 /* Close the dptr - we know it's gone */
1491 dptr_close(&dptr_num);
1494 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1495 if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
1496 dptr_close(&dptr_num);
1499 if ((numentries == 0) && !mask_contains_wcard) {
1500 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1501 END_PROFILE(SMBsearch);
1505 SSVAL(req->outbuf,smb_vwv0,numentries);
1506 SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1507 SCVAL(smb_buf(req->outbuf),0,5);
1508 SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1510 /* The replies here are never long name. */
1511 SSVAL(req->outbuf, smb_flg2,
1512 SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1513 if (!allow_long_path_components) {
1514 SSVAL(req->outbuf, smb_flg2,
1515 SVAL(req->outbuf, smb_flg2)
1516 & (~FLAGS2_LONG_PATH_COMPONENTS));
1519 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1520 SSVAL(req->outbuf, smb_flg2,
1521 (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1524 directory = dptr_path(dptr_num);
1527 DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1528 smb_fn_name(CVAL(req->inbuf,smb_com)),
1530 directory ? directory : "./",
1535 END_PROFILE(SMBsearch);
1539 /****************************************************************************
1540 Reply to a fclose (stop directory search).
1541 ****************************************************************************/
1543 void reply_fclose(struct smb_request *req)
1551 bool path_contains_wcard = False;
1552 TALLOC_CTX *ctx = talloc_tos();
1554 START_PROFILE(SMBfclose);
1556 if (lp_posix_pathnames()) {
1557 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1558 END_PROFILE(SMBfclose);
1562 p = smb_buf(req->inbuf) + 1;
1563 p += srvstr_get_path_wcard(ctx,
1571 &path_contains_wcard);
1572 if (!NT_STATUS_IS_OK(err)) {
1573 reply_nterror(req, err);
1574 END_PROFILE(SMBfclose);
1578 status_len = SVAL(p,0);
1581 if (status_len == 0) {
1582 reply_doserror(req, ERRSRV, ERRsrverror);
1583 END_PROFILE(SMBfclose);
1587 memcpy(status,p,21);
1589 if(dptr_fetch(status+12,&dptr_num)) {
1590 /* Close the dptr - we know it's gone */
1591 dptr_close(&dptr_num);
1594 reply_outbuf(req, 1, 0);
1595 SSVAL(req->outbuf,smb_vwv0,0);
1597 DEBUG(3,("search close\n"));
1599 END_PROFILE(SMBfclose);
1603 /****************************************************************************
1605 ****************************************************************************/
1607 void reply_open(struct smb_request *req)
1609 connection_struct *conn = req->conn;
1615 SMB_STRUCT_STAT sbuf;
1622 uint32 create_disposition;
1623 uint32 create_options = 0;
1625 TALLOC_CTX *ctx = talloc_tos();
1627 START_PROFILE(SMBopen);
1630 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1631 END_PROFILE(SMBopen);
1635 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1636 deny_mode = SVAL(req->inbuf,smb_vwv0);
1637 dos_attr = SVAL(req->inbuf,smb_vwv1);
1639 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1640 smb_buf(req->inbuf)+1, 0,
1641 STR_TERMINATE, &status);
1642 if (!NT_STATUS_IS_OK(status)) {
1643 reply_nterror(req, status);
1644 END_PROFILE(SMBopen);
1648 if (!map_open_params_to_ntcreate(
1649 fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
1650 &share_mode, &create_disposition, &create_options)) {
1651 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1652 END_PROFILE(SMBopen);
1656 status = create_file(conn, /* conn */
1658 0, /* root_dir_fid */
1660 access_mask, /* access_mask */
1661 share_mode, /* share_access */
1662 create_disposition, /* create_disposition*/
1663 create_options, /* create_options */
1664 dos_attr, /* file_attributes */
1665 oplock_request, /* oplock_request */
1666 0, /* allocation_size */
1673 if (!NT_STATUS_IS_OK(status)) {
1674 if (open_was_deferred(req->mid)) {
1675 /* We have re-scheduled this call. */
1676 END_PROFILE(SMBopen);
1679 reply_openerror(req, status);
1680 END_PROFILE(SMBopen);
1684 size = sbuf.st_size;
1685 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1686 mtime = sbuf.st_mtime;
1689 DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
1690 close_file(fsp,ERROR_CLOSE);
1691 reply_doserror(req, ERRDOS,ERRnoaccess);
1692 END_PROFILE(SMBopen);
1696 reply_outbuf(req, 7, 0);
1697 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1698 SSVAL(req->outbuf,smb_vwv1,fattr);
1699 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1700 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1702 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1704 SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1705 SSVAL(req->outbuf,smb_vwv6,deny_mode);
1707 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1708 SCVAL(req->outbuf,smb_flg,
1709 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1712 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1713 SCVAL(req->outbuf,smb_flg,
1714 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1716 END_PROFILE(SMBopen);
1720 /****************************************************************************
1721 Reply to an open and X.
1722 ****************************************************************************/
1724 void reply_open_and_X(struct smb_request *req)
1726 connection_struct *conn = req->conn;
1731 /* Breakout the oplock request bits so we can set the
1732 reply bits separately. */
1733 int ex_oplock_request;
1734 int core_oplock_request;
1737 int smb_sattr = SVAL(req->inbuf,smb_vwv4);
1738 uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6);
1743 SMB_STRUCT_STAT sbuf;
1747 SMB_BIG_UINT allocation_size;
1748 ssize_t retval = -1;
1751 uint32 create_disposition;
1752 uint32 create_options = 0;
1753 TALLOC_CTX *ctx = talloc_tos();
1755 START_PROFILE(SMBopenX);
1757 if (req->wct < 15) {
1758 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1759 END_PROFILE(SMBopenX);
1763 open_flags = SVAL(req->inbuf,smb_vwv2);
1764 deny_mode = SVAL(req->inbuf,smb_vwv3);
1765 smb_attr = SVAL(req->inbuf,smb_vwv5);
1766 ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1767 core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1768 oplock_request = ex_oplock_request | core_oplock_request;
1769 smb_ofun = SVAL(req->inbuf,smb_vwv8);
1770 allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv9);
1772 /* If it's an IPC, pass off the pipe handler. */
1774 if (lp_nt_pipe_support()) {
1775 reply_open_pipe_and_X(conn, req);
1777 reply_doserror(req, ERRSRV, ERRaccess);
1779 END_PROFILE(SMBopenX);
1783 /* XXXX we need to handle passed times, sattr and flags */
1784 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1785 smb_buf(req->inbuf), 0, STR_TERMINATE,
1787 if (!NT_STATUS_IS_OK(status)) {
1788 reply_nterror(req, status);
1789 END_PROFILE(SMBopenX);
1793 if (!map_open_params_to_ntcreate(
1794 fname, deny_mode, smb_ofun, &access_mask,
1795 &share_mode, &create_disposition, &create_options)) {
1796 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1797 END_PROFILE(SMBopenX);
1801 status = create_file(conn, /* conn */
1803 0, /* root_dir_fid */
1805 access_mask, /* access_mask */
1806 share_mode, /* share_access */
1807 create_disposition, /* create_disposition*/
1808 create_options, /* create_options */
1809 smb_attr, /* file_attributes */
1810 oplock_request, /* oplock_request */
1811 0, /* allocation_size */
1815 &smb_action, /* pinfo */
1818 if (!NT_STATUS_IS_OK(status)) {
1819 END_PROFILE(SMBopenX);
1820 if (open_was_deferred(req->mid)) {
1821 /* We have re-scheduled this call. */
1824 reply_openerror(req, status);
1828 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1829 if the file is truncated or created. */
1830 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1831 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1832 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1833 close_file(fsp,ERROR_CLOSE);
1834 reply_nterror(req, NT_STATUS_DISK_FULL);
1835 END_PROFILE(SMBopenX);
1838 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1840 close_file(fsp,ERROR_CLOSE);
1841 reply_nterror(req, NT_STATUS_DISK_FULL);
1842 END_PROFILE(SMBopenX);
1845 sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
1848 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1849 mtime = sbuf.st_mtime;
1851 close_file(fsp,ERROR_CLOSE);
1852 reply_doserror(req, ERRDOS, ERRnoaccess);
1853 END_PROFILE(SMBopenX);
1857 /* If the caller set the extended oplock request bit
1858 and we granted one (by whatever means) - set the
1859 correct bit for extended oplock reply.
1862 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1863 smb_action |= EXTENDED_OPLOCK_GRANTED;
1866 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1867 smb_action |= EXTENDED_OPLOCK_GRANTED;
1870 /* If the caller set the core oplock request bit
1871 and we granted one (by whatever means) - set the
1872 correct bit for core oplock reply.
1875 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1876 reply_outbuf(req, 19, 0);
1878 reply_outbuf(req, 15, 0);
1881 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1882 SCVAL(req->outbuf, smb_flg,
1883 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1886 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1887 SCVAL(req->outbuf, smb_flg,
1888 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1891 SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
1892 SSVAL(req->outbuf,smb_vwv3,fattr);
1893 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1894 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
1896 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
1898 SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size);
1899 SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
1900 SSVAL(req->outbuf,smb_vwv11,smb_action);
1902 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1903 SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
1906 END_PROFILE(SMBopenX);
1911 /****************************************************************************
1912 Reply to a SMBulogoffX.
1913 ****************************************************************************/
1915 void reply_ulogoffX(struct smb_request *req)
1919 START_PROFILE(SMBulogoffX);
1921 vuser = get_valid_user_struct(req->vuid);
1924 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
1928 /* in user level security we are supposed to close any files
1929 open by this user */
1930 if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
1931 file_close_user(req->vuid);
1934 invalidate_vuid(req->vuid);
1936 reply_outbuf(req, 2, 0);
1938 DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
1940 END_PROFILE(SMBulogoffX);
1944 /****************************************************************************
1945 Reply to a mknew or a create.
1946 ****************************************************************************/
1948 void reply_mknew(struct smb_request *req)
1950 connection_struct *conn = req->conn;
1954 struct timespec ts[2];
1956 int oplock_request = 0;
1957 SMB_STRUCT_STAT sbuf;
1959 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
1960 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1961 uint32 create_disposition;
1962 uint32 create_options = 0;
1963 TALLOC_CTX *ctx = talloc_tos();
1965 START_PROFILE(SMBcreate);
1968 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1969 END_PROFILE(SMBcreate);
1973 fattr = SVAL(req->inbuf,smb_vwv0);
1974 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1975 com = SVAL(req->inbuf,smb_com);
1977 ts[1] =convert_time_t_to_timespec(
1978 srv_make_unix_date3(req->inbuf + smb_vwv1));
1981 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1982 smb_buf(req->inbuf) + 1, 0,
1983 STR_TERMINATE, &status);
1984 if (!NT_STATUS_IS_OK(status)) {
1985 reply_nterror(req, status);
1986 END_PROFILE(SMBcreate);
1990 if (fattr & aVOLID) {
1991 DEBUG(0,("Attempt to create file (%s) with volid set - "
1992 "please report this\n", fname));
1995 if(com == SMBmknew) {
1996 /* We should fail if file exists. */
1997 create_disposition = FILE_CREATE;
1999 /* Create if file doesn't exist, truncate if it does. */
2000 create_disposition = FILE_OVERWRITE_IF;
2003 status = create_file(conn, /* conn */
2005 0, /* root_dir_fid */
2007 access_mask, /* access_mask */
2008 share_mode, /* share_access */
2009 create_disposition, /* create_disposition*/
2010 create_options, /* create_options */
2011 fattr, /* file_attributes */
2012 oplock_request, /* oplock_request */
2013 0, /* allocation_size */
2020 if (!NT_STATUS_IS_OK(status)) {
2021 END_PROFILE(SMBcreate);
2022 if (open_was_deferred(req->mid)) {
2023 /* We have re-scheduled this call. */
2026 reply_openerror(req, status);
2030 ts[0] = get_atimespec(&sbuf); /* atime. */
2031 status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true);
2032 if (!NT_STATUS_IS_OK(status)) {
2033 END_PROFILE(SMBcreate);
2034 reply_openerror(req, status);
2038 reply_outbuf(req, 1, 0);
2039 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2041 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2042 SCVAL(req->outbuf,smb_flg,
2043 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2046 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2047 SCVAL(req->outbuf,smb_flg,
2048 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2051 DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) );
2052 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
2053 fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
2055 END_PROFILE(SMBcreate);
2059 /****************************************************************************
2060 Reply to a create temporary file.
2061 ****************************************************************************/
2063 void reply_ctemp(struct smb_request *req)
2065 connection_struct *conn = req->conn;
2071 SMB_STRUCT_STAT sbuf;
2074 TALLOC_CTX *ctx = talloc_tos();
2076 START_PROFILE(SMBctemp);
2079 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2080 END_PROFILE(SMBctemp);
2084 fattr = SVAL(req->inbuf,smb_vwv0);
2085 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2087 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
2088 smb_buf(req->inbuf)+1, 0, STR_TERMINATE,
2090 if (!NT_STATUS_IS_OK(status)) {
2091 reply_nterror(req, status);
2092 END_PROFILE(SMBctemp);
2096 fname = talloc_asprintf(ctx,
2100 fname = talloc_strdup(ctx, "TMXXXXXX");
2104 reply_nterror(req, NT_STATUS_NO_MEMORY);
2105 END_PROFILE(SMBctemp);
2109 status = resolve_dfspath(ctx, conn,
2110 req->flags2 & FLAGS2_DFS_PATHNAMES,
2113 if (!NT_STATUS_IS_OK(status)) {
2114 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2115 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2116 ERRSRV, ERRbadpath);
2117 END_PROFILE(SMBctemp);
2120 reply_nterror(req, status);
2121 END_PROFILE(SMBctemp);
2125 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
2126 if (!NT_STATUS_IS_OK(status)) {
2127 reply_nterror(req, status);
2128 END_PROFILE(SMBctemp);
2132 status = check_name(conn, fname);
2133 if (!NT_STATUS_IS_OK(status)) {
2134 reply_nterror(req, status);
2135 END_PROFILE(SMBctemp);
2139 tmpfd = smb_mkstemp(fname);
2141 reply_unixerror(req, ERRDOS, ERRnoaccess);
2142 END_PROFILE(SMBctemp);
2146 SMB_VFS_STAT(conn,fname,&sbuf);
2148 /* We should fail if file does not exist. */
2149 status = open_file_ntcreate(conn, req, fname, &sbuf,
2150 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
2151 FILE_SHARE_READ|FILE_SHARE_WRITE,
2158 /* close fd from smb_mkstemp() */
2161 if (!NT_STATUS_IS_OK(status)) {
2162 if (open_was_deferred(req->mid)) {
2163 /* We have re-scheduled this call. */
2164 END_PROFILE(SMBctemp);
2167 reply_openerror(req, status);
2168 END_PROFILE(SMBctemp);
2172 reply_outbuf(req, 1, 0);
2173 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2175 /* the returned filename is relative to the directory */
2176 s = strrchr_m(fsp->fsp_name, '/');
2184 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2185 thing in the byte section. JRA */
2186 SSVALS(p, 0, -1); /* what is this? not in spec */
2188 if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2190 reply_nterror(req, NT_STATUS_NO_MEMORY);
2191 END_PROFILE(SMBctemp);
2195 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2196 SCVAL(req->outbuf, smb_flg,
2197 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2200 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2201 SCVAL(req->outbuf, smb_flg,
2202 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2205 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
2206 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
2207 fsp->fh->fd, (unsigned int)sbuf.st_mode ) );
2209 END_PROFILE(SMBctemp);
2213 /*******************************************************************
2214 Check if a user is allowed to rename a file.
2215 ********************************************************************/
2217 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2218 uint16 dirtype, SMB_STRUCT_STAT *pst)
2222 if (!CAN_WRITE(conn)) {
2223 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2226 fmode = dos_mode(conn, fsp->fsp_name, pst);
2227 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
2228 return NT_STATUS_NO_SUCH_FILE;
2231 if (S_ISDIR(pst->st_mode)) {
2232 return NT_STATUS_OK;
2235 if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
2236 return NT_STATUS_OK;
2239 return NT_STATUS_ACCESS_DENIED;
2242 /*******************************************************************
2243 * unlink a file with all relevant access checks
2244 *******************************************************************/
2246 static NTSTATUS do_unlink(connection_struct *conn,
2247 struct smb_request *req,
2251 SMB_STRUCT_STAT sbuf;
2254 uint32 dirtype_orig = dirtype;
2257 DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
2259 if (!CAN_WRITE(conn)) {
2260 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2263 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
2264 return map_nt_error_from_unix(errno);
2267 fattr = dos_mode(conn,fname,&sbuf);
2269 if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2270 dirtype = aDIR|aARCH|aRONLY;
2273 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
2275 return NT_STATUS_NO_SUCH_FILE;
2278 if (!dir_check_ftype(conn, fattr, dirtype)) {
2280 return NT_STATUS_FILE_IS_A_DIRECTORY;
2282 return NT_STATUS_NO_SUCH_FILE;
2285 if (dirtype_orig & 0x8000) {
2286 /* These will never be set for POSIX. */
2287 return NT_STATUS_NO_SUCH_FILE;
2291 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2292 return NT_STATUS_FILE_IS_A_DIRECTORY;
2295 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2296 return NT_STATUS_NO_SUCH_FILE;
2299 if (dirtype & 0xFF00) {
2300 /* These will never be set for POSIX. */
2301 return NT_STATUS_NO_SUCH_FILE;
2306 return NT_STATUS_NO_SUCH_FILE;
2309 /* Can't delete a directory. */
2311 return NT_STATUS_FILE_IS_A_DIRECTORY;
2316 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
2317 return NT_STATUS_OBJECT_NAME_INVALID;
2318 #endif /* JRATEST */
2320 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
2322 On a Windows share, a file with read-only dosmode can be opened with
2323 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
2324 fails with NT_STATUS_CANNOT_DELETE error.
2326 This semantic causes a problem that a user can not
2327 rename a file with read-only dosmode on a Samba share
2328 from a Windows command prompt (i.e. cmd.exe, but can rename
2329 from Windows Explorer).
2332 if (!lp_delete_readonly(SNUM(conn))) {
2333 if (fattr & aRONLY) {
2334 return NT_STATUS_CANNOT_DELETE;
2338 /* On open checks the open itself will check the share mode, so
2339 don't do it here as we'll get it wrong. */
2341 status = create_file_unixpath
2345 DELETE_ACCESS, /* access_mask */
2346 FILE_SHARE_NONE, /* share_access */
2347 FILE_OPEN, /* create_disposition*/
2348 FILE_NON_DIRECTORY_FILE, /* create_options */
2349 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2350 0, /* oplock_request */
2351 0, /* allocation_size */
2358 if (!NT_STATUS_IS_OK(status)) {
2359 DEBUG(10, ("create_file_unixpath failed: %s\n",
2360 nt_errstr(status)));
2364 /* The set is across all open files on this dev/inode pair. */
2365 if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) {
2366 close_file(fsp, NORMAL_CLOSE);
2367 return NT_STATUS_ACCESS_DENIED;
2370 return close_file(fsp,NORMAL_CLOSE);
2373 /****************************************************************************
2374 The guts of the unlink command, split out so it may be called by the NT SMB
2376 ****************************************************************************/
2378 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2379 uint32 dirtype, const char *name_in, bool has_wild)
2381 const char *directory = NULL;
2386 NTSTATUS status = NT_STATUS_OK;
2387 SMB_STRUCT_STAT sbuf;
2388 TALLOC_CTX *ctx = talloc_tos();
2390 status = unix_convert(ctx, conn, name_in, has_wild, &name, NULL, &sbuf);
2391 if (!NT_STATUS_IS_OK(status)) {
2395 p = strrchr_m(name,'/');
2397 directory = talloc_strdup(ctx, ".");
2399 return NT_STATUS_NO_MEMORY;
2409 * We should only check the mangled cache
2410 * here if unix_convert failed. This means
2411 * that the path in 'mask' doesn't exist
2412 * on the file system and so we need to look
2413 * for a possible mangle. This patch from
2414 * Tine Smukavec <valentin.smukavec@hermes.si>.
2417 if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) {
2418 char *new_mask = NULL;
2419 mangle_lookup_name_from_8_3(ctx,
2429 directory = talloc_asprintf(ctx,
2434 return NT_STATUS_NO_MEMORY;
2437 dirtype = FILE_ATTRIBUTE_NORMAL;
2440 status = check_name(conn, directory);
2441 if (!NT_STATUS_IS_OK(status)) {
2445 status = do_unlink(conn, req, directory, dirtype);
2446 if (!NT_STATUS_IS_OK(status)) {
2452 struct smb_Dir *dir_hnd = NULL;
2456 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2457 return NT_STATUS_OBJECT_NAME_INVALID;
2460 if (strequal(mask,"????????.???")) {
2465 status = check_name(conn, directory);
2466 if (!NT_STATUS_IS_OK(status)) {
2470 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask,
2472 if (dir_hnd == NULL) {
2473 return map_nt_error_from_unix(errno);
2476 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2477 the pattern matches against the long name, otherwise the short name
2478 We don't implement this yet XXXX
2481 status = NT_STATUS_NO_SUCH_FILE;
2483 while ((dname = ReadDirName(dir_hnd, &offset))) {
2487 if (!is_visible_file(conn, directory, dname, &st, True)) {
2491 /* Quick check for "." and ".." */
2492 if (ISDOT(dname) || ISDOTDOT(dname)) {
2496 if(!mask_match(dname, mask, conn->case_sensitive)) {
2500 fname = talloc_asprintf(ctx, "%s/%s",
2504 return NT_STATUS_NO_MEMORY;
2507 status = check_name(conn, fname);
2508 if (!NT_STATUS_IS_OK(status)) {
2509 TALLOC_FREE(dir_hnd);
2513 status = do_unlink(conn, req, fname, dirtype);
2514 if (!NT_STATUS_IS_OK(status)) {
2520 DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2525 TALLOC_FREE(dir_hnd);
2528 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
2529 status = map_nt_error_from_unix(errno);
2535 /****************************************************************************
2537 ****************************************************************************/
2539 void reply_unlink(struct smb_request *req)
2541 connection_struct *conn = req->conn;
2545 bool path_contains_wcard = False;
2546 TALLOC_CTX *ctx = talloc_tos();
2548 START_PROFILE(SMBunlink);
2551 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2552 END_PROFILE(SMBunlink);
2556 dirtype = SVAL(req->inbuf,smb_vwv0);
2558 srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
2559 smb_buf(req->inbuf) + 1, 0,
2560 STR_TERMINATE, &status, &path_contains_wcard);
2561 if (!NT_STATUS_IS_OK(status)) {
2562 reply_nterror(req, status);
2563 END_PROFILE(SMBunlink);
2567 status = resolve_dfspath_wcard(ctx, conn,
2568 req->flags2 & FLAGS2_DFS_PATHNAMES,
2571 &path_contains_wcard);
2572 if (!NT_STATUS_IS_OK(status)) {
2573 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2574 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2575 ERRSRV, ERRbadpath);
2576 END_PROFILE(SMBunlink);
2579 reply_nterror(req, status);
2580 END_PROFILE(SMBunlink);
2584 DEBUG(3,("reply_unlink : %s\n",name));
2586 status = unlink_internals(conn, req, dirtype, name,
2587 path_contains_wcard);
2588 if (!NT_STATUS_IS_OK(status)) {
2589 if (open_was_deferred(req->mid)) {
2590 /* We have re-scheduled this call. */
2591 END_PROFILE(SMBunlink);
2594 reply_nterror(req, status);
2595 END_PROFILE(SMBunlink);
2599 reply_outbuf(req, 0, 0);
2600 END_PROFILE(SMBunlink);
2605 /****************************************************************************
2607 ****************************************************************************/
2609 static void fail_readraw(void)
2611 const char *errstr = talloc_asprintf(talloc_tos(),
2612 "FAIL ! reply_readbraw: socket write fail (%s)",
2617 exit_server_cleanly(errstr);
2620 /****************************************************************************
2621 Fake (read/write) sendfile. Returns -1 on read or write fail.
2622 ****************************************************************************/
2624 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
2628 size_t tosend = nread;
2635 bufsize = MIN(nread, 65536);
2637 if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2641 while (tosend > 0) {
2645 if (tosend > bufsize) {
2650 ret = read_file(fsp,buf,startpos,cur_read);
2656 /* If we had a short read, fill with zeros. */
2657 if (ret < cur_read) {
2658 memset(buf, '\0', cur_read - ret);
2661 if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
2666 startpos += cur_read;
2670 return (ssize_t)nread;
2673 /****************************************************************************
2674 Return a readbraw error (4 bytes of zero).
2675 ****************************************************************************/
2677 static void reply_readbraw_error(void)
2681 if (write_data(smbd_server_fd(),header,4) != 4) {
2686 /****************************************************************************
2687 Use sendfile in readbraw.
2688 ****************************************************************************/
2690 void send_file_readbraw(connection_struct *conn,
2696 char *outbuf = NULL;
2699 #if defined(WITH_SENDFILE)
2701 * We can only use sendfile on a non-chained packet
2702 * but we can use on a non-oplocked file. tridge proved this
2703 * on a train in Germany :-). JRA.
2704 * reply_readbraw has already checked the length.
2707 if ( (chain_size == 0) && (nread > 0) && (fsp->base_fsp == NULL) &&
2708 (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
2710 DATA_BLOB header_blob;
2712 _smb_setlen(header,nread);
2713 header_blob = data_blob_const(header, 4);
2715 if (SMB_VFS_SENDFILE(smbd_server_fd(), fsp,
2716 &header_blob, startpos, nread) == -1) {
2717 /* Returning ENOSYS means no data at all was sent.
2718 * Do this as a normal read. */
2719 if (errno == ENOSYS) {
2720 goto normal_readbraw;
2724 * Special hack for broken Linux with no working sendfile. If we
2725 * return EINTR we sent the header but not the rest of the data.
2726 * Fake this up by doing read/write calls.
2728 if (errno == EINTR) {
2729 /* Ensure we don't do this again. */
2730 set_use_sendfile(SNUM(conn), False);
2731 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2733 if (fake_sendfile(fsp, startpos, nread) == -1) {
2734 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2735 fsp->fsp_name, strerror(errno) ));
2736 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2741 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2742 fsp->fsp_name, strerror(errno) ));
2743 exit_server_cleanly("send_file_readbraw sendfile failed");
2752 outbuf = TALLOC_ARRAY(NULL, char, nread+4);
2754 DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
2755 (unsigned)(nread+4)));
2756 reply_readbraw_error();
2761 ret = read_file(fsp,outbuf+4,startpos,nread);
2762 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2771 _smb_setlen(outbuf,ret);
2772 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2775 TALLOC_FREE(outbuf);
2778 /****************************************************************************
2779 Reply to a readbraw (core+ protocol).
2780 ****************************************************************************/
2782 void reply_readbraw(struct smb_request *req)
2784 connection_struct *conn = req->conn;
2785 ssize_t maxcount,mincount;
2792 START_PROFILE(SMBreadbraw);
2794 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
2795 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
2796 "raw reads/writes are disallowed.");
2800 reply_readbraw_error();
2801 END_PROFILE(SMBreadbraw);
2806 * Special check if an oplock break has been issued
2807 * and the readraw request croses on the wire, we must
2808 * return a zero length response here.
2811 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
2814 * We have to do a check_fsp by hand here, as
2815 * we must always return 4 zero bytes on error,
2819 if (!fsp || !conn || conn != fsp->conn ||
2820 req->vuid != fsp->vuid ||
2821 fsp->is_directory || fsp->fh->fd == -1) {
2823 * fsp could be NULL here so use the value from the packet. JRA.
2825 DEBUG(3,("reply_readbraw: fnum %d not valid "
2827 (int)SVAL(req->inbuf,smb_vwv0)));
2828 reply_readbraw_error();
2829 END_PROFILE(SMBreadbraw);
2833 /* Do a "by hand" version of CHECK_READ. */
2834 if (!(fsp->can_read ||
2835 ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
2836 (fsp->access_mask & FILE_EXECUTE)))) {
2837 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
2838 (int)SVAL(req->inbuf,smb_vwv0)));
2839 reply_readbraw_error();
2840 END_PROFILE(SMBreadbraw);
2844 flush_write_cache(fsp, READRAW_FLUSH);
2846 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
2847 if(req->wct == 10) {
2849 * This is a large offset (64 bit) read.
2851 #ifdef LARGE_SMB_OFF_T
2853 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
2855 #else /* !LARGE_SMB_OFF_T */
2858 * Ensure we haven't been sent a >32 bit offset.
2861 if(IVAL(req->inbuf,smb_vwv8) != 0) {
2862 DEBUG(0,("reply_readbraw: large offset "
2863 "(%x << 32) used and we don't support "
2864 "64 bit offsets.\n",
2865 (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
2866 reply_readbraw_error();
2867 END_PROFILE(SMBreadbraw);
2871 #endif /* LARGE_SMB_OFF_T */
2874 DEBUG(0,("reply_readbraw: negative 64 bit "
2875 "readraw offset (%.0f) !\n",
2876 (double)startpos ));
2877 reply_readbraw_error();
2878 END_PROFILE(SMBreadbraw);
2883 maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
2884 mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
2886 /* ensure we don't overrun the packet size */
2887 maxcount = MIN(65535,maxcount);
2889 if (is_locked(fsp,(uint32)req->smbpid,
2890 (SMB_BIG_UINT)maxcount,
2891 (SMB_BIG_UINT)startpos,
2893 reply_readbraw_error();
2894 END_PROFILE(SMBreadbraw);
2898 if (SMB_VFS_FSTAT(fsp, &st) == 0) {
2902 if (startpos >= size) {
2905 nread = MIN(maxcount,(size - startpos));
2908 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2909 if (nread < mincount)
2913 DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
2914 "min=%lu nread=%lu\n",
2915 fsp->fnum, (double)startpos,
2916 (unsigned long)maxcount,
2917 (unsigned long)mincount,
2918 (unsigned long)nread ) );
2920 send_file_readbraw(conn, fsp, startpos, nread, mincount);
2922 DEBUG(5,("reply_readbraw finished\n"));
2923 END_PROFILE(SMBreadbraw);
2927 #define DBGC_CLASS DBGC_LOCKING
2929 /****************************************************************************
2930 Reply to a lockread (core+ protocol).
2931 ****************************************************************************/
2933 void reply_lockread(struct smb_request *req)
2935 connection_struct *conn = req->conn;
2942 struct byte_range_lock *br_lck = NULL;
2945 START_PROFILE(SMBlockread);
2948 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2949 END_PROFILE(SMBlockread);
2953 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
2955 if (!check_fsp(conn, req, fsp)) {
2956 END_PROFILE(SMBlockread);
2960 if (!CHECK_READ(fsp,req->inbuf)) {
2961 reply_doserror(req, ERRDOS, ERRbadaccess);
2962 END_PROFILE(SMBlockread);
2966 release_level_2_oplocks_on_change(fsp);
2968 numtoread = SVAL(req->inbuf,smb_vwv1);
2969 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
2971 numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
2973 reply_outbuf(req, 5, numtoread + 3);
2975 data = smb_buf(req->outbuf) + 3;
2978 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2979 * protocol request that predates the read/write lock concept.
2980 * Thus instead of asking for a read lock here we need to ask
2981 * for a write lock. JRA.
2982 * Note that the requested lock size is unaffected by max_recv.
2985 br_lck = do_lock(smbd_messaging_context(),
2988 (SMB_BIG_UINT)numtoread,
2989 (SMB_BIG_UINT)startpos,
2992 False, /* Non-blocking lock. */
2995 TALLOC_FREE(br_lck);
2997 if (NT_STATUS_V(status)) {
2998 reply_nterror(req, status);
2999 END_PROFILE(SMBlockread);
3004 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
3007 if (numtoread > max_recv) {
3008 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
3009 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3010 (unsigned int)numtoread, (unsigned int)max_recv ));
3011 numtoread = MIN(numtoread,max_recv);
3013 nread = read_file(fsp,data,startpos,numtoread);
3016 reply_unixerror(req, ERRDOS, ERRnoaccess);
3017 END_PROFILE(SMBlockread);
3021 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3023 SSVAL(req->outbuf,smb_vwv0,nread);
3024 SSVAL(req->outbuf,smb_vwv5,nread+3);
3025 p = smb_buf(req->outbuf);
3026 SCVAL(p,0,0); /* pad byte. */
3029 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
3030 fsp->fnum, (int)numtoread, (int)nread));
3032 END_PROFILE(SMBlockread);
3037 #define DBGC_CLASS DBGC_ALL
3039 /****************************************************************************
3041 ****************************************************************************/
3043 void reply_read(struct smb_request *req)
3045 connection_struct *conn = req->conn;
3053 START_PROFILE(SMBread);
3056 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3057 END_PROFILE(SMBread);
3061 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3063 if (!check_fsp(conn, req, fsp)) {
3064 END_PROFILE(SMBread);
3068 if (!CHECK_READ(fsp,req->inbuf)) {
3069 reply_doserror(req, ERRDOS, ERRbadaccess);
3070 END_PROFILE(SMBread);
3074 numtoread = SVAL(req->inbuf,smb_vwv1);
3075 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3077 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
3080 * The requested read size cannot be greater than max_recv. JRA.
3082 if (numtoread > max_recv) {
3083 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
3084 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3085 (unsigned int)numtoread, (unsigned int)max_recv ));
3086 numtoread = MIN(numtoread,max_recv);
3089 reply_outbuf(req, 5, numtoread+3);
3091 data = smb_buf(req->outbuf) + 3;
3093 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtoread,
3094 (SMB_BIG_UINT)startpos, READ_LOCK)) {
3095 reply_doserror(req, ERRDOS,ERRlock);
3096 END_PROFILE(SMBread);
3101 nread = read_file(fsp,data,startpos,numtoread);
3104 reply_unixerror(req, ERRDOS,ERRnoaccess);
3105 END_PROFILE(SMBread);
3109 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3111 SSVAL(req->outbuf,smb_vwv0,nread);
3112 SSVAL(req->outbuf,smb_vwv5,nread+3);
3113 SCVAL(smb_buf(req->outbuf),0,1);
3114 SSVAL(smb_buf(req->outbuf),1,nread);
3116 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
3117 fsp->fnum, (int)numtoread, (int)nread ) );
3119 END_PROFILE(SMBread);
3123 /****************************************************************************
3125 ****************************************************************************/
3127 static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
3132 outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
3133 data = smb_buf(outbuf);
3135 memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
3137 SCVAL(outbuf,smb_vwv0,0xFF);
3138 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
3139 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
3140 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
3141 SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
3142 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
3143 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
3144 _smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
3148 /****************************************************************************
3149 Reply to a read and X - possibly using sendfile.
3150 ****************************************************************************/
3152 static void send_file_readX(connection_struct *conn, struct smb_request *req,
3153 files_struct *fsp, SMB_OFF_T startpos,
3156 SMB_STRUCT_STAT sbuf;
3159 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
3160 reply_unixerror(req, ERRDOS, ERRnoaccess);
3164 if (startpos > sbuf.st_size) {
3166 } else if (smb_maxcnt > (sbuf.st_size - startpos)) {
3167 smb_maxcnt = (sbuf.st_size - startpos);
3170 if (smb_maxcnt == 0) {
3174 #if defined(WITH_SENDFILE)
3176 * We can only use sendfile on a non-chained packet
3177 * but we can use on a non-oplocked file. tridge proved this
3178 * on a train in Germany :-). JRA.
3181 if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
3182 !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
3183 lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
3184 uint8 headerbuf[smb_size + 12 * 2];
3188 * Set up the packet header before send. We
3189 * assume here the sendfile will work (get the
3190 * correct amount of data).
3193 header = data_blob_const(headerbuf, sizeof(headerbuf));
3195 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3196 setup_readX_header((char *)headerbuf, smb_maxcnt);
3198 if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
3199 /* Returning ENOSYS or EINVAL means no data at all was sent.
3200 Do this as a normal read. */
3201 if (errno == ENOSYS || errno == EINVAL) {
3206 * Special hack for broken Linux with no working sendfile. If we
3207 * return EINTR we sent the header but not the rest of the data.
3208 * Fake this up by doing read/write calls.
3211 if (errno == EINTR) {
3212 /* Ensure we don't do this again. */
3213 set_use_sendfile(SNUM(conn), False);
3214 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
3215 nread = fake_sendfile(fsp, startpos,
3218 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3219 fsp->fsp_name, strerror(errno) ));
3220 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3222 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
3223 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3224 /* No outbuf here means successful sendfile. */
3225 TALLOC_FREE(req->outbuf);
3229 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
3230 fsp->fsp_name, strerror(errno) ));
3231 exit_server_cleanly("send_file_readX sendfile failed");
3234 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
3235 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3236 /* No outbuf here means successful sendfile. */
3237 TALLOC_FREE(req->outbuf);
3244 if ((smb_maxcnt & 0xFF0000) > 0x10000) {
3245 uint8 headerbuf[smb_size + 2*12];
3247 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3248 setup_readX_header((char *)headerbuf, smb_maxcnt);
3250 /* Send out the header. */
3251 if (write_data(smbd_server_fd(), (char *)headerbuf,
3252 sizeof(headerbuf)) != sizeof(headerbuf)) {
3253 DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
3254 fsp->fsp_name, strerror(errno) ));
3255 exit_server_cleanly("send_file_readX sendfile failed");
3257 nread = fake_sendfile(fsp, startpos, smb_maxcnt);
3259 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3260 fsp->fsp_name, strerror(errno) ));
3261 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3263 TALLOC_FREE(req->outbuf);
3266 reply_outbuf(req, 12, smb_maxcnt);
3268 nread = read_file(fsp, smb_buf(req->outbuf), startpos,
3271 reply_unixerror(req, ERRDOS, ERRnoaccess);
3275 setup_readX_header((char *)req->outbuf, nread);
3277 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
3278 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3286 /****************************************************************************
3287 Reply to a read and X.
3288 ****************************************************************************/
3290 void reply_read_and_X(struct smb_request *req)
3292 connection_struct *conn = req->conn;
3296 bool big_readX = False;
3298 size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
3301 START_PROFILE(SMBreadX);
3303 if ((req->wct != 10) && (req->wct != 12)) {
3304 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3308 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
3309 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3310 smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
3312 /* If it's an IPC, pass off the pipe handler. */
3314 reply_pipe_read_and_X(req);
3315 END_PROFILE(SMBreadX);
3319 if (!check_fsp(conn, req, fsp)) {
3320 END_PROFILE(SMBreadX);
3324 if (!CHECK_READ(fsp,req->inbuf)) {
3325 reply_doserror(req, ERRDOS,ERRbadaccess);
3326 END_PROFILE(SMBreadX);
3330 if (global_client_caps & CAP_LARGE_READX) {
3331 size_t upper_size = SVAL(req->inbuf,smb_vwv7);
3332 smb_maxcnt |= (upper_size<<16);
3333 if (upper_size > 1) {
3334 /* Can't do this on a chained packet. */
3335 if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) {
3336 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3337 END_PROFILE(SMBreadX);
3340 /* We currently don't do this on signed or sealed data. */
3341 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
3342 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3343 END_PROFILE(SMBreadX);
3346 /* Is there room in the reply for this data ? */
3347 if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
3349 NT_STATUS_INVALID_PARAMETER);
3350 END_PROFILE(SMBreadX);
3357 if (req->wct == 12) {
3358 #ifdef LARGE_SMB_OFF_T
3360 * This is a large offset (64 bit) read.
3362 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32);
3364 #else /* !LARGE_SMB_OFF_T */
3367 * Ensure we haven't been sent a >32 bit offset.
3370 if(IVAL(req->inbuf,smb_vwv10) != 0) {
3371 DEBUG(0,("reply_read_and_X - large offset (%x << 32) "
3372 "used and we don't support 64 bit offsets.\n",
3373 (unsigned int)IVAL(req->inbuf,smb_vwv10) ));
3374 END_PROFILE(SMBreadX);
3375 reply_doserror(req, ERRDOS, ERRbadaccess);
3379 #endif /* LARGE_SMB_OFF_T */
3383 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)smb_maxcnt,
3384 (SMB_BIG_UINT)startpos, READ_LOCK)) {
3385 END_PROFILE(SMBreadX);
3386 reply_doserror(req, ERRDOS, ERRlock);
3391 schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
3392 END_PROFILE(SMBreadX);
3396 send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
3398 END_PROFILE(SMBreadX);
3402 /****************************************************************************
3403 Error replies to writebraw must have smb_wct == 1. Fix this up.
3404 ****************************************************************************/
3406 void error_to_writebrawerr(struct smb_request *req)
3408 uint8 *old_outbuf = req->outbuf;
3410 reply_outbuf(req, 1, 0);
3412 memcpy(req->outbuf, old_outbuf, smb_size);
3413 TALLOC_FREE(old_outbuf);
3416 /****************************************************************************
3417 Reply to a writebraw (core+ or LANMAN1.0 protocol).
3418 ****************************************************************************/
3420 void reply_writebraw(struct smb_request *req)
3422 connection_struct *conn = req->conn;
3425 ssize_t total_written=0;
3426 size_t numtowrite=0;
3434 START_PROFILE(SMBwritebraw);
3437 * If we ever reply with an error, it must have the SMB command
3438 * type of SMBwritec, not SMBwriteBraw, as this tells the client
3441 SCVAL(req->inbuf,smb_com,SMBwritec);
3443 if (srv_is_signing_active()) {
3444 END_PROFILE(SMBwritebraw);
3445 exit_server_cleanly("reply_writebraw: SMB signing is active - "
3446 "raw reads/writes are disallowed.");
3449 if (req->wct < 12) {
3450 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3451 error_to_writebrawerr(req);
3452 END_PROFILE(SMBwritebraw);
3456 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3457 if (!check_fsp(conn, req, fsp)) {
3458 error_to_writebrawerr(req);
3459 END_PROFILE(SMBwritebraw);
3463 if (!CHECK_WRITE(fsp)) {
3464 reply_doserror(req, ERRDOS, ERRbadaccess);
3465 error_to_writebrawerr(req);
3466 END_PROFILE(SMBwritebraw);
3470 tcount = IVAL(req->inbuf,smb_vwv1);
3471 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3472 write_through = BITSETW(req->inbuf+smb_vwv7,0);
3474 /* We have to deal with slightly different formats depending
3475 on whether we are using the core+ or lanman1.0 protocol */
3477 if(Protocol <= PROTOCOL_COREPLUS) {
3478 numtowrite = SVAL(smb_buf(req->inbuf),-2);
3479 data = smb_buf(req->inbuf);
3481 numtowrite = SVAL(req->inbuf,smb_vwv10);
3482 data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11);
3485 /* Ensure we don't write bytes past the end of this packet. */
3486 if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) {
3487 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3488 error_to_writebrawerr(req);
3489 END_PROFILE(SMBwritebraw);
3493 if (is_locked(fsp,(uint32)req->smbpid,(SMB_BIG_UINT)tcount,
3494 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3495 reply_doserror(req, ERRDOS, ERRlock);
3496 error_to_writebrawerr(req);
3497 END_PROFILE(SMBwritebraw);
3502 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3505 DEBUG(3,("reply_writebraw: initial write fnum=%d start=%.0f num=%d "
3506 "wrote=%d sync=%d\n",
3507 fsp->fnum, (double)startpos, (int)numtowrite,
3508 (int)nwritten, (int)write_through));
3510 if (nwritten < (ssize_t)numtowrite) {
3511 reply_unixerror(req, ERRHRD, ERRdiskfull);
3512 error_to_writebrawerr(req);
3513 END_PROFILE(SMBwritebraw);
3517 total_written = nwritten;
3519 /* Allocate a buffer of 64k + length. */
3520 buf = TALLOC_ARRAY(NULL, char, 65540);
3522 reply_doserror(req, ERRDOS, ERRnomem);
3523 error_to_writebrawerr(req);
3524 END_PROFILE(SMBwritebraw);
3528 /* Return a SMBwritebraw message to the redirector to tell
3529 * it to send more bytes */
3531 memcpy(buf, req->inbuf, smb_size);
3532 srv_set_message(buf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
3533 SCVAL(buf,smb_com,SMBwritebraw);
3534 SSVALS(buf,smb_vwv0,0xFFFF);
3536 if (!srv_send_smb(smbd_server_fd(),
3538 IS_CONN_ENCRYPTED(conn))) {
3539 exit_server_cleanly("reply_writebraw: srv_send_smb "
3543 /* Now read the raw data into the buffer and write it */
3544 status = read_smb_length(smbd_server_fd(), buf, SMB_SECONDARY_WAIT,
3546 if (!NT_STATUS_IS_OK(status)) {
3547 exit_server_cleanly("secondary writebraw failed");
3550 /* Set up outbuf to return the correct size */
3551 reply_outbuf(req, 1, 0);
3553 if (numtowrite != 0) {
3555 if (numtowrite > 0xFFFF) {
3556 DEBUG(0,("reply_writebraw: Oversize secondary write "
3557 "raw requested (%u). Terminating\n",
3558 (unsigned int)numtowrite ));
3559 exit_server_cleanly("secondary writebraw failed");
3562 if (tcount > nwritten+numtowrite) {
3563 DEBUG(3,("reply_writebraw: Client overestimated the "
3565 (int)tcount,(int)nwritten,(int)numtowrite));
3568 status = read_data(smbd_server_fd(), buf+4, numtowrite);
3570 if (!NT_STATUS_IS_OK(status)) {
3571 DEBUG(0,("reply_writebraw: Oversize secondary write "
3572 "raw read failed (%s). Terminating\n",
3573 nt_errstr(status)));
3574 exit_server_cleanly("secondary writebraw failed");
3577 nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
3578 if (nwritten == -1) {
3580 reply_unixerror(req, ERRHRD, ERRdiskfull);
3581 error_to_writebrawerr(req);
3582 END_PROFILE(SMBwritebraw);
3586 if (nwritten < (ssize_t)numtowrite) {
3587 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3588 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3592 total_written += nwritten;
3597 SSVAL(req->outbuf,smb_vwv0,total_written);
3599 status = sync_file(conn, fsp, write_through);
3600 if (!NT_STATUS_IS_OK(status)) {
3601 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
3602 fsp->fsp_name, nt_errstr(status) ));
3603 reply_nterror(req, status);
3604 error_to_writebrawerr(req);
3605 END_PROFILE(SMBwritebraw);
3609 DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
3611 fsp->fnum, (double)startpos, (int)numtowrite,
3612 (int)total_written));
3614 /* We won't return a status if write through is not selected - this
3615 * follows what WfWg does */
3616 END_PROFILE(SMBwritebraw);
3618 if (!write_through && total_written==tcount) {
3620 #if RABBIT_PELLET_FIX
3622 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
3623 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this.
3626 if (!send_keepalive(smbd_server_fd())) {
3627 exit_server_cleanly("reply_writebraw: send of "
3628 "keepalive failed");
3631 TALLOC_FREE(req->outbuf);
3637 #define DBGC_CLASS DBGC_LOCKING
3639 /****************************************************************************
3640 Reply to a writeunlock (core+).
3641 ****************************************************************************/
3643 void reply_writeunlock(struct smb_request *req)
3645 connection_struct *conn = req->conn;
3646 ssize_t nwritten = -1;
3650 NTSTATUS status = NT_STATUS_OK;
3653 START_PROFILE(SMBwriteunlock);
3656 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3657 END_PROFILE(SMBwriteunlock);
3661 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3663 if (!check_fsp(conn, req, fsp)) {
3664 END_PROFILE(SMBwriteunlock);
3668 if (!CHECK_WRITE(fsp)) {
3669 reply_doserror(req, ERRDOS,ERRbadaccess);
3670 END_PROFILE(SMBwriteunlock);
3674 numtowrite = SVAL(req->inbuf,smb_vwv1);
3675 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3676 data = smb_buf(req->inbuf) + 3;
3679 && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
3680 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3681 reply_doserror(req, ERRDOS, ERRlock);
3682 END_PROFILE(SMBwriteunlock);
3686 /* The special X/Open SMB protocol handling of
3687 zero length writes is *NOT* done for
3689 if(numtowrite == 0) {
3692 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3695 status = sync_file(conn, fsp, False /* write through */);
3696 if (!NT_STATUS_IS_OK(status)) {
3697 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
3698 fsp->fsp_name, nt_errstr(status) ));
3699 reply_nterror(req, status);
3700 END_PROFILE(SMBwriteunlock);
3704 if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
3705 reply_unixerror(req, ERRHRD, ERRdiskfull);
3706 END_PROFILE(SMBwriteunlock);
3711 status = do_unlock(smbd_messaging_context(),
3714 (SMB_BIG_UINT)numtowrite,
3715 (SMB_BIG_UINT)startpos,
3718 if (NT_STATUS_V(status)) {
3719 reply_nterror(req, status);
3720 END_PROFILE(SMBwriteunlock);
3725 reply_outbuf(req, 1, 0);
3727 SSVAL(req->outbuf,smb_vwv0,nwritten);
3729 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
3730 fsp->fnum, (int)numtowrite, (int)nwritten));
3732 END_PROFILE(SMBwriteunlock);
3737 #define DBGC_CLASS DBGC_ALL
3739 /****************************************************************************
3741 ****************************************************************************/
3743 void reply_write(struct smb_request *req)
3745 connection_struct *conn = req->conn;
3747 ssize_t nwritten = -1;
3753 START_PROFILE(SMBwrite);
3756 END_PROFILE(SMBwrite);
3757 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3761 /* If it's an IPC, pass off the pipe handler. */
3763 reply_pipe_write(req);
3764 END_PROFILE(SMBwrite);
3768 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3770 if (!check_fsp(conn, req, fsp)) {
3771 END_PROFILE(SMBwrite);
3775 if (!CHECK_WRITE(fsp)) {
3776 reply_doserror(req, ERRDOS, ERRbadaccess);
3777 END_PROFILE(SMBwrite);
3781 numtowrite = SVAL(req->inbuf,smb_vwv1);
3782 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3783 data = smb_buf(req->inbuf) + 3;
3785 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
3786 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3787 reply_doserror(req, ERRDOS, ERRlock);
3788 END_PROFILE(SMBwrite);
3793 * X/Open SMB protocol says that if smb_vwv1 is
3794 * zero then the file size should be extended or
3795 * truncated to the size given in smb_vwv[2-3].
3798 if(numtowrite == 0) {
3800 * This is actually an allocate call, and set EOF. JRA.
3802 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
3804 reply_nterror(req, NT_STATUS_DISK_FULL);
3805 END_PROFILE(SMBwrite);
3808 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
3810 reply_nterror(req, NT_STATUS_DISK_FULL);
3811 END_PROFILE(SMBwrite);
3814 trigger_write_time_update_immediate(fsp);
3816 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3819 status = sync_file(conn, fsp, False);
3820 if (!NT_STATUS_IS_OK(status)) {
3821 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
3822 fsp->fsp_name, nt_errstr(status) ));
3823 reply_nterror(req, status);
3824 END_PROFILE(SMBwrite);
3828 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3829 reply_unixerror(req, ERRHRD, ERRdiskfull);
3830 END_PROFILE(SMBwrite);
3834 reply_outbuf(req, 1, 0);
3836 SSVAL(req->outbuf,smb_vwv0,nwritten);
3838 if (nwritten < (ssize_t)numtowrite) {
3839 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3840 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3843 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
3845 END_PROFILE(SMBwrite);
3849 /****************************************************************************
3850 Ensure a buffer is a valid writeX for recvfile purposes.
3851 ****************************************************************************/
3853 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
3854 (2*14) + /* word count (including bcc) */ \
3857 bool is_valid_writeX_buffer(const uint8_t *inbuf)
3860 connection_struct *conn = NULL;
3861 unsigned int doff = 0;
3862 size_t len = smb_len_large(inbuf);
3864 if (is_encrypted_packet(inbuf)) {
3865 /* Can't do this on encrypted
3870 if (CVAL(inbuf,smb_com) != SMBwriteX) {
3874 if (CVAL(inbuf,smb_vwv0) != 0xFF ||
3875 CVAL(inbuf,smb_wct) != 14) {
3876 DEBUG(10,("is_valid_writeX_buffer: chained or "
3877 "invalid word length.\n"));
3881 conn = conn_find(SVAL(inbuf, smb_tid));
3883 DEBUG(10,("is_valid_writeX_buffer: bad tid\n"));
3887 DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
3890 doff = SVAL(inbuf,smb_vwv11);
3892 numtowrite = SVAL(inbuf,smb_vwv10);
3894 if (len > doff && len - doff > 0xFFFF) {
3895 numtowrite |= (((size_t)SVAL(inbuf,smb_vwv9))<<16);
3898 if (numtowrite == 0) {
3899 DEBUG(10,("is_valid_writeX_buffer: zero write\n"));
3903 /* Ensure the sizes match up. */
3904 if (doff < STANDARD_WRITE_AND_X_HEADER_SIZE) {
3905 /* no pad byte...old smbclient :-( */
3906 DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n",
3908 (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE));
3912 if (len - doff != numtowrite) {
3913 DEBUG(10,("is_valid_writeX_buffer: doff mismatch "
3914 "len = %u, doff = %u, numtowrite = %u\n",
3917 (unsigned int)numtowrite ));
3921 DEBUG(10,("is_valid_writeX_buffer: true "
3922 "len = %u, doff = %u, numtowrite = %u\n",
3925 (unsigned int)numtowrite ));
3930 /****************************************************************************
3931 Reply to a write and X.
3932 ****************************************************************************/
3934 void reply_write_and_X(struct smb_request *req)
3936 connection_struct *conn = req->conn;
3942 unsigned int smb_doff;
3943 unsigned int smblen;
3947 START_PROFILE(SMBwriteX);
3949 if ((req->wct != 12) && (req->wct != 14)) {
3950 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3951 END_PROFILE(SMBwriteX);
3955 numtowrite = SVAL(req->inbuf,smb_vwv10);
3956 smb_doff = SVAL(req->inbuf,smb_vwv11);
3957 smblen = smb_len(req->inbuf);
3959 if (req->unread_bytes > 0xFFFF ||
3960 (smblen > smb_doff &&
3961 smblen - smb_doff > 0xFFFF)) {
3962 numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
3965 if (req->unread_bytes) {
3966 /* Can't do a recvfile write on IPC$ */
3968 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3969 END_PROFILE(SMBwriteX);
3972 if (numtowrite != req->unread_bytes) {
3973 reply_doserror(req, ERRDOS, ERRbadmem);
3974 END_PROFILE(SMBwriteX);
3978 if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
3979 smb_doff + numtowrite > smblen) {
3980 reply_doserror(req, ERRDOS, ERRbadmem);
3981 END_PROFILE(SMBwriteX);
3986 /* If it's an IPC, pass off the pipe handler. */
3988 if (req->unread_bytes) {
3989 reply_doserror(req, ERRDOS, ERRbadmem);
3990 END_PROFILE(SMBwriteX);
3993 reply_pipe_write_and_X(req);
3994 END_PROFILE(SMBwriteX);
3998 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
3999 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
4000 write_through = BITSETW(req->inbuf+smb_vwv7,0);
4002 if (!check_fsp(conn, req, fsp)) {
4003 END_PROFILE(SMBwriteX);
4007 if (!CHECK_WRITE(fsp)) {
4008 reply_doserror(req, ERRDOS, ERRbadaccess);
4009 END_PROFILE(SMBwriteX);
4013 data = smb_base(req->inbuf) + smb_doff;
4015 if(req->wct == 14) {
4016 #ifdef LARGE_SMB_OFF_T
4018 * This is a large offset (64 bit) write.
4020 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32);
4022 #else /* !LARGE_SMB_OFF_T */
4025 * Ensure we haven't been sent a >32 bit offset.
4028 if(IVAL(req->inbuf,smb_vwv12) != 0) {
4029 DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
4030 "used and we don't support 64 bit offsets.\n",
4031 (unsigned int)IVAL(req->inbuf,smb_vwv12) ));
4032 reply_doserror(req, ERRDOS, ERRbadaccess);
4033 END_PROFILE(SMBwriteX);
4037 #endif /* LARGE_SMB_OFF_T */
4040 if (is_locked(fsp,(uint32)req->smbpid,
4041 (SMB_BIG_UINT)numtowrite,
4042 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
4043 reply_doserror(req, ERRDOS, ERRlock);
4044 END_PROFILE(SMBwriteX);
4048 /* X/Open SMB protocol says that, unlike SMBwrite
4049 if the length is zero then NO truncation is
4050 done, just a write of zero. To truncate a file,
4053 if(numtowrite == 0) {
4057 if ((req->unread_bytes == 0) &&
4058 schedule_aio_write_and_X(conn, req, fsp, data, startpos,
4060 END_PROFILE(SMBwriteX);
4064 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4067 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4068 reply_unixerror(req, ERRHRD, ERRdiskfull);
4069 END_PROFILE(SMBwriteX);
4073 reply_outbuf(req, 6, 0);
4074 SSVAL(req->outbuf,smb_vwv2,nwritten);
4075 SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
4077 if (nwritten < (ssize_t)numtowrite) {
4078 SCVAL(req->outbuf,smb_rcls,ERRHRD);
4079 SSVAL(req->outbuf,smb_err,ERRdiskfull);
4082 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
4083 fsp->fnum, (int)numtowrite, (int)nwritten));
4085 status = sync_file(conn, fsp, write_through);
4086 if (!NT_STATUS_IS_OK(status)) {
4087 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
4088 fsp->fsp_name, nt_errstr(status) ));
4089 reply_nterror(req, status);
4090 END_PROFILE(SMBwriteX);
4094 END_PROFILE(SMBwriteX);
4099 /****************************************************************************
4101 ****************************************************************************/
4103 void reply_lseek(struct smb_request *req)
4105 connection_struct *conn = req->conn;
4111 START_PROFILE(SMBlseek);
4114 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4115 END_PROFILE(SMBlseek);
4119 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4121 if (!check_fsp(conn, req, fsp)) {
4125 flush_write_cache(fsp, SEEK_FLUSH);
4127 mode = SVAL(req->inbuf,smb_vwv1) & 3;
4128 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
4129 startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2);
4138 res = fsp->fh->pos + startpos;
4149 if (umode == SEEK_END) {
4150 if((res = SMB_VFS_LSEEK(fsp,startpos,umode)) == -1) {
4151 if(errno == EINVAL) {
4152 SMB_OFF_T current_pos = startpos;
4153 SMB_STRUCT_STAT sbuf;
4155 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
4156 reply_unixerror(req, ERRDOS,
4158 END_PROFILE(SMBlseek);
4162 current_pos += sbuf.st_size;
4164 res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
4169 reply_unixerror(req, ERRDOS, ERRnoaccess);
4170 END_PROFILE(SMBlseek);
4177 reply_outbuf(req, 2, 0);
4178 SIVAL(req->outbuf,smb_vwv0,res);
4180 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
4181 fsp->fnum, (double)startpos, (double)res, mode));
4183 END_PROFILE(SMBlseek);
4187 /****************************************************************************
4189 ****************************************************************************/
4191 void reply_flush(struct smb_request *req)
4193 connection_struct *conn = req->conn;
4197 START_PROFILE(SMBflush);
4200 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4204 fnum = SVAL(req->inbuf,smb_vwv0);
4205 fsp = file_fsp(fnum);
4207 if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) {
4212 file_sync_all(conn);
4214 NTSTATUS status = sync_file(conn, fsp, True);
4215 if (!NT_STATUS_IS_OK(status)) {
4216 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
4217 fsp->fsp_name, nt_errstr(status) ));
4218 reply_nterror(req, status);
4219 END_PROFILE(SMBflush);
4224 reply_outbuf(req, 0, 0);
4226 DEBUG(3,("flush\n"));
4227 END_PROFILE(SMBflush);
4231 /****************************************************************************
4233 conn POINTER CAN BE NULL HERE !
4234 ****************************************************************************/
4236 void reply_exit(struct smb_request *req)
4238 START_PROFILE(SMBexit);
4240 file_close_pid(req->smbpid, req->vuid);
4242 reply_outbuf(req, 0, 0);
4244 DEBUG(3,("exit\n"));
4246 END_PROFILE(SMBexit);
4250 /****************************************************************************
4251 Reply to a close - has to deal with closing a directory opened by NT SMB's.
4252 ****************************************************************************/
4254 void reply_close(struct smb_request *req)
4256 connection_struct *conn = req->conn;
4257 NTSTATUS status = NT_STATUS_OK;
4258 files_struct *fsp = NULL;
4259 START_PROFILE(SMBclose);
4262 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4263 END_PROFILE(SMBclose);
4267 /* If it's an IPC, pass off to the pipe handler. */
4269 reply_pipe_close(conn, req);
4270 END_PROFILE(SMBclose);
4274 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4277 * We can only use check_fsp if we know it's not a directory.
4280 if(!fsp || (fsp->conn != conn) || (fsp->vuid != req->vuid)) {
4281 reply_doserror(req, ERRDOS, ERRbadfid);
4282 END_PROFILE(SMBclose);
4286 if(fsp->is_directory) {
4288 * Special case - close NT SMB directory handle.
4290 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
4291 status = close_file(fsp,NORMAL_CLOSE);
4295 * Close ordinary file.
4298 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
4299 fsp->fh->fd, fsp->fnum,
4300 conn->num_files_open));
4303 * Take care of any time sent in the close.
4306 t = srv_make_unix_date3(req->inbuf+smb_vwv1);
4307 set_close_write_time(fsp, convert_time_t_to_timespec(t));
4310 * close_file() returns the unix errno if an error
4311 * was detected on close - normally this is due to
4312 * a disk full error. If not then it was probably an I/O error.
4315 status = close_file(fsp,NORMAL_CLOSE);
4318 if (!NT_STATUS_IS_OK(status)) {
4319 reply_nterror(req, status);
4320 END_PROFILE(SMBclose);
4324 reply_outbuf(req, 0, 0);
4325 END_PROFILE(SMBclose);
4329 /****************************************************************************
4330 Reply to a writeclose (Core+ protocol).
4331 ****************************************************************************/
4333 void reply_writeclose(struct smb_request *req)
4335 connection_struct *conn = req->conn;
4337 ssize_t nwritten = -1;
4338 NTSTATUS close_status = NT_STATUS_OK;
4341 struct timespec mtime;
4344 START_PROFILE(SMBwriteclose);
4347 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4348 END_PROFILE(SMBwriteclose);
4352 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4354 if (!check_fsp(conn, req, fsp)) {
4355 END_PROFILE(SMBwriteclose);
4358 if (!CHECK_WRITE(fsp)) {
4359 reply_doserror(req, ERRDOS,ERRbadaccess);
4360 END_PROFILE(SMBwriteclose);
4364 numtowrite = SVAL(req->inbuf,smb_vwv1);
4365 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
4366 mtime = convert_time_t_to_timespec(srv_make_unix_date3(
4367 req->inbuf+smb_vwv4));
4368 data = smb_buf(req->inbuf) + 1;
4371 && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
4372 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
4373 reply_doserror(req, ERRDOS,ERRlock);
4374 END_PROFILE(SMBwriteclose);
4378 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4380 set_close_write_time(fsp, mtime);
4383 * More insanity. W2K only closes the file if writelen > 0.
4388 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
4390 close_status = close_file(fsp,NORMAL_CLOSE);
4393 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
4394 fsp->fnum, (int)numtowrite, (int)nwritten,
4395 conn->num_files_open));
4397 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4398 reply_doserror(req, ERRHRD, ERRdiskfull);
4399 END_PROFILE(SMBwriteclose);
4403 if(!NT_STATUS_IS_OK(close_status)) {
4404 reply_nterror(req, close_status);
4405 END_PROFILE(SMBwriteclose);
4409 reply_outbuf(req, 1, 0);
4411 SSVAL(req->outbuf,smb_vwv0,nwritten);
4412 END_PROFILE(SMBwriteclose);
4417 #define DBGC_CLASS DBGC_LOCKING
4419 /****************************************************************************
4421 ****************************************************************************/
4423 void reply_lock(struct smb_request *req)
4425 connection_struct *conn = req->conn;
4426 SMB_BIG_UINT count,offset;
4429 struct byte_range_lock *br_lck = NULL;
4431 START_PROFILE(SMBlock);
4434 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4435 END_PROFILE(SMBlock);
4439 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4441 if (!check_fsp(conn, req, fsp)) {
4442 END_PROFILE(SMBlock);
4446 release_level_2_oplocks_on_change(fsp);
4448 count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
4449 offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
4451 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4452 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
4454 br_lck = do_lock(smbd_messaging_context(),
4461 False, /* Non-blocking lock. */
4465 TALLOC_FREE(br_lck);
4467 if (NT_STATUS_V(status)) {
4468 reply_nterror(req, status);
4469 END_PROFILE(SMBlock);
4473 reply_outbuf(req, 0, 0);
4475 END_PROFILE(SMBlock);
4479 /****************************************************************************
4481 ****************************************************************************/
4483 void reply_unlock(struct smb_request *req)
4485 connection_struct *conn = req->conn;
4486 SMB_BIG_UINT count,offset;
4490 START_PROFILE(SMBunlock);
4493 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4494 END_PROFILE(SMBunlock);
4498 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4500 if (!check_fsp(conn, req, fsp)) {
4501 END_PROFILE(SMBunlock);
4505 count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
4506 offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
4508 status = do_unlock(smbd_messaging_context(),
4515 if (NT_STATUS_V(status)) {
4516 reply_nterror(req, status);
4517 END_PROFILE(SMBunlock);
4521 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4522 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
4524 reply_outbuf(req, 0, 0);
4526 END_PROFILE(SMBunlock);
4531 #define DBGC_CLASS DBGC_ALL
4533 /****************************************************************************
4535 conn POINTER CAN BE NULL HERE !
4536 ****************************************************************************/
4538 void reply_tdis(struct smb_request *req)
4540 connection_struct *conn = req->conn;
4541 START_PROFILE(SMBtdis);
4544 DEBUG(4,("Invalid connection in tdis\n"));
4545 reply_doserror(req, ERRSRV, ERRinvnid);
4546 END_PROFILE(SMBtdis);
4552 close_cnum(conn,req->vuid);
4555 reply_outbuf(req, 0, 0);
4556 END_PROFILE(SMBtdis);
4560 /****************************************************************************
4562 conn POINTER CAN BE NULL HERE !
4563 ****************************************************************************/
4565 void reply_echo(struct smb_request *req)
4567 connection_struct *conn = req->conn;
4570 unsigned int data_len = smb_buflen(req->inbuf);
4572 START_PROFILE(SMBecho);
4575 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4576 END_PROFILE(SMBecho);
4580 if (data_len > BUFFER_SIZE) {
4581 DEBUG(0,("reply_echo: data_len too large.\n"));
4582 reply_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
4583 END_PROFILE(SMBecho);
4587 smb_reverb = SVAL(req->inbuf,smb_vwv0);
4589 reply_outbuf(req, 1, data_len);
4591 /* copy any incoming data back out */
4593 memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len);
4596 if (smb_reverb > 100) {
4597 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
4601 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
4602 SSVAL(req->outbuf,smb_vwv0,seq_num);
4604 show_msg((char *)req->outbuf);
4605 if (!srv_send_smb(smbd_server_fd(),
4606 (char *)req->outbuf,
4607 IS_CONN_ENCRYPTED(conn)||req->encrypted))
4608 exit_server_cleanly("reply_echo: srv_send_smb failed.");
4611 DEBUG(3,("echo %d times\n", smb_reverb));
4613 TALLOC_FREE(req->outbuf);
4615 END_PROFILE(SMBecho);
4619 /****************************************************************************
4620 Reply to a printopen.
4621 ****************************************************************************/
4623 void reply_printopen(struct smb_request *req)
4625 connection_struct *conn = req->conn;
4629 START_PROFILE(SMBsplopen);
4632 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4633 END_PROFILE(SMBsplopen);
4637 if (!CAN_PRINT(conn)) {
4638 reply_doserror(req, ERRDOS, ERRnoaccess);
4639 END_PROFILE(SMBsplopen);
4643 status = file_new(conn, &fsp);
4644 if(!NT_STATUS_IS_OK(status)) {
4645 END_PROFILE(SMBsplopen);
4649 /* Open for exclusive use, write only. */
4650 status = print_fsp_open(conn, NULL, req->vuid, &fsp);
4652 if (!NT_STATUS_IS_OK(status)) {
4654 reply_nterror(req, status);
4655 END_PROFILE(SMBsplopen);
4659 reply_outbuf(req, 1, 0);
4660 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
4662 DEBUG(3,("openprint fd=%d fnum=%d\n",
4663 fsp->fh->fd, fsp->fnum));
4665 END_PROFILE(SMBsplopen);
4669 /****************************************************************************
4670 Reply to a printclose.
4671 ****************************************************************************/
4673 void reply_printclose(struct smb_request *req)
4675 connection_struct *conn = req->conn;
4679 START_PROFILE(SMBsplclose);
4682 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4683 END_PROFILE(SMBsplclose);
4687 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4689 if (!check_fsp(conn, req, fsp)) {
4690 END_PROFILE(SMBsplclose);
4694 if (!CAN_PRINT(conn)) {
4695 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
4696 END_PROFILE(SMBsplclose);
4700 DEBUG(3,("printclose fd=%d fnum=%d\n",
4701 fsp->fh->fd,fsp->fnum));
4703 status = close_file(fsp,NORMAL_CLOSE);
4705 if(!NT_STATUS_IS_OK(status)) {
4706 reply_nterror(req, status);
4707 END_PROFILE(SMBsplclose);
4711 reply_outbuf(req, 0, 0);
4713 END_PROFILE(SMBsplclose);
4717 /****************************************************************************
4718 Reply to a printqueue.
4719 ****************************************************************************/
4721 void reply_printqueue(struct smb_request *req)
4723 connection_struct *conn = req->conn;
4727 START_PROFILE(SMBsplretq);
4730 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4731 END_PROFILE(SMBsplretq);
4735 max_count = SVAL(req->inbuf,smb_vwv0);
4736 start_index = SVAL(req->inbuf,smb_vwv1);
4738 /* we used to allow the client to get the cnum wrong, but that
4739 is really quite gross and only worked when there was only
4740 one printer - I think we should now only accept it if they
4741 get it right (tridge) */
4742 if (!CAN_PRINT(conn)) {
4743 reply_doserror(req, ERRDOS, ERRnoaccess);
4744 END_PROFILE(SMBsplretq);
4748 reply_outbuf(req, 2, 3);
4749 SSVAL(req->outbuf,smb_vwv0,0);
4750 SSVAL(req->outbuf,smb_vwv1,0);
4751 SCVAL(smb_buf(req->outbuf),0,1);
4752 SSVAL(smb_buf(req->outbuf),1,0);
4754 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
4755 start_index, max_count));
4758 print_queue_struct *queue = NULL;
4759 print_status_struct status;
4760 int count = print_queue_status(SNUM(conn), &queue, &status);
4761 int num_to_get = ABS(max_count);
4762 int first = (max_count>0?start_index:start_index+max_count+1);
4768 num_to_get = MIN(num_to_get,count-first);
4771 for (i=first;i<first+num_to_get;i++) {
4775 srv_put_dos_date2(p,0,queue[i].time);
4776 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
4777 SSVAL(p,5, queue[i].job);
4778 SIVAL(p,7,queue[i].size);
4780 srvstr_push(blob, req->flags2, p+12,
4781 queue[i].fs_user, 16, STR_ASCII);
4783 if (message_push_blob(
4786 blob, sizeof(blob))) == -1) {
4787 reply_nterror(req, NT_STATUS_NO_MEMORY);
4788 END_PROFILE(SMBsplretq);
4794 SSVAL(req->outbuf,smb_vwv0,count);
4795 SSVAL(req->outbuf,smb_vwv1,
4796 (max_count>0?first+count:first-1));
4797 SCVAL(smb_buf(req->outbuf),0,1);
4798 SSVAL(smb_buf(req->outbuf),1,28*count);
4803 DEBUG(3,("%d entries returned in queue\n",count));
4806 END_PROFILE(SMBsplretq);
4810 /****************************************************************************
4811 Reply to a printwrite.
4812 ****************************************************************************/
4814 void reply_printwrite(struct smb_request *req)
4816 connection_struct *conn = req->conn;
4821 START_PROFILE(SMBsplwr);
4824 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4825 END_PROFILE(SMBsplwr);
4829 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4831 if (!check_fsp(conn, req, fsp)) {
4832 END_PROFILE(SMBsplwr);
4836 if (!CAN_PRINT(conn)) {
4837 reply_doserror(req, ERRDOS, ERRnoaccess);
4838 END_PROFILE(SMBsplwr);
4842 if (!CHECK_WRITE(fsp)) {
4843 reply_doserror(req, ERRDOS, ERRbadaccess);
4844 END_PROFILE(SMBsplwr);
4848 numtowrite = SVAL(smb_buf(req->inbuf),1);
4850 if (smb_buflen(req->inbuf) < numtowrite + 3) {
4851 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4852 END_PROFILE(SMBsplwr);
4856 data = smb_buf(req->inbuf) + 3;
4858 if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
4859 reply_unixerror(req, ERRHRD, ERRdiskfull);
4860 END_PROFILE(SMBsplwr);
4864 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
4866 END_PROFILE(SMBsplwr);
4870 /****************************************************************************
4872 ****************************************************************************/
4874 void reply_mkdir(struct smb_request *req)
4876 connection_struct *conn = req->conn;
4877 char *directory = NULL;
4879 SMB_STRUCT_STAT sbuf;
4880 TALLOC_CTX *ctx = talloc_tos();
4882 START_PROFILE(SMBmkdir);
4884 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
4885 smb_buf(req->inbuf) + 1, 0,
4886 STR_TERMINATE, &status);
4887 if (!NT_STATUS_IS_OK(status)) {
4888 reply_nterror(req, status);
4889 END_PROFILE(SMBmkdir);
4893 status = resolve_dfspath(ctx, conn,
4894 req->flags2 & FLAGS2_DFS_PATHNAMES,
4897 if (!NT_STATUS_IS_OK(status)) {
4898 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4899 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
4900 ERRSRV, ERRbadpath);
4901 END_PROFILE(SMBmkdir);
4904 reply_nterror(req, status);
4905 END_PROFILE(SMBmkdir);
4909 status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
4910 if (!NT_STATUS_IS_OK(status)) {
4911 reply_nterror(req, status);
4912 END_PROFILE(SMBmkdir);
4916 status = check_name(conn, directory);
4917 if (!NT_STATUS_IS_OK(status)) {
4918 reply_nterror(req, status);
4919 END_PROFILE(SMBmkdir);
4923 status = create_directory(conn, req, directory);
4925 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
4927 if (!NT_STATUS_IS_OK(status)) {
4929 if (!use_nt_status()
4930 && NT_STATUS_EQUAL(status,
4931 NT_STATUS_OBJECT_NAME_COLLISION)) {
4933 * Yes, in the DOS error code case we get a
4934 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
4935 * samba4 torture test.
4937 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
4940 reply_nterror(req, status);
4941 END_PROFILE(SMBmkdir);
4945 reply_outbuf(req, 0, 0);
4947 DEBUG( 3, ( "mkdir %s\n", directory ) );
4949 END_PROFILE(SMBmkdir);
4953 /****************************************************************************
4954 Static function used by reply_rmdir to delete an entire directory
4955 tree recursively. Return True on ok, False on fail.
4956 ****************************************************************************/
4958 static bool recursive_rmdir(TALLOC_CTX *ctx,
4959 connection_struct *conn,
4962 const char *dname = NULL;
4965 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, directory,
4971 while((dname = ReadDirName(dir_hnd, &offset))) {
4972 char *fullname = NULL;
4975 if (ISDOT(dname) || ISDOTDOT(dname)) {
4979 if (!is_visible_file(conn, directory, dname, &st, False)) {
4983 /* Construct the full name. */
4984 fullname = talloc_asprintf(ctx,
4994 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
4999 if(st.st_mode & S_IFDIR) {
5000 if(!recursive_rmdir(ctx, conn, fullname)) {
5004 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
5008 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
5012 TALLOC_FREE(fullname);
5014 TALLOC_FREE(dir_hnd);
5018 /****************************************************************************
5019 The internals of the rmdir code - called elsewhere.
5020 ****************************************************************************/
5022 NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
5023 connection_struct *conn,
5024 const char *directory)
5029 /* Might be a symlink. */
5030 if(SMB_VFS_LSTAT(conn, directory, &st) != 0) {
5031 return map_nt_error_from_unix(errno);
5034 if (S_ISLNK(st.st_mode)) {
5035 /* Is what it points to a directory ? */
5036 if(SMB_VFS_STAT(conn, directory, &st) != 0) {
5037 return map_nt_error_from_unix(errno);
5039 if (!(S_ISDIR(st.st_mode))) {
5040 return NT_STATUS_NOT_A_DIRECTORY;
5042 ret = SMB_VFS_UNLINK(conn,directory);
5044 ret = SMB_VFS_RMDIR(conn,directory);
5047 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5048 FILE_NOTIFY_CHANGE_DIR_NAME,
5050 return NT_STATUS_OK;
5053 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
5055 * Check to see if the only thing in this directory are
5056 * vetoed files/directories. If so then delete them and
5057 * retry. If we fail to delete any of them (and we *don't*
5058 * do a recursive delete) then fail the rmdir.
5062 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
5063 directory, NULL, 0);
5065 if(dir_hnd == NULL) {
5070 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5071 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
5073 if (!is_visible_file(conn, directory, dname, &st, False))
5075 if(!IS_VETO_PATH(conn, dname)) {
5076 TALLOC_FREE(dir_hnd);
5082 /* We only have veto files/directories.
5083 * Are we allowed to delete them ? */
5085 if(!lp_recursive_veto_delete(SNUM(conn))) {
5086 TALLOC_FREE(dir_hnd);
5091 /* Do a recursive delete. */
5092 RewindDir(dir_hnd,&dirpos);
5093 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5094 char *fullname = NULL;
5096 if (ISDOT(dname) || ISDOTDOT(dname)) {
5099 if (!is_visible_file(conn, directory, dname, &st, False)) {
5103 fullname = talloc_asprintf(ctx,
5113 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
5116 if(st.st_mode & S_IFDIR) {
5117 if(!recursive_rmdir(ctx, conn, fullname)) {
5120 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
5123 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
5126 TALLOC_FREE(fullname);
5128 TALLOC_FREE(dir_hnd);
5129 /* Retry the rmdir */
5130 ret = SMB_VFS_RMDIR(conn,directory);
5136 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
5137 "%s\n", directory,strerror(errno)));
5138 return map_nt_error_from_unix(errno);
5141 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5142 FILE_NOTIFY_CHANGE_DIR_NAME,
5145 return NT_STATUS_OK;
5148 /****************************************************************************
5150 ****************************************************************************/
5152 void reply_rmdir(struct smb_request *req)
5154 connection_struct *conn = req->conn;
5155 char *directory = NULL;
5156 SMB_STRUCT_STAT sbuf;
5158 TALLOC_CTX *ctx = talloc_tos();
5160 START_PROFILE(SMBrmdir);
5162 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
5163 smb_buf(req->inbuf) + 1, 0,
5164 STR_TERMINATE, &status);
5165 if (!NT_STATUS_IS_OK(status)) {
5166 reply_nterror(req, status);
5167 END_PROFILE(SMBrmdir);
5171 status = resolve_dfspath(ctx, conn,
5172 req->flags2 & FLAGS2_DFS_PATHNAMES,
5175 if (!NT_STATUS_IS_OK(status)) {
5176 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5177 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5178 ERRSRV, ERRbadpath);
5179 END_PROFILE(SMBrmdir);
5182 reply_nterror(req, status);
5183 END_PROFILE(SMBrmdir);
5187 status = unix_convert(ctx, conn, directory, False, &directory,
5189 if (!NT_STATUS_IS_OK(status)) {
5190 reply_nterror(req, status);
5191 END_PROFILE(SMBrmdir);
5195 status = check_name(conn, directory);
5196 if (!NT_STATUS_IS_OK(status)) {
5197 reply_nterror(req, status);
5198 END_PROFILE(SMBrmdir);
5202 dptr_closepath(directory, req->smbpid);
5203 status = rmdir_internals(ctx, conn, directory);
5204 if (!NT_STATUS_IS_OK(status)) {
5205 reply_nterror(req, status);
5206 END_PROFILE(SMBrmdir);
5210 reply_outbuf(req, 0, 0);
5212 DEBUG( 3, ( "rmdir %s\n", directory ) );
5214 END_PROFILE(SMBrmdir);
5218 /*******************************************************************
5219 Resolve wildcards in a filename rename.
5220 ********************************************************************/
5222 static bool resolve_wildcards(TALLOC_CTX *ctx,
5227 char *name2_copy = NULL;
5232 char *p,*p2, *pname1, *pname2;
5234 name2_copy = talloc_strdup(ctx, name2);
5239 pname1 = strrchr_m(name1,'/');
5240 pname2 = strrchr_m(name2_copy,'/');
5242 if (!pname1 || !pname2) {
5246 /* Truncate the copy of name2 at the last '/' */
5249 /* Now go past the '/' */
5253 root1 = talloc_strdup(ctx, pname1);
5254 root2 = talloc_strdup(ctx, pname2);
5256 if (!root1 || !root2) {
5260 p = strrchr_m(root1,'.');
5263 ext1 = talloc_strdup(ctx, p+1);
5265 ext1 = talloc_strdup(ctx, "");
5267 p = strrchr_m(root2,'.');
5270 ext2 = talloc_strdup(ctx, p+1);
5272 ext2 = talloc_strdup(ctx, "");
5275 if (!ext1 || !ext2) {
5283 /* Hmmm. Should this be mb-aware ? */
5286 } else if (*p2 == '*') {
5288 root2 = talloc_asprintf(ctx, "%s%s",
5307 /* Hmmm. Should this be mb-aware ? */
5310 } else if (*p2 == '*') {
5312 ext2 = talloc_asprintf(ctx, "%s%s",
5328 *pp_newname = talloc_asprintf(ctx, "%s/%s.%s",
5333 *pp_newname = talloc_asprintf(ctx, "%s/%s",
5345 /****************************************************************************
5346 Ensure open files have their names updated. Updated to notify other smbd's
5348 ****************************************************************************/
5350 static void rename_open_files(connection_struct *conn,
5351 struct share_mode_lock *lck,
5352 const char *newname)
5355 bool did_rename = False;
5357 for(fsp = file_find_di_first(lck->id); fsp;
5358 fsp = file_find_di_next(fsp)) {
5359 /* fsp_name is a relative path under the fsp. To change this for other
5360 sharepaths we need to manipulate relative paths. */
5361 /* TODO - create the absolute path and manipulate the newname
5362 relative to the sharepath. */
5363 if (!strequal(fsp->conn->connectpath, conn->connectpath)) {
5366 DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
5367 fsp->fnum, file_id_string_tos(&fsp->file_id),
5368 fsp->fsp_name, newname ));
5369 string_set(&fsp->fsp_name, newname);
5374 DEBUG(10,("rename_open_files: no open files on file_id %s for %s\n",
5375 file_id_string_tos(&lck->id), newname ));
5378 /* Send messages to all smbd's (not ourself) that the name has changed. */
5379 rename_share_filename(smbd_messaging_context(), lck, conn->connectpath,
5383 /****************************************************************************
5384 We need to check if the source path is a parent directory of the destination
5385 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
5386 refuse the rename with a sharing violation. Under UNIX the above call can
5387 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
5388 probably need to check that the client is a Windows one before disallowing
5389 this as a UNIX client (one with UNIX extensions) can know the source is a
5390 symlink and make this decision intelligently. Found by an excellent bug
5391 report from <AndyLiebman@aol.com>.
5392 ****************************************************************************/
5394 static bool rename_path_prefix_equal(const char *src, const char *dest)
5396 const char *psrc = src;
5397 const char *pdst = dest;
5400 if (psrc[0] == '.' && psrc[1] == '/') {
5403 if (pdst[0] == '.' && pdst[1] == '/') {
5406 if ((slen = strlen(psrc)) > strlen(pdst)) {
5409 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
5413 * Do the notify calls from a rename
5416 static void notify_rename(connection_struct *conn, bool is_dir,
5417 const char *oldpath, const char *newpath)
5419 char *olddir, *newdir;
5420 const char *oldname, *newname;
5423 mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
5424 : FILE_NOTIFY_CHANGE_FILE_NAME;
5426 if (!parent_dirname_talloc(NULL, oldpath, &olddir, &oldname)
5427 || !parent_dirname_talloc(NULL, newpath, &newdir, &newname)) {
5428 TALLOC_FREE(olddir);
5432 if (strcmp(olddir, newdir) == 0) {
5433 notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, oldpath);
5434 notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, newpath);
5437 notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, oldpath);
5438 notify_fname(conn, NOTIFY_ACTION_ADDED, mask, newpath);
5440 TALLOC_FREE(olddir);
5441 TALLOC_FREE(newdir);
5443 /* this is a strange one. w2k3 gives an additional event for
5444 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
5445 files, but not directories */
5447 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
5448 FILE_NOTIFY_CHANGE_ATTRIBUTES
5449 |FILE_NOTIFY_CHANGE_CREATION,
5454 /****************************************************************************
5455 Rename an open file - given an fsp.
5456 ****************************************************************************/
5458 NTSTATUS rename_internals_fsp(connection_struct *conn,
5461 const char *newname_last_component,
5463 bool replace_if_exists)
5465 TALLOC_CTX *ctx = talloc_tos();
5466 SMB_STRUCT_STAT sbuf, sbuf1;
5467 NTSTATUS status = NT_STATUS_OK;
5468 struct share_mode_lock *lck = NULL;
5473 status = check_name(conn, newname);
5474 if (!NT_STATUS_IS_OK(status)) {
5478 /* Ensure newname contains a '/' */
5479 if(strrchr_m(newname,'/') == 0) {
5480 newname = talloc_asprintf(ctx,
5484 return NT_STATUS_NO_MEMORY;
5489 * Check for special case with case preserving and not
5490 * case sensitive. If the old last component differs from the original
5491 * last component only by case, then we should allow
5492 * the rename (user is trying to change the case of the
5496 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
5497 strequal(newname, fsp->fsp_name)) {
5499 char *newname_modified_last_component = NULL;
5502 * Get the last component of the modified name.
5503 * Note that we guarantee that newname contains a '/'
5506 p = strrchr_m(newname,'/');
5507 newname_modified_last_component = talloc_strdup(ctx,
5509 if (!newname_modified_last_component) {
5510 return NT_STATUS_NO_MEMORY;
5513 if(strcsequal(newname_modified_last_component,
5514 newname_last_component) == False) {
5516 * Replace the modified last component with
5519 *p = '\0'; /* Truncate at the '/' */
5520 newname = talloc_asprintf(ctx,
5523 newname_last_component);
5528 * If the src and dest names are identical - including case,
5529 * don't do the rename, just return success.
5532 if (strcsequal(fsp->fsp_name, newname)) {
5533 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
5535 return NT_STATUS_OK;
5539 * Have vfs_object_exist also fill sbuf1
5541 dst_exists = vfs_object_exist(conn, newname, &sbuf1);
5543 if(!replace_if_exists && dst_exists) {
5544 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
5545 fsp->fsp_name,newname));
5546 return NT_STATUS_OBJECT_NAME_COLLISION;
5550 struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
5551 files_struct *dst_fsp = file_find_di_first(fileid);
5553 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
5554 return NT_STATUS_ACCESS_DENIED;
5558 /* Ensure we have a valid stat struct for the source. */
5559 if (fsp->fh->fd != -1) {
5560 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
5561 return map_nt_error_from_unix(errno);
5564 if (SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) == -1) {
5565 return map_nt_error_from_unix(errno);
5569 status = can_rename(conn, fsp, attrs, &sbuf);
5571 if (!NT_STATUS_IS_OK(status)) {
5572 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5573 nt_errstr(status), fsp->fsp_name,newname));
5574 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION))
5575 status = NT_STATUS_ACCESS_DENIED;
5579 if (rename_path_prefix_equal(fsp->fsp_name, newname)) {
5580 return NT_STATUS_ACCESS_DENIED;
5583 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
5587 * We have the file open ourselves, so not being able to get the
5588 * corresponding share mode lock is a fatal error.
5591 SMB_ASSERT(lck != NULL);
5593 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
5594 uint32 create_options = fsp->fh->private_options;
5596 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
5597 fsp->fsp_name,newname));
5599 notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname);
5601 rename_open_files(conn, lck, newname);
5604 * A rename acts as a new file create w.r.t. allowing an initial delete
5605 * on close, probably because in Windows there is a new handle to the
5606 * new file. If initial delete on close was requested but not
5607 * originally set, we need to set it here. This is probably not 100% correct,
5608 * but will work for the CIFSFS client which in non-posix mode
5609 * depends on these semantics. JRA.
5612 set_allow_initial_delete_on_close(lck, fsp, True);
5614 if (create_options & FILE_DELETE_ON_CLOSE) {
5615 status = can_set_delete_on_close(fsp, True, 0);
5617 if (NT_STATUS_IS_OK(status)) {
5618 /* Note that here we set the *inital* delete on close flag,
5619 * not the regular one. The magic gets handled in close. */
5620 fsp->initial_delete_on_close = True;
5624 return NT_STATUS_OK;
5629 if (errno == ENOTDIR || errno == EISDIR) {
5630 status = NT_STATUS_OBJECT_NAME_COLLISION;
5632 status = map_nt_error_from_unix(errno);
5635 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5636 nt_errstr(status), fsp->fsp_name,newname));
5641 /****************************************************************************
5642 The guts of the rename command, split out so it may be called by the NT SMB
5644 ****************************************************************************/
5646 NTSTATUS rename_internals(TALLOC_CTX *ctx,
5647 connection_struct *conn,
5648 struct smb_request *req,
5649 const char *name_in,
5650 const char *newname_in,
5652 bool replace_if_exists,
5655 uint32_t access_mask)
5657 char *directory = NULL;
5659 char *last_component_src = NULL;
5660 char *last_component_dest = NULL;
5662 char *newname = NULL;
5665 NTSTATUS status = NT_STATUS_OK;
5666 SMB_STRUCT_STAT sbuf1, sbuf2;
5667 struct smb_Dir *dir_hnd = NULL;
5674 status = unix_convert(ctx, conn, name_in, src_has_wild, &name,
5675 &last_component_src, &sbuf1);
5676 if (!NT_STATUS_IS_OK(status)) {
5680 status = unix_convert(ctx, conn, newname_in, dest_has_wild, &newname,
5681 &last_component_dest, &sbuf2);
5682 if (!NT_STATUS_IS_OK(status)) {
5687 * Split the old name into directory and last component
5688 * strings. Note that unix_convert may have stripped off a
5689 * leading ./ from both name and newname if the rename is
5690 * at the root of the share. We need to make sure either both
5691 * name and newname contain a / character or neither of them do
5692 * as this is checked in resolve_wildcards().
5695 p = strrchr_m(name,'/');
5697 directory = talloc_strdup(ctx, ".");
5699 return NT_STATUS_NO_MEMORY;
5704 directory = talloc_strdup(ctx, name);
5706 return NT_STATUS_NO_MEMORY;
5709 *p = '/'; /* Replace needed for exceptional test below. */
5713 * We should only check the mangled cache
5714 * here if unix_convert failed. This means
5715 * that the path in 'mask' doesn't exist
5716 * on the file system and so we need to look
5717 * for a possible mangle. This patch from
5718 * Tine Smukavec <valentin.smukavec@hermes.si>.
5721 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
5722 char *new_mask = NULL;
5723 mangle_lookup_name_from_8_3(ctx,
5732 if (!src_has_wild) {
5736 * No wildcards - just process the one file.
5738 bool is_short_name = mangle_is_8_3(name, True, conn->params);
5740 /* Add a terminating '/' to the directory name. */
5741 directory = talloc_asprintf_append(directory,
5745 return NT_STATUS_NO_MEMORY;
5748 /* Ensure newname contains a '/' also */
5749 if(strrchr_m(newname,'/') == 0) {
5750 newname = talloc_asprintf(ctx,
5754 return NT_STATUS_NO_MEMORY;
5758 DEBUG(3, ("rename_internals: case_sensitive = %d, "
5759 "case_preserve = %d, short case preserve = %d, "
5760 "directory = %s, newname = %s, "
5761 "last_component_dest = %s, is_8_3 = %d\n",
5762 conn->case_sensitive, conn->case_preserve,
5763 conn->short_case_preserve, directory,
5764 newname, last_component_dest, is_short_name));
5766 /* The dest name still may have wildcards. */
5767 if (dest_has_wild) {
5768 char *mod_newname = NULL;
5769 if (!resolve_wildcards(ctx,
5770 directory,newname,&mod_newname)) {
5771 DEBUG(6, ("rename_internals: resolve_wildcards "
5775 return NT_STATUS_NO_MEMORY;
5777 newname = mod_newname;
5781 SMB_VFS_STAT(conn, directory, &sbuf1);
5783 status = S_ISDIR(sbuf1.st_mode) ?
5784 open_directory(conn, req, directory, &sbuf1,
5786 FILE_SHARE_READ|FILE_SHARE_WRITE,
5787 FILE_OPEN, 0, 0, NULL,
5789 : open_file_ntcreate(conn, req, directory, &sbuf1,
5791 FILE_SHARE_READ|FILE_SHARE_WRITE,
5792 FILE_OPEN, 0, 0, 0, NULL,
5795 if (!NT_STATUS_IS_OK(status)) {
5796 DEBUG(3, ("Could not open rename source %s: %s\n",
5797 directory, nt_errstr(status)));
5801 status = rename_internals_fsp(conn, fsp, newname,
5802 last_component_dest,
5803 attrs, replace_if_exists);
5805 close_file(fsp, NORMAL_CLOSE);
5807 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
5808 nt_errstr(status), directory,newname));
5814 * Wildcards - process each file that matches.
5816 if (strequal(mask,"????????.???")) {
5821 status = check_name(conn, directory);
5822 if (!NT_STATUS_IS_OK(status)) {
5826 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, attrs);
5827 if (dir_hnd == NULL) {
5828 return map_nt_error_from_unix(errno);
5831 status = NT_STATUS_NO_SUCH_FILE;
5833 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5834 * - gentest fix. JRA
5837 while ((dname = ReadDirName(dir_hnd, &offset))) {
5838 files_struct *fsp = NULL;
5840 char *destname = NULL;
5841 bool sysdir_entry = False;
5843 /* Quick check for "." and ".." */
5844 if (ISDOT(dname) || ISDOTDOT(dname)) {
5846 sysdir_entry = True;
5852 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
5856 if(!mask_match(dname, mask, conn->case_sensitive)) {
5861 status = NT_STATUS_OBJECT_NAME_INVALID;
5865 fname = talloc_asprintf(ctx,
5870 return NT_STATUS_NO_MEMORY;
5873 if (!resolve_wildcards(ctx,
5874 fname,newname,&destname)) {
5875 DEBUG(6, ("resolve_wildcards %s %s failed\n",
5881 return NT_STATUS_NO_MEMORY;
5885 SMB_VFS_STAT(conn, fname, &sbuf1);
5887 status = S_ISDIR(sbuf1.st_mode) ?
5888 open_directory(conn, req, fname, &sbuf1,
5890 FILE_SHARE_READ|FILE_SHARE_WRITE,
5891 FILE_OPEN, 0, 0, NULL,
5893 : open_file_ntcreate(conn, req, fname, &sbuf1,
5895 FILE_SHARE_READ|FILE_SHARE_WRITE,
5896 FILE_OPEN, 0, 0, 0, NULL,
5899 if (!NT_STATUS_IS_OK(status)) {
5900 DEBUG(3,("rename_internals: open_file_ntcreate "
5901 "returned %s rename %s -> %s\n",
5902 nt_errstr(status), directory, newname));
5906 status = rename_internals_fsp(conn, fsp, destname, dname,
5907 attrs, replace_if_exists);
5909 close_file(fsp, NORMAL_CLOSE);
5911 if (!NT_STATUS_IS_OK(status)) {
5912 DEBUG(3, ("rename_internals_fsp returned %s for "
5913 "rename %s -> %s\n", nt_errstr(status),
5914 directory, newname));
5920 DEBUG(3,("rename_internals: doing rename on %s -> "
5921 "%s\n",fname,destname));
5924 TALLOC_FREE(destname);
5926 TALLOC_FREE(dir_hnd);
5928 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
5929 status = map_nt_error_from_unix(errno);
5935 /****************************************************************************
5937 ****************************************************************************/
5939 void reply_mv(struct smb_request *req)
5941 connection_struct *conn = req->conn;
5943 char *newname = NULL;
5947 bool src_has_wcard = False;
5948 bool dest_has_wcard = False;
5949 TALLOC_CTX *ctx = talloc_tos();
5951 START_PROFILE(SMBmv);
5954 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5959 attrs = SVAL(req->inbuf,smb_vwv0);
5961 p = smb_buf(req->inbuf) + 1;
5962 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
5963 0, STR_TERMINATE, &status,
5965 if (!NT_STATUS_IS_OK(status)) {
5966 reply_nterror(req, status);
5971 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
5972 0, STR_TERMINATE, &status,
5974 if (!NT_STATUS_IS_OK(status)) {
5975 reply_nterror(req, status);
5980 status = resolve_dfspath_wcard(ctx, conn,
5981 req->flags2 & FLAGS2_DFS_PATHNAMES,
5985 if (!NT_STATUS_IS_OK(status)) {
5986 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5987 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5988 ERRSRV, ERRbadpath);
5992 reply_nterror(req, status);
5997 status = resolve_dfspath_wcard(ctx, conn,
5998 req->flags2 & FLAGS2_DFS_PATHNAMES,
6002 if (!NT_STATUS_IS_OK(status)) {
6003 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6004 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6005 ERRSRV, ERRbadpath);
6009 reply_nterror(req, status);
6014 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
6016 status = rename_internals(ctx, conn, req, name, newname, attrs, False,
6017 src_has_wcard, dest_has_wcard, DELETE_ACCESS);
6018 if (!NT_STATUS_IS_OK(status)) {
6019 if (open_was_deferred(req->mid)) {
6020 /* We have re-scheduled this call. */
6024 reply_nterror(req, status);
6029 reply_outbuf(req, 0, 0);
6035 /*******************************************************************
6036 Copy a file as part of a reply_copy.
6037 ******************************************************************/
6040 * TODO: check error codes on all callers
6043 NTSTATUS copy_file(TALLOC_CTX *ctx,
6044 connection_struct *conn,
6049 bool target_is_directory)
6051 SMB_STRUCT_STAT src_sbuf, sbuf2;
6053 files_struct *fsp1,*fsp2;
6056 uint32 new_create_disposition;
6059 dest = talloc_strdup(ctx, dest1);
6061 return NT_STATUS_NO_MEMORY;
6063 if (target_is_directory) {
6064 const char *p = strrchr_m(src,'/');
6070 dest = talloc_asprintf_append(dest,
6074 return NT_STATUS_NO_MEMORY;
6078 if (!vfs_file_exist(conn,src,&src_sbuf)) {
6080 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6083 if (!target_is_directory && count) {
6084 new_create_disposition = FILE_OPEN;
6086 if (!map_open_params_to_ntcreate(dest1,0,ofun,
6087 NULL, NULL, &new_create_disposition, NULL)) {
6089 return NT_STATUS_INVALID_PARAMETER;
6093 status = open_file_ntcreate(conn, NULL, src, &src_sbuf,
6095 FILE_SHARE_READ|FILE_SHARE_WRITE,
6098 FILE_ATTRIBUTE_NORMAL,
6102 if (!NT_STATUS_IS_OK(status)) {
6107 dosattrs = dos_mode(conn, src, &src_sbuf);
6108 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) {
6109 ZERO_STRUCTP(&sbuf2);
6112 status = open_file_ntcreate(conn, NULL, dest, &sbuf2,
6114 FILE_SHARE_READ|FILE_SHARE_WRITE,
6115 new_create_disposition,
6123 if (!NT_STATUS_IS_OK(status)) {
6124 close_file(fsp1,ERROR_CLOSE);
6128 if ((ofun&3) == 1) {
6129 if(SMB_VFS_LSEEK(fsp2,0,SEEK_END) == -1) {
6130 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
6132 * Stop the copy from occurring.
6135 src_sbuf.st_size = 0;
6139 if (src_sbuf.st_size) {
6140 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
6143 close_file(fsp1,NORMAL_CLOSE);
6145 /* Ensure the modtime is set correctly on the destination file. */
6146 set_close_write_time(fsp2, get_mtimespec(&src_sbuf));
6149 * As we are opening fsp1 read-only we only expect
6150 * an error on close on fsp2 if we are out of space.
6151 * Thus we don't look at the error return from the
6154 status = close_file(fsp2,NORMAL_CLOSE);
6156 if (!NT_STATUS_IS_OK(status)) {
6160 if (ret != (SMB_OFF_T)src_sbuf.st_size) {
6161 return NT_STATUS_DISK_FULL;
6164 return NT_STATUS_OK;
6167 /****************************************************************************
6168 Reply to a file copy.
6169 ****************************************************************************/
6171 void reply_copy(struct smb_request *req)
6173 connection_struct *conn = req->conn;
6175 char *newname = NULL;
6176 char *directory = NULL;
6180 int error = ERRnoaccess;
6185 bool target_is_directory=False;
6186 bool source_has_wild = False;
6187 bool dest_has_wild = False;
6188 SMB_STRUCT_STAT sbuf1, sbuf2;
6190 TALLOC_CTX *ctx = talloc_tos();
6192 START_PROFILE(SMBcopy);
6195 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6196 END_PROFILE(SMBcopy);
6200 tid2 = SVAL(req->inbuf,smb_vwv0);
6201 ofun = SVAL(req->inbuf,smb_vwv1);
6202 flags = SVAL(req->inbuf,smb_vwv2);
6204 p = smb_buf(req->inbuf);
6205 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
6206 0, STR_TERMINATE, &status,
6208 if (!NT_STATUS_IS_OK(status)) {
6209 reply_nterror(req, status);
6210 END_PROFILE(SMBcopy);
6213 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
6214 0, STR_TERMINATE, &status,
6216 if (!NT_STATUS_IS_OK(status)) {
6217 reply_nterror(req, status);
6218 END_PROFILE(SMBcopy);
6222 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
6224 if (tid2 != conn->cnum) {
6225 /* can't currently handle inter share copies XXXX */
6226 DEBUG(3,("Rejecting inter-share copy\n"));
6227 reply_doserror(req, ERRSRV, ERRinvdevice);
6228 END_PROFILE(SMBcopy);
6232 status = resolve_dfspath_wcard(ctx, conn,
6233 req->flags2 & FLAGS2_DFS_PATHNAMES,
6237 if (!NT_STATUS_IS_OK(status)) {
6238 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6239 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6240 ERRSRV, ERRbadpath);
6241 END_PROFILE(SMBcopy);
6244 reply_nterror(req, status);
6245 END_PROFILE(SMBcopy);
6249 status = resolve_dfspath_wcard(ctx, conn,
6250 req->flags2 & FLAGS2_DFS_PATHNAMES,
6254 if (!NT_STATUS_IS_OK(status)) {
6255 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6256 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6257 ERRSRV, ERRbadpath);
6258 END_PROFILE(SMBcopy);
6261 reply_nterror(req, status);
6262 END_PROFILE(SMBcopy);
6266 status = unix_convert(ctx, conn, name, source_has_wild,
6267 &name, NULL, &sbuf1);
6268 if (!NT_STATUS_IS_OK(status)) {
6269 reply_nterror(req, status);
6270 END_PROFILE(SMBcopy);
6274 status = unix_convert(ctx, conn, newname, dest_has_wild,
6275 &newname, NULL, &sbuf2);
6276 if (!NT_STATUS_IS_OK(status)) {
6277 reply_nterror(req, status);
6278 END_PROFILE(SMBcopy);
6282 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
6284 if ((flags&1) && target_is_directory) {
6285 reply_doserror(req, ERRDOS, ERRbadfile);
6286 END_PROFILE(SMBcopy);
6290 if ((flags&2) && !target_is_directory) {
6291 reply_doserror(req, ERRDOS, ERRbadpath);
6292 END_PROFILE(SMBcopy);
6296 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
6297 /* wants a tree copy! XXXX */
6298 DEBUG(3,("Rejecting tree copy\n"));
6299 reply_doserror(req, ERRSRV, ERRerror);
6300 END_PROFILE(SMBcopy);
6304 p = strrchr_m(name,'/');
6306 directory = talloc_strdup(ctx, "./");
6308 reply_nterror(req, NT_STATUS_NO_MEMORY);
6309 END_PROFILE(SMBcopy);
6315 directory = talloc_strdup(ctx, name);
6317 reply_nterror(req, NT_STATUS_NO_MEMORY);
6318 END_PROFILE(SMBcopy);
6325 * We should only check the mangled cache
6326 * here if unix_convert failed. This means
6327 * that the path in 'mask' doesn't exist
6328 * on the file system and so we need to look
6329 * for a possible mangle. This patch from
6330 * Tine Smukavec <valentin.smukavec@hermes.si>.
6333 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
6334 char *new_mask = NULL;
6335 mangle_lookup_name_from_8_3(ctx,
6344 if (!source_has_wild) {
6345 directory = talloc_asprintf_append(directory,
6348 if (dest_has_wild) {
6349 char *mod_newname = NULL;
6350 if (!resolve_wildcards(ctx,
6351 directory,newname,&mod_newname)) {
6352 reply_nterror(req, NT_STATUS_NO_MEMORY);
6353 END_PROFILE(SMBcopy);
6356 newname = mod_newname;
6359 status = check_name(conn, directory);
6360 if (!NT_STATUS_IS_OK(status)) {
6361 reply_nterror(req, status);
6362 END_PROFILE(SMBcopy);
6366 status = check_name(conn, newname);
6367 if (!NT_STATUS_IS_OK(status)) {
6368 reply_nterror(req, status);
6369 END_PROFILE(SMBcopy);
6373 status = copy_file(ctx,conn,directory,newname,ofun,
6374 count,target_is_directory);
6376 if(!NT_STATUS_IS_OK(status)) {
6377 reply_nterror(req, status);
6378 END_PROFILE(SMBcopy);
6384 struct smb_Dir *dir_hnd = NULL;
6385 const char *dname = NULL;
6388 if (strequal(mask,"????????.???")) {
6393 status = check_name(conn, directory);
6394 if (!NT_STATUS_IS_OK(status)) {
6395 reply_nterror(req, status);
6396 END_PROFILE(SMBcopy);
6400 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, 0);
6401 if (dir_hnd == NULL) {
6402 status = map_nt_error_from_unix(errno);
6403 reply_nterror(req, status);
6404 END_PROFILE(SMBcopy);
6410 while ((dname = ReadDirName(dir_hnd, &offset))) {
6411 char *destname = NULL;
6414 if (ISDOT(dname) || ISDOTDOT(dname)) {
6418 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
6422 if(!mask_match(dname, mask, conn->case_sensitive)) {
6426 error = ERRnoaccess;
6427 fname = talloc_asprintf(ctx,
6432 TALLOC_FREE(dir_hnd);
6433 reply_nterror(req, NT_STATUS_NO_MEMORY);
6434 END_PROFILE(SMBcopy);
6438 if (!resolve_wildcards(ctx,
6439 fname,newname,&destname)) {
6443 TALLOC_FREE(dir_hnd);
6444 reply_nterror(req, NT_STATUS_NO_MEMORY);
6445 END_PROFILE(SMBcopy);
6449 status = check_name(conn, fname);
6450 if (!NT_STATUS_IS_OK(status)) {
6451 TALLOC_FREE(dir_hnd);
6452 reply_nterror(req, status);
6453 END_PROFILE(SMBcopy);
6457 status = check_name(conn, destname);
6458 if (!NT_STATUS_IS_OK(status)) {
6459 TALLOC_FREE(dir_hnd);
6460 reply_nterror(req, status);
6461 END_PROFILE(SMBcopy);
6465 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
6467 status = copy_file(ctx,conn,fname,destname,ofun,
6468 count,target_is_directory);
6469 if (NT_STATUS_IS_OK(status)) {
6473 TALLOC_FREE(destname);
6475 TALLOC_FREE(dir_hnd);
6480 /* Error on close... */
6482 reply_unixerror(req, ERRHRD, ERRgeneral);
6483 END_PROFILE(SMBcopy);
6487 reply_doserror(req, ERRDOS, error);
6488 END_PROFILE(SMBcopy);
6492 reply_outbuf(req, 1, 0);
6493 SSVAL(req->outbuf,smb_vwv0,count);
6495 END_PROFILE(SMBcopy);
6500 #define DBGC_CLASS DBGC_LOCKING
6502 /****************************************************************************
6503 Get a lock pid, dealing with large count requests.
6504 ****************************************************************************/
6506 uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
6508 if(!large_file_format)
6509 return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
6511 return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
6514 /****************************************************************************
6515 Get a lock count, dealing with large count requests.
6516 ****************************************************************************/
6518 SMB_BIG_UINT get_lock_count( char *data, int data_offset, bool large_file_format)
6520 SMB_BIG_UINT count = 0;
6522 if(!large_file_format) {
6523 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
6526 #if defined(HAVE_LONGLONG)
6527 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
6528 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
6529 #else /* HAVE_LONGLONG */
6532 * NT4.x seems to be broken in that it sends large file (64 bit)
6533 * lockingX calls even if the CAP_LARGE_FILES was *not*
6534 * negotiated. For boxes without large unsigned ints truncate the
6535 * lock count by dropping the top 32 bits.
6538 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
6539 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
6540 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
6541 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
6542 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
6545 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
6546 #endif /* HAVE_LONGLONG */
6552 #if !defined(HAVE_LONGLONG)
6553 /****************************************************************************
6554 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
6555 ****************************************************************************/
6557 static uint32 map_lock_offset(uint32 high, uint32 low)
6561 uint32 highcopy = high;
6564 * Try and find out how many significant bits there are in high.
6567 for(i = 0; highcopy; i++)
6571 * We use 31 bits not 32 here as POSIX
6572 * lock offsets may not be negative.
6575 mask = (~0) << (31 - i);
6578 return 0; /* Fail. */
6584 #endif /* !defined(HAVE_LONGLONG) */
6586 /****************************************************************************
6587 Get a lock offset, dealing with large offset requests.
6588 ****************************************************************************/
6590 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err)
6592 SMB_BIG_UINT offset = 0;
6596 if(!large_file_format) {
6597 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
6600 #if defined(HAVE_LONGLONG)
6601 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
6602 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
6603 #else /* HAVE_LONGLONG */
6606 * NT4.x seems to be broken in that it sends large file (64 bit)
6607 * lockingX calls even if the CAP_LARGE_FILES was *not*
6608 * negotiated. For boxes without large unsigned ints mangle the
6609 * lock offset by mapping the top 32 bits onto the lower 32.
6612 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
6613 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6614 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
6617 if((new_low = map_lock_offset(high, low)) == 0) {
6619 return (SMB_BIG_UINT)-1;
6622 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
6623 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
6624 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
6625 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
6628 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6629 #endif /* HAVE_LONGLONG */
6635 /****************************************************************************
6636 Reply to a lockingX request.
6637 ****************************************************************************/
6639 void reply_lockingX(struct smb_request *req)
6641 connection_struct *conn = req->conn;
6643 unsigned char locktype;
6644 unsigned char oplocklevel;
6647 SMB_BIG_UINT count = 0, offset = 0;
6652 bool large_file_format;
6654 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
6656 START_PROFILE(SMBlockingX);
6659 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6660 END_PROFILE(SMBlockingX);
6664 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
6665 locktype = CVAL(req->inbuf,smb_vwv3);
6666 oplocklevel = CVAL(req->inbuf,smb_vwv3+1);
6667 num_ulocks = SVAL(req->inbuf,smb_vwv6);
6668 num_locks = SVAL(req->inbuf,smb_vwv7);
6669 lock_timeout = IVAL(req->inbuf,smb_vwv4);
6670 large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
6672 if (!check_fsp(conn, req, fsp)) {
6673 END_PROFILE(SMBlockingX);
6677 data = smb_buf(req->inbuf);
6679 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
6680 /* we don't support these - and CANCEL_LOCK makes w2k
6681 and XP reboot so I don't really want to be
6682 compatible! (tridge) */
6683 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
6684 END_PROFILE(SMBlockingX);
6688 /* Check if this is an oplock break on a file
6689 we have granted an oplock on.
6691 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
6692 /* Client can insist on breaking to none. */
6693 bool break_to_none = (oplocklevel == 0);
6696 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
6697 "for fnum = %d\n", (unsigned int)oplocklevel,
6701 * Make sure we have granted an exclusive or batch oplock on
6705 if (fsp->oplock_type == 0) {
6707 /* The Samba4 nbench simulator doesn't understand
6708 the difference between break to level2 and break
6709 to none from level2 - it sends oplock break
6710 replies in both cases. Don't keep logging an error
6711 message here - just ignore it. JRA. */
6713 DEBUG(5,("reply_lockingX: Error : oplock break from "
6714 "client for fnum = %d (oplock=%d) and no "
6715 "oplock granted on this file (%s).\n",
6716 fsp->fnum, fsp->oplock_type, fsp->fsp_name));
6718 /* if this is a pure oplock break request then don't
6720 if (num_locks == 0 && num_ulocks == 0) {
6721 END_PROFILE(SMBlockingX);
6724 END_PROFILE(SMBlockingX);
6725 reply_doserror(req, ERRDOS, ERRlock);
6730 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
6732 result = remove_oplock(fsp);
6734 result = downgrade_oplock(fsp);
6738 DEBUG(0, ("reply_lockingX: error in removing "
6739 "oplock on file %s\n", fsp->fsp_name));
6740 /* Hmmm. Is this panic justified? */
6741 smb_panic("internal tdb error");
6744 reply_to_oplock_break_requests(fsp);
6746 /* if this is a pure oplock break request then don't send a
6748 if (num_locks == 0 && num_ulocks == 0) {
6749 /* Sanity check - ensure a pure oplock break is not a
6751 if(CVAL(req->inbuf,smb_vwv0) != 0xff)
6752 DEBUG(0,("reply_lockingX: Error : pure oplock "
6753 "break is a chained %d request !\n",
6754 (unsigned int)CVAL(req->inbuf,
6756 END_PROFILE(SMBlockingX);
6762 * We do this check *after* we have checked this is not a oplock break
6763 * response message. JRA.
6766 release_level_2_oplocks_on_change(fsp);
6768 if (smb_buflen(req->inbuf) <
6769 (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
6770 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6771 END_PROFILE(SMBlockingX);
6775 /* Data now points at the beginning of the list
6776 of smb_unlkrng structs */
6777 for(i = 0; i < (int)num_ulocks; i++) {
6778 lock_pid = get_lock_pid( data, i, large_file_format);
6779 count = get_lock_count( data, i, large_file_format);
6780 offset = get_lock_offset( data, i, large_file_format, &err);
6783 * There is no error code marked "stupid client bug".... :-).
6786 END_PROFILE(SMBlockingX);
6787 reply_doserror(req, ERRDOS, ERRnoaccess);
6791 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
6792 "pid %u, file %s\n", (double)offset, (double)count,
6793 (unsigned int)lock_pid, fsp->fsp_name ));
6795 status = do_unlock(smbd_messaging_context(),
6802 if (NT_STATUS_V(status)) {
6803 END_PROFILE(SMBlockingX);
6804 reply_nterror(req, status);
6809 /* Setup the timeout in seconds. */
6811 if (!lp_blocking_locks(SNUM(conn))) {
6815 /* Now do any requested locks */
6816 data += ((large_file_format ? 20 : 10)*num_ulocks);
6818 /* Data now points at the beginning of the list
6819 of smb_lkrng structs */
6821 for(i = 0; i < (int)num_locks; i++) {
6822 enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
6823 READ_LOCK:WRITE_LOCK);
6824 lock_pid = get_lock_pid( data, i, large_file_format);
6825 count = get_lock_count( data, i, large_file_format);
6826 offset = get_lock_offset( data, i, large_file_format, &err);
6829 * There is no error code marked "stupid client bug".... :-).
6832 END_PROFILE(SMBlockingX);
6833 reply_doserror(req, ERRDOS, ERRnoaccess);
6837 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
6838 "%u, file %s timeout = %d\n", (double)offset,
6839 (double)count, (unsigned int)lock_pid,
6840 fsp->fsp_name, (int)lock_timeout ));
6842 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
6843 if (lp_blocking_locks(SNUM(conn))) {
6845 /* Schedule a message to ourselves to
6846 remove the blocking lock record and
6847 return the right error. */
6849 if (!blocking_lock_cancel(fsp,
6855 NT_STATUS_FILE_LOCK_CONFLICT)) {
6856 END_PROFILE(SMBlockingX);
6861 ERRcancelviolation));
6865 /* Remove a matching pending lock. */
6866 status = do_lock_cancel(fsp,
6872 bool blocking_lock = lock_timeout ? True : False;
6873 bool defer_lock = False;
6874 struct byte_range_lock *br_lck;
6875 uint32 block_smbpid;
6877 br_lck = do_lock(smbd_messaging_context(),
6888 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6889 /* Windows internal resolution for blocking locks seems
6890 to be about 200ms... Don't wait for less than that. JRA. */
6891 if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
6892 lock_timeout = lp_lock_spin_time();
6897 /* This heuristic seems to match W2K3 very well. If a
6898 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
6899 it pretends we asked for a timeout of between 150 - 300 milliseconds as
6900 far as I can tell. Replacement for do_lock_spin(). JRA. */
6902 if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
6903 NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
6905 lock_timeout = lp_lock_spin_time();
6908 if (br_lck && defer_lock) {
6910 * A blocking lock was requested. Package up
6911 * this smb into a queued request and push it
6912 * onto the blocking lock queue.
6914 if(push_blocking_lock_request(br_lck,
6925 TALLOC_FREE(br_lck);
6926 END_PROFILE(SMBlockingX);
6931 TALLOC_FREE(br_lck);
6934 if (NT_STATUS_V(status)) {
6935 END_PROFILE(SMBlockingX);
6936 reply_nterror(req, status);
6941 /* If any of the above locks failed, then we must unlock
6942 all of the previous locks (X/Open spec). */
6944 if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) &&
6948 * Ensure we don't do a remove on the lock that just failed,
6949 * as under POSIX rules, if we have a lock already there, we
6950 * will delete it (and we shouldn't) .....
6952 for(i--; i >= 0; i--) {
6953 lock_pid = get_lock_pid( data, i, large_file_format);
6954 count = get_lock_count( data, i, large_file_format);
6955 offset = get_lock_offset( data, i, large_file_format,
6959 * There is no error code marked "stupid client
6963 END_PROFILE(SMBlockingX);
6964 reply_doserror(req, ERRDOS, ERRnoaccess);
6968 do_unlock(smbd_messaging_context(),
6975 END_PROFILE(SMBlockingX);
6976 reply_nterror(req, status);
6980 reply_outbuf(req, 2, 0);
6982 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
6983 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
6985 END_PROFILE(SMBlockingX);
6990 #define DBGC_CLASS DBGC_ALL
6992 /****************************************************************************
6993 Reply to a SMBreadbmpx (read block multiplex) request.
6994 Always reply with an error, if someone has a platform really needs this,
6995 please contact vl@samba.org
6996 ****************************************************************************/
6998 void reply_readbmpx(struct smb_request *req)
7000 START_PROFILE(SMBreadBmpx);
7001 reply_doserror(req, ERRSRV, ERRuseSTD);
7002 END_PROFILE(SMBreadBmpx);
7006 /****************************************************************************
7007 Reply to a SMBreadbs (read block multiplex secondary) request.
7008 Always reply with an error, if someone has a platform really needs this,
7009 please contact vl@samba.org
7010 ****************************************************************************/
7012 void reply_readbs(struct smb_request *req)
7014 START_PROFILE(SMBreadBs);
7015 reply_doserror(req, ERRSRV, ERRuseSTD);
7016 END_PROFILE(SMBreadBs);
7020 /****************************************************************************
7021 Reply to a SMBsetattrE.
7022 ****************************************************************************/
7024 void reply_setattrE(struct smb_request *req)
7026 connection_struct *conn = req->conn;
7027 struct timespec ts[2];
7029 SMB_STRUCT_STAT sbuf;
7032 START_PROFILE(SMBsetattrE);
7035 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7036 END_PROFILE(SMBsetattrE);
7040 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
7042 if(!fsp || (fsp->conn != conn)) {
7043 reply_doserror(req, ERRDOS, ERRbadfid);
7044 END_PROFILE(SMBsetattrE);
7050 * Convert the DOS times into unix times. Ignore create
7051 * time as UNIX can't set this.
7054 ts[0] = convert_time_t_to_timespec(
7055 srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */
7056 ts[1] = convert_time_t_to_timespec(
7057 srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */
7059 reply_outbuf(req, 0, 0);
7062 * Patch from Ray Frush <frush@engr.colostate.edu>
7063 * Sometimes times are sent as zero - ignore them.
7066 /* Ensure we have a valid stat struct for the source. */
7067 if (fsp->fh->fd != -1) {
7068 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
7069 status = map_nt_error_from_unix(errno);
7070 reply_nterror(req, status);
7071 END_PROFILE(SMBsetattrE);
7075 if (SMB_VFS_STAT(conn, fsp->fsp_name, &sbuf) == -1) {
7076 status = map_nt_error_from_unix(errno);
7077 reply_nterror(req, status);
7078 END_PROFILE(SMBsetattrE);
7083 status = smb_set_file_time(conn, fsp, fsp->fsp_name,
7085 if (!NT_STATUS_IS_OK(status)) {
7086 reply_doserror(req, ERRDOS, ERRnoaccess);
7087 END_PROFILE(SMBsetattrE);
7091 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
7093 (unsigned int)ts[0].tv_sec,
7094 (unsigned int)ts[1].tv_sec));
7096 END_PROFILE(SMBsetattrE);
7101 /* Back from the dead for OS/2..... JRA. */
7103 /****************************************************************************
7104 Reply to a SMBwritebmpx (write block multiplex primary) request.
7105 Always reply with an error, if someone has a platform really needs this,
7106 please contact vl@samba.org
7107 ****************************************************************************/
7109 void reply_writebmpx(struct smb_request *req)
7111 START_PROFILE(SMBwriteBmpx);
7112 reply_doserror(req, ERRSRV, ERRuseSTD);
7113 END_PROFILE(SMBwriteBmpx);
7117 /****************************************************************************
7118 Reply to a SMBwritebs (write block multiplex secondary) request.
7119 Always reply with an error, if someone has a platform really needs this,
7120 please contact vl@samba.org
7121 ****************************************************************************/
7123 void reply_writebs(struct smb_request *req)
7125 START_PROFILE(SMBwriteBs);
7126 reply_doserror(req, ERRSRV, ERRuseSTD);
7127 END_PROFILE(SMBwriteBs);
7131 /****************************************************************************
7132 Reply to a SMBgetattrE.
7133 ****************************************************************************/
7135 void reply_getattrE(struct smb_request *req)
7137 connection_struct *conn = req->conn;
7138 SMB_STRUCT_STAT sbuf;
7141 struct timespec create_ts;
7143 START_PROFILE(SMBgetattrE);
7146 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7147 END_PROFILE(SMBgetattrE);
7151 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
7153 if(!fsp || (fsp->conn != conn)) {
7154 reply_doserror(req, ERRDOS, ERRbadfid);
7155 END_PROFILE(SMBgetattrE);
7159 /* Do an fstat on this file */
7160 if(fsp_stat(fsp, &sbuf)) {
7161 reply_unixerror(req, ERRDOS, ERRnoaccess);
7162 END_PROFILE(SMBgetattrE);
7166 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
7169 * Convert the times into dos times. Set create
7170 * date to be last modify date as UNIX doesn't save
7174 reply_outbuf(req, 11, 0);
7176 create_ts = get_create_timespec(&sbuf,
7177 lp_fake_dir_create_times(SNUM(conn)));
7178 srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec);
7179 srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime);
7180 /* Should we check pending modtime here ? JRA */
7181 srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime);
7184 SIVAL(req->outbuf, smb_vwv6, 0);
7185 SIVAL(req->outbuf, smb_vwv8, 0);
7187 uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
7188 SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
7189 SIVAL(req->outbuf, smb_vwv8, allocation_size);
7191 SSVAL(req->outbuf,smb_vwv10, mode);
7193 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
7195 END_PROFILE(SMBgetattrE);