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 unsigned int smb_echo_count = 0;
33 extern uint32 global_client_caps;
35 extern struct current_user current_user;
36 extern bool global_encrypted_passwords_negotiated;
38 /****************************************************************************
39 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
40 path or anything including wildcards.
41 We're assuming here that '/' is not the second byte in any multibyte char
42 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
44 ****************************************************************************/
46 /* Custom version for processing POSIX paths. */
47 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
49 static NTSTATUS check_path_syntax_internal(char *path,
51 bool *p_last_component_contains_wcard)
55 NTSTATUS ret = NT_STATUS_OK;
56 bool start_of_name_component = True;
58 *p_last_component_contains_wcard = False;
61 if (IS_PATH_SEP(*s,posix_path)) {
63 * Safe to assume is not the second part of a mb char
64 * as this is handled below.
66 /* Eat multiple '/' or '\\' */
67 while (IS_PATH_SEP(*s,posix_path)) {
70 if ((d != path) && (*s != '\0')) {
71 /* We only care about non-leading or trailing '/' or '\\' */
75 start_of_name_component = True;
77 *p_last_component_contains_wcard = False;
81 if (start_of_name_component) {
82 if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
83 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
86 * No mb char starts with '.' so we're safe checking the directory separator here.
89 /* If we just added a '/' - delete it */
90 if ((d > path) && (*(d-1) == '/')) {
95 /* Are we at the start ? Can't go back further if so. */
97 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
100 /* Go back one level... */
101 /* We know this is safe as '/' cannot be part of a mb sequence. */
102 /* NOTE - if this assumption is invalid we are not in good shape... */
103 /* Decrement d first as d points to the *next* char to write into. */
104 for (d--; d > path; d--) {
108 s += 2; /* Else go past the .. */
109 /* We're still at the start of a name component, just the previous one. */
112 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
125 return NT_STATUS_OBJECT_NAME_INVALID;
133 *p_last_component_contains_wcard = True;
142 /* Get the size of the next MB character. */
143 next_codepoint(s,&siz);
161 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
163 return NT_STATUS_INVALID_PARAMETER;
166 start_of_name_component = False;
174 /****************************************************************************
175 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
176 No wildcards allowed.
177 ****************************************************************************/
179 NTSTATUS check_path_syntax(char *path)
182 return check_path_syntax_internal(path, False, &ignore);
185 /****************************************************************************
186 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
187 Wildcards allowed - p_contains_wcard returns true if the last component contained
189 ****************************************************************************/
191 NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
193 return check_path_syntax_internal(path, False, p_contains_wcard);
196 /****************************************************************************
197 Check the path for a POSIX client.
198 We're assuming here that '/' is not the second byte in any multibyte char
199 set (a safe assumption).
200 ****************************************************************************/
202 NTSTATUS check_path_syntax_posix(char *path)
205 return check_path_syntax_internal(path, True, &ignore);
208 /****************************************************************************
209 Pull a string and check the path allowing a wilcard - provide for error return.
210 ****************************************************************************/
212 size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
220 bool *contains_wcard)
227 ret = srvstr_pull_buf_talloc(ctx,
234 ret = srvstr_pull_talloc(ctx,
244 *err = NT_STATUS_INVALID_PARAMETER;
248 *contains_wcard = False;
250 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
252 * For a DFS path the function parse_dfs_path()
253 * will do the path processing, just make a copy.
259 if (lp_posix_pathnames()) {
260 *err = check_path_syntax_posix(*pp_dest);
262 *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
268 /****************************************************************************
269 Pull a string and check the path - provide for error return.
270 ****************************************************************************/
272 size_t srvstr_get_path(TALLOC_CTX *ctx,
286 ret = srvstr_pull_buf_talloc(ctx,
293 ret = srvstr_pull_talloc(ctx,
303 *err = NT_STATUS_INVALID_PARAMETER;
307 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
309 * For a DFS path the function parse_dfs_path()
310 * will do the path processing, just make a copy.
316 if (lp_posix_pathnames()) {
317 *err = check_path_syntax_posix(*pp_dest);
319 *err = check_path_syntax(*pp_dest);
325 /****************************************************************************
326 Check if we have a correct fsp pointing to a file. Basic check for open fsp.
327 ****************************************************************************/
329 bool check_fsp_open(connection_struct *conn, struct smb_request *req,
330 files_struct *fsp, struct current_user *user)
332 if (!(fsp) || !(conn)) {
333 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
336 if (((conn) != (fsp)->conn) || user->vuid != (fsp)->vuid) {
337 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
343 /****************************************************************************
344 Check if we have a correct fsp pointing to a file. Replacement for the
346 ****************************************************************************/
348 bool check_fsp(connection_struct *conn, struct smb_request *req,
349 files_struct *fsp, struct current_user *user)
351 if (!check_fsp_open(conn, req, fsp, user)) {
354 if ((fsp)->is_directory) {
355 reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
358 if ((fsp)->fh->fd == -1) {
359 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
362 (fsp)->num_smb_operations++;
366 /****************************************************************************
367 Check if we have a correct fsp. Replacement for the FSP_BELONGS_CONN macro
368 ****************************************************************************/
370 bool fsp_belongs_conn(connection_struct *conn, struct smb_request *req,
371 files_struct *fsp, struct current_user *user)
373 if ((fsp) && (conn) && ((conn)==(fsp)->conn)
374 && (current_user.vuid==(fsp)->vuid)) {
378 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
382 /****************************************************************************
383 Reply to a (netbios-level) special message.
384 ****************************************************************************/
386 void reply_special(char *inbuf)
388 int msg_type = CVAL(inbuf,0);
389 int msg_flags = CVAL(inbuf,1);
394 * We only really use 4 bytes of the outbuf, but for the smb_setlen
395 * calculation & friends (srv_send_smb uses that) we need the full smb
398 char outbuf[smb_size];
400 static bool already_got_session = False;
404 memset(outbuf, '\0', sizeof(outbuf));
406 smb_setlen(outbuf,0);
409 case 0x81: /* session request */
411 if (already_got_session) {
412 exit_server_cleanly("multiple session request not permitted");
415 SCVAL(outbuf,0,0x82);
417 if (name_len(inbuf+4) > 50 ||
418 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
419 DEBUG(0,("Invalid name length in session request\n"));
422 name_extract(inbuf,4,name1);
423 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
424 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
427 set_local_machine_name(name1, True);
428 set_remote_machine_name(name2, True);
430 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
431 get_local_machine_name(), get_remote_machine_name(),
434 if (name_type == 'R') {
435 /* We are being asked for a pathworks session ---
437 SCVAL(outbuf, 0,0x83);
441 /* only add the client's machine name to the list
442 of possibly valid usernames if we are operating
443 in share mode security */
444 if (lp_security() == SEC_SHARE) {
445 add_session_user(get_remote_machine_name());
448 reload_services(True);
451 already_got_session = True;
454 case 0x89: /* session keepalive request
455 (some old clients produce this?) */
456 SCVAL(outbuf,0,SMBkeepalive);
460 case 0x82: /* positive session response */
461 case 0x83: /* negative session response */
462 case 0x84: /* retarget session response */
463 DEBUG(0,("Unexpected session response\n"));
466 case SMBkeepalive: /* session keepalive */
471 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
472 msg_type, msg_flags));
474 srv_send_smb(smbd_server_fd(), outbuf, false);
478 /****************************************************************************
480 conn POINTER CAN BE NULL HERE !
481 ****************************************************************************/
483 void reply_tcon(struct smb_request *req)
485 connection_struct *conn = req->conn;
487 char *service_buf = NULL;
488 char *password = NULL;
493 DATA_BLOB password_blob;
494 TALLOC_CTX *ctx = talloc_tos();
496 START_PROFILE(SMBtcon);
498 if (smb_buflen(req->inbuf) < 4) {
499 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
500 END_PROFILE(SMBtcon);
504 p = smb_buf(req->inbuf)+1;
505 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
506 &service_buf, p, STR_TERMINATE) + 1;
507 pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
508 &password, p, STR_TERMINATE) + 1;
510 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
511 &dev, p, STR_TERMINATE) + 1;
513 if (service_buf == NULL || password == NULL || dev == NULL) {
514 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
515 END_PROFILE(SMBtcon);
518 p = strrchr_m(service_buf,'\\');
522 service = service_buf;
525 password_blob = data_blob(password, pwlen+1);
527 conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
530 data_blob_clear_free(&password_blob);
533 reply_nterror(req, nt_status);
534 END_PROFILE(SMBtcon);
538 reply_outbuf(req, 2, 0);
539 SSVAL(req->outbuf,smb_vwv0,max_recv);
540 SSVAL(req->outbuf,smb_vwv1,conn->cnum);
541 SSVAL(req->outbuf,smb_tid,conn->cnum);
543 DEBUG(3,("tcon service=%s cnum=%d\n",
544 service, conn->cnum));
546 END_PROFILE(SMBtcon);
550 /****************************************************************************
551 Reply to a tcon and X.
552 conn POINTER CAN BE NULL HERE !
553 ****************************************************************************/
555 void reply_tcon_and_X(struct smb_request *req)
557 connection_struct *conn = req->conn;
558 char *service = NULL;
560 TALLOC_CTX *ctx = talloc_tos();
561 /* what the cleint thinks the device is */
562 char *client_devicetype = NULL;
563 /* what the server tells the client the share represents */
564 const char *server_devicetype;
571 START_PROFILE(SMBtconX);
574 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
575 END_PROFILE(SMBtconX);
579 passlen = SVAL(req->inbuf,smb_vwv3);
580 tcon_flags = SVAL(req->inbuf,smb_vwv2);
582 /* we might have to close an old one */
583 if ((tcon_flags & 0x1) && conn) {
584 close_cnum(conn,req->vuid);
589 if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
590 reply_doserror(req, ERRDOS, ERRbuftoosmall);
591 END_PROFILE(SMBtconX);
595 if (global_encrypted_passwords_negotiated) {
596 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
598 if (lp_security() == SEC_SHARE) {
600 * Security = share always has a pad byte
601 * after the password.
603 p = smb_buf(req->inbuf) + passlen + 1;
605 p = smb_buf(req->inbuf) + passlen;
608 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
610 /* Ensure correct termination */
611 password.data[passlen]=0;
612 p = smb_buf(req->inbuf) + passlen + 1;
615 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
619 data_blob_clear_free(&password);
620 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
621 END_PROFILE(SMBtconX);
626 * the service name can be either: \\server\share
627 * or share directly like on the DELL PowerVault 705
630 q = strchr_m(path+2,'\\');
632 data_blob_clear_free(&password);
633 reply_doserror(req, ERRDOS, ERRnosuchshare);
634 END_PROFILE(SMBtconX);
642 p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
643 &client_devicetype, p,
644 MIN(6,smb_bufrem(req->inbuf, p)), STR_ASCII);
646 if (client_devicetype == NULL) {
647 data_blob_clear_free(&password);
648 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
649 END_PROFILE(SMBtconX);
653 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
655 conn = make_connection(service, password, client_devicetype,
656 req->vuid, &nt_status);
659 data_blob_clear_free(&password);
662 reply_nterror(req, nt_status);
663 END_PROFILE(SMBtconX);
668 server_devicetype = "IPC";
669 else if ( IS_PRINT(conn) )
670 server_devicetype = "LPT1:";
672 server_devicetype = "A:";
674 if (Protocol < PROTOCOL_NT1) {
675 reply_outbuf(req, 2, 0);
676 if (message_push_string(&req->outbuf, server_devicetype,
677 STR_TERMINATE|STR_ASCII) == -1) {
678 reply_nterror(req, NT_STATUS_NO_MEMORY);
679 END_PROFILE(SMBtconX);
683 /* NT sets the fstype of IPC$ to the null string */
684 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
686 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
687 /* Return permissions. */
691 reply_outbuf(req, 7, 0);
694 perm1 = FILE_ALL_ACCESS;
695 perm2 = FILE_ALL_ACCESS;
697 perm1 = CAN_WRITE(conn) ?
702 SIVAL(req->outbuf, smb_vwv3, perm1);
703 SIVAL(req->outbuf, smb_vwv5, perm2);
705 reply_outbuf(req, 3, 0);
708 if ((message_push_string(&req->outbuf, server_devicetype,
709 STR_TERMINATE|STR_ASCII) == -1)
710 || (message_push_string(&req->outbuf, fstype,
711 STR_TERMINATE) == -1)) {
712 reply_nterror(req, NT_STATUS_NO_MEMORY);
713 END_PROFILE(SMBtconX);
717 /* what does setting this bit do? It is set by NT4 and
718 may affect the ability to autorun mounted cdroms */
719 SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
720 (lp_csc_policy(SNUM(conn)) << 2));
722 init_dfsroot(conn, req->inbuf, req->outbuf);
726 DEBUG(3,("tconX service=%s \n",
729 /* set the incoming and outgoing tid to the just created one */
730 SSVAL(req->inbuf,smb_tid,conn->cnum);
731 SSVAL(req->outbuf,smb_tid,conn->cnum);
733 END_PROFILE(SMBtconX);
739 /****************************************************************************
740 Reply to an unknown type.
741 ****************************************************************************/
743 void reply_unknown_new(struct smb_request *req, uint8 type)
745 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
746 smb_fn_name(type), type, type));
747 reply_doserror(req, ERRSRV, ERRunknownsmb);
751 /****************************************************************************
753 conn POINTER CAN BE NULL HERE !
754 ****************************************************************************/
756 void reply_ioctl(struct smb_request *req)
758 connection_struct *conn = req->conn;
765 START_PROFILE(SMBioctl);
768 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
769 END_PROFILE(SMBioctl);
773 device = SVAL(req->inbuf,smb_vwv1);
774 function = SVAL(req->inbuf,smb_vwv2);
775 ioctl_code = (device << 16) + function;
777 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
779 switch (ioctl_code) {
780 case IOCTL_QUERY_JOB_INFO:
784 reply_doserror(req, ERRSRV, ERRnosupport);
785 END_PROFILE(SMBioctl);
789 reply_outbuf(req, 8, replysize+1);
790 SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
791 SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
792 SSVAL(req->outbuf,smb_vwv6,52); /* Offset to data */
793 p = smb_buf(req->outbuf);
794 memset(p, '\0', replysize+1); /* valgrind-safe. */
795 p += 1; /* Allow for alignment */
797 switch (ioctl_code) {
798 case IOCTL_QUERY_JOB_INFO:
800 files_struct *fsp = file_fsp(SVAL(req->inbuf,
803 reply_doserror(req, ERRDOS, ERRbadfid);
804 END_PROFILE(SMBioctl);
807 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
808 srvstr_push((char *)req->outbuf, req->flags2, p+2,
810 STR_TERMINATE|STR_ASCII);
812 srvstr_push((char *)req->outbuf, req->flags2,
813 p+18, lp_servicename(SNUM(conn)),
814 13, STR_TERMINATE|STR_ASCII);
822 END_PROFILE(SMBioctl);
826 /****************************************************************************
827 Strange checkpath NTSTATUS mapping.
828 ****************************************************************************/
830 static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
832 /* Strange DOS error code semantics only for checkpath... */
833 if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
834 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
835 /* We need to map to ERRbadpath */
836 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
842 /****************************************************************************
843 Reply to a checkpath.
844 ****************************************************************************/
846 void reply_checkpath(struct smb_request *req)
848 connection_struct *conn = req->conn;
850 SMB_STRUCT_STAT sbuf;
852 TALLOC_CTX *ctx = talloc_tos();
854 START_PROFILE(SMBcheckpath);
856 srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
857 smb_buf(req->inbuf) + 1, 0,
858 STR_TERMINATE, &status);
859 if (!NT_STATUS_IS_OK(status)) {
860 status = map_checkpath_error((char *)req->inbuf, status);
861 reply_nterror(req, status);
862 END_PROFILE(SMBcheckpath);
866 status = resolve_dfspath(ctx, conn,
867 req->flags2 & FLAGS2_DFS_PATHNAMES,
870 if (!NT_STATUS_IS_OK(status)) {
871 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
872 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
874 END_PROFILE(SMBcheckpath);
880 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
882 status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
883 if (!NT_STATUS_IS_OK(status)) {
887 status = check_name(conn, name);
888 if (!NT_STATUS_IS_OK(status)) {
889 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status)));
893 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
894 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
895 status = map_nt_error_from_unix(errno);
899 if (!S_ISDIR(sbuf.st_mode)) {
900 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
902 END_PROFILE(SMBcheckpath);
906 reply_outbuf(req, 0, 0);
908 END_PROFILE(SMBcheckpath);
913 END_PROFILE(SMBcheckpath);
915 /* We special case this - as when a Windows machine
916 is parsing a path is steps through the components
917 one at a time - if a component fails it expects
918 ERRbadpath, not ERRbadfile.
920 status = map_checkpath_error((char *)req->inbuf, status);
921 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
923 * Windows returns different error codes if
924 * the parent directory is valid but not the
925 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
926 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
927 * if the path is invalid.
929 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
934 reply_nterror(req, status);
937 /****************************************************************************
939 ****************************************************************************/
941 void reply_getatr(struct smb_request *req)
943 connection_struct *conn = req->conn;
945 SMB_STRUCT_STAT sbuf;
951 TALLOC_CTX *ctx = talloc_tos();
953 START_PROFILE(SMBgetatr);
955 p = smb_buf(req->inbuf) + 1;
956 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
957 0, STR_TERMINATE, &status);
958 if (!NT_STATUS_IS_OK(status)) {
959 reply_nterror(req, status);
960 END_PROFILE(SMBgetatr);
964 status = resolve_dfspath(ctx, conn,
965 req->flags2 & FLAGS2_DFS_PATHNAMES,
968 if (!NT_STATUS_IS_OK(status)) {
969 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
970 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
972 END_PROFILE(SMBgetatr);
975 reply_nterror(req, status);
976 END_PROFILE(SMBgetatr);
980 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
981 under WfWg - weird! */
982 if (*fname == '\0') {
983 mode = aHIDDEN | aDIR;
984 if (!CAN_WRITE(conn)) {
990 status = unix_convert(ctx, conn, fname, False, &fname, NULL,&sbuf);
991 if (!NT_STATUS_IS_OK(status)) {
992 reply_nterror(req, status);
993 END_PROFILE(SMBgetatr);
996 status = check_name(conn, fname);
997 if (!NT_STATUS_IS_OK(status)) {
998 DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
999 reply_nterror(req, status);
1000 END_PROFILE(SMBgetatr);
1003 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
1004 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
1005 reply_unixerror(req, ERRDOS,ERRbadfile);
1006 END_PROFILE(SMBgetatr);
1010 mode = dos_mode(conn,fname,&sbuf);
1011 size = sbuf.st_size;
1012 mtime = sbuf.st_mtime;
1018 reply_outbuf(req, 10, 0);
1020 SSVAL(req->outbuf,smb_vwv0,mode);
1021 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1022 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1024 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1026 SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1028 if (Protocol >= PROTOCOL_NT1) {
1029 SSVAL(req->outbuf, smb_flg2,
1030 SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1033 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
1035 END_PROFILE(SMBgetatr);
1039 /****************************************************************************
1041 ****************************************************************************/
1043 void reply_setatr(struct smb_request *req)
1045 struct timespec ts[2];
1046 connection_struct *conn = req->conn;
1050 SMB_STRUCT_STAT sbuf;
1053 TALLOC_CTX *ctx = talloc_tos();
1055 START_PROFILE(SMBsetatr);
1060 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1064 p = smb_buf(req->inbuf) + 1;
1065 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
1066 0, STR_TERMINATE, &status);
1067 if (!NT_STATUS_IS_OK(status)) {
1068 reply_nterror(req, status);
1069 END_PROFILE(SMBsetatr);
1073 status = resolve_dfspath(ctx, conn,
1074 req->flags2 & FLAGS2_DFS_PATHNAMES,
1077 if (!NT_STATUS_IS_OK(status)) {
1078 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1079 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1080 ERRSRV, ERRbadpath);
1081 END_PROFILE(SMBsetatr);
1084 reply_nterror(req, status);
1085 END_PROFILE(SMBsetatr);
1089 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
1090 if (!NT_STATUS_IS_OK(status)) {
1091 reply_nterror(req, status);
1092 END_PROFILE(SMBsetatr);
1096 status = check_name(conn, fname);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 reply_nterror(req, status);
1099 END_PROFILE(SMBsetatr);
1103 if (fname[0] == '.' && fname[1] == '\0') {
1105 * Not sure here is the right place to catch this
1106 * condition. Might be moved to somewhere else later -- vl
1108 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1109 END_PROFILE(SMBsetatr);
1113 mode = SVAL(req->inbuf,smb_vwv0);
1114 mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
1116 ts[1] = convert_time_t_to_timespec(mtime);
1117 status = smb_set_file_time(conn, NULL, fname,
1119 if (!NT_STATUS_IS_OK(status)) {
1120 reply_unixerror(req, ERRDOS, ERRnoaccess);
1121 END_PROFILE(SMBsetatr);
1125 if (mode != FILE_ATTRIBUTE_NORMAL) {
1126 if (VALID_STAT_OF_DIR(sbuf))
1131 if (file_set_dosmode(conn,fname,mode,&sbuf,NULL,false) != 0) {
1132 reply_unixerror(req, ERRDOS, ERRnoaccess);
1133 END_PROFILE(SMBsetatr);
1138 reply_outbuf(req, 0, 0);
1140 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1142 END_PROFILE(SMBsetatr);
1146 /****************************************************************************
1148 ****************************************************************************/
1150 void reply_dskattr(struct smb_request *req)
1152 connection_struct *conn = req->conn;
1153 SMB_BIG_UINT dfree,dsize,bsize;
1154 START_PROFILE(SMBdskattr);
1156 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
1157 reply_unixerror(req, ERRHRD, ERRgeneral);
1158 END_PROFILE(SMBdskattr);
1162 reply_outbuf(req, 5, 0);
1164 if (Protocol <= PROTOCOL_LANMAN2) {
1165 double total_space, free_space;
1166 /* we need to scale this to a number that DOS6 can handle. We
1167 use floating point so we can handle large drives on systems
1168 that don't have 64 bit integers
1170 we end up displaying a maximum of 2G to DOS systems
1172 total_space = dsize * (double)bsize;
1173 free_space = dfree * (double)bsize;
1175 dsize = (SMB_BIG_UINT)((total_space+63*512) / (64*512));
1176 dfree = (SMB_BIG_UINT)((free_space+63*512) / (64*512));
1178 if (dsize > 0xFFFF) dsize = 0xFFFF;
1179 if (dfree > 0xFFFF) dfree = 0xFFFF;
1181 SSVAL(req->outbuf,smb_vwv0,dsize);
1182 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1183 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1184 SSVAL(req->outbuf,smb_vwv3,dfree);
1186 SSVAL(req->outbuf,smb_vwv0,dsize);
1187 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1188 SSVAL(req->outbuf,smb_vwv2,512);
1189 SSVAL(req->outbuf,smb_vwv3,dfree);
1192 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1194 END_PROFILE(SMBdskattr);
1198 /****************************************************************************
1200 Can be called from SMBsearch, SMBffirst or SMBfunique.
1201 ****************************************************************************/
1203 void reply_search(struct smb_request *req)
1205 connection_struct *conn = req->conn;
1207 char *directory = NULL;
1213 unsigned int numentries = 0;
1214 unsigned int maxentries = 0;
1215 bool finished = False;
1221 bool check_descend = False;
1222 bool expect_close = False;
1224 bool mask_contains_wcard = False;
1225 bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1226 TALLOC_CTX *ctx = talloc_tos();
1227 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1229 START_PROFILE(SMBsearch);
1232 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1233 END_PROFILE(SMBsearch);
1237 if (lp_posix_pathnames()) {
1238 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1239 END_PROFILE(SMBsearch);
1243 /* If we were called as SMBffirst then we must expect close. */
1244 if(CVAL(req->inbuf,smb_com) == SMBffirst) {
1245 expect_close = True;
1248 reply_outbuf(req, 1, 3);
1249 maxentries = SVAL(req->inbuf,smb_vwv0);
1250 dirtype = SVAL(req->inbuf,smb_vwv1);
1251 p = smb_buf(req->inbuf) + 1;
1252 p += srvstr_get_path_wcard(ctx,
1260 &mask_contains_wcard);
1261 if (!NT_STATUS_IS_OK(nt_status)) {
1262 reply_nterror(req, nt_status);
1263 END_PROFILE(SMBsearch);
1267 nt_status = resolve_dfspath_wcard(ctx, conn,
1268 req->flags2 & FLAGS2_DFS_PATHNAMES,
1271 &mask_contains_wcard);
1272 if (!NT_STATUS_IS_OK(nt_status)) {
1273 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1274 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1275 ERRSRV, ERRbadpath);
1276 END_PROFILE(SMBsearch);
1279 reply_nterror(req, nt_status);
1280 END_PROFILE(SMBsearch);
1285 status_len = SVAL(p, 0);
1288 /* dirtype &= ~aDIR; */
1290 if (status_len == 0) {
1291 SMB_STRUCT_STAT sbuf;
1293 nt_status = unix_convert(ctx, conn, path, True,
1294 &directory, NULL, &sbuf);
1295 if (!NT_STATUS_IS_OK(nt_status)) {
1296 reply_nterror(req, nt_status);
1297 END_PROFILE(SMBsearch);
1301 nt_status = check_name(conn, directory);
1302 if (!NT_STATUS_IS_OK(nt_status)) {
1303 reply_nterror(req, nt_status);
1304 END_PROFILE(SMBsearch);
1308 p = strrchr_m(directory,'/');
1311 directory = talloc_strdup(ctx,".");
1313 reply_nterror(req, NT_STATUS_NO_MEMORY);
1314 END_PROFILE(SMBsearch);
1322 if (*directory == '\0') {
1323 directory = talloc_strdup(ctx,".");
1325 reply_nterror(req, NT_STATUS_NO_MEMORY);
1326 END_PROFILE(SMBsearch);
1330 memset((char *)status,'\0',21);
1331 SCVAL(status,0,(dirtype & 0x1F));
1333 nt_status = dptr_create(conn,
1339 mask_contains_wcard,
1342 if (!NT_STATUS_IS_OK(nt_status)) {
1343 reply_nterror(req, nt_status);
1344 END_PROFILE(SMBsearch);
1347 dptr_num = dptr_dnum(conn->dirptr);
1351 memcpy(status,p,21);
1352 status_dirtype = CVAL(status,0) & 0x1F;
1353 if (status_dirtype != (dirtype & 0x1F)) {
1354 dirtype = status_dirtype;
1357 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1358 if (!conn->dirptr) {
1361 string_set(&conn->dirpath,dptr_path(dptr_num));
1362 mask = dptr_wcard(dptr_num);
1367 * For a 'continue' search we have no string. So
1368 * check from the initial saved string.
1370 mask_contains_wcard = ms_has_wild(mask);
1371 dirtype = dptr_attr(dptr_num);
1374 DEBUG(4,("dptr_num is %d\n",dptr_num));
1376 if ((dirtype&0x1F) == aVOLID) {
1377 char buf[DIR_STRUCT_SIZE];
1378 memcpy(buf,status,21);
1379 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1380 0,aVOLID,0,!allow_long_path_components)) {
1381 reply_nterror(req, NT_STATUS_NO_MEMORY);
1382 END_PROFILE(SMBsearch);
1385 dptr_fill(buf+12,dptr_num);
1386 if (dptr_zero(buf+12) && (status_len==0)) {
1391 if (message_push_blob(&req->outbuf,
1392 data_blob_const(buf, sizeof(buf)))
1394 reply_nterror(req, NT_STATUS_NO_MEMORY);
1395 END_PROFILE(SMBsearch);
1403 ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1406 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1407 conn->dirpath,lp_dontdescend(SNUM(conn))));
1408 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) {
1409 check_descend = True;
1412 for (i=numentries;(i<maxentries) && !finished;i++) {
1413 finished = !get_dir_entry(ctx,
1424 char buf[DIR_STRUCT_SIZE];
1425 memcpy(buf,status,21);
1426 if (!make_dir_struct(ctx,
1433 !allow_long_path_components)) {
1434 reply_nterror(req, NT_STATUS_NO_MEMORY);
1435 END_PROFILE(SMBsearch);
1438 if (!dptr_fill(buf+12,dptr_num)) {
1441 if (message_push_blob(&req->outbuf,
1442 data_blob_const(buf, sizeof(buf)))
1444 reply_nterror(req, NT_STATUS_NO_MEMORY);
1445 END_PROFILE(SMBsearch);
1455 /* If we were called as SMBffirst with smb_search_id == NULL
1456 and no entries were found then return error and close dirptr
1459 if (numentries == 0) {
1460 dptr_close(&dptr_num);
1461 } else if(expect_close && status_len == 0) {
1462 /* Close the dptr - we know it's gone */
1463 dptr_close(&dptr_num);
1466 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1467 if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
1468 dptr_close(&dptr_num);
1471 if ((numentries == 0) && !mask_contains_wcard) {
1472 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1473 END_PROFILE(SMBsearch);
1477 SSVAL(req->outbuf,smb_vwv0,numentries);
1478 SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1479 SCVAL(smb_buf(req->outbuf),0,5);
1480 SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1482 /* The replies here are never long name. */
1483 SSVAL(req->outbuf, smb_flg2,
1484 SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1485 if (!allow_long_path_components) {
1486 SSVAL(req->outbuf, smb_flg2,
1487 SVAL(req->outbuf, smb_flg2)
1488 & (~FLAGS2_LONG_PATH_COMPONENTS));
1491 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1492 SSVAL(req->outbuf, smb_flg2,
1493 (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1496 directory = dptr_path(dptr_num);
1499 DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1500 smb_fn_name(CVAL(req->inbuf,smb_com)),
1502 directory ? directory : "./",
1507 END_PROFILE(SMBsearch);
1511 /****************************************************************************
1512 Reply to a fclose (stop directory search).
1513 ****************************************************************************/
1515 void reply_fclose(struct smb_request *req)
1523 bool path_contains_wcard = False;
1524 TALLOC_CTX *ctx = talloc_tos();
1526 START_PROFILE(SMBfclose);
1528 if (lp_posix_pathnames()) {
1529 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1530 END_PROFILE(SMBfclose);
1534 p = smb_buf(req->inbuf) + 1;
1535 p += srvstr_get_path_wcard(ctx,
1543 &path_contains_wcard);
1544 if (!NT_STATUS_IS_OK(err)) {
1545 reply_nterror(req, err);
1546 END_PROFILE(SMBfclose);
1550 status_len = SVAL(p,0);
1553 if (status_len == 0) {
1554 reply_doserror(req, ERRSRV, ERRsrverror);
1555 END_PROFILE(SMBfclose);
1559 memcpy(status,p,21);
1561 if(dptr_fetch(status+12,&dptr_num)) {
1562 /* Close the dptr - we know it's gone */
1563 dptr_close(&dptr_num);
1566 reply_outbuf(req, 1, 0);
1567 SSVAL(req->outbuf,smb_vwv0,0);
1569 DEBUG(3,("search close\n"));
1571 END_PROFILE(SMBfclose);
1575 /****************************************************************************
1577 ****************************************************************************/
1579 void reply_open(struct smb_request *req)
1581 connection_struct *conn = req->conn;
1587 SMB_STRUCT_STAT sbuf;
1594 uint32 create_disposition;
1595 uint32 create_options = 0;
1597 TALLOC_CTX *ctx = talloc_tos();
1599 START_PROFILE(SMBopen);
1602 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1603 END_PROFILE(SMBopen);
1607 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1608 deny_mode = SVAL(req->inbuf,smb_vwv0);
1609 dos_attr = SVAL(req->inbuf,smb_vwv1);
1611 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1612 smb_buf(req->inbuf)+1, 0,
1613 STR_TERMINATE, &status);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 reply_nterror(req, status);
1616 END_PROFILE(SMBopen);
1620 if (!map_open_params_to_ntcreate(
1621 fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
1622 &share_mode, &create_disposition, &create_options)) {
1623 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1624 END_PROFILE(SMBopen);
1628 status = create_file(conn, /* conn */
1630 0, /* root_dir_fid */
1632 access_mask, /* access_mask */
1633 share_mode, /* share_access */
1634 create_disposition, /* create_disposition*/
1635 create_options, /* create_options */
1636 dos_attr, /* file_attributes */
1637 oplock_request, /* oplock_request */
1638 0, /* allocation_size */
1645 if (!NT_STATUS_IS_OK(status)) {
1646 if (open_was_deferred(req->mid)) {
1647 /* We have re-scheduled this call. */
1648 END_PROFILE(SMBopen);
1651 reply_openerror(req, status);
1652 END_PROFILE(SMBopen);
1656 size = sbuf.st_size;
1657 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1658 mtime = sbuf.st_mtime;
1661 DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
1662 close_file(fsp,ERROR_CLOSE);
1663 reply_doserror(req, ERRDOS,ERRnoaccess);
1664 END_PROFILE(SMBopen);
1668 reply_outbuf(req, 7, 0);
1669 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1670 SSVAL(req->outbuf,smb_vwv1,fattr);
1671 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1672 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1674 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1676 SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1677 SSVAL(req->outbuf,smb_vwv6,deny_mode);
1679 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1680 SCVAL(req->outbuf,smb_flg,
1681 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1684 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1685 SCVAL(req->outbuf,smb_flg,
1686 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1688 END_PROFILE(SMBopen);
1692 /****************************************************************************
1693 Reply to an open and X.
1694 ****************************************************************************/
1696 void reply_open_and_X(struct smb_request *req)
1698 connection_struct *conn = req->conn;
1703 /* Breakout the oplock request bits so we can set the
1704 reply bits separately. */
1705 int ex_oplock_request;
1706 int core_oplock_request;
1709 int smb_sattr = SVAL(req->inbuf,smb_vwv4);
1710 uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6);
1715 SMB_STRUCT_STAT sbuf;
1719 SMB_BIG_UINT allocation_size;
1720 ssize_t retval = -1;
1723 uint32 create_disposition;
1724 uint32 create_options = 0;
1725 TALLOC_CTX *ctx = talloc_tos();
1727 START_PROFILE(SMBopenX);
1729 if (req->wct < 15) {
1730 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1731 END_PROFILE(SMBopenX);
1735 open_flags = SVAL(req->inbuf,smb_vwv2);
1736 deny_mode = SVAL(req->inbuf,smb_vwv3);
1737 smb_attr = SVAL(req->inbuf,smb_vwv5);
1738 ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1739 core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1740 oplock_request = ex_oplock_request | core_oplock_request;
1741 smb_ofun = SVAL(req->inbuf,smb_vwv8);
1742 allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv9);
1744 /* If it's an IPC, pass off the pipe handler. */
1746 if (lp_nt_pipe_support()) {
1747 reply_open_pipe_and_X(conn, req);
1749 reply_doserror(req, ERRSRV, ERRaccess);
1751 END_PROFILE(SMBopenX);
1755 /* XXXX we need to handle passed times, sattr and flags */
1756 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1757 smb_buf(req->inbuf), 0, STR_TERMINATE,
1759 if (!NT_STATUS_IS_OK(status)) {
1760 reply_nterror(req, status);
1761 END_PROFILE(SMBopenX);
1765 if (!map_open_params_to_ntcreate(
1766 fname, deny_mode, smb_ofun, &access_mask,
1767 &share_mode, &create_disposition, &create_options)) {
1768 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1769 END_PROFILE(SMBopenX);
1773 status = create_file(conn, /* conn */
1775 0, /* root_dir_fid */
1777 access_mask, /* access_mask */
1778 share_mode, /* share_access */
1779 create_disposition, /* create_disposition*/
1780 create_options, /* create_options */
1781 smb_attr, /* file_attributes */
1782 oplock_request, /* oplock_request */
1783 0, /* allocation_size */
1787 &smb_action, /* pinfo */
1790 if (!NT_STATUS_IS_OK(status)) {
1791 END_PROFILE(SMBopenX);
1792 if (open_was_deferred(req->mid)) {
1793 /* We have re-scheduled this call. */
1796 reply_openerror(req, status);
1800 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1801 if the file is truncated or created. */
1802 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1803 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1804 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1805 close_file(fsp,ERROR_CLOSE);
1806 reply_nterror(req, NT_STATUS_DISK_FULL);
1807 END_PROFILE(SMBopenX);
1810 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1812 close_file(fsp,ERROR_CLOSE);
1813 reply_nterror(req, NT_STATUS_DISK_FULL);
1814 END_PROFILE(SMBopenX);
1817 sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
1820 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1821 mtime = sbuf.st_mtime;
1823 close_file(fsp,ERROR_CLOSE);
1824 reply_doserror(req, ERRDOS, ERRnoaccess);
1825 END_PROFILE(SMBopenX);
1829 /* If the caller set the extended oplock request bit
1830 and we granted one (by whatever means) - set the
1831 correct bit for extended oplock reply.
1834 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1835 smb_action |= EXTENDED_OPLOCK_GRANTED;
1838 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1839 smb_action |= EXTENDED_OPLOCK_GRANTED;
1842 /* If the caller set the core oplock request bit
1843 and we granted one (by whatever means) - set the
1844 correct bit for core oplock reply.
1847 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1848 reply_outbuf(req, 19, 0);
1850 reply_outbuf(req, 15, 0);
1853 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1854 SCVAL(req->outbuf, smb_flg,
1855 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1858 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1859 SCVAL(req->outbuf, smb_flg,
1860 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1863 SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
1864 SSVAL(req->outbuf,smb_vwv3,fattr);
1865 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1866 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
1868 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
1870 SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size);
1871 SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
1872 SSVAL(req->outbuf,smb_vwv11,smb_action);
1874 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1875 SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
1878 END_PROFILE(SMBopenX);
1883 /****************************************************************************
1884 Reply to a SMBulogoffX.
1885 ****************************************************************************/
1887 void reply_ulogoffX(struct smb_request *req)
1891 START_PROFILE(SMBulogoffX);
1893 vuser = get_valid_user_struct(req->vuid);
1896 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
1900 /* in user level security we are supposed to close any files
1901 open by this user */
1902 if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
1903 file_close_user(req->vuid);
1906 invalidate_vuid(req->vuid);
1908 reply_outbuf(req, 2, 0);
1910 DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
1912 END_PROFILE(SMBulogoffX);
1916 /****************************************************************************
1917 Reply to a mknew or a create.
1918 ****************************************************************************/
1920 void reply_mknew(struct smb_request *req)
1922 connection_struct *conn = req->conn;
1926 struct timespec ts[2];
1928 int oplock_request = 0;
1929 SMB_STRUCT_STAT sbuf;
1931 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
1932 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1933 uint32 create_disposition;
1934 uint32 create_options = 0;
1935 TALLOC_CTX *ctx = talloc_tos();
1937 START_PROFILE(SMBcreate);
1940 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1941 END_PROFILE(SMBcreate);
1945 fattr = SVAL(req->inbuf,smb_vwv0);
1946 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1947 com = SVAL(req->inbuf,smb_com);
1949 ts[1] =convert_time_t_to_timespec(
1950 srv_make_unix_date3(req->inbuf + smb_vwv1));
1953 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1954 smb_buf(req->inbuf) + 1, 0,
1955 STR_TERMINATE, &status);
1956 if (!NT_STATUS_IS_OK(status)) {
1957 reply_nterror(req, status);
1958 END_PROFILE(SMBcreate);
1962 if (fattr & aVOLID) {
1963 DEBUG(0,("Attempt to create file (%s) with volid set - "
1964 "please report this\n", fname));
1967 if(com == SMBmknew) {
1968 /* We should fail if file exists. */
1969 create_disposition = FILE_CREATE;
1971 /* Create if file doesn't exist, truncate if it does. */
1972 create_disposition = FILE_OVERWRITE_IF;
1975 status = create_file(conn, /* conn */
1977 0, /* root_dir_fid */
1979 access_mask, /* access_mask */
1980 share_mode, /* share_access */
1981 create_disposition, /* create_disposition*/
1982 create_options, /* create_options */
1983 fattr, /* file_attributes */
1984 oplock_request, /* oplock_request */
1985 0, /* allocation_size */
1992 if (!NT_STATUS_IS_OK(status)) {
1993 END_PROFILE(SMBcreate);
1994 if (open_was_deferred(req->mid)) {
1995 /* We have re-scheduled this call. */
1998 reply_openerror(req, status);
2002 ts[0] = get_atimespec(&sbuf); /* atime. */
2003 status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true);
2004 if (!NT_STATUS_IS_OK(status)) {
2005 END_PROFILE(SMBcreate);
2006 reply_openerror(req, status);
2010 reply_outbuf(req, 1, 0);
2011 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2013 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2014 SCVAL(req->outbuf,smb_flg,
2015 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2018 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2019 SCVAL(req->outbuf,smb_flg,
2020 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2023 DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) );
2024 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
2025 fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
2027 END_PROFILE(SMBcreate);
2031 /****************************************************************************
2032 Reply to a create temporary file.
2033 ****************************************************************************/
2035 void reply_ctemp(struct smb_request *req)
2037 connection_struct *conn = req->conn;
2043 SMB_STRUCT_STAT sbuf;
2046 TALLOC_CTX *ctx = talloc_tos();
2048 START_PROFILE(SMBctemp);
2051 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2052 END_PROFILE(SMBctemp);
2056 fattr = SVAL(req->inbuf,smb_vwv0);
2057 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2059 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
2060 smb_buf(req->inbuf)+1, 0, STR_TERMINATE,
2062 if (!NT_STATUS_IS_OK(status)) {
2063 reply_nterror(req, status);
2064 END_PROFILE(SMBctemp);
2068 fname = talloc_asprintf(ctx,
2072 fname = talloc_strdup(ctx, "TMXXXXXX");
2076 reply_nterror(req, NT_STATUS_NO_MEMORY);
2077 END_PROFILE(SMBctemp);
2081 status = resolve_dfspath(ctx, conn,
2082 req->flags2 & FLAGS2_DFS_PATHNAMES,
2085 if (!NT_STATUS_IS_OK(status)) {
2086 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2087 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2088 ERRSRV, ERRbadpath);
2089 END_PROFILE(SMBctemp);
2092 reply_nterror(req, status);
2093 END_PROFILE(SMBctemp);
2097 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
2098 if (!NT_STATUS_IS_OK(status)) {
2099 reply_nterror(req, status);
2100 END_PROFILE(SMBctemp);
2104 status = check_name(conn, CONST_DISCARD(char *,fname));
2105 if (!NT_STATUS_IS_OK(status)) {
2106 reply_nterror(req, status);
2107 END_PROFILE(SMBctemp);
2111 tmpfd = smb_mkstemp(fname);
2113 reply_unixerror(req, ERRDOS, ERRnoaccess);
2114 END_PROFILE(SMBctemp);
2118 SMB_VFS_STAT(conn,fname,&sbuf);
2120 /* We should fail if file does not exist. */
2121 status = open_file_ntcreate(conn, req, fname, &sbuf,
2122 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
2123 FILE_SHARE_READ|FILE_SHARE_WRITE,
2130 /* close fd from smb_mkstemp() */
2133 if (!NT_STATUS_IS_OK(status)) {
2134 if (open_was_deferred(req->mid)) {
2135 /* We have re-scheduled this call. */
2136 END_PROFILE(SMBctemp);
2139 reply_openerror(req, status);
2140 END_PROFILE(SMBctemp);
2144 reply_outbuf(req, 1, 0);
2145 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2147 /* the returned filename is relative to the directory */
2148 s = strrchr_m(fsp->fsp_name, '/');
2156 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2157 thing in the byte section. JRA */
2158 SSVALS(p, 0, -1); /* what is this? not in spec */
2160 if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2162 reply_nterror(req, NT_STATUS_NO_MEMORY);
2163 END_PROFILE(SMBctemp);
2167 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2168 SCVAL(req->outbuf, smb_flg,
2169 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2172 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2173 SCVAL(req->outbuf, smb_flg,
2174 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2177 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
2178 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
2179 fsp->fh->fd, (unsigned int)sbuf.st_mode ) );
2181 END_PROFILE(SMBctemp);
2185 /*******************************************************************
2186 Check if a user is allowed to rename a file.
2187 ********************************************************************/
2189 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2190 uint16 dirtype, SMB_STRUCT_STAT *pst)
2194 if (!CAN_WRITE(conn)) {
2195 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2198 fmode = dos_mode(conn, fsp->fsp_name, pst);
2199 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
2200 return NT_STATUS_NO_SUCH_FILE;
2203 if (S_ISDIR(pst->st_mode)) {
2204 return NT_STATUS_OK;
2207 if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
2208 return NT_STATUS_OK;
2211 return NT_STATUS_ACCESS_DENIED;
2214 /*******************************************************************
2215 * unlink a file with all relevant access checks
2216 *******************************************************************/
2218 static NTSTATUS do_unlink(connection_struct *conn,
2219 struct smb_request *req,
2223 SMB_STRUCT_STAT sbuf;
2226 uint32 dirtype_orig = dirtype;
2229 DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
2231 if (!CAN_WRITE(conn)) {
2232 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2235 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
2236 return map_nt_error_from_unix(errno);
2239 fattr = dos_mode(conn,fname,&sbuf);
2241 if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2242 dirtype = aDIR|aARCH|aRONLY;
2245 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
2247 return NT_STATUS_NO_SUCH_FILE;
2250 if (!dir_check_ftype(conn, fattr, dirtype)) {
2252 return NT_STATUS_FILE_IS_A_DIRECTORY;
2254 return NT_STATUS_NO_SUCH_FILE;
2257 if (dirtype_orig & 0x8000) {
2258 /* These will never be set for POSIX. */
2259 return NT_STATUS_NO_SUCH_FILE;
2263 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2264 return NT_STATUS_FILE_IS_A_DIRECTORY;
2267 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2268 return NT_STATUS_NO_SUCH_FILE;
2271 if (dirtype & 0xFF00) {
2272 /* These will never be set for POSIX. */
2273 return NT_STATUS_NO_SUCH_FILE;
2278 return NT_STATUS_NO_SUCH_FILE;
2281 /* Can't delete a directory. */
2283 return NT_STATUS_FILE_IS_A_DIRECTORY;
2288 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
2289 return NT_STATUS_OBJECT_NAME_INVALID;
2290 #endif /* JRATEST */
2292 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
2294 On a Windows share, a file with read-only dosmode can be opened with
2295 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
2296 fails with NT_STATUS_CANNOT_DELETE error.
2298 This semantic causes a problem that a user can not
2299 rename a file with read-only dosmode on a Samba share
2300 from a Windows command prompt (i.e. cmd.exe, but can rename
2301 from Windows Explorer).
2304 if (!lp_delete_readonly(SNUM(conn))) {
2305 if (fattr & aRONLY) {
2306 return NT_STATUS_CANNOT_DELETE;
2310 /* On open checks the open itself will check the share mode, so
2311 don't do it here as we'll get it wrong. */
2313 status = create_file_unixpath
2317 DELETE_ACCESS, /* access_mask */
2318 FILE_SHARE_NONE, /* share_access */
2319 FILE_OPEN, /* create_disposition*/
2320 FILE_NON_DIRECTORY_FILE, /* create_options */
2321 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2322 0, /* oplock_request */
2323 0, /* allocation_size */
2330 if (!NT_STATUS_IS_OK(status)) {
2331 DEBUG(10, ("open_file_ntcreate failed: %s\n",
2332 nt_errstr(status)));
2336 /* The set is across all open files on this dev/inode pair. */
2337 if (!set_delete_on_close(fsp, True, ¤t_user.ut)) {
2338 close_file(fsp, NORMAL_CLOSE);
2339 return NT_STATUS_ACCESS_DENIED;
2342 return close_file(fsp,NORMAL_CLOSE);
2345 /****************************************************************************
2346 The guts of the unlink command, split out so it may be called by the NT SMB
2348 ****************************************************************************/
2350 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2351 uint32 dirtype, const char *name_in, bool has_wild)
2353 const char *directory = NULL;
2358 NTSTATUS status = NT_STATUS_OK;
2359 SMB_STRUCT_STAT sbuf;
2360 TALLOC_CTX *ctx = talloc_tos();
2362 status = unix_convert(ctx, conn, name_in, has_wild, &name, NULL, &sbuf);
2363 if (!NT_STATUS_IS_OK(status)) {
2367 p = strrchr_m(name,'/');
2369 directory = talloc_strdup(ctx, ".");
2371 return NT_STATUS_NO_MEMORY;
2381 * We should only check the mangled cache
2382 * here if unix_convert failed. This means
2383 * that the path in 'mask' doesn't exist
2384 * on the file system and so we need to look
2385 * for a possible mangle. This patch from
2386 * Tine Smukavec <valentin.smukavec@hermes.si>.
2389 if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) {
2390 char *new_mask = NULL;
2391 mangle_lookup_name_from_8_3(ctx,
2401 directory = talloc_asprintf(ctx,
2406 return NT_STATUS_NO_MEMORY;
2409 dirtype = FILE_ATTRIBUTE_NORMAL;
2412 status = check_name(conn, directory);
2413 if (!NT_STATUS_IS_OK(status)) {
2417 status = do_unlink(conn, req, directory, dirtype);
2418 if (!NT_STATUS_IS_OK(status)) {
2424 struct smb_Dir *dir_hnd = NULL;
2428 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2429 return NT_STATUS_OBJECT_NAME_INVALID;
2432 if (strequal(mask,"????????.???")) {
2437 status = check_name(conn, directory);
2438 if (!NT_STATUS_IS_OK(status)) {
2442 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask,
2444 if (dir_hnd == NULL) {
2445 return map_nt_error_from_unix(errno);
2448 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2449 the pattern matches against the long name, otherwise the short name
2450 We don't implement this yet XXXX
2453 status = NT_STATUS_NO_SUCH_FILE;
2455 while ((dname = ReadDirName(dir_hnd, &offset))) {
2459 if (!is_visible_file(conn, directory, dname, &st, True)) {
2463 /* Quick check for "." and ".." */
2464 if (ISDOT(dname) || ISDOTDOT(dname)) {
2468 if(!mask_match(dname, mask, conn->case_sensitive)) {
2472 fname = talloc_asprintf(ctx, "%s/%s",
2476 return NT_STATUS_NO_MEMORY;
2479 status = check_name(conn, fname);
2480 if (!NT_STATUS_IS_OK(status)) {
2481 TALLOC_FREE(dir_hnd);
2485 status = do_unlink(conn, req, fname, dirtype);
2486 if (!NT_STATUS_IS_OK(status)) {
2492 DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2497 TALLOC_FREE(dir_hnd);
2500 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
2501 status = map_nt_error_from_unix(errno);
2507 /****************************************************************************
2509 ****************************************************************************/
2511 void reply_unlink(struct smb_request *req)
2513 connection_struct *conn = req->conn;
2517 bool path_contains_wcard = False;
2518 TALLOC_CTX *ctx = talloc_tos();
2520 START_PROFILE(SMBunlink);
2523 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2524 END_PROFILE(SMBunlink);
2528 dirtype = SVAL(req->inbuf,smb_vwv0);
2530 srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
2531 smb_buf(req->inbuf) + 1, 0,
2532 STR_TERMINATE, &status, &path_contains_wcard);
2533 if (!NT_STATUS_IS_OK(status)) {
2534 reply_nterror(req, status);
2535 END_PROFILE(SMBunlink);
2539 status = resolve_dfspath_wcard(ctx, conn,
2540 req->flags2 & FLAGS2_DFS_PATHNAMES,
2543 &path_contains_wcard);
2544 if (!NT_STATUS_IS_OK(status)) {
2545 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2546 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2547 ERRSRV, ERRbadpath);
2548 END_PROFILE(SMBunlink);
2551 reply_nterror(req, status);
2552 END_PROFILE(SMBunlink);
2556 DEBUG(3,("reply_unlink : %s\n",name));
2558 status = unlink_internals(conn, req, dirtype, name,
2559 path_contains_wcard);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 if (open_was_deferred(req->mid)) {
2562 /* We have re-scheduled this call. */
2563 END_PROFILE(SMBunlink);
2566 reply_nterror(req, status);
2567 END_PROFILE(SMBunlink);
2571 reply_outbuf(req, 0, 0);
2572 END_PROFILE(SMBunlink);
2577 /****************************************************************************
2579 ****************************************************************************/
2581 static void fail_readraw(void)
2583 const char *errstr = talloc_asprintf(talloc_tos(),
2584 "FAIL ! reply_readbraw: socket write fail (%s)",
2589 exit_server_cleanly(errstr);
2592 /****************************************************************************
2593 Fake (read/write) sendfile. Returns -1 on read or write fail.
2594 ****************************************************************************/
2596 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
2600 size_t tosend = nread;
2607 bufsize = MIN(nread, 65536);
2609 if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2613 while (tosend > 0) {
2617 if (tosend > bufsize) {
2622 ret = read_file(fsp,buf,startpos,cur_read);
2628 /* If we had a short read, fill with zeros. */
2629 if (ret < cur_read) {
2630 memset(buf, '\0', cur_read - ret);
2633 if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
2638 startpos += cur_read;
2642 return (ssize_t)nread;
2645 /****************************************************************************
2646 Return a readbraw error (4 bytes of zero).
2647 ****************************************************************************/
2649 static void reply_readbraw_error(void)
2653 if (write_data(smbd_server_fd(),header,4) != 4) {
2658 /****************************************************************************
2659 Use sendfile in readbraw.
2660 ****************************************************************************/
2662 void send_file_readbraw(connection_struct *conn,
2668 char *outbuf = NULL;
2671 #if defined(WITH_SENDFILE)
2673 * We can only use sendfile on a non-chained packet
2674 * but we can use on a non-oplocked file. tridge proved this
2675 * on a train in Germany :-). JRA.
2676 * reply_readbraw has already checked the length.
2679 if ( (chain_size == 0) && (nread > 0) && (fsp->base_fsp == NULL) &&
2680 (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
2682 DATA_BLOB header_blob;
2684 _smb_setlen(header,nread);
2685 header_blob = data_blob_const(header, 4);
2687 if (SMB_VFS_SENDFILE(smbd_server_fd(), fsp,
2688 &header_blob, startpos, nread) == -1) {
2689 /* Returning ENOSYS means no data at all was sent.
2690 * Do this as a normal read. */
2691 if (errno == ENOSYS) {
2692 goto normal_readbraw;
2696 * Special hack for broken Linux with no working sendfile. If we
2697 * return EINTR we sent the header but not the rest of the data.
2698 * Fake this up by doing read/write calls.
2700 if (errno == EINTR) {
2701 /* Ensure we don't do this again. */
2702 set_use_sendfile(SNUM(conn), False);
2703 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2705 if (fake_sendfile(fsp, startpos, nread) == -1) {
2706 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2707 fsp->fsp_name, strerror(errno) ));
2708 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2713 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2714 fsp->fsp_name, strerror(errno) ));
2715 exit_server_cleanly("send_file_readbraw sendfile failed");
2724 outbuf = TALLOC_ARRAY(NULL, char, nread+4);
2726 DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
2727 (unsigned)(nread+4)));
2728 reply_readbraw_error();
2733 ret = read_file(fsp,outbuf+4,startpos,nread);
2734 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2743 _smb_setlen(outbuf,ret);
2744 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2747 TALLOC_FREE(outbuf);
2750 /****************************************************************************
2751 Reply to a readbraw (core+ protocol).
2752 ****************************************************************************/
2754 void reply_readbraw(struct smb_request *req)
2756 connection_struct *conn = req->conn;
2757 ssize_t maxcount,mincount;
2764 START_PROFILE(SMBreadbraw);
2766 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
2767 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
2768 "raw reads/writes are disallowed.");
2772 reply_readbraw_error();
2773 END_PROFILE(SMBreadbraw);
2778 * Special check if an oplock break has been issued
2779 * and the readraw request croses on the wire, we must
2780 * return a zero length response here.
2783 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
2786 * We have to do a check_fsp by hand here, as
2787 * we must always return 4 zero bytes on error,
2791 if (!fsp || !conn || conn != fsp->conn ||
2792 current_user.vuid != fsp->vuid ||
2793 fsp->is_directory || fsp->fh->fd == -1) {
2795 * fsp could be NULL here so use the value from the packet. JRA.
2797 DEBUG(3,("reply_readbraw: fnum %d not valid "
2799 (int)SVAL(req->inbuf,smb_vwv0)));
2800 reply_readbraw_error();
2801 END_PROFILE(SMBreadbraw);
2805 /* Do a "by hand" version of CHECK_READ. */
2806 if (!(fsp->can_read ||
2807 ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
2808 (fsp->access_mask & FILE_EXECUTE)))) {
2809 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
2810 (int)SVAL(req->inbuf,smb_vwv0)));
2811 reply_readbraw_error();
2812 END_PROFILE(SMBreadbraw);
2816 flush_write_cache(fsp, READRAW_FLUSH);
2818 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
2819 if(req->wct == 10) {
2821 * This is a large offset (64 bit) read.
2823 #ifdef LARGE_SMB_OFF_T
2825 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
2827 #else /* !LARGE_SMB_OFF_T */
2830 * Ensure we haven't been sent a >32 bit offset.
2833 if(IVAL(req->inbuf,smb_vwv8) != 0) {
2834 DEBUG(0,("reply_readbraw: large offset "
2835 "(%x << 32) used and we don't support "
2836 "64 bit offsets.\n",
2837 (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
2838 reply_readbraw_error();
2839 END_PROFILE(SMBreadbraw);
2843 #endif /* LARGE_SMB_OFF_T */
2846 DEBUG(0,("reply_readbraw: negative 64 bit "
2847 "readraw offset (%.0f) !\n",
2848 (double)startpos ));
2849 reply_readbraw_error();
2850 END_PROFILE(SMBreadbraw);
2855 maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
2856 mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
2858 /* ensure we don't overrun the packet size */
2859 maxcount = MIN(65535,maxcount);
2861 if (is_locked(fsp,(uint32)req->smbpid,
2862 (SMB_BIG_UINT)maxcount,
2863 (SMB_BIG_UINT)startpos,
2865 reply_readbraw_error();
2866 END_PROFILE(SMBreadbraw);
2870 if (SMB_VFS_FSTAT(fsp, &st) == 0) {
2874 if (startpos >= size) {
2877 nread = MIN(maxcount,(size - startpos));
2880 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2881 if (nread < mincount)
2885 DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
2886 "min=%lu nread=%lu\n",
2887 fsp->fnum, (double)startpos,
2888 (unsigned long)maxcount,
2889 (unsigned long)mincount,
2890 (unsigned long)nread ) );
2892 send_file_readbraw(conn, fsp, startpos, nread, mincount);
2894 DEBUG(5,("reply_readbraw finished\n"));
2895 END_PROFILE(SMBreadbraw);
2899 #define DBGC_CLASS DBGC_LOCKING
2901 /****************************************************************************
2902 Reply to a lockread (core+ protocol).
2903 ****************************************************************************/
2905 void reply_lockread(struct smb_request *req)
2907 connection_struct *conn = req->conn;
2914 struct byte_range_lock *br_lck = NULL;
2917 START_PROFILE(SMBlockread);
2920 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2921 END_PROFILE(SMBlockread);
2925 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
2927 if (!check_fsp(conn, req, fsp, ¤t_user)) {
2928 END_PROFILE(SMBlockread);
2932 if (!CHECK_READ(fsp,req->inbuf)) {
2933 reply_doserror(req, ERRDOS, ERRbadaccess);
2934 END_PROFILE(SMBlockread);
2938 release_level_2_oplocks_on_change(fsp);
2940 numtoread = SVAL(req->inbuf,smb_vwv1);
2941 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
2943 numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
2945 reply_outbuf(req, 5, numtoread + 3);
2947 data = smb_buf(req->outbuf) + 3;
2950 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2951 * protocol request that predates the read/write lock concept.
2952 * Thus instead of asking for a read lock here we need to ask
2953 * for a write lock. JRA.
2954 * Note that the requested lock size is unaffected by max_recv.
2957 br_lck = do_lock(smbd_messaging_context(),
2960 (SMB_BIG_UINT)numtoread,
2961 (SMB_BIG_UINT)startpos,
2964 False, /* Non-blocking lock. */
2967 TALLOC_FREE(br_lck);
2969 if (NT_STATUS_V(status)) {
2970 reply_nterror(req, status);
2971 END_PROFILE(SMBlockread);
2976 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
2979 if (numtoread > max_recv) {
2980 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
2981 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2982 (unsigned int)numtoread, (unsigned int)max_recv ));
2983 numtoread = MIN(numtoread,max_recv);
2985 nread = read_file(fsp,data,startpos,numtoread);
2988 reply_unixerror(req, ERRDOS, ERRnoaccess);
2989 END_PROFILE(SMBlockread);
2993 srv_set_message((char *)req->outbuf, 5, nread+3, False);
2995 SSVAL(req->outbuf,smb_vwv0,nread);
2996 SSVAL(req->outbuf,smb_vwv5,nread+3);
2997 p = smb_buf(req->outbuf);
2998 SCVAL(p,0,0); /* pad byte. */
3001 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
3002 fsp->fnum, (int)numtoread, (int)nread));
3004 END_PROFILE(SMBlockread);
3009 #define DBGC_CLASS DBGC_ALL
3011 /****************************************************************************
3013 ****************************************************************************/
3015 void reply_read(struct smb_request *req)
3017 connection_struct *conn = req->conn;
3025 START_PROFILE(SMBread);
3028 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3029 END_PROFILE(SMBread);
3033 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3035 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3036 END_PROFILE(SMBread);
3040 if (!CHECK_READ(fsp,req->inbuf)) {
3041 reply_doserror(req, ERRDOS, ERRbadaccess);
3042 END_PROFILE(SMBread);
3046 numtoread = SVAL(req->inbuf,smb_vwv1);
3047 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3049 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
3052 * The requested read size cannot be greater than max_recv. JRA.
3054 if (numtoread > max_recv) {
3055 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
3056 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3057 (unsigned int)numtoread, (unsigned int)max_recv ));
3058 numtoread = MIN(numtoread,max_recv);
3061 reply_outbuf(req, 5, numtoread+3);
3063 data = smb_buf(req->outbuf) + 3;
3065 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtoread,
3066 (SMB_BIG_UINT)startpos, READ_LOCK)) {
3067 reply_doserror(req, ERRDOS,ERRlock);
3068 END_PROFILE(SMBread);
3073 nread = read_file(fsp,data,startpos,numtoread);
3076 reply_unixerror(req, ERRDOS,ERRnoaccess);
3077 END_PROFILE(SMBread);
3081 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3083 SSVAL(req->outbuf,smb_vwv0,nread);
3084 SSVAL(req->outbuf,smb_vwv5,nread+3);
3085 SCVAL(smb_buf(req->outbuf),0,1);
3086 SSVAL(smb_buf(req->outbuf),1,nread);
3088 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
3089 fsp->fnum, (int)numtoread, (int)nread ) );
3091 END_PROFILE(SMBread);
3095 /****************************************************************************
3097 ****************************************************************************/
3099 static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
3104 outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
3105 data = smb_buf(outbuf);
3107 memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
3109 SCVAL(outbuf,smb_vwv0,0xFF);
3110 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
3111 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
3112 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
3113 SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
3114 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
3115 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
3116 _smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
3120 /****************************************************************************
3121 Reply to a read and X - possibly using sendfile.
3122 ****************************************************************************/
3124 static void send_file_readX(connection_struct *conn, struct smb_request *req,
3125 files_struct *fsp, SMB_OFF_T startpos,
3128 SMB_STRUCT_STAT sbuf;
3131 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
3132 reply_unixerror(req, ERRDOS, ERRnoaccess);
3136 if (startpos > sbuf.st_size) {
3138 } else if (smb_maxcnt > (sbuf.st_size - startpos)) {
3139 smb_maxcnt = (sbuf.st_size - startpos);
3142 if (smb_maxcnt == 0) {
3146 #if defined(WITH_SENDFILE)
3148 * We can only use sendfile on a non-chained packet
3149 * but we can use on a non-oplocked file. tridge proved this
3150 * on a train in Germany :-). JRA.
3153 if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
3154 !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
3155 lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
3156 uint8 headerbuf[smb_size + 12 * 2];
3160 * Set up the packet header before send. We
3161 * assume here the sendfile will work (get the
3162 * correct amount of data).
3165 header = data_blob_const(headerbuf, sizeof(headerbuf));
3167 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3168 setup_readX_header((char *)headerbuf, smb_maxcnt);
3170 if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
3171 /* Returning ENOSYS or EINVAL means no data at all was sent.
3172 Do this as a normal read. */
3173 if (errno == ENOSYS || errno == EINVAL) {
3178 * Special hack for broken Linux with no working sendfile. If we
3179 * return EINTR we sent the header but not the rest of the data.
3180 * Fake this up by doing read/write calls.
3183 if (errno == EINTR) {
3184 /* Ensure we don't do this again. */
3185 set_use_sendfile(SNUM(conn), False);
3186 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
3187 nread = fake_sendfile(fsp, startpos,
3190 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3191 fsp->fsp_name, strerror(errno) ));
3192 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3194 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
3195 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3196 /* No outbuf here means successful sendfile. */
3197 TALLOC_FREE(req->outbuf);
3201 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
3202 fsp->fsp_name, strerror(errno) ));
3203 exit_server_cleanly("send_file_readX sendfile failed");
3206 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
3207 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3208 /* No outbuf here means successful sendfile. */
3209 TALLOC_FREE(req->outbuf);
3216 if ((smb_maxcnt & 0xFF0000) > 0x10000) {
3217 uint8 headerbuf[smb_size + 2*12];
3219 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3220 setup_readX_header((char *)headerbuf, smb_maxcnt);
3222 /* Send out the header. */
3223 if (write_data(smbd_server_fd(), (char *)headerbuf,
3224 sizeof(headerbuf)) != sizeof(headerbuf)) {
3225 DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
3226 fsp->fsp_name, strerror(errno) ));
3227 exit_server_cleanly("send_file_readX sendfile failed");
3229 nread = fake_sendfile(fsp, startpos, smb_maxcnt);
3231 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3232 fsp->fsp_name, strerror(errno) ));
3233 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3235 TALLOC_FREE(req->outbuf);
3238 reply_outbuf(req, 12, smb_maxcnt);
3240 nread = read_file(fsp, smb_buf(req->outbuf), startpos,
3243 reply_unixerror(req, ERRDOS, ERRnoaccess);
3247 setup_readX_header((char *)req->outbuf, nread);
3249 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
3250 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3258 /****************************************************************************
3259 Reply to a read and X.
3260 ****************************************************************************/
3262 void reply_read_and_X(struct smb_request *req)
3264 connection_struct *conn = req->conn;
3268 bool big_readX = False;
3270 size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
3273 START_PROFILE(SMBreadX);
3275 if ((req->wct != 10) && (req->wct != 12)) {
3276 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3280 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
3281 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3282 smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
3284 /* If it's an IPC, pass off the pipe handler. */
3286 reply_pipe_read_and_X(req);
3287 END_PROFILE(SMBreadX);
3291 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3292 END_PROFILE(SMBreadX);
3296 if (!CHECK_READ(fsp,req->inbuf)) {
3297 reply_doserror(req, ERRDOS,ERRbadaccess);
3298 END_PROFILE(SMBreadX);
3302 if (global_client_caps & CAP_LARGE_READX) {
3303 size_t upper_size = SVAL(req->inbuf,smb_vwv7);
3304 smb_maxcnt |= (upper_size<<16);
3305 if (upper_size > 1) {
3306 /* Can't do this on a chained packet. */
3307 if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) {
3308 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3309 END_PROFILE(SMBreadX);
3312 /* We currently don't do this on signed or sealed data. */
3313 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
3314 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3315 END_PROFILE(SMBreadX);
3318 /* Is there room in the reply for this data ? */
3319 if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
3321 NT_STATUS_INVALID_PARAMETER);
3322 END_PROFILE(SMBreadX);
3329 if (req->wct == 12) {
3330 #ifdef LARGE_SMB_OFF_T
3332 * This is a large offset (64 bit) read.
3334 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32);
3336 #else /* !LARGE_SMB_OFF_T */
3339 * Ensure we haven't been sent a >32 bit offset.
3342 if(IVAL(req->inbuf,smb_vwv10) != 0) {
3343 DEBUG(0,("reply_read_and_X - large offset (%x << 32) "
3344 "used and we don't support 64 bit offsets.\n",
3345 (unsigned int)IVAL(req->inbuf,smb_vwv10) ));
3346 END_PROFILE(SMBreadX);
3347 reply_doserror(req, ERRDOS, ERRbadaccess);
3351 #endif /* LARGE_SMB_OFF_T */
3355 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)smb_maxcnt,
3356 (SMB_BIG_UINT)startpos, READ_LOCK)) {
3357 END_PROFILE(SMBreadX);
3358 reply_doserror(req, ERRDOS, ERRlock);
3363 schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
3364 END_PROFILE(SMBreadX);
3368 send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
3370 END_PROFILE(SMBreadX);
3374 /****************************************************************************
3375 Error replies to writebraw must have smb_wct == 1. Fix this up.
3376 ****************************************************************************/
3378 void error_to_writebrawerr(struct smb_request *req)
3380 uint8 *old_outbuf = req->outbuf;
3382 reply_outbuf(req, 1, 0);
3384 memcpy(req->outbuf, old_outbuf, smb_size);
3385 TALLOC_FREE(old_outbuf);
3388 /****************************************************************************
3389 Reply to a writebraw (core+ or LANMAN1.0 protocol).
3390 ****************************************************************************/
3392 void reply_writebraw(struct smb_request *req)
3394 connection_struct *conn = req->conn;
3397 ssize_t total_written=0;
3398 size_t numtowrite=0;
3406 START_PROFILE(SMBwritebraw);
3409 * If we ever reply with an error, it must have the SMB command
3410 * type of SMBwritec, not SMBwriteBraw, as this tells the client
3413 SCVAL(req->inbuf,smb_com,SMBwritec);
3415 if (srv_is_signing_active()) {
3416 END_PROFILE(SMBwritebraw);
3417 exit_server_cleanly("reply_writebraw: SMB signing is active - "
3418 "raw reads/writes are disallowed.");
3421 if (req->wct < 12) {
3422 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3423 error_to_writebrawerr(req);
3424 END_PROFILE(SMBwritebraw);
3428 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3429 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3430 error_to_writebrawerr(req);
3431 END_PROFILE(SMBwritebraw);
3435 if (!CHECK_WRITE(fsp)) {
3436 reply_doserror(req, ERRDOS, ERRbadaccess);
3437 error_to_writebrawerr(req);
3438 END_PROFILE(SMBwritebraw);
3442 tcount = IVAL(req->inbuf,smb_vwv1);
3443 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3444 write_through = BITSETW(req->inbuf+smb_vwv7,0);
3446 /* We have to deal with slightly different formats depending
3447 on whether we are using the core+ or lanman1.0 protocol */
3449 if(Protocol <= PROTOCOL_COREPLUS) {
3450 numtowrite = SVAL(smb_buf(req->inbuf),-2);
3451 data = smb_buf(req->inbuf);
3453 numtowrite = SVAL(req->inbuf,smb_vwv10);
3454 data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11);
3457 /* Ensure we don't write bytes past the end of this packet. */
3458 if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) {
3459 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3460 error_to_writebrawerr(req);
3461 END_PROFILE(SMBwritebraw);
3465 if (is_locked(fsp,(uint32)req->smbpid,(SMB_BIG_UINT)tcount,
3466 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3467 reply_doserror(req, ERRDOS, ERRlock);
3468 error_to_writebrawerr(req);
3469 END_PROFILE(SMBwritebraw);
3474 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3477 DEBUG(3,("reply_writebraw: initial write fnum=%d start=%.0f num=%d "
3478 "wrote=%d sync=%d\n",
3479 fsp->fnum, (double)startpos, (int)numtowrite,
3480 (int)nwritten, (int)write_through));
3482 if (nwritten < (ssize_t)numtowrite) {
3483 reply_unixerror(req, ERRHRD, ERRdiskfull);
3484 error_to_writebrawerr(req);
3485 END_PROFILE(SMBwritebraw);
3489 total_written = nwritten;
3491 /* Allocate a buffer of 64k + length. */
3492 buf = TALLOC_ARRAY(NULL, char, 65540);
3494 reply_doserror(req, ERRDOS, ERRnomem);
3495 error_to_writebrawerr(req);
3496 END_PROFILE(SMBwritebraw);
3500 /* Return a SMBwritebraw message to the redirector to tell
3501 * it to send more bytes */
3503 memcpy(buf, req->inbuf, smb_size);
3504 srv_set_message(buf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
3505 SCVAL(buf,smb_com,SMBwritebraw);
3506 SSVALS(buf,smb_vwv0,0xFFFF);
3508 if (!srv_send_smb(smbd_server_fd(),
3510 IS_CONN_ENCRYPTED(conn))) {
3511 exit_server_cleanly("reply_writebraw: srv_send_smb "
3515 /* Now read the raw data into the buffer and write it */
3516 status = read_smb_length(smbd_server_fd(), buf, SMB_SECONDARY_WAIT,
3518 if (!NT_STATUS_IS_OK(status)) {
3519 exit_server_cleanly("secondary writebraw failed");
3522 /* Set up outbuf to return the correct size */
3523 reply_outbuf(req, 1, 0);
3525 if (numtowrite != 0) {
3527 if (numtowrite > 0xFFFF) {
3528 DEBUG(0,("reply_writebraw: Oversize secondary write "
3529 "raw requested (%u). Terminating\n",
3530 (unsigned int)numtowrite ));
3531 exit_server_cleanly("secondary writebraw failed");
3534 if (tcount > nwritten+numtowrite) {
3535 DEBUG(3,("reply_writebraw: Client overestimated the "
3537 (int)tcount,(int)nwritten,(int)numtowrite));
3540 status = read_data(smbd_server_fd(), buf+4, numtowrite);
3542 if (!NT_STATUS_IS_OK(status)) {
3543 DEBUG(0,("reply_writebraw: Oversize secondary write "
3544 "raw read failed (%s). Terminating\n",
3545 nt_errstr(status)));
3546 exit_server_cleanly("secondary writebraw failed");
3549 nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
3550 if (nwritten == -1) {
3552 reply_unixerror(req, ERRHRD, ERRdiskfull);
3553 error_to_writebrawerr(req);
3554 END_PROFILE(SMBwritebraw);
3558 if (nwritten < (ssize_t)numtowrite) {
3559 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3560 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3564 total_written += nwritten;
3569 SSVAL(req->outbuf,smb_vwv0,total_written);
3571 status = sync_file(conn, fsp, write_through);
3572 if (!NT_STATUS_IS_OK(status)) {
3573 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
3574 fsp->fsp_name, nt_errstr(status) ));
3575 reply_nterror(req, status);
3576 error_to_writebrawerr(req);
3577 END_PROFILE(SMBwritebraw);
3581 DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
3583 fsp->fnum, (double)startpos, (int)numtowrite,
3584 (int)total_written));
3586 /* We won't return a status if write through is not selected - this
3587 * follows what WfWg does */
3588 END_PROFILE(SMBwritebraw);
3590 if (!write_through && total_written==tcount) {
3592 #if RABBIT_PELLET_FIX
3594 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
3595 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this.
3598 if (!send_keepalive(smbd_server_fd())) {
3599 exit_server_cleanly("reply_writebraw: send of "
3600 "keepalive failed");
3603 TALLOC_FREE(req->outbuf);
3609 #define DBGC_CLASS DBGC_LOCKING
3611 /****************************************************************************
3612 Reply to a writeunlock (core+).
3613 ****************************************************************************/
3615 void reply_writeunlock(struct smb_request *req)
3617 connection_struct *conn = req->conn;
3618 ssize_t nwritten = -1;
3622 NTSTATUS status = NT_STATUS_OK;
3625 START_PROFILE(SMBwriteunlock);
3628 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3629 END_PROFILE(SMBwriteunlock);
3633 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3635 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3636 END_PROFILE(SMBwriteunlock);
3640 if (!CHECK_WRITE(fsp)) {
3641 reply_doserror(req, ERRDOS,ERRbadaccess);
3642 END_PROFILE(SMBwriteunlock);
3646 numtowrite = SVAL(req->inbuf,smb_vwv1);
3647 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3648 data = smb_buf(req->inbuf) + 3;
3651 && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
3652 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3653 reply_doserror(req, ERRDOS, ERRlock);
3654 END_PROFILE(SMBwriteunlock);
3658 /* The special X/Open SMB protocol handling of
3659 zero length writes is *NOT* done for
3661 if(numtowrite == 0) {
3664 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3667 status = sync_file(conn, fsp, False /* write through */);
3668 if (!NT_STATUS_IS_OK(status)) {
3669 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
3670 fsp->fsp_name, nt_errstr(status) ));
3671 reply_nterror(req, status);
3672 END_PROFILE(SMBwriteunlock);
3676 if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
3677 reply_unixerror(req, ERRHRD, ERRdiskfull);
3678 END_PROFILE(SMBwriteunlock);
3683 status = do_unlock(smbd_messaging_context(),
3686 (SMB_BIG_UINT)numtowrite,
3687 (SMB_BIG_UINT)startpos,
3690 if (NT_STATUS_V(status)) {
3691 reply_nterror(req, status);
3692 END_PROFILE(SMBwriteunlock);
3697 reply_outbuf(req, 1, 0);
3699 SSVAL(req->outbuf,smb_vwv0,nwritten);
3701 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
3702 fsp->fnum, (int)numtowrite, (int)nwritten));
3704 END_PROFILE(SMBwriteunlock);
3709 #define DBGC_CLASS DBGC_ALL
3711 /****************************************************************************
3713 ****************************************************************************/
3715 void reply_write(struct smb_request *req)
3717 connection_struct *conn = req->conn;
3719 ssize_t nwritten = -1;
3725 START_PROFILE(SMBwrite);
3728 END_PROFILE(SMBwrite);
3729 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3733 /* If it's an IPC, pass off the pipe handler. */
3735 reply_pipe_write(req);
3736 END_PROFILE(SMBwrite);
3740 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3742 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3743 END_PROFILE(SMBwrite);
3747 if (!CHECK_WRITE(fsp)) {
3748 reply_doserror(req, ERRDOS, ERRbadaccess);
3749 END_PROFILE(SMBwrite);
3753 numtowrite = SVAL(req->inbuf,smb_vwv1);
3754 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3755 data = smb_buf(req->inbuf) + 3;
3757 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
3758 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3759 reply_doserror(req, ERRDOS, ERRlock);
3760 END_PROFILE(SMBwrite);
3765 * X/Open SMB protocol says that if smb_vwv1 is
3766 * zero then the file size should be extended or
3767 * truncated to the size given in smb_vwv[2-3].
3770 if(numtowrite == 0) {
3772 * This is actually an allocate call, and set EOF. JRA.
3774 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
3776 reply_nterror(req, NT_STATUS_DISK_FULL);
3777 END_PROFILE(SMBwrite);
3780 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
3782 reply_nterror(req, NT_STATUS_DISK_FULL);
3783 END_PROFILE(SMBwrite);
3787 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3789 status = sync_file(conn, fsp, False);
3790 if (!NT_STATUS_IS_OK(status)) {
3791 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
3792 fsp->fsp_name, nt_errstr(status) ));
3793 reply_nterror(req, status);
3794 END_PROFILE(SMBwrite);
3798 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3799 reply_unixerror(req, ERRHRD, ERRdiskfull);
3800 END_PROFILE(SMBwrite);
3804 reply_outbuf(req, 1, 0);
3806 SSVAL(req->outbuf,smb_vwv0,nwritten);
3808 if (nwritten < (ssize_t)numtowrite) {
3809 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3810 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3813 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
3815 END_PROFILE(SMBwrite);
3819 /****************************************************************************
3820 Ensure a buffer is a valid writeX for recvfile purposes.
3821 ****************************************************************************/
3823 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
3824 (2*14) + /* word count (including bcc) */ \
3827 bool is_valid_writeX_buffer(const uint8_t *inbuf)
3830 connection_struct *conn = NULL;
3831 unsigned int doff = 0;
3832 size_t len = smb_len_large(inbuf);
3834 if (is_encrypted_packet(inbuf)) {
3835 /* Can't do this on encrypted
3840 if (CVAL(inbuf,smb_com) != SMBwriteX) {
3844 if (CVAL(inbuf,smb_vwv0) != 0xFF ||
3845 CVAL(inbuf,smb_wct) != 14) {
3846 DEBUG(10,("is_valid_writeX_buffer: chained or "
3847 "invalid word length.\n"));
3851 conn = conn_find(SVAL(inbuf, smb_tid));
3853 DEBUG(10,("is_valid_writeX_buffer: bad tid\n"));
3857 DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
3860 doff = SVAL(inbuf,smb_vwv11);
3862 numtowrite = SVAL(inbuf,smb_vwv10);
3864 if (len > doff && len - doff > 0xFFFF) {
3865 numtowrite |= (((size_t)SVAL(inbuf,smb_vwv9))<<16);
3868 if (numtowrite == 0) {
3869 DEBUG(10,("is_valid_writeX_buffer: zero write\n"));
3873 /* Ensure the sizes match up. */
3874 if (doff < STANDARD_WRITE_AND_X_HEADER_SIZE) {
3875 /* no pad byte...old smbclient :-( */
3876 DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n",
3878 (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE));
3882 if (len - doff != numtowrite) {
3883 DEBUG(10,("is_valid_writeX_buffer: doff mismatch "
3884 "len = %u, doff = %u, numtowrite = %u\n",
3887 (unsigned int)numtowrite ));
3891 DEBUG(10,("is_valid_writeX_buffer: true "
3892 "len = %u, doff = %u, numtowrite = %u\n",
3895 (unsigned int)numtowrite ));
3900 /****************************************************************************
3901 Reply to a write and X.
3902 ****************************************************************************/
3904 void reply_write_and_X(struct smb_request *req)
3906 connection_struct *conn = req->conn;
3912 unsigned int smb_doff;
3913 unsigned int smblen;
3917 START_PROFILE(SMBwriteX);
3919 if ((req->wct != 12) && (req->wct != 14)) {
3920 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3921 END_PROFILE(SMBwriteX);
3925 numtowrite = SVAL(req->inbuf,smb_vwv10);
3926 smb_doff = SVAL(req->inbuf,smb_vwv11);
3927 smblen = smb_len(req->inbuf);
3929 if (req->unread_bytes > 0xFFFF ||
3930 (smblen > smb_doff &&
3931 smblen - smb_doff > 0xFFFF)) {
3932 numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
3935 if (req->unread_bytes) {
3936 /* Can't do a recvfile write on IPC$ */
3938 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3939 END_PROFILE(SMBwriteX);
3942 if (numtowrite != req->unread_bytes) {
3943 reply_doserror(req, ERRDOS, ERRbadmem);
3944 END_PROFILE(SMBwriteX);
3948 if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
3949 smb_doff + numtowrite > smblen) {
3950 reply_doserror(req, ERRDOS, ERRbadmem);
3951 END_PROFILE(SMBwriteX);
3956 /* If it's an IPC, pass off the pipe handler. */
3958 if (req->unread_bytes) {
3959 reply_doserror(req, ERRDOS, ERRbadmem);
3960 END_PROFILE(SMBwriteX);
3963 reply_pipe_write_and_X(req);
3964 END_PROFILE(SMBwriteX);
3968 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
3969 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3970 write_through = BITSETW(req->inbuf+smb_vwv7,0);
3972 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3973 END_PROFILE(SMBwriteX);
3977 if (!CHECK_WRITE(fsp)) {
3978 reply_doserror(req, ERRDOS, ERRbadaccess);
3979 END_PROFILE(SMBwriteX);
3983 data = smb_base(req->inbuf) + smb_doff;
3985 if(req->wct == 14) {
3986 #ifdef LARGE_SMB_OFF_T
3988 * This is a large offset (64 bit) write.
3990 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32);
3992 #else /* !LARGE_SMB_OFF_T */
3995 * Ensure we haven't been sent a >32 bit offset.
3998 if(IVAL(req->inbuf,smb_vwv12) != 0) {
3999 DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
4000 "used and we don't support 64 bit offsets.\n",
4001 (unsigned int)IVAL(req->inbuf,smb_vwv12) ));
4002 reply_doserror(req, ERRDOS, ERRbadaccess);
4003 END_PROFILE(SMBwriteX);
4007 #endif /* LARGE_SMB_OFF_T */
4010 if (is_locked(fsp,(uint32)req->smbpid,
4011 (SMB_BIG_UINT)numtowrite,
4012 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
4013 reply_doserror(req, ERRDOS, ERRlock);
4014 END_PROFILE(SMBwriteX);
4018 /* X/Open SMB protocol says that, unlike SMBwrite
4019 if the length is zero then NO truncation is
4020 done, just a write of zero. To truncate a file,
4023 if(numtowrite == 0) {
4027 if ((req->unread_bytes == 0) &&
4028 schedule_aio_write_and_X(conn, req, fsp, data, startpos,
4030 END_PROFILE(SMBwriteX);
4034 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4037 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4038 reply_unixerror(req, ERRHRD, ERRdiskfull);
4039 END_PROFILE(SMBwriteX);
4043 reply_outbuf(req, 6, 0);
4044 SSVAL(req->outbuf,smb_vwv2,nwritten);
4045 SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
4047 if (nwritten < (ssize_t)numtowrite) {
4048 SCVAL(req->outbuf,smb_rcls,ERRHRD);
4049 SSVAL(req->outbuf,smb_err,ERRdiskfull);
4052 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
4053 fsp->fnum, (int)numtowrite, (int)nwritten));
4055 status = sync_file(conn, fsp, write_through);
4056 if (!NT_STATUS_IS_OK(status)) {
4057 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
4058 fsp->fsp_name, nt_errstr(status) ));
4059 reply_nterror(req, status);
4060 END_PROFILE(SMBwriteX);
4064 END_PROFILE(SMBwriteX);
4069 /****************************************************************************
4071 ****************************************************************************/
4073 void reply_lseek(struct smb_request *req)
4075 connection_struct *conn = req->conn;
4081 START_PROFILE(SMBlseek);
4084 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4085 END_PROFILE(SMBlseek);
4089 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4091 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4095 flush_write_cache(fsp, SEEK_FLUSH);
4097 mode = SVAL(req->inbuf,smb_vwv1) & 3;
4098 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
4099 startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2);
4108 res = fsp->fh->pos + startpos;
4119 if (umode == SEEK_END) {
4120 if((res = SMB_VFS_LSEEK(fsp,startpos,umode)) == -1) {
4121 if(errno == EINVAL) {
4122 SMB_OFF_T current_pos = startpos;
4123 SMB_STRUCT_STAT sbuf;
4125 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
4126 reply_unixerror(req, ERRDOS,
4128 END_PROFILE(SMBlseek);
4132 current_pos += sbuf.st_size;
4134 res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
4139 reply_unixerror(req, ERRDOS, ERRnoaccess);
4140 END_PROFILE(SMBlseek);
4147 reply_outbuf(req, 2, 0);
4148 SIVAL(req->outbuf,smb_vwv0,res);
4150 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
4151 fsp->fnum, (double)startpos, (double)res, mode));
4153 END_PROFILE(SMBlseek);
4157 /****************************************************************************
4159 ****************************************************************************/
4161 void reply_flush(struct smb_request *req)
4163 connection_struct *conn = req->conn;
4167 START_PROFILE(SMBflush);
4170 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4174 fnum = SVAL(req->inbuf,smb_vwv0);
4175 fsp = file_fsp(fnum);
4177 if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp, ¤t_user)) {
4182 file_sync_all(conn);
4184 NTSTATUS status = sync_file(conn, fsp, True);
4185 if (!NT_STATUS_IS_OK(status)) {
4186 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
4187 fsp->fsp_name, nt_errstr(status) ));
4188 reply_nterror(req, status);
4189 END_PROFILE(SMBflush);
4194 reply_outbuf(req, 0, 0);
4196 DEBUG(3,("flush\n"));
4197 END_PROFILE(SMBflush);
4201 /****************************************************************************
4203 conn POINTER CAN BE NULL HERE !
4204 ****************************************************************************/
4206 void reply_exit(struct smb_request *req)
4208 START_PROFILE(SMBexit);
4210 file_close_pid(req->smbpid, req->vuid);
4212 reply_outbuf(req, 0, 0);
4214 DEBUG(3,("exit\n"));
4216 END_PROFILE(SMBexit);
4220 /****************************************************************************
4221 Reply to a close - has to deal with closing a directory opened by NT SMB's.
4222 ****************************************************************************/
4224 void reply_close(struct smb_request *req)
4226 connection_struct *conn = req->conn;
4227 NTSTATUS status = NT_STATUS_OK;
4228 files_struct *fsp = NULL;
4229 START_PROFILE(SMBclose);
4232 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4233 END_PROFILE(SMBclose);
4237 /* If it's an IPC, pass off to the pipe handler. */
4239 reply_pipe_close(conn, req);
4240 END_PROFILE(SMBclose);
4244 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4247 * We can only use CHECK_FSP if we know it's not a directory.
4250 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
4251 reply_doserror(req, ERRDOS, ERRbadfid);
4252 END_PROFILE(SMBclose);
4256 if(fsp->is_directory) {
4258 * Special case - close NT SMB directory handle.
4260 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
4261 status = close_file(fsp,NORMAL_CLOSE);
4265 * Close ordinary file.
4268 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
4269 fsp->fh->fd, fsp->fnum,
4270 conn->num_files_open));
4273 * Take care of any time sent in the close.
4276 t = srv_make_unix_date3(req->inbuf+smb_vwv1);
4277 set_close_write_time(fsp, convert_time_t_to_timespec(t));
4280 * close_file() returns the unix errno if an error
4281 * was detected on close - normally this is due to
4282 * a disk full error. If not then it was probably an I/O error.
4285 status = close_file(fsp,NORMAL_CLOSE);
4288 if (!NT_STATUS_IS_OK(status)) {
4289 reply_nterror(req, status);
4290 END_PROFILE(SMBclose);
4294 reply_outbuf(req, 0, 0);
4295 END_PROFILE(SMBclose);
4299 /****************************************************************************
4300 Reply to a writeclose (Core+ protocol).
4301 ****************************************************************************/
4303 void reply_writeclose(struct smb_request *req)
4305 connection_struct *conn = req->conn;
4307 ssize_t nwritten = -1;
4308 NTSTATUS close_status = NT_STATUS_OK;
4311 struct timespec mtime;
4314 START_PROFILE(SMBwriteclose);
4317 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4318 END_PROFILE(SMBwriteclose);
4322 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4324 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4325 END_PROFILE(SMBwriteclose);
4328 if (!CHECK_WRITE(fsp)) {
4329 reply_doserror(req, ERRDOS,ERRbadaccess);
4330 END_PROFILE(SMBwriteclose);
4334 numtowrite = SVAL(req->inbuf,smb_vwv1);
4335 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
4336 mtime = convert_time_t_to_timespec(srv_make_unix_date3(
4337 req->inbuf+smb_vwv4));
4338 data = smb_buf(req->inbuf) + 1;
4341 && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
4342 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
4343 reply_doserror(req, ERRDOS,ERRlock);
4344 END_PROFILE(SMBwriteclose);
4348 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4350 set_close_write_time(fsp, mtime);
4353 * More insanity. W2K only closes the file if writelen > 0.
4358 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
4360 close_status = close_file(fsp,NORMAL_CLOSE);
4363 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
4364 fsp->fnum, (int)numtowrite, (int)nwritten,
4365 conn->num_files_open));
4367 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4368 reply_doserror(req, ERRHRD, ERRdiskfull);
4369 END_PROFILE(SMBwriteclose);
4373 if(!NT_STATUS_IS_OK(close_status)) {
4374 reply_nterror(req, close_status);
4375 END_PROFILE(SMBwriteclose);
4379 reply_outbuf(req, 1, 0);
4381 SSVAL(req->outbuf,smb_vwv0,nwritten);
4382 END_PROFILE(SMBwriteclose);
4387 #define DBGC_CLASS DBGC_LOCKING
4389 /****************************************************************************
4391 ****************************************************************************/
4393 void reply_lock(struct smb_request *req)
4395 connection_struct *conn = req->conn;
4396 SMB_BIG_UINT count,offset;
4399 struct byte_range_lock *br_lck = NULL;
4401 START_PROFILE(SMBlock);
4404 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4405 END_PROFILE(SMBlock);
4409 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4411 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4412 END_PROFILE(SMBlock);
4416 release_level_2_oplocks_on_change(fsp);
4418 count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
4419 offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
4421 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4422 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
4424 br_lck = do_lock(smbd_messaging_context(),
4431 False, /* Non-blocking lock. */
4435 TALLOC_FREE(br_lck);
4437 if (NT_STATUS_V(status)) {
4438 reply_nterror(req, status);
4439 END_PROFILE(SMBlock);
4443 reply_outbuf(req, 0, 0);
4445 END_PROFILE(SMBlock);
4449 /****************************************************************************
4451 ****************************************************************************/
4453 void reply_unlock(struct smb_request *req)
4455 connection_struct *conn = req->conn;
4456 SMB_BIG_UINT count,offset;
4460 START_PROFILE(SMBunlock);
4463 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4464 END_PROFILE(SMBunlock);
4468 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4470 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4471 END_PROFILE(SMBunlock);
4475 count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
4476 offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
4478 status = do_unlock(smbd_messaging_context(),
4485 if (NT_STATUS_V(status)) {
4486 reply_nterror(req, status);
4487 END_PROFILE(SMBunlock);
4491 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4492 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
4494 reply_outbuf(req, 0, 0);
4496 END_PROFILE(SMBunlock);
4501 #define DBGC_CLASS DBGC_ALL
4503 /****************************************************************************
4505 conn POINTER CAN BE NULL HERE !
4506 ****************************************************************************/
4508 void reply_tdis(struct smb_request *req)
4510 connection_struct *conn = req->conn;
4511 START_PROFILE(SMBtdis);
4514 DEBUG(4,("Invalid connection in tdis\n"));
4515 reply_doserror(req, ERRSRV, ERRinvnid);
4516 END_PROFILE(SMBtdis);
4522 close_cnum(conn,req->vuid);
4525 reply_outbuf(req, 0, 0);
4526 END_PROFILE(SMBtdis);
4530 /****************************************************************************
4532 conn POINTER CAN BE NULL HERE !
4533 ****************************************************************************/
4535 void reply_echo(struct smb_request *req)
4537 connection_struct *conn = req->conn;
4540 unsigned int data_len = smb_buflen(req->inbuf);
4542 START_PROFILE(SMBecho);
4545 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4546 END_PROFILE(SMBecho);
4550 if (data_len > BUFFER_SIZE) {
4551 DEBUG(0,("reply_echo: data_len too large.\n"));
4552 reply_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
4553 END_PROFILE(SMBecho);
4557 smb_reverb = SVAL(req->inbuf,smb_vwv0);
4559 reply_outbuf(req, 1, data_len);
4561 /* copy any incoming data back out */
4563 memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len);
4566 if (smb_reverb > 100) {
4567 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
4571 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
4572 SSVAL(req->outbuf,smb_vwv0,seq_num);
4574 show_msg((char *)req->outbuf);
4575 if (!srv_send_smb(smbd_server_fd(),
4576 (char *)req->outbuf,
4577 IS_CONN_ENCRYPTED(conn)||req->encrypted))
4578 exit_server_cleanly("reply_echo: srv_send_smb failed.");
4581 DEBUG(3,("echo %d times\n", smb_reverb));
4583 TALLOC_FREE(req->outbuf);
4587 END_PROFILE(SMBecho);
4591 /****************************************************************************
4592 Reply to a printopen.
4593 ****************************************************************************/
4595 void reply_printopen(struct smb_request *req)
4597 connection_struct *conn = req->conn;
4601 START_PROFILE(SMBsplopen);
4604 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4605 END_PROFILE(SMBsplopen);
4609 if (!CAN_PRINT(conn)) {
4610 reply_doserror(req, ERRDOS, ERRnoaccess);
4611 END_PROFILE(SMBsplopen);
4615 /* Open for exclusive use, write only. */
4616 status = print_fsp_open(conn, NULL, &fsp);
4618 if (!NT_STATUS_IS_OK(status)) {
4619 reply_nterror(req, status);
4620 END_PROFILE(SMBsplopen);
4624 reply_outbuf(req, 1, 0);
4625 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
4627 DEBUG(3,("openprint fd=%d fnum=%d\n",
4628 fsp->fh->fd, fsp->fnum));
4630 END_PROFILE(SMBsplopen);
4634 /****************************************************************************
4635 Reply to a printclose.
4636 ****************************************************************************/
4638 void reply_printclose(struct smb_request *req)
4640 connection_struct *conn = req->conn;
4644 START_PROFILE(SMBsplclose);
4647 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4648 END_PROFILE(SMBsplclose);
4652 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4654 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4655 END_PROFILE(SMBsplclose);
4659 if (!CAN_PRINT(conn)) {
4660 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
4661 END_PROFILE(SMBsplclose);
4665 DEBUG(3,("printclose fd=%d fnum=%d\n",
4666 fsp->fh->fd,fsp->fnum));
4668 status = close_file(fsp,NORMAL_CLOSE);
4670 if(!NT_STATUS_IS_OK(status)) {
4671 reply_nterror(req, status);
4672 END_PROFILE(SMBsplclose);
4676 reply_outbuf(req, 0, 0);
4678 END_PROFILE(SMBsplclose);
4682 /****************************************************************************
4683 Reply to a printqueue.
4684 ****************************************************************************/
4686 void reply_printqueue(struct smb_request *req)
4688 connection_struct *conn = req->conn;
4692 START_PROFILE(SMBsplretq);
4695 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4696 END_PROFILE(SMBsplretq);
4700 max_count = SVAL(req->inbuf,smb_vwv0);
4701 start_index = SVAL(req->inbuf,smb_vwv1);
4703 /* we used to allow the client to get the cnum wrong, but that
4704 is really quite gross and only worked when there was only
4705 one printer - I think we should now only accept it if they
4706 get it right (tridge) */
4707 if (!CAN_PRINT(conn)) {
4708 reply_doserror(req, ERRDOS, ERRnoaccess);
4709 END_PROFILE(SMBsplretq);
4713 reply_outbuf(req, 2, 3);
4714 SSVAL(req->outbuf,smb_vwv0,0);
4715 SSVAL(req->outbuf,smb_vwv1,0);
4716 SCVAL(smb_buf(req->outbuf),0,1);
4717 SSVAL(smb_buf(req->outbuf),1,0);
4719 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
4720 start_index, max_count));
4723 print_queue_struct *queue = NULL;
4724 print_status_struct status;
4725 int count = print_queue_status(SNUM(conn), &queue, &status);
4726 int num_to_get = ABS(max_count);
4727 int first = (max_count>0?start_index:start_index+max_count+1);
4733 num_to_get = MIN(num_to_get,count-first);
4736 for (i=first;i<first+num_to_get;i++) {
4740 srv_put_dos_date2(p,0,queue[i].time);
4741 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
4742 SSVAL(p,5, queue[i].job);
4743 SIVAL(p,7,queue[i].size);
4745 srvstr_push(blob, req->flags2, p+12,
4746 queue[i].fs_user, 16, STR_ASCII);
4748 if (message_push_blob(
4751 blob, sizeof(blob))) == -1) {
4752 reply_nterror(req, NT_STATUS_NO_MEMORY);
4753 END_PROFILE(SMBsplretq);
4759 SSVAL(req->outbuf,smb_vwv0,count);
4760 SSVAL(req->outbuf,smb_vwv1,
4761 (max_count>0?first+count:first-1));
4762 SCVAL(smb_buf(req->outbuf),0,1);
4763 SSVAL(smb_buf(req->outbuf),1,28*count);
4768 DEBUG(3,("%d entries returned in queue\n",count));
4771 END_PROFILE(SMBsplretq);
4775 /****************************************************************************
4776 Reply to a printwrite.
4777 ****************************************************************************/
4779 void reply_printwrite(struct smb_request *req)
4781 connection_struct *conn = req->conn;
4786 START_PROFILE(SMBsplwr);
4789 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4790 END_PROFILE(SMBsplwr);
4794 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4796 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4797 END_PROFILE(SMBsplwr);
4801 if (!CAN_PRINT(conn)) {
4802 reply_doserror(req, ERRDOS, ERRnoaccess);
4803 END_PROFILE(SMBsplwr);
4807 if (!CHECK_WRITE(fsp)) {
4808 reply_doserror(req, ERRDOS, ERRbadaccess);
4809 END_PROFILE(SMBsplwr);
4813 numtowrite = SVAL(smb_buf(req->inbuf),1);
4815 if (smb_buflen(req->inbuf) < numtowrite + 3) {
4816 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4817 END_PROFILE(SMBsplwr);
4821 data = smb_buf(req->inbuf) + 3;
4823 if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
4824 reply_unixerror(req, ERRHRD, ERRdiskfull);
4825 END_PROFILE(SMBsplwr);
4829 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
4831 END_PROFILE(SMBsplwr);
4835 /****************************************************************************
4837 ****************************************************************************/
4839 void reply_mkdir(struct smb_request *req)
4841 connection_struct *conn = req->conn;
4842 char *directory = NULL;
4844 SMB_STRUCT_STAT sbuf;
4845 TALLOC_CTX *ctx = talloc_tos();
4847 START_PROFILE(SMBmkdir);
4849 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
4850 smb_buf(req->inbuf) + 1, 0,
4851 STR_TERMINATE, &status);
4852 if (!NT_STATUS_IS_OK(status)) {
4853 reply_nterror(req, status);
4854 END_PROFILE(SMBmkdir);
4858 status = resolve_dfspath(ctx, conn,
4859 req->flags2 & FLAGS2_DFS_PATHNAMES,
4862 if (!NT_STATUS_IS_OK(status)) {
4863 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4864 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
4865 ERRSRV, ERRbadpath);
4866 END_PROFILE(SMBmkdir);
4869 reply_nterror(req, status);
4870 END_PROFILE(SMBmkdir);
4874 status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
4875 if (!NT_STATUS_IS_OK(status)) {
4876 reply_nterror(req, status);
4877 END_PROFILE(SMBmkdir);
4881 status = check_name(conn, directory);
4882 if (!NT_STATUS_IS_OK(status)) {
4883 reply_nterror(req, status);
4884 END_PROFILE(SMBmkdir);
4888 status = create_directory(conn, req, directory);
4890 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
4892 if (!NT_STATUS_IS_OK(status)) {
4894 if (!use_nt_status()
4895 && NT_STATUS_EQUAL(status,
4896 NT_STATUS_OBJECT_NAME_COLLISION)) {
4898 * Yes, in the DOS error code case we get a
4899 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
4900 * samba4 torture test.
4902 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
4905 reply_nterror(req, status);
4906 END_PROFILE(SMBmkdir);
4910 reply_outbuf(req, 0, 0);
4912 DEBUG( 3, ( "mkdir %s\n", directory ) );
4914 END_PROFILE(SMBmkdir);
4918 /****************************************************************************
4919 Static function used by reply_rmdir to delete an entire directory
4920 tree recursively. Return True on ok, False on fail.
4921 ****************************************************************************/
4923 static bool recursive_rmdir(TALLOC_CTX *ctx,
4924 connection_struct *conn,
4927 const char *dname = NULL;
4930 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, directory,
4936 while((dname = ReadDirName(dir_hnd, &offset))) {
4937 char *fullname = NULL;
4940 if (ISDOT(dname) || ISDOTDOT(dname)) {
4944 if (!is_visible_file(conn, directory, dname, &st, False)) {
4948 /* Construct the full name. */
4949 fullname = talloc_asprintf(ctx,
4959 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
4964 if(st.st_mode & S_IFDIR) {
4965 if(!recursive_rmdir(ctx, conn, fullname)) {
4969 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
4973 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
4977 TALLOC_FREE(fullname);
4979 TALLOC_FREE(dir_hnd);
4983 /****************************************************************************
4984 The internals of the rmdir code - called elsewhere.
4985 ****************************************************************************/
4987 NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
4988 connection_struct *conn,
4989 const char *directory)
4994 /* Might be a symlink. */
4995 if(SMB_VFS_LSTAT(conn, directory, &st) != 0) {
4996 return map_nt_error_from_unix(errno);
4999 if (S_ISLNK(st.st_mode)) {
5000 /* Is what it points to a directory ? */
5001 if(SMB_VFS_STAT(conn, directory, &st) != 0) {
5002 return map_nt_error_from_unix(errno);
5004 if (!(S_ISDIR(st.st_mode))) {
5005 return NT_STATUS_NOT_A_DIRECTORY;
5007 ret = SMB_VFS_UNLINK(conn,directory);
5009 ret = SMB_VFS_RMDIR(conn,directory);
5012 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5013 FILE_NOTIFY_CHANGE_DIR_NAME,
5015 return NT_STATUS_OK;
5018 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
5020 * Check to see if the only thing in this directory are
5021 * vetoed files/directories. If so then delete them and
5022 * retry. If we fail to delete any of them (and we *don't*
5023 * do a recursive delete) then fail the rmdir.
5027 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
5028 directory, NULL, 0);
5030 if(dir_hnd == NULL) {
5035 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5036 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
5038 if (!is_visible_file(conn, directory, dname, &st, False))
5040 if(!IS_VETO_PATH(conn, dname)) {
5041 TALLOC_FREE(dir_hnd);
5047 /* We only have veto files/directories. Recursive delete. */
5049 RewindDir(dir_hnd,&dirpos);
5050 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5051 char *fullname = NULL;
5053 if (ISDOT(dname) || ISDOTDOT(dname)) {
5056 if (!is_visible_file(conn, directory, dname, &st, False)) {
5060 fullname = talloc_asprintf(ctx,
5070 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
5073 if(st.st_mode & S_IFDIR) {
5074 if(lp_recursive_veto_delete(SNUM(conn))) {
5075 if(!recursive_rmdir(ctx, conn, fullname))
5078 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
5081 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
5084 TALLOC_FREE(fullname);
5086 TALLOC_FREE(dir_hnd);
5087 /* Retry the rmdir */
5088 ret = SMB_VFS_RMDIR(conn,directory);
5094 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
5095 "%s\n", directory,strerror(errno)));
5096 return map_nt_error_from_unix(errno);
5099 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5100 FILE_NOTIFY_CHANGE_DIR_NAME,
5103 return NT_STATUS_OK;
5106 /****************************************************************************
5108 ****************************************************************************/
5110 void reply_rmdir(struct smb_request *req)
5112 connection_struct *conn = req->conn;
5113 char *directory = NULL;
5114 SMB_STRUCT_STAT sbuf;
5116 TALLOC_CTX *ctx = talloc_tos();
5118 START_PROFILE(SMBrmdir);
5120 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
5121 smb_buf(req->inbuf) + 1, 0,
5122 STR_TERMINATE, &status);
5123 if (!NT_STATUS_IS_OK(status)) {
5124 reply_nterror(req, status);
5125 END_PROFILE(SMBrmdir);
5129 status = resolve_dfspath(ctx, conn,
5130 req->flags2 & FLAGS2_DFS_PATHNAMES,
5133 if (!NT_STATUS_IS_OK(status)) {
5134 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5135 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5136 ERRSRV, ERRbadpath);
5137 END_PROFILE(SMBrmdir);
5140 reply_nterror(req, status);
5141 END_PROFILE(SMBrmdir);
5145 status = unix_convert(ctx, conn, directory, False, &directory,
5147 if (!NT_STATUS_IS_OK(status)) {
5148 reply_nterror(req, status);
5149 END_PROFILE(SMBrmdir);
5153 status = check_name(conn, directory);
5154 if (!NT_STATUS_IS_OK(status)) {
5155 reply_nterror(req, status);
5156 END_PROFILE(SMBrmdir);
5160 dptr_closepath(directory, req->smbpid);
5161 status = rmdir_internals(ctx, conn, directory);
5162 if (!NT_STATUS_IS_OK(status)) {
5163 reply_nterror(req, status);
5164 END_PROFILE(SMBrmdir);
5168 reply_outbuf(req, 0, 0);
5170 DEBUG( 3, ( "rmdir %s\n", directory ) );
5172 END_PROFILE(SMBrmdir);
5176 /*******************************************************************
5177 Resolve wildcards in a filename rename.
5178 ********************************************************************/
5180 static bool resolve_wildcards(TALLOC_CTX *ctx,
5185 char *name2_copy = NULL;
5190 char *p,*p2, *pname1, *pname2;
5192 name2_copy = talloc_strdup(ctx, name2);
5197 pname1 = strrchr_m(name1,'/');
5198 pname2 = strrchr_m(name2_copy,'/');
5200 if (!pname1 || !pname2) {
5204 /* Truncate the copy of name2 at the last '/' */
5207 /* Now go past the '/' */
5211 root1 = talloc_strdup(ctx, pname1);
5212 root2 = talloc_strdup(ctx, pname2);
5214 if (!root1 || !root2) {
5218 p = strrchr_m(root1,'.');
5221 ext1 = talloc_strdup(ctx, p+1);
5223 ext1 = talloc_strdup(ctx, "");
5225 p = strrchr_m(root2,'.');
5228 ext2 = talloc_strdup(ctx, p+1);
5230 ext2 = talloc_strdup(ctx, "");
5233 if (!ext1 || !ext2) {
5241 /* Hmmm. Should this be mb-aware ? */
5244 } else if (*p2 == '*') {
5246 root2 = talloc_asprintf(ctx, "%s%s",
5265 /* Hmmm. Should this be mb-aware ? */
5268 } else if (*p2 == '*') {
5270 ext2 = talloc_asprintf(ctx, "%s%s",
5286 *pp_newname = talloc_asprintf(ctx, "%s/%s.%s",
5291 *pp_newname = talloc_asprintf(ctx, "%s/%s",
5303 /****************************************************************************
5304 Ensure open files have their names updated. Updated to notify other smbd's
5306 ****************************************************************************/
5308 static void rename_open_files(connection_struct *conn,
5309 struct share_mode_lock *lck,
5310 const char *newname)
5313 bool did_rename = False;
5315 for(fsp = file_find_di_first(lck->id); fsp;
5316 fsp = file_find_di_next(fsp)) {
5317 /* fsp_name is a relative path under the fsp. To change this for other
5318 sharepaths we need to manipulate relative paths. */
5319 /* TODO - create the absolute path and manipulate the newname
5320 relative to the sharepath. */
5321 if (!strequal(fsp->conn->connectpath, conn->connectpath)) {
5324 DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
5325 fsp->fnum, file_id_string_tos(&fsp->file_id),
5326 fsp->fsp_name, newname ));
5327 string_set(&fsp->fsp_name, newname);
5332 DEBUG(10,("rename_open_files: no open files on file_id %s for %s\n",
5333 file_id_string_tos(&lck->id), newname ));
5336 /* Send messages to all smbd's (not ourself) that the name has changed. */
5337 rename_share_filename(smbd_messaging_context(), lck, conn->connectpath,
5341 /****************************************************************************
5342 We need to check if the source path is a parent directory of the destination
5343 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
5344 refuse the rename with a sharing violation. Under UNIX the above call can
5345 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
5346 probably need to check that the client is a Windows one before disallowing
5347 this as a UNIX client (one with UNIX extensions) can know the source is a
5348 symlink and make this decision intelligently. Found by an excellent bug
5349 report from <AndyLiebman@aol.com>.
5350 ****************************************************************************/
5352 static bool rename_path_prefix_equal(const char *src, const char *dest)
5354 const char *psrc = src;
5355 const char *pdst = dest;
5358 if (psrc[0] == '.' && psrc[1] == '/') {
5361 if (pdst[0] == '.' && pdst[1] == '/') {
5364 if ((slen = strlen(psrc)) > strlen(pdst)) {
5367 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
5371 * Do the notify calls from a rename
5374 static void notify_rename(connection_struct *conn, bool is_dir,
5375 const char *oldpath, const char *newpath)
5377 char *olddir, *newdir;
5378 const char *oldname, *newname;
5381 mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
5382 : FILE_NOTIFY_CHANGE_FILE_NAME;
5384 if (!parent_dirname_talloc(NULL, oldpath, &olddir, &oldname)
5385 || !parent_dirname_talloc(NULL, newpath, &newdir, &newname)) {
5386 TALLOC_FREE(olddir);
5390 if (strcmp(olddir, newdir) == 0) {
5391 notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, oldpath);
5392 notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, newpath);
5395 notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, oldpath);
5396 notify_fname(conn, NOTIFY_ACTION_ADDED, mask, newpath);
5398 TALLOC_FREE(olddir);
5399 TALLOC_FREE(newdir);
5401 /* this is a strange one. w2k3 gives an additional event for
5402 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
5403 files, but not directories */
5405 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
5406 FILE_NOTIFY_CHANGE_ATTRIBUTES
5407 |FILE_NOTIFY_CHANGE_CREATION,
5412 /****************************************************************************
5413 Rename an open file - given an fsp.
5414 ****************************************************************************/
5416 NTSTATUS rename_internals_fsp(connection_struct *conn,
5419 const char *newname_last_component,
5421 bool replace_if_exists)
5423 TALLOC_CTX *ctx = talloc_tos();
5424 SMB_STRUCT_STAT sbuf, sbuf1;
5425 NTSTATUS status = NT_STATUS_OK;
5426 struct share_mode_lock *lck = NULL;
5431 status = check_name(conn, newname);
5432 if (!NT_STATUS_IS_OK(status)) {
5436 /* Ensure newname contains a '/' */
5437 if(strrchr_m(newname,'/') == 0) {
5438 newname = talloc_asprintf(ctx,
5442 return NT_STATUS_NO_MEMORY;
5447 * Check for special case with case preserving and not
5448 * case sensitive. If the old last component differs from the original
5449 * last component only by case, then we should allow
5450 * the rename (user is trying to change the case of the
5454 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
5455 strequal(newname, fsp->fsp_name)) {
5457 char *newname_modified_last_component = NULL;
5460 * Get the last component of the modified name.
5461 * Note that we guarantee that newname contains a '/'
5464 p = strrchr_m(newname,'/');
5465 newname_modified_last_component = talloc_strdup(ctx,
5467 if (!newname_modified_last_component) {
5468 return NT_STATUS_NO_MEMORY;
5471 if(strcsequal(newname_modified_last_component,
5472 newname_last_component) == False) {
5474 * Replace the modified last component with
5477 *p = '\0'; /* Truncate at the '/' */
5478 newname = talloc_asprintf(ctx,
5481 newname_last_component);
5486 * If the src and dest names are identical - including case,
5487 * don't do the rename, just return success.
5490 if (strcsequal(fsp->fsp_name, newname)) {
5491 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
5493 return NT_STATUS_OK;
5497 * Have vfs_object_exist also fill sbuf1
5499 dst_exists = vfs_object_exist(conn, newname, &sbuf1);
5501 if(!replace_if_exists && dst_exists) {
5502 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
5503 fsp->fsp_name,newname));
5504 return NT_STATUS_OBJECT_NAME_COLLISION;
5508 struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
5509 files_struct *dst_fsp = file_find_di_first(fileid);
5511 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
5512 return NT_STATUS_ACCESS_DENIED;
5516 /* Ensure we have a valid stat struct for the source. */
5517 if (fsp->fh->fd != -1) {
5518 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
5519 return map_nt_error_from_unix(errno);
5522 if (SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) == -1) {
5523 return map_nt_error_from_unix(errno);
5527 status = can_rename(conn, fsp, attrs, &sbuf);
5529 if (!NT_STATUS_IS_OK(status)) {
5530 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5531 nt_errstr(status), fsp->fsp_name,newname));
5532 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION))
5533 status = NT_STATUS_ACCESS_DENIED;
5537 if (rename_path_prefix_equal(fsp->fsp_name, newname)) {
5538 return NT_STATUS_ACCESS_DENIED;
5541 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
5545 * We have the file open ourselves, so not being able to get the
5546 * corresponding share mode lock is a fatal error.
5549 SMB_ASSERT(lck != NULL);
5551 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
5552 uint32 create_options = fsp->fh->private_options;
5554 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
5555 fsp->fsp_name,newname));
5557 rename_open_files(conn, lck, newname);
5559 notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname);
5562 * A rename acts as a new file create w.r.t. allowing an initial delete
5563 * on close, probably because in Windows there is a new handle to the
5564 * new file. If initial delete on close was requested but not
5565 * originally set, we need to set it here. This is probably not 100% correct,
5566 * but will work for the CIFSFS client which in non-posix mode
5567 * depends on these semantics. JRA.
5570 set_allow_initial_delete_on_close(lck, fsp, True);
5572 if (create_options & FILE_DELETE_ON_CLOSE) {
5573 status = can_set_delete_on_close(fsp, True, 0);
5575 if (NT_STATUS_IS_OK(status)) {
5576 /* Note that here we set the *inital* delete on close flag,
5577 * not the regular one. The magic gets handled in close. */
5578 fsp->initial_delete_on_close = True;
5582 return NT_STATUS_OK;
5587 if (errno == ENOTDIR || errno == EISDIR) {
5588 status = NT_STATUS_OBJECT_NAME_COLLISION;
5590 status = map_nt_error_from_unix(errno);
5593 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5594 nt_errstr(status), fsp->fsp_name,newname));
5599 /****************************************************************************
5600 The guts of the rename command, split out so it may be called by the NT SMB
5602 ****************************************************************************/
5604 NTSTATUS rename_internals(TALLOC_CTX *ctx,
5605 connection_struct *conn,
5606 struct smb_request *req,
5607 const char *name_in,
5608 const char *newname_in,
5610 bool replace_if_exists,
5613 uint32_t access_mask)
5615 char *directory = NULL;
5617 char *last_component_src = NULL;
5618 char *last_component_dest = NULL;
5620 char *newname = NULL;
5623 NTSTATUS status = NT_STATUS_OK;
5624 SMB_STRUCT_STAT sbuf1, sbuf2;
5625 struct smb_Dir *dir_hnd = NULL;
5632 status = unix_convert(ctx, conn, name_in, src_has_wild, &name,
5633 &last_component_src, &sbuf1);
5634 if (!NT_STATUS_IS_OK(status)) {
5638 status = unix_convert(ctx, conn, newname_in, dest_has_wild, &newname,
5639 &last_component_dest, &sbuf2);
5640 if (!NT_STATUS_IS_OK(status)) {
5645 * Split the old name into directory and last component
5646 * strings. Note that unix_convert may have stripped off a
5647 * leading ./ from both name and newname if the rename is
5648 * at the root of the share. We need to make sure either both
5649 * name and newname contain a / character or neither of them do
5650 * as this is checked in resolve_wildcards().
5653 p = strrchr_m(name,'/');
5655 directory = talloc_strdup(ctx, ".");
5657 return NT_STATUS_NO_MEMORY;
5662 directory = talloc_strdup(ctx, name);
5664 return NT_STATUS_NO_MEMORY;
5667 *p = '/'; /* Replace needed for exceptional test below. */
5671 * We should only check the mangled cache
5672 * here if unix_convert failed. This means
5673 * that the path in 'mask' doesn't exist
5674 * on the file system and so we need to look
5675 * for a possible mangle. This patch from
5676 * Tine Smukavec <valentin.smukavec@hermes.si>.
5679 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
5680 char *new_mask = NULL;
5681 mangle_lookup_name_from_8_3(ctx,
5690 if (!src_has_wild) {
5694 * No wildcards - just process the one file.
5696 bool is_short_name = mangle_is_8_3(name, True, conn->params);
5698 /* Add a terminating '/' to the directory name. */
5699 directory = talloc_asprintf_append(directory,
5703 return NT_STATUS_NO_MEMORY;
5706 /* Ensure newname contains a '/' also */
5707 if(strrchr_m(newname,'/') == 0) {
5708 newname = talloc_asprintf(ctx,
5712 return NT_STATUS_NO_MEMORY;
5716 DEBUG(3, ("rename_internals: case_sensitive = %d, "
5717 "case_preserve = %d, short case preserve = %d, "
5718 "directory = %s, newname = %s, "
5719 "last_component_dest = %s, is_8_3 = %d\n",
5720 conn->case_sensitive, conn->case_preserve,
5721 conn->short_case_preserve, directory,
5722 newname, last_component_dest, is_short_name));
5724 /* The dest name still may have wildcards. */
5725 if (dest_has_wild) {
5726 char *mod_newname = NULL;
5727 if (!resolve_wildcards(ctx,
5728 directory,newname,&mod_newname)) {
5729 DEBUG(6, ("rename_internals: resolve_wildcards "
5733 return NT_STATUS_NO_MEMORY;
5735 newname = mod_newname;
5739 SMB_VFS_STAT(conn, directory, &sbuf1);
5741 status = S_ISDIR(sbuf1.st_mode) ?
5742 open_directory(conn, req, directory, &sbuf1,
5744 FILE_SHARE_READ|FILE_SHARE_WRITE,
5745 FILE_OPEN, 0, 0, NULL,
5747 : open_file_ntcreate(conn, req, directory, &sbuf1,
5749 FILE_SHARE_READ|FILE_SHARE_WRITE,
5750 FILE_OPEN, 0, 0, 0, NULL,
5753 if (!NT_STATUS_IS_OK(status)) {
5754 DEBUG(3, ("Could not open rename source %s: %s\n",
5755 directory, nt_errstr(status)));
5759 status = rename_internals_fsp(conn, fsp, newname,
5760 last_component_dest,
5761 attrs, replace_if_exists);
5763 close_file(fsp, NORMAL_CLOSE);
5765 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
5766 nt_errstr(status), directory,newname));
5772 * Wildcards - process each file that matches.
5774 if (strequal(mask,"????????.???")) {
5779 status = check_name(conn, directory);
5780 if (!NT_STATUS_IS_OK(status)) {
5784 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, attrs);
5785 if (dir_hnd == NULL) {
5786 return map_nt_error_from_unix(errno);
5789 status = NT_STATUS_NO_SUCH_FILE;
5791 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5792 * - gentest fix. JRA
5795 while ((dname = ReadDirName(dir_hnd, &offset))) {
5796 files_struct *fsp = NULL;
5798 char *destname = NULL;
5799 bool sysdir_entry = False;
5801 /* Quick check for "." and ".." */
5802 if (ISDOT(dname) || ISDOTDOT(dname)) {
5804 sysdir_entry = True;
5810 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
5814 if(!mask_match(dname, mask, conn->case_sensitive)) {
5819 status = NT_STATUS_OBJECT_NAME_INVALID;
5823 fname = talloc_asprintf(ctx,
5828 return NT_STATUS_NO_MEMORY;
5831 if (!resolve_wildcards(ctx,
5832 fname,newname,&destname)) {
5833 DEBUG(6, ("resolve_wildcards %s %s failed\n",
5839 return NT_STATUS_NO_MEMORY;
5843 SMB_VFS_STAT(conn, fname, &sbuf1);
5845 status = S_ISDIR(sbuf1.st_mode) ?
5846 open_directory(conn, req, fname, &sbuf1,
5848 FILE_SHARE_READ|FILE_SHARE_WRITE,
5849 FILE_OPEN, 0, 0, NULL,
5851 : open_file_ntcreate(conn, req, fname, &sbuf1,
5853 FILE_SHARE_READ|FILE_SHARE_WRITE,
5854 FILE_OPEN, 0, 0, 0, NULL,
5857 if (!NT_STATUS_IS_OK(status)) {
5858 DEBUG(3,("rename_internals: open_file_ntcreate "
5859 "returned %s rename %s -> %s\n",
5860 nt_errstr(status), directory, newname));
5864 status = rename_internals_fsp(conn, fsp, destname, dname,
5865 attrs, replace_if_exists);
5867 close_file(fsp, NORMAL_CLOSE);
5869 if (!NT_STATUS_IS_OK(status)) {
5870 DEBUG(3, ("rename_internals_fsp returned %s for "
5871 "rename %s -> %s\n", nt_errstr(status),
5872 directory, newname));
5878 DEBUG(3,("rename_internals: doing rename on %s -> "
5879 "%s\n",fname,destname));
5882 TALLOC_FREE(destname);
5884 TALLOC_FREE(dir_hnd);
5886 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
5887 status = map_nt_error_from_unix(errno);
5893 /****************************************************************************
5895 ****************************************************************************/
5897 void reply_mv(struct smb_request *req)
5899 connection_struct *conn = req->conn;
5901 char *newname = NULL;
5905 bool src_has_wcard = False;
5906 bool dest_has_wcard = False;
5907 TALLOC_CTX *ctx = talloc_tos();
5909 START_PROFILE(SMBmv);
5912 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5917 attrs = SVAL(req->inbuf,smb_vwv0);
5919 p = smb_buf(req->inbuf) + 1;
5920 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
5921 0, STR_TERMINATE, &status,
5923 if (!NT_STATUS_IS_OK(status)) {
5924 reply_nterror(req, status);
5929 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
5930 0, STR_TERMINATE, &status,
5932 if (!NT_STATUS_IS_OK(status)) {
5933 reply_nterror(req, status);
5938 status = resolve_dfspath_wcard(ctx, conn,
5939 req->flags2 & FLAGS2_DFS_PATHNAMES,
5943 if (!NT_STATUS_IS_OK(status)) {
5944 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5945 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5946 ERRSRV, ERRbadpath);
5950 reply_nterror(req, status);
5955 status = resolve_dfspath_wcard(ctx, conn,
5956 req->flags2 & FLAGS2_DFS_PATHNAMES,
5960 if (!NT_STATUS_IS_OK(status)) {
5961 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5962 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5963 ERRSRV, ERRbadpath);
5967 reply_nterror(req, status);
5972 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
5974 status = rename_internals(ctx, conn, req, name, newname, attrs, False,
5975 src_has_wcard, dest_has_wcard, DELETE_ACCESS);
5976 if (!NT_STATUS_IS_OK(status)) {
5977 if (open_was_deferred(req->mid)) {
5978 /* We have re-scheduled this call. */
5982 reply_nterror(req, status);
5987 reply_outbuf(req, 0, 0);
5993 /*******************************************************************
5994 Copy a file as part of a reply_copy.
5995 ******************************************************************/
5998 * TODO: check error codes on all callers
6001 NTSTATUS copy_file(TALLOC_CTX *ctx,
6002 connection_struct *conn,
6007 bool target_is_directory)
6009 SMB_STRUCT_STAT src_sbuf, sbuf2;
6011 files_struct *fsp1,*fsp2;
6014 uint32 new_create_disposition;
6017 dest = talloc_strdup(ctx, dest1);
6019 return NT_STATUS_NO_MEMORY;
6021 if (target_is_directory) {
6022 const char *p = strrchr_m(src,'/');
6028 dest = talloc_asprintf_append(dest,
6032 return NT_STATUS_NO_MEMORY;
6036 if (!vfs_file_exist(conn,src,&src_sbuf)) {
6038 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6041 if (!target_is_directory && count) {
6042 new_create_disposition = FILE_OPEN;
6044 if (!map_open_params_to_ntcreate(dest1,0,ofun,
6045 NULL, NULL, &new_create_disposition, NULL)) {
6047 return NT_STATUS_INVALID_PARAMETER;
6051 status = open_file_ntcreate(conn, NULL, src, &src_sbuf,
6053 FILE_SHARE_READ|FILE_SHARE_WRITE,
6056 FILE_ATTRIBUTE_NORMAL,
6060 if (!NT_STATUS_IS_OK(status)) {
6065 dosattrs = dos_mode(conn, src, &src_sbuf);
6066 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) {
6067 ZERO_STRUCTP(&sbuf2);
6070 status = open_file_ntcreate(conn, NULL, dest, &sbuf2,
6072 FILE_SHARE_READ|FILE_SHARE_WRITE,
6073 new_create_disposition,
6081 if (!NT_STATUS_IS_OK(status)) {
6082 close_file(fsp1,ERROR_CLOSE);
6086 if ((ofun&3) == 1) {
6087 if(SMB_VFS_LSEEK(fsp2,0,SEEK_END) == -1) {
6088 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
6090 * Stop the copy from occurring.
6093 src_sbuf.st_size = 0;
6097 if (src_sbuf.st_size) {
6098 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
6101 close_file(fsp1,NORMAL_CLOSE);
6103 /* Ensure the modtime is set correctly on the destination file. */
6104 set_close_write_time(fsp2, get_mtimespec(&src_sbuf));
6107 * As we are opening fsp1 read-only we only expect
6108 * an error on close on fsp2 if we are out of space.
6109 * Thus we don't look at the error return from the
6112 status = close_file(fsp2,NORMAL_CLOSE);
6114 if (!NT_STATUS_IS_OK(status)) {
6118 if (ret != (SMB_OFF_T)src_sbuf.st_size) {
6119 return NT_STATUS_DISK_FULL;
6122 return NT_STATUS_OK;
6125 /****************************************************************************
6126 Reply to a file copy.
6127 ****************************************************************************/
6129 void reply_copy(struct smb_request *req)
6131 connection_struct *conn = req->conn;
6133 char *newname = NULL;
6134 char *directory = NULL;
6138 int error = ERRnoaccess;
6143 bool target_is_directory=False;
6144 bool source_has_wild = False;
6145 bool dest_has_wild = False;
6146 SMB_STRUCT_STAT sbuf1, sbuf2;
6148 TALLOC_CTX *ctx = talloc_tos();
6150 START_PROFILE(SMBcopy);
6153 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6154 END_PROFILE(SMBcopy);
6158 tid2 = SVAL(req->inbuf,smb_vwv0);
6159 ofun = SVAL(req->inbuf,smb_vwv1);
6160 flags = SVAL(req->inbuf,smb_vwv2);
6162 p = smb_buf(req->inbuf);
6163 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
6164 0, STR_TERMINATE, &status,
6166 if (!NT_STATUS_IS_OK(status)) {
6167 reply_nterror(req, status);
6168 END_PROFILE(SMBcopy);
6171 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
6172 0, STR_TERMINATE, &status,
6174 if (!NT_STATUS_IS_OK(status)) {
6175 reply_nterror(req, status);
6176 END_PROFILE(SMBcopy);
6180 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
6182 if (tid2 != conn->cnum) {
6183 /* can't currently handle inter share copies XXXX */
6184 DEBUG(3,("Rejecting inter-share copy\n"));
6185 reply_doserror(req, ERRSRV, ERRinvdevice);
6186 END_PROFILE(SMBcopy);
6190 status = resolve_dfspath_wcard(ctx, conn,
6191 req->flags2 & FLAGS2_DFS_PATHNAMES,
6195 if (!NT_STATUS_IS_OK(status)) {
6196 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6197 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6198 ERRSRV, ERRbadpath);
6199 END_PROFILE(SMBcopy);
6202 reply_nterror(req, status);
6203 END_PROFILE(SMBcopy);
6207 status = resolve_dfspath_wcard(ctx, conn,
6208 req->flags2 & FLAGS2_DFS_PATHNAMES,
6212 if (!NT_STATUS_IS_OK(status)) {
6213 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6214 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6215 ERRSRV, ERRbadpath);
6216 END_PROFILE(SMBcopy);
6219 reply_nterror(req, status);
6220 END_PROFILE(SMBcopy);
6224 status = unix_convert(ctx, conn, name, source_has_wild,
6225 &name, NULL, &sbuf1);
6226 if (!NT_STATUS_IS_OK(status)) {
6227 reply_nterror(req, status);
6228 END_PROFILE(SMBcopy);
6232 status = unix_convert(ctx, conn, newname, dest_has_wild,
6233 &newname, NULL, &sbuf2);
6234 if (!NT_STATUS_IS_OK(status)) {
6235 reply_nterror(req, status);
6236 END_PROFILE(SMBcopy);
6240 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
6242 if ((flags&1) && target_is_directory) {
6243 reply_doserror(req, ERRDOS, ERRbadfile);
6244 END_PROFILE(SMBcopy);
6248 if ((flags&2) && !target_is_directory) {
6249 reply_doserror(req, ERRDOS, ERRbadpath);
6250 END_PROFILE(SMBcopy);
6254 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
6255 /* wants a tree copy! XXXX */
6256 DEBUG(3,("Rejecting tree copy\n"));
6257 reply_doserror(req, ERRSRV, ERRerror);
6258 END_PROFILE(SMBcopy);
6262 p = strrchr_m(name,'/');
6264 directory = talloc_strdup(ctx, "./");
6266 reply_nterror(req, NT_STATUS_NO_MEMORY);
6267 END_PROFILE(SMBcopy);
6273 directory = talloc_strdup(ctx, name);
6275 reply_nterror(req, NT_STATUS_NO_MEMORY);
6276 END_PROFILE(SMBcopy);
6283 * We should only check the mangled cache
6284 * here if unix_convert failed. This means
6285 * that the path in 'mask' doesn't exist
6286 * on the file system and so we need to look
6287 * for a possible mangle. This patch from
6288 * Tine Smukavec <valentin.smukavec@hermes.si>.
6291 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
6292 char *new_mask = NULL;
6293 mangle_lookup_name_from_8_3(ctx,
6302 if (!source_has_wild) {
6303 directory = talloc_asprintf_append(directory,
6306 if (dest_has_wild) {
6307 char *mod_newname = NULL;
6308 if (!resolve_wildcards(ctx,
6309 directory,newname,&mod_newname)) {
6310 reply_nterror(req, NT_STATUS_NO_MEMORY);
6311 END_PROFILE(SMBcopy);
6314 newname = mod_newname;
6317 status = check_name(conn, directory);
6318 if (!NT_STATUS_IS_OK(status)) {
6319 reply_nterror(req, status);
6320 END_PROFILE(SMBcopy);
6324 status = check_name(conn, newname);
6325 if (!NT_STATUS_IS_OK(status)) {
6326 reply_nterror(req, status);
6327 END_PROFILE(SMBcopy);
6331 status = copy_file(ctx,conn,directory,newname,ofun,
6332 count,target_is_directory);
6334 if(!NT_STATUS_IS_OK(status)) {
6335 reply_nterror(req, status);
6336 END_PROFILE(SMBcopy);
6342 struct smb_Dir *dir_hnd = NULL;
6343 const char *dname = NULL;
6346 if (strequal(mask,"????????.???")) {
6351 status = check_name(conn, directory);
6352 if (!NT_STATUS_IS_OK(status)) {
6353 reply_nterror(req, status);
6354 END_PROFILE(SMBcopy);
6358 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, 0);
6359 if (dir_hnd == NULL) {
6360 status = map_nt_error_from_unix(errno);
6361 reply_nterror(req, status);
6362 END_PROFILE(SMBcopy);
6368 while ((dname = ReadDirName(dir_hnd, &offset))) {
6369 char *destname = NULL;
6372 if (ISDOT(dname) || ISDOTDOT(dname)) {
6376 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
6380 if(!mask_match(dname, mask, conn->case_sensitive)) {
6384 error = ERRnoaccess;
6385 fname = talloc_asprintf(ctx,
6390 TALLOC_FREE(dir_hnd);
6391 reply_nterror(req, NT_STATUS_NO_MEMORY);
6392 END_PROFILE(SMBcopy);
6396 if (!resolve_wildcards(ctx,
6397 fname,newname,&destname)) {
6401 TALLOC_FREE(dir_hnd);
6402 reply_nterror(req, NT_STATUS_NO_MEMORY);
6403 END_PROFILE(SMBcopy);
6407 status = check_name(conn, fname);
6408 if (!NT_STATUS_IS_OK(status)) {
6409 TALLOC_FREE(dir_hnd);
6410 reply_nterror(req, status);
6411 END_PROFILE(SMBcopy);
6415 status = check_name(conn, destname);
6416 if (!NT_STATUS_IS_OK(status)) {
6417 TALLOC_FREE(dir_hnd);
6418 reply_nterror(req, status);
6419 END_PROFILE(SMBcopy);
6423 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
6425 status = copy_file(ctx,conn,fname,destname,ofun,
6426 count,target_is_directory);
6427 if (NT_STATUS_IS_OK(status)) {
6431 TALLOC_FREE(destname);
6433 TALLOC_FREE(dir_hnd);
6438 /* Error on close... */
6440 reply_unixerror(req, ERRHRD, ERRgeneral);
6441 END_PROFILE(SMBcopy);
6445 reply_doserror(req, ERRDOS, error);
6446 END_PROFILE(SMBcopy);
6450 reply_outbuf(req, 1, 0);
6451 SSVAL(req->outbuf,smb_vwv0,count);
6453 END_PROFILE(SMBcopy);
6458 #define DBGC_CLASS DBGC_LOCKING
6460 /****************************************************************************
6461 Get a lock pid, dealing with large count requests.
6462 ****************************************************************************/
6464 uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
6466 if(!large_file_format)
6467 return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
6469 return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
6472 /****************************************************************************
6473 Get a lock count, dealing with large count requests.
6474 ****************************************************************************/
6476 SMB_BIG_UINT get_lock_count( char *data, int data_offset, bool large_file_format)
6478 SMB_BIG_UINT count = 0;
6480 if(!large_file_format) {
6481 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
6484 #if defined(HAVE_LONGLONG)
6485 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
6486 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
6487 #else /* HAVE_LONGLONG */
6490 * NT4.x seems to be broken in that it sends large file (64 bit)
6491 * lockingX calls even if the CAP_LARGE_FILES was *not*
6492 * negotiated. For boxes without large unsigned ints truncate the
6493 * lock count by dropping the top 32 bits.
6496 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
6497 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
6498 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
6499 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
6500 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
6503 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
6504 #endif /* HAVE_LONGLONG */
6510 #if !defined(HAVE_LONGLONG)
6511 /****************************************************************************
6512 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
6513 ****************************************************************************/
6515 static uint32 map_lock_offset(uint32 high, uint32 low)
6519 uint32 highcopy = high;
6522 * Try and find out how many significant bits there are in high.
6525 for(i = 0; highcopy; i++)
6529 * We use 31 bits not 32 here as POSIX
6530 * lock offsets may not be negative.
6533 mask = (~0) << (31 - i);
6536 return 0; /* Fail. */
6542 #endif /* !defined(HAVE_LONGLONG) */
6544 /****************************************************************************
6545 Get a lock offset, dealing with large offset requests.
6546 ****************************************************************************/
6548 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err)
6550 SMB_BIG_UINT offset = 0;
6554 if(!large_file_format) {
6555 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
6558 #if defined(HAVE_LONGLONG)
6559 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
6560 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
6561 #else /* HAVE_LONGLONG */
6564 * NT4.x seems to be broken in that it sends large file (64 bit)
6565 * lockingX calls even if the CAP_LARGE_FILES was *not*
6566 * negotiated. For boxes without large unsigned ints mangle the
6567 * lock offset by mapping the top 32 bits onto the lower 32.
6570 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
6571 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6572 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
6575 if((new_low = map_lock_offset(high, low)) == 0) {
6577 return (SMB_BIG_UINT)-1;
6580 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
6581 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
6582 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
6583 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
6586 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6587 #endif /* HAVE_LONGLONG */
6593 /****************************************************************************
6594 Reply to a lockingX request.
6595 ****************************************************************************/
6597 void reply_lockingX(struct smb_request *req)
6599 connection_struct *conn = req->conn;
6601 unsigned char locktype;
6602 unsigned char oplocklevel;
6605 SMB_BIG_UINT count = 0, offset = 0;
6610 bool large_file_format;
6612 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
6614 START_PROFILE(SMBlockingX);
6617 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6618 END_PROFILE(SMBlockingX);
6622 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
6623 locktype = CVAL(req->inbuf,smb_vwv3);
6624 oplocklevel = CVAL(req->inbuf,smb_vwv3+1);
6625 num_ulocks = SVAL(req->inbuf,smb_vwv6);
6626 num_locks = SVAL(req->inbuf,smb_vwv7);
6627 lock_timeout = IVAL(req->inbuf,smb_vwv4);
6628 large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
6630 if (!check_fsp(conn, req, fsp, ¤t_user)) {
6631 END_PROFILE(SMBlockingX);
6635 data = smb_buf(req->inbuf);
6637 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
6638 /* we don't support these - and CANCEL_LOCK makes w2k
6639 and XP reboot so I don't really want to be
6640 compatible! (tridge) */
6641 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
6642 END_PROFILE(SMBlockingX);
6646 /* Check if this is an oplock break on a file
6647 we have granted an oplock on.
6649 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
6650 /* Client can insist on breaking to none. */
6651 bool break_to_none = (oplocklevel == 0);
6654 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
6655 "for fnum = %d\n", (unsigned int)oplocklevel,
6659 * Make sure we have granted an exclusive or batch oplock on
6663 if (fsp->oplock_type == 0) {
6665 /* The Samba4 nbench simulator doesn't understand
6666 the difference between break to level2 and break
6667 to none from level2 - it sends oplock break
6668 replies in both cases. Don't keep logging an error
6669 message here - just ignore it. JRA. */
6671 DEBUG(5,("reply_lockingX: Error : oplock break from "
6672 "client for fnum = %d (oplock=%d) and no "
6673 "oplock granted on this file (%s).\n",
6674 fsp->fnum, fsp->oplock_type, fsp->fsp_name));
6676 /* if this is a pure oplock break request then don't
6678 if (num_locks == 0 && num_ulocks == 0) {
6679 END_PROFILE(SMBlockingX);
6682 END_PROFILE(SMBlockingX);
6683 reply_doserror(req, ERRDOS, ERRlock);
6688 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
6690 result = remove_oplock(fsp);
6692 result = downgrade_oplock(fsp);
6696 DEBUG(0, ("reply_lockingX: error in removing "
6697 "oplock on file %s\n", fsp->fsp_name));
6698 /* Hmmm. Is this panic justified? */
6699 smb_panic("internal tdb error");
6702 reply_to_oplock_break_requests(fsp);
6704 /* if this is a pure oplock break request then don't send a
6706 if (num_locks == 0 && num_ulocks == 0) {
6707 /* Sanity check - ensure a pure oplock break is not a
6709 if(CVAL(req->inbuf,smb_vwv0) != 0xff)
6710 DEBUG(0,("reply_lockingX: Error : pure oplock "
6711 "break is a chained %d request !\n",
6712 (unsigned int)CVAL(req->inbuf,
6714 END_PROFILE(SMBlockingX);
6720 * We do this check *after* we have checked this is not a oplock break
6721 * response message. JRA.
6724 release_level_2_oplocks_on_change(fsp);
6726 if (smb_buflen(req->inbuf) <
6727 (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
6728 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6729 END_PROFILE(SMBlockingX);
6733 /* Data now points at the beginning of the list
6734 of smb_unlkrng structs */
6735 for(i = 0; i < (int)num_ulocks; i++) {
6736 lock_pid = get_lock_pid( data, i, large_file_format);
6737 count = get_lock_count( data, i, large_file_format);
6738 offset = get_lock_offset( data, i, large_file_format, &err);
6741 * There is no error code marked "stupid client bug".... :-).
6744 END_PROFILE(SMBlockingX);
6745 reply_doserror(req, ERRDOS, ERRnoaccess);
6749 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
6750 "pid %u, file %s\n", (double)offset, (double)count,
6751 (unsigned int)lock_pid, fsp->fsp_name ));
6753 status = do_unlock(smbd_messaging_context(),
6760 if (NT_STATUS_V(status)) {
6761 END_PROFILE(SMBlockingX);
6762 reply_nterror(req, status);
6767 /* Setup the timeout in seconds. */
6769 if (!lp_blocking_locks(SNUM(conn))) {
6773 /* Now do any requested locks */
6774 data += ((large_file_format ? 20 : 10)*num_ulocks);
6776 /* Data now points at the beginning of the list
6777 of smb_lkrng structs */
6779 for(i = 0; i < (int)num_locks; i++) {
6780 enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
6781 READ_LOCK:WRITE_LOCK);
6782 lock_pid = get_lock_pid( data, i, large_file_format);
6783 count = get_lock_count( data, i, large_file_format);
6784 offset = get_lock_offset( data, i, large_file_format, &err);
6787 * There is no error code marked "stupid client bug".... :-).
6790 END_PROFILE(SMBlockingX);
6791 reply_doserror(req, ERRDOS, ERRnoaccess);
6795 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
6796 "%u, file %s timeout = %d\n", (double)offset,
6797 (double)count, (unsigned int)lock_pid,
6798 fsp->fsp_name, (int)lock_timeout ));
6800 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
6801 if (lp_blocking_locks(SNUM(conn))) {
6803 /* Schedule a message to ourselves to
6804 remove the blocking lock record and
6805 return the right error. */
6807 if (!blocking_lock_cancel(fsp,
6813 NT_STATUS_FILE_LOCK_CONFLICT)) {
6814 END_PROFILE(SMBlockingX);
6819 ERRcancelviolation));
6823 /* Remove a matching pending lock. */
6824 status = do_lock_cancel(fsp,
6830 bool blocking_lock = lock_timeout ? True : False;
6831 bool defer_lock = False;
6832 struct byte_range_lock *br_lck;
6833 uint32 block_smbpid;
6835 br_lck = do_lock(smbd_messaging_context(),
6846 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6847 /* Windows internal resolution for blocking locks seems
6848 to be about 200ms... Don't wait for less than that. JRA. */
6849 if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
6850 lock_timeout = lp_lock_spin_time();
6855 /* This heuristic seems to match W2K3 very well. If a
6856 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
6857 it pretends we asked for a timeout of between 150 - 300 milliseconds as
6858 far as I can tell. Replacement for do_lock_spin(). JRA. */
6860 if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
6861 NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
6863 lock_timeout = lp_lock_spin_time();
6866 if (br_lck && defer_lock) {
6868 * A blocking lock was requested. Package up
6869 * this smb into a queued request and push it
6870 * onto the blocking lock queue.
6872 if(push_blocking_lock_request(br_lck,
6883 TALLOC_FREE(br_lck);
6884 END_PROFILE(SMBlockingX);
6889 TALLOC_FREE(br_lck);
6892 if (NT_STATUS_V(status)) {
6893 END_PROFILE(SMBlockingX);
6894 reply_nterror(req, status);
6899 /* If any of the above locks failed, then we must unlock
6900 all of the previous locks (X/Open spec). */
6902 if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) &&
6906 * Ensure we don't do a remove on the lock that just failed,
6907 * as under POSIX rules, if we have a lock already there, we
6908 * will delete it (and we shouldn't) .....
6910 for(i--; i >= 0; i--) {
6911 lock_pid = get_lock_pid( data, i, large_file_format);
6912 count = get_lock_count( data, i, large_file_format);
6913 offset = get_lock_offset( data, i, large_file_format,
6917 * There is no error code marked "stupid client
6921 END_PROFILE(SMBlockingX);
6922 reply_doserror(req, ERRDOS, ERRnoaccess);
6926 do_unlock(smbd_messaging_context(),
6933 END_PROFILE(SMBlockingX);
6934 reply_nterror(req, status);
6938 reply_outbuf(req, 2, 0);
6940 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
6941 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
6943 END_PROFILE(SMBlockingX);
6948 #define DBGC_CLASS DBGC_ALL
6950 /****************************************************************************
6951 Reply to a SMBreadbmpx (read block multiplex) request.
6952 Always reply with an error, if someone has a platform really needs this,
6953 please contact vl@samba.org
6954 ****************************************************************************/
6956 void reply_readbmpx(struct smb_request *req)
6958 START_PROFILE(SMBreadBmpx);
6959 reply_doserror(req, ERRSRV, ERRuseSTD);
6960 END_PROFILE(SMBreadBmpx);
6964 /****************************************************************************
6965 Reply to a SMBreadbs (read block multiplex secondary) request.
6966 Always reply with an error, if someone has a platform really needs this,
6967 please contact vl@samba.org
6968 ****************************************************************************/
6970 void reply_readbs(struct smb_request *req)
6972 START_PROFILE(SMBreadBs);
6973 reply_doserror(req, ERRSRV, ERRuseSTD);
6974 END_PROFILE(SMBreadBs);
6978 /****************************************************************************
6979 Reply to a SMBsetattrE.
6980 ****************************************************************************/
6982 void reply_setattrE(struct smb_request *req)
6984 connection_struct *conn = req->conn;
6985 struct timespec ts[2];
6987 SMB_STRUCT_STAT sbuf;
6990 START_PROFILE(SMBsetattrE);
6993 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6994 END_PROFILE(SMBsetattrE);
6998 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
7000 if(!fsp || (fsp->conn != conn)) {
7001 reply_doserror(req, ERRDOS, ERRbadfid);
7002 END_PROFILE(SMBsetattrE);
7008 * Convert the DOS times into unix times. Ignore create
7009 * time as UNIX can't set this.
7012 ts[0] = convert_time_t_to_timespec(
7013 srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */
7014 ts[1] = convert_time_t_to_timespec(
7015 srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */
7017 reply_outbuf(req, 0, 0);
7020 * Patch from Ray Frush <frush@engr.colostate.edu>
7021 * Sometimes times are sent as zero - ignore them.
7024 /* Ensure we have a valid stat struct for the source. */
7025 if (fsp->fh->fd != -1) {
7026 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
7027 status = map_nt_error_from_unix(errno);
7028 reply_nterror(req, status);
7029 END_PROFILE(SMBsetattrE);
7033 if (SMB_VFS_STAT(conn, fsp->fsp_name, &sbuf) == -1) {
7034 status = map_nt_error_from_unix(errno);
7035 reply_nterror(req, status);
7036 END_PROFILE(SMBsetattrE);
7041 status = smb_set_file_time(conn, fsp, fsp->fsp_name,
7043 if (!NT_STATUS_IS_OK(status)) {
7044 reply_doserror(req, ERRDOS, ERRnoaccess);
7045 END_PROFILE(SMBsetattrE);
7049 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
7051 (unsigned int)ts[0].tv_sec,
7052 (unsigned int)ts[1].tv_sec));
7054 END_PROFILE(SMBsetattrE);
7059 /* Back from the dead for OS/2..... JRA. */
7061 /****************************************************************************
7062 Reply to a SMBwritebmpx (write block multiplex primary) request.
7063 Always reply with an error, if someone has a platform really needs this,
7064 please contact vl@samba.org
7065 ****************************************************************************/
7067 void reply_writebmpx(struct smb_request *req)
7069 START_PROFILE(SMBwriteBmpx);
7070 reply_doserror(req, ERRSRV, ERRuseSTD);
7071 END_PROFILE(SMBwriteBmpx);
7075 /****************************************************************************
7076 Reply to a SMBwritebs (write block multiplex secondary) request.
7077 Always reply with an error, if someone has a platform really needs this,
7078 please contact vl@samba.org
7079 ****************************************************************************/
7081 void reply_writebs(struct smb_request *req)
7083 START_PROFILE(SMBwriteBs);
7084 reply_doserror(req, ERRSRV, ERRuseSTD);
7085 END_PROFILE(SMBwriteBs);
7089 /****************************************************************************
7090 Reply to a SMBgetattrE.
7091 ****************************************************************************/
7093 void reply_getattrE(struct smb_request *req)
7095 connection_struct *conn = req->conn;
7096 SMB_STRUCT_STAT sbuf;
7099 struct timespec create_ts;
7101 START_PROFILE(SMBgetattrE);
7104 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7105 END_PROFILE(SMBgetattrE);
7109 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
7111 if(!fsp || (fsp->conn != conn)) {
7112 reply_doserror(req, ERRDOS, ERRbadfid);
7113 END_PROFILE(SMBgetattrE);
7117 /* Do an fstat on this file */
7118 if(fsp_stat(fsp, &sbuf)) {
7119 reply_unixerror(req, ERRDOS, ERRnoaccess);
7120 END_PROFILE(SMBgetattrE);
7124 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
7127 * Convert the times into dos times. Set create
7128 * date to be last modify date as UNIX doesn't save
7132 reply_outbuf(req, 11, 0);
7134 create_ts = get_create_timespec(&sbuf,
7135 lp_fake_dir_create_times(SNUM(conn)));
7136 srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec);
7137 srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime);
7138 /* Should we check pending modtime here ? JRA */
7139 srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime);
7142 SIVAL(req->outbuf, smb_vwv6, 0);
7143 SIVAL(req->outbuf, smb_vwv8, 0);
7145 uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
7146 SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
7147 SIVAL(req->outbuf, smb_vwv8, allocation_size);
7149 SSVAL(req->outbuf,smb_vwv10, mode);
7151 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
7153 END_PROFILE(SMBgetattrE);