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(
829 req, SVAL(req->inbuf, smb_vwv0));
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(req, 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(req, 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(req, 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(req, 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(req, fsp, NORMAL_CLOSE);
2367 return NT_STATUS_ACCESS_DENIED;
2370 return close_file(req, 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(req, 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(req, 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(req, 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);
3267 reply_outbuf(req, 12, smb_maxcnt);
3269 nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
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 ) );
3283 /****************************************************************************
3284 Reply to a read and X.
3285 ****************************************************************************/
3287 void reply_read_and_X(struct smb_request *req)
3289 connection_struct *conn = req->conn;
3293 bool big_readX = False;
3295 size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
3298 START_PROFILE(SMBreadX);
3300 if ((req->wct != 10) && (req->wct != 12)) {
3301 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3305 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
3306 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3307 smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
3309 /* If it's an IPC, pass off the pipe handler. */
3311 reply_pipe_read_and_X(req);
3312 END_PROFILE(SMBreadX);
3316 if (!check_fsp(conn, req, fsp)) {
3317 END_PROFILE(SMBreadX);
3321 if (!CHECK_READ(fsp,req->inbuf)) {
3322 reply_doserror(req, ERRDOS,ERRbadaccess);
3323 END_PROFILE(SMBreadX);
3327 if (global_client_caps & CAP_LARGE_READX) {
3328 size_t upper_size = SVAL(req->inbuf,smb_vwv7);
3329 smb_maxcnt |= (upper_size<<16);
3330 if (upper_size > 1) {
3331 /* Can't do this on a chained packet. */
3332 if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) {
3333 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3334 END_PROFILE(SMBreadX);
3337 /* We currently don't do this on signed or sealed data. */
3338 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
3339 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3340 END_PROFILE(SMBreadX);
3343 /* Is there room in the reply for this data ? */
3344 if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
3346 NT_STATUS_INVALID_PARAMETER);
3347 END_PROFILE(SMBreadX);
3354 if (req->wct == 12) {
3355 #ifdef LARGE_SMB_OFF_T
3357 * This is a large offset (64 bit) read.
3359 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32);
3361 #else /* !LARGE_SMB_OFF_T */
3364 * Ensure we haven't been sent a >32 bit offset.
3367 if(IVAL(req->inbuf,smb_vwv10) != 0) {
3368 DEBUG(0,("reply_read_and_X - large offset (%x << 32) "
3369 "used and we don't support 64 bit offsets.\n",
3370 (unsigned int)IVAL(req->inbuf,smb_vwv10) ));
3371 END_PROFILE(SMBreadX);
3372 reply_doserror(req, ERRDOS, ERRbadaccess);
3376 #endif /* LARGE_SMB_OFF_T */
3380 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)smb_maxcnt,
3381 (SMB_BIG_UINT)startpos, READ_LOCK)) {
3382 END_PROFILE(SMBreadX);
3383 reply_doserror(req, ERRDOS, ERRlock);
3388 schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
3389 END_PROFILE(SMBreadX);
3393 send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
3395 END_PROFILE(SMBreadX);
3399 /****************************************************************************
3400 Error replies to writebraw must have smb_wct == 1. Fix this up.
3401 ****************************************************************************/
3403 void error_to_writebrawerr(struct smb_request *req)
3405 uint8 *old_outbuf = req->outbuf;
3407 reply_outbuf(req, 1, 0);
3409 memcpy(req->outbuf, old_outbuf, smb_size);
3410 TALLOC_FREE(old_outbuf);
3413 /****************************************************************************
3414 Reply to a writebraw (core+ or LANMAN1.0 protocol).
3415 ****************************************************************************/
3417 void reply_writebraw(struct smb_request *req)
3419 connection_struct *conn = req->conn;
3422 ssize_t total_written=0;
3423 size_t numtowrite=0;
3431 START_PROFILE(SMBwritebraw);
3434 * If we ever reply with an error, it must have the SMB command
3435 * type of SMBwritec, not SMBwriteBraw, as this tells the client
3438 SCVAL(req->inbuf,smb_com,SMBwritec);
3440 if (srv_is_signing_active()) {
3441 END_PROFILE(SMBwritebraw);
3442 exit_server_cleanly("reply_writebraw: SMB signing is active - "
3443 "raw reads/writes are disallowed.");
3446 if (req->wct < 12) {
3447 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3448 error_to_writebrawerr(req);
3449 END_PROFILE(SMBwritebraw);
3453 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
3454 if (!check_fsp(conn, req, fsp)) {
3455 error_to_writebrawerr(req);
3456 END_PROFILE(SMBwritebraw);
3460 if (!CHECK_WRITE(fsp)) {
3461 reply_doserror(req, ERRDOS, ERRbadaccess);
3462 error_to_writebrawerr(req);
3463 END_PROFILE(SMBwritebraw);
3467 tcount = IVAL(req->inbuf,smb_vwv1);
3468 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3469 write_through = BITSETW(req->inbuf+smb_vwv7,0);
3471 /* We have to deal with slightly different formats depending
3472 on whether we are using the core+ or lanman1.0 protocol */
3474 if(Protocol <= PROTOCOL_COREPLUS) {
3475 numtowrite = SVAL(smb_buf(req->inbuf),-2);
3476 data = smb_buf(req->inbuf);
3478 numtowrite = SVAL(req->inbuf,smb_vwv10);
3479 data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11);
3482 /* Ensure we don't write bytes past the end of this packet. */
3483 if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) {
3484 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3485 error_to_writebrawerr(req);
3486 END_PROFILE(SMBwritebraw);
3490 if (is_locked(fsp,(uint32)req->smbpid,(SMB_BIG_UINT)tcount,
3491 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3492 reply_doserror(req, ERRDOS, ERRlock);
3493 error_to_writebrawerr(req);
3494 END_PROFILE(SMBwritebraw);
3499 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3502 DEBUG(3,("reply_writebraw: initial write fnum=%d start=%.0f num=%d "
3503 "wrote=%d sync=%d\n",
3504 fsp->fnum, (double)startpos, (int)numtowrite,
3505 (int)nwritten, (int)write_through));
3507 if (nwritten < (ssize_t)numtowrite) {
3508 reply_unixerror(req, ERRHRD, ERRdiskfull);
3509 error_to_writebrawerr(req);
3510 END_PROFILE(SMBwritebraw);
3514 total_written = nwritten;
3516 /* Allocate a buffer of 64k + length. */
3517 buf = TALLOC_ARRAY(NULL, char, 65540);
3519 reply_doserror(req, ERRDOS, ERRnomem);
3520 error_to_writebrawerr(req);
3521 END_PROFILE(SMBwritebraw);
3525 /* Return a SMBwritebraw message to the redirector to tell
3526 * it to send more bytes */
3528 memcpy(buf, req->inbuf, smb_size);
3529 srv_set_message(buf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
3530 SCVAL(buf,smb_com,SMBwritebraw);
3531 SSVALS(buf,smb_vwv0,0xFFFF);
3533 if (!srv_send_smb(smbd_server_fd(),
3535 IS_CONN_ENCRYPTED(conn))) {
3536 exit_server_cleanly("reply_writebraw: srv_send_smb "
3540 /* Now read the raw data into the buffer and write it */
3541 status = read_smb_length(smbd_server_fd(), buf, SMB_SECONDARY_WAIT,
3543 if (!NT_STATUS_IS_OK(status)) {
3544 exit_server_cleanly("secondary writebraw failed");
3547 /* Set up outbuf to return the correct size */
3548 reply_outbuf(req, 1, 0);
3550 if (numtowrite != 0) {
3552 if (numtowrite > 0xFFFF) {
3553 DEBUG(0,("reply_writebraw: Oversize secondary write "
3554 "raw requested (%u). Terminating\n",
3555 (unsigned int)numtowrite ));
3556 exit_server_cleanly("secondary writebraw failed");
3559 if (tcount > nwritten+numtowrite) {
3560 DEBUG(3,("reply_writebraw: Client overestimated the "
3562 (int)tcount,(int)nwritten,(int)numtowrite));
3565 status = read_data(smbd_server_fd(), buf+4, numtowrite);
3567 if (!NT_STATUS_IS_OK(status)) {
3568 DEBUG(0,("reply_writebraw: Oversize secondary write "
3569 "raw read failed (%s). Terminating\n",
3570 nt_errstr(status)));
3571 exit_server_cleanly("secondary writebraw failed");
3574 nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
3575 if (nwritten == -1) {
3577 reply_unixerror(req, ERRHRD, ERRdiskfull);
3578 error_to_writebrawerr(req);
3579 END_PROFILE(SMBwritebraw);
3583 if (nwritten < (ssize_t)numtowrite) {
3584 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3585 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3589 total_written += nwritten;
3594 SSVAL(req->outbuf,smb_vwv0,total_written);
3596 status = sync_file(conn, fsp, write_through);
3597 if (!NT_STATUS_IS_OK(status)) {
3598 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
3599 fsp->fsp_name, nt_errstr(status) ));
3600 reply_nterror(req, status);
3601 error_to_writebrawerr(req);
3602 END_PROFILE(SMBwritebraw);
3606 DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
3608 fsp->fnum, (double)startpos, (int)numtowrite,
3609 (int)total_written));
3611 /* We won't return a status if write through is not selected - this
3612 * follows what WfWg does */
3613 END_PROFILE(SMBwritebraw);
3615 if (!write_through && total_written==tcount) {
3617 #if RABBIT_PELLET_FIX
3619 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
3620 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this.
3623 if (!send_keepalive(smbd_server_fd())) {
3624 exit_server_cleanly("reply_writebraw: send of "
3625 "keepalive failed");
3628 TALLOC_FREE(req->outbuf);
3634 #define DBGC_CLASS DBGC_LOCKING
3636 /****************************************************************************
3637 Reply to a writeunlock (core+).
3638 ****************************************************************************/
3640 void reply_writeunlock(struct smb_request *req)
3642 connection_struct *conn = req->conn;
3643 ssize_t nwritten = -1;
3647 NTSTATUS status = NT_STATUS_OK;
3650 START_PROFILE(SMBwriteunlock);
3653 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3654 END_PROFILE(SMBwriteunlock);
3658 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
3660 if (!check_fsp(conn, req, fsp)) {
3661 END_PROFILE(SMBwriteunlock);
3665 if (!CHECK_WRITE(fsp)) {
3666 reply_doserror(req, ERRDOS,ERRbadaccess);
3667 END_PROFILE(SMBwriteunlock);
3671 numtowrite = SVAL(req->inbuf,smb_vwv1);
3672 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3673 data = smb_buf(req->inbuf) + 3;
3676 && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
3677 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3678 reply_doserror(req, ERRDOS, ERRlock);
3679 END_PROFILE(SMBwriteunlock);
3683 /* The special X/Open SMB protocol handling of
3684 zero length writes is *NOT* done for
3686 if(numtowrite == 0) {
3689 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3692 status = sync_file(conn, fsp, False /* write through */);
3693 if (!NT_STATUS_IS_OK(status)) {
3694 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
3695 fsp->fsp_name, nt_errstr(status) ));
3696 reply_nterror(req, status);
3697 END_PROFILE(SMBwriteunlock);
3701 if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
3702 reply_unixerror(req, ERRHRD, ERRdiskfull);
3703 END_PROFILE(SMBwriteunlock);
3708 status = do_unlock(smbd_messaging_context(),
3711 (SMB_BIG_UINT)numtowrite,
3712 (SMB_BIG_UINT)startpos,
3715 if (NT_STATUS_V(status)) {
3716 reply_nterror(req, status);
3717 END_PROFILE(SMBwriteunlock);
3722 reply_outbuf(req, 1, 0);
3724 SSVAL(req->outbuf,smb_vwv0,nwritten);
3726 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
3727 fsp->fnum, (int)numtowrite, (int)nwritten));
3729 END_PROFILE(SMBwriteunlock);
3734 #define DBGC_CLASS DBGC_ALL
3736 /****************************************************************************
3738 ****************************************************************************/
3740 void reply_write(struct smb_request *req)
3742 connection_struct *conn = req->conn;
3744 ssize_t nwritten = -1;
3750 START_PROFILE(SMBwrite);
3753 END_PROFILE(SMBwrite);
3754 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3758 /* If it's an IPC, pass off the pipe handler. */
3760 reply_pipe_write(req);
3761 END_PROFILE(SMBwrite);
3765 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
3767 if (!check_fsp(conn, req, fsp)) {
3768 END_PROFILE(SMBwrite);
3772 if (!CHECK_WRITE(fsp)) {
3773 reply_doserror(req, ERRDOS, ERRbadaccess);
3774 END_PROFILE(SMBwrite);
3778 numtowrite = SVAL(req->inbuf,smb_vwv1);
3779 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3780 data = smb_buf(req->inbuf) + 3;
3782 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
3783 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3784 reply_doserror(req, ERRDOS, ERRlock);
3785 END_PROFILE(SMBwrite);
3790 * X/Open SMB protocol says that if smb_vwv1 is
3791 * zero then the file size should be extended or
3792 * truncated to the size given in smb_vwv[2-3].
3795 if(numtowrite == 0) {
3797 * This is actually an allocate call, and set EOF. JRA.
3799 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
3801 reply_nterror(req, NT_STATUS_DISK_FULL);
3802 END_PROFILE(SMBwrite);
3805 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
3807 reply_nterror(req, NT_STATUS_DISK_FULL);
3808 END_PROFILE(SMBwrite);
3811 trigger_write_time_update_immediate(fsp);
3813 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3816 status = sync_file(conn, fsp, False);
3817 if (!NT_STATUS_IS_OK(status)) {
3818 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
3819 fsp->fsp_name, nt_errstr(status) ));
3820 reply_nterror(req, status);
3821 END_PROFILE(SMBwrite);
3825 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3826 reply_unixerror(req, ERRHRD, ERRdiskfull);
3827 END_PROFILE(SMBwrite);
3831 reply_outbuf(req, 1, 0);
3833 SSVAL(req->outbuf,smb_vwv0,nwritten);
3835 if (nwritten < (ssize_t)numtowrite) {
3836 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3837 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3840 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
3842 END_PROFILE(SMBwrite);
3846 /****************************************************************************
3847 Ensure a buffer is a valid writeX for recvfile purposes.
3848 ****************************************************************************/
3850 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
3851 (2*14) + /* word count (including bcc) */ \
3854 bool is_valid_writeX_buffer(const uint8_t *inbuf)
3857 connection_struct *conn = NULL;
3858 unsigned int doff = 0;
3859 size_t len = smb_len_large(inbuf);
3861 if (is_encrypted_packet(inbuf)) {
3862 /* Can't do this on encrypted
3867 if (CVAL(inbuf,smb_com) != SMBwriteX) {
3871 if (CVAL(inbuf,smb_vwv0) != 0xFF ||
3872 CVAL(inbuf,smb_wct) != 14) {
3873 DEBUG(10,("is_valid_writeX_buffer: chained or "
3874 "invalid word length.\n"));
3878 conn = conn_find(SVAL(inbuf, smb_tid));
3880 DEBUG(10,("is_valid_writeX_buffer: bad tid\n"));
3884 DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
3887 doff = SVAL(inbuf,smb_vwv11);
3889 numtowrite = SVAL(inbuf,smb_vwv10);
3891 if (len > doff && len - doff > 0xFFFF) {
3892 numtowrite |= (((size_t)SVAL(inbuf,smb_vwv9))<<16);
3895 if (numtowrite == 0) {
3896 DEBUG(10,("is_valid_writeX_buffer: zero write\n"));
3900 /* Ensure the sizes match up. */
3901 if (doff < STANDARD_WRITE_AND_X_HEADER_SIZE) {
3902 /* no pad byte...old smbclient :-( */
3903 DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n",
3905 (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE));
3909 if (len - doff != numtowrite) {
3910 DEBUG(10,("is_valid_writeX_buffer: doff mismatch "
3911 "len = %u, doff = %u, numtowrite = %u\n",
3914 (unsigned int)numtowrite ));
3918 DEBUG(10,("is_valid_writeX_buffer: true "
3919 "len = %u, doff = %u, numtowrite = %u\n",
3922 (unsigned int)numtowrite ));
3927 /****************************************************************************
3928 Reply to a write and X.
3929 ****************************************************************************/
3931 void reply_write_and_X(struct smb_request *req)
3933 connection_struct *conn = req->conn;
3939 unsigned int smb_doff;
3940 unsigned int smblen;
3944 START_PROFILE(SMBwriteX);
3946 if ((req->wct != 12) && (req->wct != 14)) {
3947 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3948 END_PROFILE(SMBwriteX);
3952 numtowrite = SVAL(req->inbuf,smb_vwv10);
3953 smb_doff = SVAL(req->inbuf,smb_vwv11);
3954 smblen = smb_len(req->inbuf);
3956 if (req->unread_bytes > 0xFFFF ||
3957 (smblen > smb_doff &&
3958 smblen - smb_doff > 0xFFFF)) {
3959 numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
3962 if (req->unread_bytes) {
3963 /* Can't do a recvfile write on IPC$ */
3965 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3966 END_PROFILE(SMBwriteX);
3969 if (numtowrite != req->unread_bytes) {
3970 reply_doserror(req, ERRDOS, ERRbadmem);
3971 END_PROFILE(SMBwriteX);
3975 if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
3976 smb_doff + numtowrite > smblen) {
3977 reply_doserror(req, ERRDOS, ERRbadmem);
3978 END_PROFILE(SMBwriteX);
3983 /* If it's an IPC, pass off the pipe handler. */
3985 if (req->unread_bytes) {
3986 reply_doserror(req, ERRDOS, ERRbadmem);
3987 END_PROFILE(SMBwriteX);
3990 reply_pipe_write_and_X(req);
3991 END_PROFILE(SMBwriteX);
3995 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
3996 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3997 write_through = BITSETW(req->inbuf+smb_vwv7,0);
3999 if (!check_fsp(conn, req, fsp)) {
4000 END_PROFILE(SMBwriteX);
4004 if (!CHECK_WRITE(fsp)) {
4005 reply_doserror(req, ERRDOS, ERRbadaccess);
4006 END_PROFILE(SMBwriteX);
4010 data = smb_base(req->inbuf) + smb_doff;
4012 if(req->wct == 14) {
4013 #ifdef LARGE_SMB_OFF_T
4015 * This is a large offset (64 bit) write.
4017 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32);
4019 #else /* !LARGE_SMB_OFF_T */
4022 * Ensure we haven't been sent a >32 bit offset.
4025 if(IVAL(req->inbuf,smb_vwv12) != 0) {
4026 DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
4027 "used and we don't support 64 bit offsets.\n",
4028 (unsigned int)IVAL(req->inbuf,smb_vwv12) ));
4029 reply_doserror(req, ERRDOS, ERRbadaccess);
4030 END_PROFILE(SMBwriteX);
4034 #endif /* LARGE_SMB_OFF_T */
4037 if (is_locked(fsp,(uint32)req->smbpid,
4038 (SMB_BIG_UINT)numtowrite,
4039 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
4040 reply_doserror(req, ERRDOS, ERRlock);
4041 END_PROFILE(SMBwriteX);
4045 /* X/Open SMB protocol says that, unlike SMBwrite
4046 if the length is zero then NO truncation is
4047 done, just a write of zero. To truncate a file,
4050 if(numtowrite == 0) {
4054 if ((req->unread_bytes == 0) &&
4055 schedule_aio_write_and_X(conn, req, fsp, data, startpos,
4057 END_PROFILE(SMBwriteX);
4061 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4064 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4065 reply_unixerror(req, ERRHRD, ERRdiskfull);
4066 END_PROFILE(SMBwriteX);
4070 reply_outbuf(req, 6, 0);
4071 SSVAL(req->outbuf,smb_vwv2,nwritten);
4072 SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
4074 if (nwritten < (ssize_t)numtowrite) {
4075 SCVAL(req->outbuf,smb_rcls,ERRHRD);
4076 SSVAL(req->outbuf,smb_err,ERRdiskfull);
4079 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
4080 fsp->fnum, (int)numtowrite, (int)nwritten));
4082 status = sync_file(conn, fsp, write_through);
4083 if (!NT_STATUS_IS_OK(status)) {
4084 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
4085 fsp->fsp_name, nt_errstr(status) ));
4086 reply_nterror(req, status);
4087 END_PROFILE(SMBwriteX);
4091 END_PROFILE(SMBwriteX);
4096 /****************************************************************************
4098 ****************************************************************************/
4100 void reply_lseek(struct smb_request *req)
4102 connection_struct *conn = req->conn;
4108 START_PROFILE(SMBlseek);
4111 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4112 END_PROFILE(SMBlseek);
4116 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4118 if (!check_fsp(conn, req, fsp)) {
4122 flush_write_cache(fsp, SEEK_FLUSH);
4124 mode = SVAL(req->inbuf,smb_vwv1) & 3;
4125 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
4126 startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2);
4135 res = fsp->fh->pos + startpos;
4146 if (umode == SEEK_END) {
4147 if((res = SMB_VFS_LSEEK(fsp,startpos,umode)) == -1) {
4148 if(errno == EINVAL) {
4149 SMB_OFF_T current_pos = startpos;
4150 SMB_STRUCT_STAT sbuf;
4152 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
4153 reply_unixerror(req, ERRDOS,
4155 END_PROFILE(SMBlseek);
4159 current_pos += sbuf.st_size;
4161 res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
4166 reply_unixerror(req, ERRDOS, ERRnoaccess);
4167 END_PROFILE(SMBlseek);
4174 reply_outbuf(req, 2, 0);
4175 SIVAL(req->outbuf,smb_vwv0,res);
4177 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
4178 fsp->fnum, (double)startpos, (double)res, mode));
4180 END_PROFILE(SMBlseek);
4184 /****************************************************************************
4186 ****************************************************************************/
4188 void reply_flush(struct smb_request *req)
4190 connection_struct *conn = req->conn;
4194 START_PROFILE(SMBflush);
4197 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4201 fnum = SVAL(req->inbuf,smb_vwv0);
4202 fsp = file_fsp(req, fnum);
4204 if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) {
4209 file_sync_all(conn);
4211 NTSTATUS status = sync_file(conn, fsp, True);
4212 if (!NT_STATUS_IS_OK(status)) {
4213 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
4214 fsp->fsp_name, nt_errstr(status) ));
4215 reply_nterror(req, status);
4216 END_PROFILE(SMBflush);
4221 reply_outbuf(req, 0, 0);
4223 DEBUG(3,("flush\n"));
4224 END_PROFILE(SMBflush);
4228 /****************************************************************************
4230 conn POINTER CAN BE NULL HERE !
4231 ****************************************************************************/
4233 void reply_exit(struct smb_request *req)
4235 START_PROFILE(SMBexit);
4237 file_close_pid(req->smbpid, req->vuid);
4239 reply_outbuf(req, 0, 0);
4241 DEBUG(3,("exit\n"));
4243 END_PROFILE(SMBexit);
4247 /****************************************************************************
4248 Reply to a close - has to deal with closing a directory opened by NT SMB's.
4249 ****************************************************************************/
4251 void reply_close(struct smb_request *req)
4253 connection_struct *conn = req->conn;
4254 NTSTATUS status = NT_STATUS_OK;
4255 files_struct *fsp = NULL;
4256 START_PROFILE(SMBclose);
4259 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4260 END_PROFILE(SMBclose);
4264 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4267 * We can only use check_fsp if we know it's not a directory.
4270 if(!fsp || (fsp->conn != conn) || (fsp->vuid != req->vuid)) {
4271 reply_doserror(req, ERRDOS, ERRbadfid);
4272 END_PROFILE(SMBclose);
4276 if(fsp->is_directory) {
4278 * Special case - close NT SMB directory handle.
4280 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
4281 status = close_file(req, fsp, NORMAL_CLOSE);
4285 * Close ordinary file.
4288 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
4289 fsp->fh->fd, fsp->fnum,
4290 conn->num_files_open));
4293 * Take care of any time sent in the close.
4296 t = srv_make_unix_date3(req->inbuf+smb_vwv1);
4297 set_close_write_time(fsp, convert_time_t_to_timespec(t));
4300 * close_file() returns the unix errno if an error
4301 * was detected on close - normally this is due to
4302 * a disk full error. If not then it was probably an I/O error.
4305 status = close_file(req, fsp, NORMAL_CLOSE);
4308 if (!NT_STATUS_IS_OK(status)) {
4309 reply_nterror(req, status);
4310 END_PROFILE(SMBclose);
4314 reply_outbuf(req, 0, 0);
4315 END_PROFILE(SMBclose);
4319 /****************************************************************************
4320 Reply to a writeclose (Core+ protocol).
4321 ****************************************************************************/
4323 void reply_writeclose(struct smb_request *req)
4325 connection_struct *conn = req->conn;
4327 ssize_t nwritten = -1;
4328 NTSTATUS close_status = NT_STATUS_OK;
4331 struct timespec mtime;
4334 START_PROFILE(SMBwriteclose);
4337 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4338 END_PROFILE(SMBwriteclose);
4342 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4344 if (!check_fsp(conn, req, fsp)) {
4345 END_PROFILE(SMBwriteclose);
4348 if (!CHECK_WRITE(fsp)) {
4349 reply_doserror(req, ERRDOS,ERRbadaccess);
4350 END_PROFILE(SMBwriteclose);
4354 numtowrite = SVAL(req->inbuf,smb_vwv1);
4355 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
4356 mtime = convert_time_t_to_timespec(srv_make_unix_date3(
4357 req->inbuf+smb_vwv4));
4358 data = smb_buf(req->inbuf) + 1;
4361 && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
4362 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
4363 reply_doserror(req, ERRDOS,ERRlock);
4364 END_PROFILE(SMBwriteclose);
4368 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4370 set_close_write_time(fsp, mtime);
4373 * More insanity. W2K only closes the file if writelen > 0.
4378 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
4380 close_status = close_file(req, fsp, NORMAL_CLOSE);
4383 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
4384 fsp->fnum, (int)numtowrite, (int)nwritten,
4385 conn->num_files_open));
4387 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4388 reply_doserror(req, ERRHRD, ERRdiskfull);
4389 END_PROFILE(SMBwriteclose);
4393 if(!NT_STATUS_IS_OK(close_status)) {
4394 reply_nterror(req, close_status);
4395 END_PROFILE(SMBwriteclose);
4399 reply_outbuf(req, 1, 0);
4401 SSVAL(req->outbuf,smb_vwv0,nwritten);
4402 END_PROFILE(SMBwriteclose);
4407 #define DBGC_CLASS DBGC_LOCKING
4409 /****************************************************************************
4411 ****************************************************************************/
4413 void reply_lock(struct smb_request *req)
4415 connection_struct *conn = req->conn;
4416 SMB_BIG_UINT count,offset;
4419 struct byte_range_lock *br_lck = NULL;
4421 START_PROFILE(SMBlock);
4424 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4425 END_PROFILE(SMBlock);
4429 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4431 if (!check_fsp(conn, req, fsp)) {
4432 END_PROFILE(SMBlock);
4436 release_level_2_oplocks_on_change(fsp);
4438 count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
4439 offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
4441 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4442 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
4444 br_lck = do_lock(smbd_messaging_context(),
4451 False, /* Non-blocking lock. */
4455 TALLOC_FREE(br_lck);
4457 if (NT_STATUS_V(status)) {
4458 reply_nterror(req, status);
4459 END_PROFILE(SMBlock);
4463 reply_outbuf(req, 0, 0);
4465 END_PROFILE(SMBlock);
4469 /****************************************************************************
4471 ****************************************************************************/
4473 void reply_unlock(struct smb_request *req)
4475 connection_struct *conn = req->conn;
4476 SMB_BIG_UINT count,offset;
4480 START_PROFILE(SMBunlock);
4483 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4484 END_PROFILE(SMBunlock);
4488 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4490 if (!check_fsp(conn, req, fsp)) {
4491 END_PROFILE(SMBunlock);
4495 count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
4496 offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
4498 status = do_unlock(smbd_messaging_context(),
4505 if (NT_STATUS_V(status)) {
4506 reply_nterror(req, status);
4507 END_PROFILE(SMBunlock);
4511 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4512 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
4514 reply_outbuf(req, 0, 0);
4516 END_PROFILE(SMBunlock);
4521 #define DBGC_CLASS DBGC_ALL
4523 /****************************************************************************
4525 conn POINTER CAN BE NULL HERE !
4526 ****************************************************************************/
4528 void reply_tdis(struct smb_request *req)
4530 connection_struct *conn = req->conn;
4531 START_PROFILE(SMBtdis);
4534 DEBUG(4,("Invalid connection in tdis\n"));
4535 reply_doserror(req, ERRSRV, ERRinvnid);
4536 END_PROFILE(SMBtdis);
4542 close_cnum(conn,req->vuid);
4545 reply_outbuf(req, 0, 0);
4546 END_PROFILE(SMBtdis);
4550 /****************************************************************************
4552 conn POINTER CAN BE NULL HERE !
4553 ****************************************************************************/
4555 void reply_echo(struct smb_request *req)
4557 connection_struct *conn = req->conn;
4560 unsigned int data_len = smb_buflen(req->inbuf);
4562 START_PROFILE(SMBecho);
4565 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4566 END_PROFILE(SMBecho);
4570 if (data_len > BUFFER_SIZE) {
4571 DEBUG(0,("reply_echo: data_len too large.\n"));
4572 reply_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
4573 END_PROFILE(SMBecho);
4577 smb_reverb = SVAL(req->inbuf,smb_vwv0);
4579 reply_outbuf(req, 1, data_len);
4581 /* copy any incoming data back out */
4583 memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len);
4586 if (smb_reverb > 100) {
4587 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
4591 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
4592 SSVAL(req->outbuf,smb_vwv0,seq_num);
4594 show_msg((char *)req->outbuf);
4595 if (!srv_send_smb(smbd_server_fd(),
4596 (char *)req->outbuf,
4597 IS_CONN_ENCRYPTED(conn)||req->encrypted))
4598 exit_server_cleanly("reply_echo: srv_send_smb failed.");
4601 DEBUG(3,("echo %d times\n", smb_reverb));
4603 TALLOC_FREE(req->outbuf);
4605 END_PROFILE(SMBecho);
4609 /****************************************************************************
4610 Reply to a printopen.
4611 ****************************************************************************/
4613 void reply_printopen(struct smb_request *req)
4615 connection_struct *conn = req->conn;
4619 START_PROFILE(SMBsplopen);
4622 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4623 END_PROFILE(SMBsplopen);
4627 if (!CAN_PRINT(conn)) {
4628 reply_doserror(req, ERRDOS, ERRnoaccess);
4629 END_PROFILE(SMBsplopen);
4633 /* Open for exclusive use, write only. */
4634 status = print_fsp_open(req, conn, NULL, req->vuid, &fsp);
4636 if (!NT_STATUS_IS_OK(status)) {
4637 reply_nterror(req, status);
4638 END_PROFILE(SMBsplopen);
4642 reply_outbuf(req, 1, 0);
4643 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
4645 DEBUG(3,("openprint fd=%d fnum=%d\n",
4646 fsp->fh->fd, fsp->fnum));
4648 END_PROFILE(SMBsplopen);
4652 /****************************************************************************
4653 Reply to a printclose.
4654 ****************************************************************************/
4656 void reply_printclose(struct smb_request *req)
4658 connection_struct *conn = req->conn;
4662 START_PROFILE(SMBsplclose);
4665 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4666 END_PROFILE(SMBsplclose);
4670 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4672 if (!check_fsp(conn, req, fsp)) {
4673 END_PROFILE(SMBsplclose);
4677 if (!CAN_PRINT(conn)) {
4678 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
4679 END_PROFILE(SMBsplclose);
4683 DEBUG(3,("printclose fd=%d fnum=%d\n",
4684 fsp->fh->fd,fsp->fnum));
4686 status = close_file(req, fsp, NORMAL_CLOSE);
4688 if(!NT_STATUS_IS_OK(status)) {
4689 reply_nterror(req, status);
4690 END_PROFILE(SMBsplclose);
4694 reply_outbuf(req, 0, 0);
4696 END_PROFILE(SMBsplclose);
4700 /****************************************************************************
4701 Reply to a printqueue.
4702 ****************************************************************************/
4704 void reply_printqueue(struct smb_request *req)
4706 connection_struct *conn = req->conn;
4710 START_PROFILE(SMBsplretq);
4713 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4714 END_PROFILE(SMBsplretq);
4718 max_count = SVAL(req->inbuf,smb_vwv0);
4719 start_index = SVAL(req->inbuf,smb_vwv1);
4721 /* we used to allow the client to get the cnum wrong, but that
4722 is really quite gross and only worked when there was only
4723 one printer - I think we should now only accept it if they
4724 get it right (tridge) */
4725 if (!CAN_PRINT(conn)) {
4726 reply_doserror(req, ERRDOS, ERRnoaccess);
4727 END_PROFILE(SMBsplretq);
4731 reply_outbuf(req, 2, 3);
4732 SSVAL(req->outbuf,smb_vwv0,0);
4733 SSVAL(req->outbuf,smb_vwv1,0);
4734 SCVAL(smb_buf(req->outbuf),0,1);
4735 SSVAL(smb_buf(req->outbuf),1,0);
4737 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
4738 start_index, max_count));
4741 print_queue_struct *queue = NULL;
4742 print_status_struct status;
4743 int count = print_queue_status(SNUM(conn), &queue, &status);
4744 int num_to_get = ABS(max_count);
4745 int first = (max_count>0?start_index:start_index+max_count+1);
4751 num_to_get = MIN(num_to_get,count-first);
4754 for (i=first;i<first+num_to_get;i++) {
4758 srv_put_dos_date2(p,0,queue[i].time);
4759 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
4760 SSVAL(p,5, queue[i].job);
4761 SIVAL(p,7,queue[i].size);
4763 srvstr_push(blob, req->flags2, p+12,
4764 queue[i].fs_user, 16, STR_ASCII);
4766 if (message_push_blob(
4769 blob, sizeof(blob))) == -1) {
4770 reply_nterror(req, NT_STATUS_NO_MEMORY);
4771 END_PROFILE(SMBsplretq);
4777 SSVAL(req->outbuf,smb_vwv0,count);
4778 SSVAL(req->outbuf,smb_vwv1,
4779 (max_count>0?first+count:first-1));
4780 SCVAL(smb_buf(req->outbuf),0,1);
4781 SSVAL(smb_buf(req->outbuf),1,28*count);
4786 DEBUG(3,("%d entries returned in queue\n",count));
4789 END_PROFILE(SMBsplretq);
4793 /****************************************************************************
4794 Reply to a printwrite.
4795 ****************************************************************************/
4797 void reply_printwrite(struct smb_request *req)
4799 connection_struct *conn = req->conn;
4804 START_PROFILE(SMBsplwr);
4807 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4808 END_PROFILE(SMBsplwr);
4812 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
4814 if (!check_fsp(conn, req, fsp)) {
4815 END_PROFILE(SMBsplwr);
4819 if (!CAN_PRINT(conn)) {
4820 reply_doserror(req, ERRDOS, ERRnoaccess);
4821 END_PROFILE(SMBsplwr);
4825 if (!CHECK_WRITE(fsp)) {
4826 reply_doserror(req, ERRDOS, ERRbadaccess);
4827 END_PROFILE(SMBsplwr);
4831 numtowrite = SVAL(smb_buf(req->inbuf),1);
4833 if (smb_buflen(req->inbuf) < numtowrite + 3) {
4834 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4835 END_PROFILE(SMBsplwr);
4839 data = smb_buf(req->inbuf) + 3;
4841 if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
4842 reply_unixerror(req, ERRHRD, ERRdiskfull);
4843 END_PROFILE(SMBsplwr);
4847 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
4849 END_PROFILE(SMBsplwr);
4853 /****************************************************************************
4855 ****************************************************************************/
4857 void reply_mkdir(struct smb_request *req)
4859 connection_struct *conn = req->conn;
4860 char *directory = NULL;
4862 SMB_STRUCT_STAT sbuf;
4863 TALLOC_CTX *ctx = talloc_tos();
4865 START_PROFILE(SMBmkdir);
4867 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
4868 smb_buf(req->inbuf) + 1, 0,
4869 STR_TERMINATE, &status);
4870 if (!NT_STATUS_IS_OK(status)) {
4871 reply_nterror(req, status);
4872 END_PROFILE(SMBmkdir);
4876 status = resolve_dfspath(ctx, conn,
4877 req->flags2 & FLAGS2_DFS_PATHNAMES,
4880 if (!NT_STATUS_IS_OK(status)) {
4881 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4882 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
4883 ERRSRV, ERRbadpath);
4884 END_PROFILE(SMBmkdir);
4887 reply_nterror(req, status);
4888 END_PROFILE(SMBmkdir);
4892 status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
4893 if (!NT_STATUS_IS_OK(status)) {
4894 reply_nterror(req, status);
4895 END_PROFILE(SMBmkdir);
4899 status = check_name(conn, directory);
4900 if (!NT_STATUS_IS_OK(status)) {
4901 reply_nterror(req, status);
4902 END_PROFILE(SMBmkdir);
4906 status = create_directory(conn, req, directory);
4908 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
4910 if (!NT_STATUS_IS_OK(status)) {
4912 if (!use_nt_status()
4913 && NT_STATUS_EQUAL(status,
4914 NT_STATUS_OBJECT_NAME_COLLISION)) {
4916 * Yes, in the DOS error code case we get a
4917 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
4918 * samba4 torture test.
4920 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
4923 reply_nterror(req, status);
4924 END_PROFILE(SMBmkdir);
4928 reply_outbuf(req, 0, 0);
4930 DEBUG( 3, ( "mkdir %s\n", directory ) );
4932 END_PROFILE(SMBmkdir);
4936 /****************************************************************************
4937 Static function used by reply_rmdir to delete an entire directory
4938 tree recursively. Return True on ok, False on fail.
4939 ****************************************************************************/
4941 static bool recursive_rmdir(TALLOC_CTX *ctx,
4942 connection_struct *conn,
4945 const char *dname = NULL;
4948 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, directory,
4954 while((dname = ReadDirName(dir_hnd, &offset))) {
4955 char *fullname = NULL;
4958 if (ISDOT(dname) || ISDOTDOT(dname)) {
4962 if (!is_visible_file(conn, directory, dname, &st, False)) {
4966 /* Construct the full name. */
4967 fullname = talloc_asprintf(ctx,
4977 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
4982 if(st.st_mode & S_IFDIR) {
4983 if(!recursive_rmdir(ctx, conn, fullname)) {
4987 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
4991 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
4995 TALLOC_FREE(fullname);
4997 TALLOC_FREE(dir_hnd);
5001 /****************************************************************************
5002 The internals of the rmdir code - called elsewhere.
5003 ****************************************************************************/
5005 NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
5006 connection_struct *conn,
5007 const char *directory)
5012 /* Might be a symlink. */
5013 if(SMB_VFS_LSTAT(conn, directory, &st) != 0) {
5014 return map_nt_error_from_unix(errno);
5017 if (S_ISLNK(st.st_mode)) {
5018 /* Is what it points to a directory ? */
5019 if(SMB_VFS_STAT(conn, directory, &st) != 0) {
5020 return map_nt_error_from_unix(errno);
5022 if (!(S_ISDIR(st.st_mode))) {
5023 return NT_STATUS_NOT_A_DIRECTORY;
5025 ret = SMB_VFS_UNLINK(conn,directory);
5027 ret = SMB_VFS_RMDIR(conn,directory);
5030 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5031 FILE_NOTIFY_CHANGE_DIR_NAME,
5033 return NT_STATUS_OK;
5036 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
5038 * Check to see if the only thing in this directory are
5039 * vetoed files/directories. If so then delete them and
5040 * retry. If we fail to delete any of them (and we *don't*
5041 * do a recursive delete) then fail the rmdir.
5045 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
5046 directory, NULL, 0);
5048 if(dir_hnd == NULL) {
5053 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5054 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
5056 if (!is_visible_file(conn, directory, dname, &st, False))
5058 if(!IS_VETO_PATH(conn, dname)) {
5059 TALLOC_FREE(dir_hnd);
5065 /* We only have veto files/directories. Recursive delete. */
5067 RewindDir(dir_hnd,&dirpos);
5068 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5069 char *fullname = NULL;
5071 if (ISDOT(dname) || ISDOTDOT(dname)) {
5074 if (!is_visible_file(conn, directory, dname, &st, False)) {
5078 fullname = talloc_asprintf(ctx,
5088 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
5091 if(st.st_mode & S_IFDIR) {
5092 if(lp_recursive_veto_delete(SNUM(conn))) {
5093 if(!recursive_rmdir(ctx, conn, fullname))
5096 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
5099 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
5102 TALLOC_FREE(fullname);
5104 TALLOC_FREE(dir_hnd);
5105 /* Retry the rmdir */
5106 ret = SMB_VFS_RMDIR(conn,directory);
5112 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
5113 "%s\n", directory,strerror(errno)));
5114 return map_nt_error_from_unix(errno);
5117 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5118 FILE_NOTIFY_CHANGE_DIR_NAME,
5121 return NT_STATUS_OK;
5124 /****************************************************************************
5126 ****************************************************************************/
5128 void reply_rmdir(struct smb_request *req)
5130 connection_struct *conn = req->conn;
5131 char *directory = NULL;
5132 SMB_STRUCT_STAT sbuf;
5134 TALLOC_CTX *ctx = talloc_tos();
5136 START_PROFILE(SMBrmdir);
5138 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
5139 smb_buf(req->inbuf) + 1, 0,
5140 STR_TERMINATE, &status);
5141 if (!NT_STATUS_IS_OK(status)) {
5142 reply_nterror(req, status);
5143 END_PROFILE(SMBrmdir);
5147 status = resolve_dfspath(ctx, conn,
5148 req->flags2 & FLAGS2_DFS_PATHNAMES,
5151 if (!NT_STATUS_IS_OK(status)) {
5152 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5153 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5154 ERRSRV, ERRbadpath);
5155 END_PROFILE(SMBrmdir);
5158 reply_nterror(req, status);
5159 END_PROFILE(SMBrmdir);
5163 status = unix_convert(ctx, conn, directory, False, &directory,
5165 if (!NT_STATUS_IS_OK(status)) {
5166 reply_nterror(req, status);
5167 END_PROFILE(SMBrmdir);
5171 status = check_name(conn, directory);
5172 if (!NT_STATUS_IS_OK(status)) {
5173 reply_nterror(req, status);
5174 END_PROFILE(SMBrmdir);
5178 dptr_closepath(directory, req->smbpid);
5179 status = rmdir_internals(ctx, conn, directory);
5180 if (!NT_STATUS_IS_OK(status)) {
5181 reply_nterror(req, status);
5182 END_PROFILE(SMBrmdir);
5186 reply_outbuf(req, 0, 0);
5188 DEBUG( 3, ( "rmdir %s\n", directory ) );
5190 END_PROFILE(SMBrmdir);
5194 /*******************************************************************
5195 Resolve wildcards in a filename rename.
5196 ********************************************************************/
5198 static bool resolve_wildcards(TALLOC_CTX *ctx,
5203 char *name2_copy = NULL;
5208 char *p,*p2, *pname1, *pname2;
5210 name2_copy = talloc_strdup(ctx, name2);
5215 pname1 = strrchr_m(name1,'/');
5216 pname2 = strrchr_m(name2_copy,'/');
5218 if (!pname1 || !pname2) {
5222 /* Truncate the copy of name2 at the last '/' */
5225 /* Now go past the '/' */
5229 root1 = talloc_strdup(ctx, pname1);
5230 root2 = talloc_strdup(ctx, pname2);
5232 if (!root1 || !root2) {
5236 p = strrchr_m(root1,'.');
5239 ext1 = talloc_strdup(ctx, p+1);
5241 ext1 = talloc_strdup(ctx, "");
5243 p = strrchr_m(root2,'.');
5246 ext2 = talloc_strdup(ctx, p+1);
5248 ext2 = talloc_strdup(ctx, "");
5251 if (!ext1 || !ext2) {
5259 /* Hmmm. Should this be mb-aware ? */
5262 } else if (*p2 == '*') {
5264 root2 = talloc_asprintf(ctx, "%s%s",
5283 /* Hmmm. Should this be mb-aware ? */
5286 } else if (*p2 == '*') {
5288 ext2 = talloc_asprintf(ctx, "%s%s",
5304 *pp_newname = talloc_asprintf(ctx, "%s/%s.%s",
5309 *pp_newname = talloc_asprintf(ctx, "%s/%s",
5321 /****************************************************************************
5322 Ensure open files have their names updated. Updated to notify other smbd's
5324 ****************************************************************************/
5326 static void rename_open_files(connection_struct *conn,
5327 struct share_mode_lock *lck,
5328 const char *newname)
5331 bool did_rename = False;
5333 for(fsp = file_find_di_first(lck->id); fsp;
5334 fsp = file_find_di_next(fsp)) {
5335 /* fsp_name is a relative path under the fsp. To change this for other
5336 sharepaths we need to manipulate relative paths. */
5337 /* TODO - create the absolute path and manipulate the newname
5338 relative to the sharepath. */
5339 if (!strequal(fsp->conn->connectpath, conn->connectpath)) {
5342 DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
5343 fsp->fnum, file_id_string_tos(&fsp->file_id),
5344 fsp->fsp_name, newname ));
5345 string_set(&fsp->fsp_name, newname);
5350 DEBUG(10,("rename_open_files: no open files on file_id %s for %s\n",
5351 file_id_string_tos(&lck->id), newname ));
5354 /* Send messages to all smbd's (not ourself) that the name has changed. */
5355 rename_share_filename(smbd_messaging_context(), lck, conn->connectpath,
5359 /****************************************************************************
5360 We need to check if the source path is a parent directory of the destination
5361 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
5362 refuse the rename with a sharing violation. Under UNIX the above call can
5363 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
5364 probably need to check that the client is a Windows one before disallowing
5365 this as a UNIX client (one with UNIX extensions) can know the source is a
5366 symlink and make this decision intelligently. Found by an excellent bug
5367 report from <AndyLiebman@aol.com>.
5368 ****************************************************************************/
5370 static bool rename_path_prefix_equal(const char *src, const char *dest)
5372 const char *psrc = src;
5373 const char *pdst = dest;
5376 if (psrc[0] == '.' && psrc[1] == '/') {
5379 if (pdst[0] == '.' && pdst[1] == '/') {
5382 if ((slen = strlen(psrc)) > strlen(pdst)) {
5385 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
5389 * Do the notify calls from a rename
5392 static void notify_rename(connection_struct *conn, bool is_dir,
5393 const char *oldpath, const char *newpath)
5395 char *olddir, *newdir;
5396 const char *oldname, *newname;
5399 mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
5400 : FILE_NOTIFY_CHANGE_FILE_NAME;
5402 if (!parent_dirname_talloc(NULL, oldpath, &olddir, &oldname)
5403 || !parent_dirname_talloc(NULL, newpath, &newdir, &newname)) {
5404 TALLOC_FREE(olddir);
5408 if (strcmp(olddir, newdir) == 0) {
5409 notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, oldpath);
5410 notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, newpath);
5413 notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, oldpath);
5414 notify_fname(conn, NOTIFY_ACTION_ADDED, mask, newpath);
5416 TALLOC_FREE(olddir);
5417 TALLOC_FREE(newdir);
5419 /* this is a strange one. w2k3 gives an additional event for
5420 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
5421 files, but not directories */
5423 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
5424 FILE_NOTIFY_CHANGE_ATTRIBUTES
5425 |FILE_NOTIFY_CHANGE_CREATION,
5430 /****************************************************************************
5431 Rename an open file - given an fsp.
5432 ****************************************************************************/
5434 NTSTATUS rename_internals_fsp(connection_struct *conn,
5437 const char *newname_last_component,
5439 bool replace_if_exists)
5441 TALLOC_CTX *ctx = talloc_tos();
5442 SMB_STRUCT_STAT sbuf, sbuf1;
5443 NTSTATUS status = NT_STATUS_OK;
5444 struct share_mode_lock *lck = NULL;
5449 status = check_name(conn, newname);
5450 if (!NT_STATUS_IS_OK(status)) {
5454 /* Ensure newname contains a '/' */
5455 if(strrchr_m(newname,'/') == 0) {
5456 newname = talloc_asprintf(ctx,
5460 return NT_STATUS_NO_MEMORY;
5465 * Check for special case with case preserving and not
5466 * case sensitive. If the old last component differs from the original
5467 * last component only by case, then we should allow
5468 * the rename (user is trying to change the case of the
5472 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
5473 strequal(newname, fsp->fsp_name)) {
5475 char *newname_modified_last_component = NULL;
5478 * Get the last component of the modified name.
5479 * Note that we guarantee that newname contains a '/'
5482 p = strrchr_m(newname,'/');
5483 newname_modified_last_component = talloc_strdup(ctx,
5485 if (!newname_modified_last_component) {
5486 return NT_STATUS_NO_MEMORY;
5489 if(strcsequal(newname_modified_last_component,
5490 newname_last_component) == False) {
5492 * Replace the modified last component with
5495 *p = '\0'; /* Truncate at the '/' */
5496 newname = talloc_asprintf(ctx,
5499 newname_last_component);
5504 * If the src and dest names are identical - including case,
5505 * don't do the rename, just return success.
5508 if (strcsequal(fsp->fsp_name, newname)) {
5509 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
5511 return NT_STATUS_OK;
5515 * Have vfs_object_exist also fill sbuf1
5517 dst_exists = vfs_object_exist(conn, newname, &sbuf1);
5519 if(!replace_if_exists && dst_exists) {
5520 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
5521 fsp->fsp_name,newname));
5522 return NT_STATUS_OBJECT_NAME_COLLISION;
5526 struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
5527 files_struct *dst_fsp = file_find_di_first(fileid);
5529 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
5530 return NT_STATUS_ACCESS_DENIED;
5534 /* Ensure we have a valid stat struct for the source. */
5535 if (fsp->fh->fd != -1) {
5536 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
5537 return map_nt_error_from_unix(errno);
5540 if (SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) == -1) {
5541 return map_nt_error_from_unix(errno);
5545 status = can_rename(conn, fsp, attrs, &sbuf);
5547 if (!NT_STATUS_IS_OK(status)) {
5548 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5549 nt_errstr(status), fsp->fsp_name,newname));
5550 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION))
5551 status = NT_STATUS_ACCESS_DENIED;
5555 if (rename_path_prefix_equal(fsp->fsp_name, newname)) {
5556 return NT_STATUS_ACCESS_DENIED;
5559 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
5563 * We have the file open ourselves, so not being able to get the
5564 * corresponding share mode lock is a fatal error.
5567 SMB_ASSERT(lck != NULL);
5569 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
5570 uint32 create_options = fsp->fh->private_options;
5572 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
5573 fsp->fsp_name,newname));
5575 notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname);
5577 rename_open_files(conn, lck, newname);
5580 * A rename acts as a new file create w.r.t. allowing an initial delete
5581 * on close, probably because in Windows there is a new handle to the
5582 * new file. If initial delete on close was requested but not
5583 * originally set, we need to set it here. This is probably not 100% correct,
5584 * but will work for the CIFSFS client which in non-posix mode
5585 * depends on these semantics. JRA.
5588 set_allow_initial_delete_on_close(lck, fsp, True);
5590 if (create_options & FILE_DELETE_ON_CLOSE) {
5591 status = can_set_delete_on_close(fsp, True, 0);
5593 if (NT_STATUS_IS_OK(status)) {
5594 /* Note that here we set the *inital* delete on close flag,
5595 * not the regular one. The magic gets handled in close. */
5596 fsp->initial_delete_on_close = True;
5600 return NT_STATUS_OK;
5605 if (errno == ENOTDIR || errno == EISDIR) {
5606 status = NT_STATUS_OBJECT_NAME_COLLISION;
5608 status = map_nt_error_from_unix(errno);
5611 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5612 nt_errstr(status), fsp->fsp_name,newname));
5617 /****************************************************************************
5618 The guts of the rename command, split out so it may be called by the NT SMB
5620 ****************************************************************************/
5622 NTSTATUS rename_internals(TALLOC_CTX *ctx,
5623 connection_struct *conn,
5624 struct smb_request *req,
5625 const char *name_in,
5626 const char *newname_in,
5628 bool replace_if_exists,
5631 uint32_t access_mask)
5633 char *directory = NULL;
5635 char *last_component_src = NULL;
5636 char *last_component_dest = NULL;
5638 char *newname = NULL;
5641 NTSTATUS status = NT_STATUS_OK;
5642 SMB_STRUCT_STAT sbuf1, sbuf2;
5643 struct smb_Dir *dir_hnd = NULL;
5650 status = unix_convert(ctx, conn, name_in, src_has_wild, &name,
5651 &last_component_src, &sbuf1);
5652 if (!NT_STATUS_IS_OK(status)) {
5656 status = unix_convert(ctx, conn, newname_in, dest_has_wild, &newname,
5657 &last_component_dest, &sbuf2);
5658 if (!NT_STATUS_IS_OK(status)) {
5663 * Split the old name into directory and last component
5664 * strings. Note that unix_convert may have stripped off a
5665 * leading ./ from both name and newname if the rename is
5666 * at the root of the share. We need to make sure either both
5667 * name and newname contain a / character or neither of them do
5668 * as this is checked in resolve_wildcards().
5671 p = strrchr_m(name,'/');
5673 directory = talloc_strdup(ctx, ".");
5675 return NT_STATUS_NO_MEMORY;
5680 directory = talloc_strdup(ctx, name);
5682 return NT_STATUS_NO_MEMORY;
5685 *p = '/'; /* Replace needed for exceptional test below. */
5689 * We should only check the mangled cache
5690 * here if unix_convert failed. This means
5691 * that the path in 'mask' doesn't exist
5692 * on the file system and so we need to look
5693 * for a possible mangle. This patch from
5694 * Tine Smukavec <valentin.smukavec@hermes.si>.
5697 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
5698 char *new_mask = NULL;
5699 mangle_lookup_name_from_8_3(ctx,
5708 if (!src_has_wild) {
5712 * No wildcards - just process the one file.
5714 bool is_short_name = mangle_is_8_3(name, True, conn->params);
5716 /* Add a terminating '/' to the directory name. */
5717 directory = talloc_asprintf_append(directory,
5721 return NT_STATUS_NO_MEMORY;
5724 /* Ensure newname contains a '/' also */
5725 if(strrchr_m(newname,'/') == 0) {
5726 newname = talloc_asprintf(ctx,
5730 return NT_STATUS_NO_MEMORY;
5734 DEBUG(3, ("rename_internals: case_sensitive = %d, "
5735 "case_preserve = %d, short case preserve = %d, "
5736 "directory = %s, newname = %s, "
5737 "last_component_dest = %s, is_8_3 = %d\n",
5738 conn->case_sensitive, conn->case_preserve,
5739 conn->short_case_preserve, directory,
5740 newname, last_component_dest, is_short_name));
5742 /* The dest name still may have wildcards. */
5743 if (dest_has_wild) {
5744 char *mod_newname = NULL;
5745 if (!resolve_wildcards(ctx,
5746 directory,newname,&mod_newname)) {
5747 DEBUG(6, ("rename_internals: resolve_wildcards "
5751 return NT_STATUS_NO_MEMORY;
5753 newname = mod_newname;
5757 SMB_VFS_STAT(conn, directory, &sbuf1);
5759 status = S_ISDIR(sbuf1.st_mode) ?
5760 open_directory(conn, req, directory, &sbuf1,
5762 FILE_SHARE_READ|FILE_SHARE_WRITE,
5763 FILE_OPEN, 0, 0, NULL,
5765 : open_file_ntcreate(conn, req, directory, &sbuf1,
5767 FILE_SHARE_READ|FILE_SHARE_WRITE,
5768 FILE_OPEN, 0, 0, 0, NULL,
5771 if (!NT_STATUS_IS_OK(status)) {
5772 DEBUG(3, ("Could not open rename source %s: %s\n",
5773 directory, nt_errstr(status)));
5777 status = rename_internals_fsp(conn, fsp, newname,
5778 last_component_dest,
5779 attrs, replace_if_exists);
5781 close_file(req, fsp, NORMAL_CLOSE);
5783 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
5784 nt_errstr(status), directory,newname));
5790 * Wildcards - process each file that matches.
5792 if (strequal(mask,"????????.???")) {
5797 status = check_name(conn, directory);
5798 if (!NT_STATUS_IS_OK(status)) {
5802 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, attrs);
5803 if (dir_hnd == NULL) {
5804 return map_nt_error_from_unix(errno);
5807 status = NT_STATUS_NO_SUCH_FILE;
5809 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5810 * - gentest fix. JRA
5813 while ((dname = ReadDirName(dir_hnd, &offset))) {
5814 files_struct *fsp = NULL;
5816 char *destname = NULL;
5817 bool sysdir_entry = False;
5819 /* Quick check for "." and ".." */
5820 if (ISDOT(dname) || ISDOTDOT(dname)) {
5822 sysdir_entry = True;
5828 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
5832 if(!mask_match(dname, mask, conn->case_sensitive)) {
5837 status = NT_STATUS_OBJECT_NAME_INVALID;
5841 fname = talloc_asprintf(ctx,
5846 return NT_STATUS_NO_MEMORY;
5849 if (!resolve_wildcards(ctx,
5850 fname,newname,&destname)) {
5851 DEBUG(6, ("resolve_wildcards %s %s failed\n",
5857 return NT_STATUS_NO_MEMORY;
5861 SMB_VFS_STAT(conn, fname, &sbuf1);
5863 status = S_ISDIR(sbuf1.st_mode) ?
5864 open_directory(conn, req, fname, &sbuf1,
5866 FILE_SHARE_READ|FILE_SHARE_WRITE,
5867 FILE_OPEN, 0, 0, NULL,
5869 : open_file_ntcreate(conn, req, fname, &sbuf1,
5871 FILE_SHARE_READ|FILE_SHARE_WRITE,
5872 FILE_OPEN, 0, 0, 0, NULL,
5875 if (!NT_STATUS_IS_OK(status)) {
5876 DEBUG(3,("rename_internals: open_file_ntcreate "
5877 "returned %s rename %s -> %s\n",
5878 nt_errstr(status), directory, newname));
5882 status = rename_internals_fsp(conn, fsp, destname, dname,
5883 attrs, replace_if_exists);
5885 close_file(req, fsp, NORMAL_CLOSE);
5887 if (!NT_STATUS_IS_OK(status)) {
5888 DEBUG(3, ("rename_internals_fsp returned %s for "
5889 "rename %s -> %s\n", nt_errstr(status),
5890 directory, newname));
5896 DEBUG(3,("rename_internals: doing rename on %s -> "
5897 "%s\n",fname,destname));
5900 TALLOC_FREE(destname);
5902 TALLOC_FREE(dir_hnd);
5904 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
5905 status = map_nt_error_from_unix(errno);
5911 /****************************************************************************
5913 ****************************************************************************/
5915 void reply_mv(struct smb_request *req)
5917 connection_struct *conn = req->conn;
5919 char *newname = NULL;
5923 bool src_has_wcard = False;
5924 bool dest_has_wcard = False;
5925 TALLOC_CTX *ctx = talloc_tos();
5927 START_PROFILE(SMBmv);
5930 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5935 attrs = SVAL(req->inbuf,smb_vwv0);
5937 p = smb_buf(req->inbuf) + 1;
5938 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
5939 0, STR_TERMINATE, &status,
5941 if (!NT_STATUS_IS_OK(status)) {
5942 reply_nterror(req, status);
5947 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
5948 0, STR_TERMINATE, &status,
5950 if (!NT_STATUS_IS_OK(status)) {
5951 reply_nterror(req, status);
5956 status = resolve_dfspath_wcard(ctx, conn,
5957 req->flags2 & FLAGS2_DFS_PATHNAMES,
5961 if (!NT_STATUS_IS_OK(status)) {
5962 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5963 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5964 ERRSRV, ERRbadpath);
5968 reply_nterror(req, status);
5973 status = resolve_dfspath_wcard(ctx, conn,
5974 req->flags2 & FLAGS2_DFS_PATHNAMES,
5978 if (!NT_STATUS_IS_OK(status)) {
5979 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5980 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5981 ERRSRV, ERRbadpath);
5985 reply_nterror(req, status);
5990 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
5992 status = rename_internals(ctx, conn, req, name, newname, attrs, False,
5993 src_has_wcard, dest_has_wcard, DELETE_ACCESS);
5994 if (!NT_STATUS_IS_OK(status)) {
5995 if (open_was_deferred(req->mid)) {
5996 /* We have re-scheduled this call. */
6000 reply_nterror(req, status);
6005 reply_outbuf(req, 0, 0);
6011 /*******************************************************************
6012 Copy a file as part of a reply_copy.
6013 ******************************************************************/
6016 * TODO: check error codes on all callers
6019 NTSTATUS copy_file(TALLOC_CTX *ctx,
6020 connection_struct *conn,
6025 bool target_is_directory)
6027 SMB_STRUCT_STAT src_sbuf, sbuf2;
6029 files_struct *fsp1,*fsp2;
6032 uint32 new_create_disposition;
6035 dest = talloc_strdup(ctx, dest1);
6037 return NT_STATUS_NO_MEMORY;
6039 if (target_is_directory) {
6040 const char *p = strrchr_m(src,'/');
6046 dest = talloc_asprintf_append(dest,
6050 return NT_STATUS_NO_MEMORY;
6054 if (!vfs_file_exist(conn,src,&src_sbuf)) {
6056 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6059 if (!target_is_directory && count) {
6060 new_create_disposition = FILE_OPEN;
6062 if (!map_open_params_to_ntcreate(dest1,0,ofun,
6063 NULL, NULL, &new_create_disposition, NULL)) {
6065 return NT_STATUS_INVALID_PARAMETER;
6069 status = open_file_ntcreate(conn, NULL, src, &src_sbuf,
6071 FILE_SHARE_READ|FILE_SHARE_WRITE,
6074 FILE_ATTRIBUTE_NORMAL,
6078 if (!NT_STATUS_IS_OK(status)) {
6083 dosattrs = dos_mode(conn, src, &src_sbuf);
6084 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) {
6085 ZERO_STRUCTP(&sbuf2);
6088 status = open_file_ntcreate(conn, NULL, dest, &sbuf2,
6090 FILE_SHARE_READ|FILE_SHARE_WRITE,
6091 new_create_disposition,
6099 if (!NT_STATUS_IS_OK(status)) {
6100 close_file(NULL, fsp1, ERROR_CLOSE);
6104 if ((ofun&3) == 1) {
6105 if(SMB_VFS_LSEEK(fsp2,0,SEEK_END) == -1) {
6106 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
6108 * Stop the copy from occurring.
6111 src_sbuf.st_size = 0;
6115 if (src_sbuf.st_size) {
6116 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
6119 close_file(NULL, fsp1, NORMAL_CLOSE);
6121 /* Ensure the modtime is set correctly on the destination file. */
6122 set_close_write_time(fsp2, get_mtimespec(&src_sbuf));
6125 * As we are opening fsp1 read-only we only expect
6126 * an error on close on fsp2 if we are out of space.
6127 * Thus we don't look at the error return from the
6130 status = close_file(NULL, fsp2, NORMAL_CLOSE);
6132 if (!NT_STATUS_IS_OK(status)) {
6136 if (ret != (SMB_OFF_T)src_sbuf.st_size) {
6137 return NT_STATUS_DISK_FULL;
6140 return NT_STATUS_OK;
6143 /****************************************************************************
6144 Reply to a file copy.
6145 ****************************************************************************/
6147 void reply_copy(struct smb_request *req)
6149 connection_struct *conn = req->conn;
6151 char *newname = NULL;
6152 char *directory = NULL;
6156 int error = ERRnoaccess;
6161 bool target_is_directory=False;
6162 bool source_has_wild = False;
6163 bool dest_has_wild = False;
6164 SMB_STRUCT_STAT sbuf1, sbuf2;
6166 TALLOC_CTX *ctx = talloc_tos();
6168 START_PROFILE(SMBcopy);
6171 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6172 END_PROFILE(SMBcopy);
6176 tid2 = SVAL(req->inbuf,smb_vwv0);
6177 ofun = SVAL(req->inbuf,smb_vwv1);
6178 flags = SVAL(req->inbuf,smb_vwv2);
6180 p = smb_buf(req->inbuf);
6181 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
6182 0, STR_TERMINATE, &status,
6184 if (!NT_STATUS_IS_OK(status)) {
6185 reply_nterror(req, status);
6186 END_PROFILE(SMBcopy);
6189 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
6190 0, STR_TERMINATE, &status,
6192 if (!NT_STATUS_IS_OK(status)) {
6193 reply_nterror(req, status);
6194 END_PROFILE(SMBcopy);
6198 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
6200 if (tid2 != conn->cnum) {
6201 /* can't currently handle inter share copies XXXX */
6202 DEBUG(3,("Rejecting inter-share copy\n"));
6203 reply_doserror(req, ERRSRV, ERRinvdevice);
6204 END_PROFILE(SMBcopy);
6208 status = resolve_dfspath_wcard(ctx, conn,
6209 req->flags2 & FLAGS2_DFS_PATHNAMES,
6213 if (!NT_STATUS_IS_OK(status)) {
6214 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6215 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6216 ERRSRV, ERRbadpath);
6217 END_PROFILE(SMBcopy);
6220 reply_nterror(req, status);
6221 END_PROFILE(SMBcopy);
6225 status = resolve_dfspath_wcard(ctx, conn,
6226 req->flags2 & FLAGS2_DFS_PATHNAMES,
6230 if (!NT_STATUS_IS_OK(status)) {
6231 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6232 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6233 ERRSRV, ERRbadpath);
6234 END_PROFILE(SMBcopy);
6237 reply_nterror(req, status);
6238 END_PROFILE(SMBcopy);
6242 status = unix_convert(ctx, conn, name, source_has_wild,
6243 &name, NULL, &sbuf1);
6244 if (!NT_STATUS_IS_OK(status)) {
6245 reply_nterror(req, status);
6246 END_PROFILE(SMBcopy);
6250 status = unix_convert(ctx, conn, newname, dest_has_wild,
6251 &newname, NULL, &sbuf2);
6252 if (!NT_STATUS_IS_OK(status)) {
6253 reply_nterror(req, status);
6254 END_PROFILE(SMBcopy);
6258 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
6260 if ((flags&1) && target_is_directory) {
6261 reply_doserror(req, ERRDOS, ERRbadfile);
6262 END_PROFILE(SMBcopy);
6266 if ((flags&2) && !target_is_directory) {
6267 reply_doserror(req, ERRDOS, ERRbadpath);
6268 END_PROFILE(SMBcopy);
6272 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
6273 /* wants a tree copy! XXXX */
6274 DEBUG(3,("Rejecting tree copy\n"));
6275 reply_doserror(req, ERRSRV, ERRerror);
6276 END_PROFILE(SMBcopy);
6280 p = strrchr_m(name,'/');
6282 directory = talloc_strdup(ctx, "./");
6284 reply_nterror(req, NT_STATUS_NO_MEMORY);
6285 END_PROFILE(SMBcopy);
6291 directory = talloc_strdup(ctx, name);
6293 reply_nterror(req, NT_STATUS_NO_MEMORY);
6294 END_PROFILE(SMBcopy);
6301 * We should only check the mangled cache
6302 * here if unix_convert failed. This means
6303 * that the path in 'mask' doesn't exist
6304 * on the file system and so we need to look
6305 * for a possible mangle. This patch from
6306 * Tine Smukavec <valentin.smukavec@hermes.si>.
6309 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
6310 char *new_mask = NULL;
6311 mangle_lookup_name_from_8_3(ctx,
6320 if (!source_has_wild) {
6321 directory = talloc_asprintf_append(directory,
6324 if (dest_has_wild) {
6325 char *mod_newname = NULL;
6326 if (!resolve_wildcards(ctx,
6327 directory,newname,&mod_newname)) {
6328 reply_nterror(req, NT_STATUS_NO_MEMORY);
6329 END_PROFILE(SMBcopy);
6332 newname = mod_newname;
6335 status = check_name(conn, directory);
6336 if (!NT_STATUS_IS_OK(status)) {
6337 reply_nterror(req, status);
6338 END_PROFILE(SMBcopy);
6342 status = check_name(conn, newname);
6343 if (!NT_STATUS_IS_OK(status)) {
6344 reply_nterror(req, status);
6345 END_PROFILE(SMBcopy);
6349 status = copy_file(ctx,conn,directory,newname,ofun,
6350 count,target_is_directory);
6352 if(!NT_STATUS_IS_OK(status)) {
6353 reply_nterror(req, status);
6354 END_PROFILE(SMBcopy);
6360 struct smb_Dir *dir_hnd = NULL;
6361 const char *dname = NULL;
6364 if (strequal(mask,"????????.???")) {
6369 status = check_name(conn, directory);
6370 if (!NT_STATUS_IS_OK(status)) {
6371 reply_nterror(req, status);
6372 END_PROFILE(SMBcopy);
6376 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, 0);
6377 if (dir_hnd == NULL) {
6378 status = map_nt_error_from_unix(errno);
6379 reply_nterror(req, status);
6380 END_PROFILE(SMBcopy);
6386 while ((dname = ReadDirName(dir_hnd, &offset))) {
6387 char *destname = NULL;
6390 if (ISDOT(dname) || ISDOTDOT(dname)) {
6394 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
6398 if(!mask_match(dname, mask, conn->case_sensitive)) {
6402 error = ERRnoaccess;
6403 fname = talloc_asprintf(ctx,
6408 TALLOC_FREE(dir_hnd);
6409 reply_nterror(req, NT_STATUS_NO_MEMORY);
6410 END_PROFILE(SMBcopy);
6414 if (!resolve_wildcards(ctx,
6415 fname,newname,&destname)) {
6419 TALLOC_FREE(dir_hnd);
6420 reply_nterror(req, NT_STATUS_NO_MEMORY);
6421 END_PROFILE(SMBcopy);
6425 status = check_name(conn, fname);
6426 if (!NT_STATUS_IS_OK(status)) {
6427 TALLOC_FREE(dir_hnd);
6428 reply_nterror(req, status);
6429 END_PROFILE(SMBcopy);
6433 status = check_name(conn, destname);
6434 if (!NT_STATUS_IS_OK(status)) {
6435 TALLOC_FREE(dir_hnd);
6436 reply_nterror(req, status);
6437 END_PROFILE(SMBcopy);
6441 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
6443 status = copy_file(ctx,conn,fname,destname,ofun,
6444 count,target_is_directory);
6445 if (NT_STATUS_IS_OK(status)) {
6449 TALLOC_FREE(destname);
6451 TALLOC_FREE(dir_hnd);
6456 /* Error on close... */
6458 reply_unixerror(req, ERRHRD, ERRgeneral);
6459 END_PROFILE(SMBcopy);
6463 reply_doserror(req, ERRDOS, error);
6464 END_PROFILE(SMBcopy);
6468 reply_outbuf(req, 1, 0);
6469 SSVAL(req->outbuf,smb_vwv0,count);
6471 END_PROFILE(SMBcopy);
6476 #define DBGC_CLASS DBGC_LOCKING
6478 /****************************************************************************
6479 Get a lock pid, dealing with large count requests.
6480 ****************************************************************************/
6482 uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
6484 if(!large_file_format)
6485 return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
6487 return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
6490 /****************************************************************************
6491 Get a lock count, dealing with large count requests.
6492 ****************************************************************************/
6494 SMB_BIG_UINT get_lock_count( char *data, int data_offset, bool large_file_format)
6496 SMB_BIG_UINT count = 0;
6498 if(!large_file_format) {
6499 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
6502 #if defined(HAVE_LONGLONG)
6503 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
6504 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
6505 #else /* HAVE_LONGLONG */
6508 * NT4.x seems to be broken in that it sends large file (64 bit)
6509 * lockingX calls even if the CAP_LARGE_FILES was *not*
6510 * negotiated. For boxes without large unsigned ints truncate the
6511 * lock count by dropping the top 32 bits.
6514 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
6515 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
6516 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
6517 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
6518 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
6521 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
6522 #endif /* HAVE_LONGLONG */
6528 #if !defined(HAVE_LONGLONG)
6529 /****************************************************************************
6530 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
6531 ****************************************************************************/
6533 static uint32 map_lock_offset(uint32 high, uint32 low)
6537 uint32 highcopy = high;
6540 * Try and find out how many significant bits there are in high.
6543 for(i = 0; highcopy; i++)
6547 * We use 31 bits not 32 here as POSIX
6548 * lock offsets may not be negative.
6551 mask = (~0) << (31 - i);
6554 return 0; /* Fail. */
6560 #endif /* !defined(HAVE_LONGLONG) */
6562 /****************************************************************************
6563 Get a lock offset, dealing with large offset requests.
6564 ****************************************************************************/
6566 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err)
6568 SMB_BIG_UINT offset = 0;
6572 if(!large_file_format) {
6573 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
6576 #if defined(HAVE_LONGLONG)
6577 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
6578 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
6579 #else /* HAVE_LONGLONG */
6582 * NT4.x seems to be broken in that it sends large file (64 bit)
6583 * lockingX calls even if the CAP_LARGE_FILES was *not*
6584 * negotiated. For boxes without large unsigned ints mangle the
6585 * lock offset by mapping the top 32 bits onto the lower 32.
6588 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
6589 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6590 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
6593 if((new_low = map_lock_offset(high, low)) == 0) {
6595 return (SMB_BIG_UINT)-1;
6598 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
6599 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
6600 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
6601 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
6604 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6605 #endif /* HAVE_LONGLONG */
6611 /****************************************************************************
6612 Reply to a lockingX request.
6613 ****************************************************************************/
6615 void reply_lockingX(struct smb_request *req)
6617 connection_struct *conn = req->conn;
6619 unsigned char locktype;
6620 unsigned char oplocklevel;
6623 SMB_BIG_UINT count = 0, offset = 0;
6628 bool large_file_format;
6630 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
6632 START_PROFILE(SMBlockingX);
6635 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6636 END_PROFILE(SMBlockingX);
6640 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
6641 locktype = CVAL(req->inbuf,smb_vwv3);
6642 oplocklevel = CVAL(req->inbuf,smb_vwv3+1);
6643 num_ulocks = SVAL(req->inbuf,smb_vwv6);
6644 num_locks = SVAL(req->inbuf,smb_vwv7);
6645 lock_timeout = IVAL(req->inbuf,smb_vwv4);
6646 large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
6648 if (!check_fsp(conn, req, fsp)) {
6649 END_PROFILE(SMBlockingX);
6653 data = smb_buf(req->inbuf);
6655 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
6656 /* we don't support these - and CANCEL_LOCK makes w2k
6657 and XP reboot so I don't really want to be
6658 compatible! (tridge) */
6659 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
6660 END_PROFILE(SMBlockingX);
6664 /* Check if this is an oplock break on a file
6665 we have granted an oplock on.
6667 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
6668 /* Client can insist on breaking to none. */
6669 bool break_to_none = (oplocklevel == 0);
6672 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
6673 "for fnum = %d\n", (unsigned int)oplocklevel,
6677 * Make sure we have granted an exclusive or batch oplock on
6681 if (fsp->oplock_type == 0) {
6683 /* The Samba4 nbench simulator doesn't understand
6684 the difference between break to level2 and break
6685 to none from level2 - it sends oplock break
6686 replies in both cases. Don't keep logging an error
6687 message here - just ignore it. JRA. */
6689 DEBUG(5,("reply_lockingX: Error : oplock break from "
6690 "client for fnum = %d (oplock=%d) and no "
6691 "oplock granted on this file (%s).\n",
6692 fsp->fnum, fsp->oplock_type, fsp->fsp_name));
6694 /* if this is a pure oplock break request then don't
6696 if (num_locks == 0 && num_ulocks == 0) {
6697 END_PROFILE(SMBlockingX);
6700 END_PROFILE(SMBlockingX);
6701 reply_doserror(req, ERRDOS, ERRlock);
6706 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
6708 result = remove_oplock(fsp);
6710 result = downgrade_oplock(fsp);
6714 DEBUG(0, ("reply_lockingX: error in removing "
6715 "oplock on file %s\n", fsp->fsp_name));
6716 /* Hmmm. Is this panic justified? */
6717 smb_panic("internal tdb error");
6720 reply_to_oplock_break_requests(fsp);
6722 /* if this is a pure oplock break request then don't send a
6724 if (num_locks == 0 && num_ulocks == 0) {
6725 /* Sanity check - ensure a pure oplock break is not a
6727 if(CVAL(req->inbuf,smb_vwv0) != 0xff)
6728 DEBUG(0,("reply_lockingX: Error : pure oplock "
6729 "break is a chained %d request !\n",
6730 (unsigned int)CVAL(req->inbuf,
6732 END_PROFILE(SMBlockingX);
6738 * We do this check *after* we have checked this is not a oplock break
6739 * response message. JRA.
6742 release_level_2_oplocks_on_change(fsp);
6744 if (smb_buflen(req->inbuf) <
6745 (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
6746 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6747 END_PROFILE(SMBlockingX);
6751 /* Data now points at the beginning of the list
6752 of smb_unlkrng structs */
6753 for(i = 0; i < (int)num_ulocks; i++) {
6754 lock_pid = get_lock_pid( data, i, large_file_format);
6755 count = get_lock_count( data, i, large_file_format);
6756 offset = get_lock_offset( data, i, large_file_format, &err);
6759 * There is no error code marked "stupid client bug".... :-).
6762 END_PROFILE(SMBlockingX);
6763 reply_doserror(req, ERRDOS, ERRnoaccess);
6767 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
6768 "pid %u, file %s\n", (double)offset, (double)count,
6769 (unsigned int)lock_pid, fsp->fsp_name ));
6771 status = do_unlock(smbd_messaging_context(),
6778 if (NT_STATUS_V(status)) {
6779 END_PROFILE(SMBlockingX);
6780 reply_nterror(req, status);
6785 /* Setup the timeout in seconds. */
6787 if (!lp_blocking_locks(SNUM(conn))) {
6791 /* Now do any requested locks */
6792 data += ((large_file_format ? 20 : 10)*num_ulocks);
6794 /* Data now points at the beginning of the list
6795 of smb_lkrng structs */
6797 for(i = 0; i < (int)num_locks; i++) {
6798 enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
6799 READ_LOCK:WRITE_LOCK);
6800 lock_pid = get_lock_pid( data, i, large_file_format);
6801 count = get_lock_count( data, i, large_file_format);
6802 offset = get_lock_offset( data, i, large_file_format, &err);
6805 * There is no error code marked "stupid client bug".... :-).
6808 END_PROFILE(SMBlockingX);
6809 reply_doserror(req, ERRDOS, ERRnoaccess);
6813 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
6814 "%u, file %s timeout = %d\n", (double)offset,
6815 (double)count, (unsigned int)lock_pid,
6816 fsp->fsp_name, (int)lock_timeout ));
6818 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
6819 if (lp_blocking_locks(SNUM(conn))) {
6821 /* Schedule a message to ourselves to
6822 remove the blocking lock record and
6823 return the right error. */
6825 if (!blocking_lock_cancel(fsp,
6831 NT_STATUS_FILE_LOCK_CONFLICT)) {
6832 END_PROFILE(SMBlockingX);
6837 ERRcancelviolation));
6841 /* Remove a matching pending lock. */
6842 status = do_lock_cancel(fsp,
6848 bool blocking_lock = lock_timeout ? True : False;
6849 bool defer_lock = False;
6850 struct byte_range_lock *br_lck;
6851 uint32 block_smbpid;
6853 br_lck = do_lock(smbd_messaging_context(),
6864 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6865 /* Windows internal resolution for blocking locks seems
6866 to be about 200ms... Don't wait for less than that. JRA. */
6867 if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
6868 lock_timeout = lp_lock_spin_time();
6873 /* This heuristic seems to match W2K3 very well. If a
6874 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
6875 it pretends we asked for a timeout of between 150 - 300 milliseconds as
6876 far as I can tell. Replacement for do_lock_spin(). JRA. */
6878 if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
6879 NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
6881 lock_timeout = lp_lock_spin_time();
6884 if (br_lck && defer_lock) {
6886 * A blocking lock was requested. Package up
6887 * this smb into a queued request and push it
6888 * onto the blocking lock queue.
6890 if(push_blocking_lock_request(br_lck,
6901 TALLOC_FREE(br_lck);
6902 END_PROFILE(SMBlockingX);
6907 TALLOC_FREE(br_lck);
6910 if (NT_STATUS_V(status)) {
6911 END_PROFILE(SMBlockingX);
6912 reply_nterror(req, status);
6917 /* If any of the above locks failed, then we must unlock
6918 all of the previous locks (X/Open spec). */
6920 if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) &&
6924 * Ensure we don't do a remove on the lock that just failed,
6925 * as under POSIX rules, if we have a lock already there, we
6926 * will delete it (and we shouldn't) .....
6928 for(i--; i >= 0; i--) {
6929 lock_pid = get_lock_pid( data, i, large_file_format);
6930 count = get_lock_count( data, i, large_file_format);
6931 offset = get_lock_offset( data, i, large_file_format,
6935 * There is no error code marked "stupid client
6939 END_PROFILE(SMBlockingX);
6940 reply_doserror(req, ERRDOS, ERRnoaccess);
6944 do_unlock(smbd_messaging_context(),
6951 END_PROFILE(SMBlockingX);
6952 reply_nterror(req, status);
6956 reply_outbuf(req, 2, 0);
6958 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
6959 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
6961 END_PROFILE(SMBlockingX);
6966 #define DBGC_CLASS DBGC_ALL
6968 /****************************************************************************
6969 Reply to a SMBreadbmpx (read block multiplex) request.
6970 Always reply with an error, if someone has a platform really needs this,
6971 please contact vl@samba.org
6972 ****************************************************************************/
6974 void reply_readbmpx(struct smb_request *req)
6976 START_PROFILE(SMBreadBmpx);
6977 reply_doserror(req, ERRSRV, ERRuseSTD);
6978 END_PROFILE(SMBreadBmpx);
6982 /****************************************************************************
6983 Reply to a SMBreadbs (read block multiplex secondary) request.
6984 Always reply with an error, if someone has a platform really needs this,
6985 please contact vl@samba.org
6986 ****************************************************************************/
6988 void reply_readbs(struct smb_request *req)
6990 START_PROFILE(SMBreadBs);
6991 reply_doserror(req, ERRSRV, ERRuseSTD);
6992 END_PROFILE(SMBreadBs);
6996 /****************************************************************************
6997 Reply to a SMBsetattrE.
6998 ****************************************************************************/
7000 void reply_setattrE(struct smb_request *req)
7002 connection_struct *conn = req->conn;
7003 struct timespec ts[2];
7005 SMB_STRUCT_STAT sbuf;
7008 START_PROFILE(SMBsetattrE);
7011 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7012 END_PROFILE(SMBsetattrE);
7016 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
7018 if(!fsp || (fsp->conn != conn)) {
7019 reply_doserror(req, ERRDOS, ERRbadfid);
7020 END_PROFILE(SMBsetattrE);
7026 * Convert the DOS times into unix times. Ignore create
7027 * time as UNIX can't set this.
7030 ts[0] = convert_time_t_to_timespec(
7031 srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */
7032 ts[1] = convert_time_t_to_timespec(
7033 srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */
7035 reply_outbuf(req, 0, 0);
7038 * Patch from Ray Frush <frush@engr.colostate.edu>
7039 * Sometimes times are sent as zero - ignore them.
7042 /* Ensure we have a valid stat struct for the source. */
7043 if (fsp->fh->fd != -1) {
7044 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
7045 status = map_nt_error_from_unix(errno);
7046 reply_nterror(req, status);
7047 END_PROFILE(SMBsetattrE);
7051 if (SMB_VFS_STAT(conn, fsp->fsp_name, &sbuf) == -1) {
7052 status = map_nt_error_from_unix(errno);
7053 reply_nterror(req, status);
7054 END_PROFILE(SMBsetattrE);
7059 status = smb_set_file_time(conn, fsp, fsp->fsp_name,
7061 if (!NT_STATUS_IS_OK(status)) {
7062 reply_doserror(req, ERRDOS, ERRnoaccess);
7063 END_PROFILE(SMBsetattrE);
7067 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
7069 (unsigned int)ts[0].tv_sec,
7070 (unsigned int)ts[1].tv_sec));
7072 END_PROFILE(SMBsetattrE);
7077 /* Back from the dead for OS/2..... JRA. */
7079 /****************************************************************************
7080 Reply to a SMBwritebmpx (write block multiplex primary) request.
7081 Always reply with an error, if someone has a platform really needs this,
7082 please contact vl@samba.org
7083 ****************************************************************************/
7085 void reply_writebmpx(struct smb_request *req)
7087 START_PROFILE(SMBwriteBmpx);
7088 reply_doserror(req, ERRSRV, ERRuseSTD);
7089 END_PROFILE(SMBwriteBmpx);
7093 /****************************************************************************
7094 Reply to a SMBwritebs (write block multiplex secondary) request.
7095 Always reply with an error, if someone has a platform really needs this,
7096 please contact vl@samba.org
7097 ****************************************************************************/
7099 void reply_writebs(struct smb_request *req)
7101 START_PROFILE(SMBwriteBs);
7102 reply_doserror(req, ERRSRV, ERRuseSTD);
7103 END_PROFILE(SMBwriteBs);
7107 /****************************************************************************
7108 Reply to a SMBgetattrE.
7109 ****************************************************************************/
7111 void reply_getattrE(struct smb_request *req)
7113 connection_struct *conn = req->conn;
7114 SMB_STRUCT_STAT sbuf;
7117 struct timespec create_ts;
7119 START_PROFILE(SMBgetattrE);
7122 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7123 END_PROFILE(SMBgetattrE);
7127 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
7129 if(!fsp || (fsp->conn != conn)) {
7130 reply_doserror(req, ERRDOS, ERRbadfid);
7131 END_PROFILE(SMBgetattrE);
7135 /* Do an fstat on this file */
7136 if(fsp_stat(fsp, &sbuf)) {
7137 reply_unixerror(req, ERRDOS, ERRnoaccess);
7138 END_PROFILE(SMBgetattrE);
7142 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
7145 * Convert the times into dos times. Set create
7146 * date to be last modify date as UNIX doesn't save
7150 reply_outbuf(req, 11, 0);
7152 create_ts = get_create_timespec(&sbuf,
7153 lp_fake_dir_create_times(SNUM(conn)));
7154 srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec);
7155 srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime);
7156 /* Should we check pending modtime here ? JRA */
7157 srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime);
7160 SIVAL(req->outbuf, smb_vwv6, 0);
7161 SIVAL(req->outbuf, smb_vwv8, 0);
7163 uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
7164 SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
7165 SIVAL(req->outbuf, smb_vwv8, allocation_size);
7167 SSVAL(req->outbuf,smb_vwv10, mode);
7169 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
7171 END_PROFILE(SMBgetattrE);