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;
171 if (NT_STATUS_IS_OK(ret) && !posix_path) {
172 ret = split_ntfs_stream_name(NULL, path, NULL, NULL);
177 /****************************************************************************
178 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
179 No wildcards allowed.
180 ****************************************************************************/
182 NTSTATUS check_path_syntax(char *path)
185 return check_path_syntax_internal(path, False, &ignore);
188 /****************************************************************************
189 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
190 Wildcards allowed - p_contains_wcard returns true if the last component contained
192 ****************************************************************************/
194 NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
196 return check_path_syntax_internal(path, False, p_contains_wcard);
199 /****************************************************************************
200 Check the path for a POSIX client.
201 We're assuming here that '/' is not the second byte in any multibyte char
202 set (a safe assumption).
203 ****************************************************************************/
205 NTSTATUS check_path_syntax_posix(char *path)
208 return check_path_syntax_internal(path, True, &ignore);
211 /****************************************************************************
212 Pull a string and check the path allowing a wilcard - provide for error return.
213 ****************************************************************************/
215 size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
223 bool *contains_wcard)
230 ret = srvstr_pull_buf_talloc(ctx,
237 ret = srvstr_pull_talloc(ctx,
247 *err = NT_STATUS_INVALID_PARAMETER;
251 *contains_wcard = False;
253 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
255 * For a DFS path the function parse_dfs_path()
256 * will do the path processing, just make a copy.
262 if (lp_posix_pathnames()) {
263 *err = check_path_syntax_posix(*pp_dest);
265 *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
271 /****************************************************************************
272 Pull a string and check the path - provide for error return.
273 ****************************************************************************/
275 size_t srvstr_get_path(TALLOC_CTX *ctx,
289 ret = srvstr_pull_buf_talloc(ctx,
296 ret = srvstr_pull_talloc(ctx,
306 *err = NT_STATUS_INVALID_PARAMETER;
310 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
312 * For a DFS path the function parse_dfs_path()
313 * will do the path processing, just make a copy.
319 if (lp_posix_pathnames()) {
320 *err = check_path_syntax_posix(*pp_dest);
322 *err = check_path_syntax(*pp_dest);
328 /****************************************************************************
329 Check if we have a correct fsp pointing to a file. Basic check for open fsp.
330 ****************************************************************************/
332 bool check_fsp_open(connection_struct *conn, struct smb_request *req,
333 files_struct *fsp, struct current_user *user)
335 if (!(fsp) || !(conn)) {
336 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
339 if (((conn) != (fsp)->conn) || user->vuid != (fsp)->vuid) {
340 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
346 /****************************************************************************
347 Check if we have a correct fsp pointing to a file. Replacement for the
349 ****************************************************************************/
351 bool check_fsp(connection_struct *conn, struct smb_request *req,
352 files_struct *fsp, struct current_user *user)
354 if (!check_fsp_open(conn, req, fsp, user)) {
357 if ((fsp)->is_directory) {
358 reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
361 if ((fsp)->fh->fd == -1) {
362 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
365 (fsp)->num_smb_operations++;
369 /****************************************************************************
370 Check if we have a correct fsp. Replacement for the FSP_BELONGS_CONN macro
371 ****************************************************************************/
373 bool fsp_belongs_conn(connection_struct *conn, struct smb_request *req,
374 files_struct *fsp, struct current_user *user)
376 if ((fsp) && (conn) && ((conn)==(fsp)->conn)
377 && (current_user.vuid==(fsp)->vuid)) {
381 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
385 /****************************************************************************
386 Reply to a (netbios-level) special message.
387 ****************************************************************************/
389 void reply_special(char *inbuf)
391 int msg_type = CVAL(inbuf,0);
392 int msg_flags = CVAL(inbuf,1);
397 * We only really use 4 bytes of the outbuf, but for the smb_setlen
398 * calculation & friends (srv_send_smb uses that) we need the full smb
401 char outbuf[smb_size];
403 static bool already_got_session = False;
407 memset(outbuf, '\0', sizeof(outbuf));
409 smb_setlen(outbuf,0);
412 case 0x81: /* session request */
414 if (already_got_session) {
415 exit_server_cleanly("multiple session request not permitted");
418 SCVAL(outbuf,0,0x82);
420 if (name_len(inbuf+4) > 50 ||
421 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
422 DEBUG(0,("Invalid name length in session request\n"));
425 name_extract(inbuf,4,name1);
426 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
427 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
430 set_local_machine_name(name1, True);
431 set_remote_machine_name(name2, True);
433 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
434 get_local_machine_name(), get_remote_machine_name(),
437 if (name_type == 'R') {
438 /* We are being asked for a pathworks session ---
440 SCVAL(outbuf, 0,0x83);
444 /* only add the client's machine name to the list
445 of possibly valid usernames if we are operating
446 in share mode security */
447 if (lp_security() == SEC_SHARE) {
448 add_session_user(get_remote_machine_name());
451 reload_services(True);
454 already_got_session = True;
457 case 0x89: /* session keepalive request
458 (some old clients produce this?) */
459 SCVAL(outbuf,0,SMBkeepalive);
463 case 0x82: /* positive session response */
464 case 0x83: /* negative session response */
465 case 0x84: /* retarget session response */
466 DEBUG(0,("Unexpected session response\n"));
469 case SMBkeepalive: /* session keepalive */
474 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
475 msg_type, msg_flags));
477 srv_send_smb(smbd_server_fd(), outbuf, false);
481 /****************************************************************************
483 conn POINTER CAN BE NULL HERE !
484 ****************************************************************************/
486 void reply_tcon(struct smb_request *req)
488 connection_struct *conn = req->conn;
490 char *service_buf = NULL;
491 char *password = NULL;
496 DATA_BLOB password_blob;
497 TALLOC_CTX *ctx = talloc_tos();
499 START_PROFILE(SMBtcon);
501 if (smb_buflen(req->inbuf) < 4) {
502 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
503 END_PROFILE(SMBtcon);
507 p = smb_buf(req->inbuf)+1;
508 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
509 &service_buf, p, STR_TERMINATE) + 1;
510 pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
511 &password, p, STR_TERMINATE) + 1;
513 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
514 &dev, p, STR_TERMINATE) + 1;
516 if (service_buf == NULL || password == NULL || dev == NULL) {
517 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
518 END_PROFILE(SMBtcon);
521 p = strrchr_m(service_buf,'\\');
525 service = service_buf;
528 password_blob = data_blob(password, pwlen+1);
530 conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
533 data_blob_clear_free(&password_blob);
536 reply_nterror(req, nt_status);
537 END_PROFILE(SMBtcon);
541 reply_outbuf(req, 2, 0);
542 SSVAL(req->outbuf,smb_vwv0,max_recv);
543 SSVAL(req->outbuf,smb_vwv1,conn->cnum);
544 SSVAL(req->outbuf,smb_tid,conn->cnum);
546 DEBUG(3,("tcon service=%s cnum=%d\n",
547 service, conn->cnum));
549 END_PROFILE(SMBtcon);
553 /****************************************************************************
554 Reply to a tcon and X.
555 conn POINTER CAN BE NULL HERE !
556 ****************************************************************************/
558 void reply_tcon_and_X(struct smb_request *req)
560 connection_struct *conn = req->conn;
561 char *service = NULL;
563 TALLOC_CTX *ctx = talloc_tos();
564 /* what the cleint thinks the device is */
565 char *client_devicetype = NULL;
566 /* what the server tells the client the share represents */
567 const char *server_devicetype;
574 START_PROFILE(SMBtconX);
577 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
578 END_PROFILE(SMBtconX);
582 passlen = SVAL(req->inbuf,smb_vwv3);
583 tcon_flags = SVAL(req->inbuf,smb_vwv2);
585 /* we might have to close an old one */
586 if ((tcon_flags & 0x1) && conn) {
587 close_cnum(conn,req->vuid);
592 if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
593 reply_doserror(req, ERRDOS, ERRbuftoosmall);
594 END_PROFILE(SMBtconX);
598 if (global_encrypted_passwords_negotiated) {
599 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
601 if (lp_security() == SEC_SHARE) {
603 * Security = share always has a pad byte
604 * after the password.
606 p = smb_buf(req->inbuf) + passlen + 1;
608 p = smb_buf(req->inbuf) + passlen;
611 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
613 /* Ensure correct termination */
614 password.data[passlen]=0;
615 p = smb_buf(req->inbuf) + passlen + 1;
618 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
622 data_blob_clear_free(&password);
623 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
624 END_PROFILE(SMBtconX);
629 * the service name can be either: \\server\share
630 * or share directly like on the DELL PowerVault 705
633 q = strchr_m(path+2,'\\');
635 data_blob_clear_free(&password);
636 reply_doserror(req, ERRDOS, ERRnosuchshare);
637 END_PROFILE(SMBtconX);
645 p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
646 &client_devicetype, p,
647 MIN(6,smb_bufrem(req->inbuf, p)), STR_ASCII);
649 if (client_devicetype == NULL) {
650 data_blob_clear_free(&password);
651 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
652 END_PROFILE(SMBtconX);
656 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
658 conn = make_connection(service, password, client_devicetype,
659 req->vuid, &nt_status);
662 data_blob_clear_free(&password);
665 reply_nterror(req, nt_status);
666 END_PROFILE(SMBtconX);
671 server_devicetype = "IPC";
672 else if ( IS_PRINT(conn) )
673 server_devicetype = "LPT1:";
675 server_devicetype = "A:";
677 if (Protocol < PROTOCOL_NT1) {
678 reply_outbuf(req, 2, 0);
679 if (message_push_string(&req->outbuf, server_devicetype,
680 STR_TERMINATE|STR_ASCII) == -1) {
681 reply_nterror(req, NT_STATUS_NO_MEMORY);
682 END_PROFILE(SMBtconX);
686 /* NT sets the fstype of IPC$ to the null string */
687 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
689 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
690 /* Return permissions. */
694 reply_outbuf(req, 7, 0);
697 perm1 = FILE_ALL_ACCESS;
698 perm2 = FILE_ALL_ACCESS;
700 perm1 = CAN_WRITE(conn) ?
705 SIVAL(req->outbuf, smb_vwv3, perm1);
706 SIVAL(req->outbuf, smb_vwv5, perm2);
708 reply_outbuf(req, 3, 0);
711 if ((message_push_string(&req->outbuf, server_devicetype,
712 STR_TERMINATE|STR_ASCII) == -1)
713 || (message_push_string(&req->outbuf, fstype,
714 STR_TERMINATE) == -1)) {
715 reply_nterror(req, NT_STATUS_NO_MEMORY);
716 END_PROFILE(SMBtconX);
720 /* what does setting this bit do? It is set by NT4 and
721 may affect the ability to autorun mounted cdroms */
722 SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
723 (lp_csc_policy(SNUM(conn)) << 2));
725 init_dfsroot(conn, req->inbuf, req->outbuf);
729 DEBUG(3,("tconX service=%s \n",
732 /* set the incoming and outgoing tid to the just created one */
733 SSVAL(req->inbuf,smb_tid,conn->cnum);
734 SSVAL(req->outbuf,smb_tid,conn->cnum);
736 END_PROFILE(SMBtconX);
742 /****************************************************************************
743 Reply to an unknown type.
744 ****************************************************************************/
746 void reply_unknown_new(struct smb_request *req, uint8 type)
748 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
749 smb_fn_name(type), type, type));
750 reply_doserror(req, ERRSRV, ERRunknownsmb);
754 /****************************************************************************
756 conn POINTER CAN BE NULL HERE !
757 ****************************************************************************/
759 void reply_ioctl(struct smb_request *req)
761 connection_struct *conn = req->conn;
768 START_PROFILE(SMBioctl);
771 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
772 END_PROFILE(SMBioctl);
776 device = SVAL(req->inbuf,smb_vwv1);
777 function = SVAL(req->inbuf,smb_vwv2);
778 ioctl_code = (device << 16) + function;
780 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
782 switch (ioctl_code) {
783 case IOCTL_QUERY_JOB_INFO:
787 reply_doserror(req, ERRSRV, ERRnosupport);
788 END_PROFILE(SMBioctl);
792 reply_outbuf(req, 8, replysize+1);
793 SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
794 SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
795 SSVAL(req->outbuf,smb_vwv6,52); /* Offset to data */
796 p = smb_buf(req->outbuf);
797 memset(p, '\0', replysize+1); /* valgrind-safe. */
798 p += 1; /* Allow for alignment */
800 switch (ioctl_code) {
801 case IOCTL_QUERY_JOB_INFO:
803 files_struct *fsp = file_fsp(SVAL(req->inbuf,
806 reply_doserror(req, ERRDOS, ERRbadfid);
807 END_PROFILE(SMBioctl);
810 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
811 srvstr_push((char *)req->outbuf, req->flags2, p+2,
813 STR_TERMINATE|STR_ASCII);
815 srvstr_push((char *)req->outbuf, req->flags2,
816 p+18, lp_servicename(SNUM(conn)),
817 13, STR_TERMINATE|STR_ASCII);
825 END_PROFILE(SMBioctl);
829 /****************************************************************************
830 Strange checkpath NTSTATUS mapping.
831 ****************************************************************************/
833 static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
835 /* Strange DOS error code semantics only for checkpath... */
836 if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
837 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
838 /* We need to map to ERRbadpath */
839 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
845 /****************************************************************************
846 Reply to a checkpath.
847 ****************************************************************************/
849 void reply_checkpath(struct smb_request *req)
851 connection_struct *conn = req->conn;
853 SMB_STRUCT_STAT sbuf;
855 TALLOC_CTX *ctx = talloc_tos();
857 START_PROFILE(SMBcheckpath);
859 srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
860 smb_buf(req->inbuf) + 1, 0,
861 STR_TERMINATE, &status);
862 if (!NT_STATUS_IS_OK(status)) {
863 status = map_checkpath_error((char *)req->inbuf, status);
864 reply_nterror(req, status);
865 END_PROFILE(SMBcheckpath);
869 status = resolve_dfspath(ctx, conn,
870 req->flags2 & FLAGS2_DFS_PATHNAMES,
873 if (!NT_STATUS_IS_OK(status)) {
874 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
875 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
877 END_PROFILE(SMBcheckpath);
883 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
885 status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
886 if (!NT_STATUS_IS_OK(status)) {
890 status = check_name(conn, name);
891 if (!NT_STATUS_IS_OK(status)) {
892 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status)));
896 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
897 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
898 status = map_nt_error_from_unix(errno);
902 if (!S_ISDIR(sbuf.st_mode)) {
903 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
905 END_PROFILE(SMBcheckpath);
909 reply_outbuf(req, 0, 0);
911 END_PROFILE(SMBcheckpath);
916 END_PROFILE(SMBcheckpath);
918 /* We special case this - as when a Windows machine
919 is parsing a path is steps through the components
920 one at a time - if a component fails it expects
921 ERRbadpath, not ERRbadfile.
923 status = map_checkpath_error((char *)req->inbuf, status);
924 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
926 * Windows returns different error codes if
927 * the parent directory is valid but not the
928 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
929 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
930 * if the path is invalid.
932 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
937 reply_nterror(req, status);
940 /****************************************************************************
942 ****************************************************************************/
944 void reply_getatr(struct smb_request *req)
946 connection_struct *conn = req->conn;
948 SMB_STRUCT_STAT sbuf;
954 TALLOC_CTX *ctx = talloc_tos();
956 START_PROFILE(SMBgetatr);
958 p = smb_buf(req->inbuf) + 1;
959 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
960 0, STR_TERMINATE, &status);
961 if (!NT_STATUS_IS_OK(status)) {
962 reply_nterror(req, status);
963 END_PROFILE(SMBgetatr);
967 status = resolve_dfspath(ctx, conn,
968 req->flags2 & FLAGS2_DFS_PATHNAMES,
971 if (!NT_STATUS_IS_OK(status)) {
972 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
973 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
975 END_PROFILE(SMBgetatr);
978 reply_nterror(req, status);
979 END_PROFILE(SMBgetatr);
983 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
984 under WfWg - weird! */
985 if (*fname == '\0') {
986 mode = aHIDDEN | aDIR;
987 if (!CAN_WRITE(conn)) {
993 status = unix_convert(ctx, conn, fname, False, &fname, NULL,&sbuf);
994 if (!NT_STATUS_IS_OK(status)) {
995 reply_nterror(req, status);
996 END_PROFILE(SMBgetatr);
999 status = check_name(conn, fname);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
1002 reply_nterror(req, status);
1003 END_PROFILE(SMBgetatr);
1006 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
1007 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
1008 reply_unixerror(req, ERRDOS,ERRbadfile);
1009 END_PROFILE(SMBgetatr);
1013 mode = dos_mode(conn,fname,&sbuf);
1014 size = sbuf.st_size;
1015 mtime = sbuf.st_mtime;
1021 reply_outbuf(req, 10, 0);
1023 SSVAL(req->outbuf,smb_vwv0,mode);
1024 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1025 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1027 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1029 SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1031 if (Protocol >= PROTOCOL_NT1) {
1032 SSVAL(req->outbuf, smb_flg2,
1033 SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1036 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
1038 END_PROFILE(SMBgetatr);
1042 /****************************************************************************
1044 ****************************************************************************/
1046 void reply_setatr(struct smb_request *req)
1048 connection_struct *conn = req->conn;
1052 SMB_STRUCT_STAT sbuf;
1055 TALLOC_CTX *ctx = talloc_tos();
1057 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 if (mode != FILE_ATTRIBUTE_NORMAL) {
1117 if (VALID_STAT_OF_DIR(sbuf))
1122 if (file_set_dosmode(conn,fname,mode,&sbuf,NULL,false) != 0) {
1123 reply_unixerror(req, ERRDOS, ERRnoaccess);
1124 END_PROFILE(SMBsetatr);
1129 if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) {
1130 reply_unixerror(req, ERRDOS, ERRnoaccess);
1131 END_PROFILE(SMBsetatr);
1135 reply_outbuf(req, 0, 0);
1137 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1139 END_PROFILE(SMBsetatr);
1143 /****************************************************************************
1145 ****************************************************************************/
1147 void reply_dskattr(struct smb_request *req)
1149 connection_struct *conn = req->conn;
1150 SMB_BIG_UINT dfree,dsize,bsize;
1151 START_PROFILE(SMBdskattr);
1153 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
1154 reply_unixerror(req, ERRHRD, ERRgeneral);
1155 END_PROFILE(SMBdskattr);
1159 reply_outbuf(req, 5, 0);
1161 if (Protocol <= PROTOCOL_LANMAN2) {
1162 double total_space, free_space;
1163 /* we need to scale this to a number that DOS6 can handle. We
1164 use floating point so we can handle large drives on systems
1165 that don't have 64 bit integers
1167 we end up displaying a maximum of 2G to DOS systems
1169 total_space = dsize * (double)bsize;
1170 free_space = dfree * (double)bsize;
1172 dsize = (SMB_BIG_UINT)((total_space+63*512) / (64*512));
1173 dfree = (SMB_BIG_UINT)((free_space+63*512) / (64*512));
1175 if (dsize > 0xFFFF) dsize = 0xFFFF;
1176 if (dfree > 0xFFFF) dfree = 0xFFFF;
1178 SSVAL(req->outbuf,smb_vwv0,dsize);
1179 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1180 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1181 SSVAL(req->outbuf,smb_vwv3,dfree);
1183 SSVAL(req->outbuf,smb_vwv0,dsize);
1184 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1185 SSVAL(req->outbuf,smb_vwv2,512);
1186 SSVAL(req->outbuf,smb_vwv3,dfree);
1189 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1191 END_PROFILE(SMBdskattr);
1195 /****************************************************************************
1197 Can be called from SMBsearch, SMBffirst or SMBfunique.
1198 ****************************************************************************/
1200 void reply_search(struct smb_request *req)
1202 connection_struct *conn = req->conn;
1204 char *directory = NULL;
1210 unsigned int numentries = 0;
1211 unsigned int maxentries = 0;
1212 bool finished = False;
1218 bool check_descend = False;
1219 bool expect_close = False;
1221 bool mask_contains_wcard = False;
1222 bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1223 TALLOC_CTX *ctx = talloc_tos();
1225 START_PROFILE(SMBsearch);
1228 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1229 END_PROFILE(SMBsearch);
1233 if (lp_posix_pathnames()) {
1234 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1235 END_PROFILE(SMBsearch);
1239 /* If we were called as SMBffirst then we must expect close. */
1240 if(CVAL(req->inbuf,smb_com) == SMBffirst) {
1241 expect_close = True;
1244 reply_outbuf(req, 1, 3);
1245 maxentries = SVAL(req->inbuf,smb_vwv0);
1246 dirtype = SVAL(req->inbuf,smb_vwv1);
1247 p = smb_buf(req->inbuf) + 1;
1248 p += srvstr_get_path_wcard(ctx,
1256 &mask_contains_wcard);
1257 if (!NT_STATUS_IS_OK(nt_status)) {
1258 reply_nterror(req, nt_status);
1259 END_PROFILE(SMBsearch);
1263 nt_status = resolve_dfspath_wcard(ctx, conn,
1264 req->flags2 & FLAGS2_DFS_PATHNAMES,
1267 &mask_contains_wcard);
1268 if (!NT_STATUS_IS_OK(nt_status)) {
1269 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1270 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1271 ERRSRV, ERRbadpath);
1272 END_PROFILE(SMBsearch);
1275 reply_nterror(req, nt_status);
1276 END_PROFILE(SMBsearch);
1281 status_len = SVAL(p, 0);
1284 /* dirtype &= ~aDIR; */
1286 if (status_len == 0) {
1287 SMB_STRUCT_STAT sbuf;
1289 nt_status = unix_convert(ctx, conn, path, True,
1290 &directory, NULL, &sbuf);
1291 if (!NT_STATUS_IS_OK(nt_status)) {
1292 reply_nterror(req, nt_status);
1293 END_PROFILE(SMBsearch);
1297 nt_status = check_name(conn, directory);
1298 if (!NT_STATUS_IS_OK(nt_status)) {
1299 reply_nterror(req, nt_status);
1300 END_PROFILE(SMBsearch);
1304 p = strrchr_m(directory,'/');
1307 directory = talloc_strdup(ctx,".");
1309 reply_nterror(req, NT_STATUS_NO_MEMORY);
1310 END_PROFILE(SMBsearch);
1318 if (*directory == '\0') {
1319 directory = talloc_strdup(ctx,".");
1321 reply_nterror(req, NT_STATUS_NO_MEMORY);
1322 END_PROFILE(SMBsearch);
1326 memset((char *)status,'\0',21);
1327 SCVAL(status,0,(dirtype & 0x1F));
1329 nt_status = dptr_create(conn,
1335 mask_contains_wcard,
1338 if (!NT_STATUS_IS_OK(nt_status)) {
1339 reply_nterror(req, nt_status);
1340 END_PROFILE(SMBsearch);
1343 dptr_num = dptr_dnum(conn->dirptr);
1347 memcpy(status,p,21);
1348 status_dirtype = CVAL(status,0) & 0x1F;
1349 if (status_dirtype != (dirtype & 0x1F)) {
1350 dirtype = status_dirtype;
1353 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1354 if (!conn->dirptr) {
1357 string_set(&conn->dirpath,dptr_path(dptr_num));
1358 mask = dptr_wcard(dptr_num);
1363 * For a 'continue' search we have no string. So
1364 * check from the initial saved string.
1366 mask_contains_wcard = ms_has_wild(mask);
1367 dirtype = dptr_attr(dptr_num);
1370 DEBUG(4,("dptr_num is %d\n",dptr_num));
1372 if ((dirtype&0x1F) == aVOLID) {
1373 char buf[DIR_STRUCT_SIZE];
1374 memcpy(buf,status,21);
1375 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1376 0,aVOLID,0,!allow_long_path_components)) {
1377 reply_nterror(req, NT_STATUS_NO_MEMORY);
1378 END_PROFILE(SMBsearch);
1381 dptr_fill(buf+12,dptr_num);
1382 if (dptr_zero(buf+12) && (status_len==0)) {
1387 if (message_push_blob(&req->outbuf,
1388 data_blob_const(buf, sizeof(buf)))
1390 reply_nterror(req, NT_STATUS_NO_MEMORY);
1391 END_PROFILE(SMBsearch);
1399 ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1402 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1403 conn->dirpath,lp_dontdescend(SNUM(conn))));
1404 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) {
1405 check_descend = True;
1408 for (i=numentries;(i<maxentries) && !finished;i++) {
1409 finished = !get_dir_entry(ctx,conn,mask,dirtype,&fname,
1410 &size,&mode,&date,check_descend);
1412 char buf[DIR_STRUCT_SIZE];
1413 memcpy(buf,status,21);
1414 if (!make_dir_struct(ctx,
1421 !allow_long_path_components)) {
1422 reply_nterror(req, NT_STATUS_NO_MEMORY);
1423 END_PROFILE(SMBsearch);
1426 if (!dptr_fill(buf+12,dptr_num)) {
1429 if (message_push_blob(&req->outbuf,
1430 data_blob_const(buf, sizeof(buf)))
1432 reply_nterror(req, NT_STATUS_NO_MEMORY);
1433 END_PROFILE(SMBsearch);
1443 /* If we were called as SMBffirst with smb_search_id == NULL
1444 and no entries were found then return error and close dirptr
1447 if (numentries == 0) {
1448 dptr_close(&dptr_num);
1449 } else if(expect_close && status_len == 0) {
1450 /* Close the dptr - we know it's gone */
1451 dptr_close(&dptr_num);
1454 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1455 if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
1456 dptr_close(&dptr_num);
1459 if ((numentries == 0) && !mask_contains_wcard) {
1460 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1461 END_PROFILE(SMBsearch);
1465 SSVAL(req->outbuf,smb_vwv0,numentries);
1466 SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1467 SCVAL(smb_buf(req->outbuf),0,5);
1468 SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1470 /* The replies here are never long name. */
1471 SSVAL(req->outbuf, smb_flg2,
1472 SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1473 if (!allow_long_path_components) {
1474 SSVAL(req->outbuf, smb_flg2,
1475 SVAL(req->outbuf, smb_flg2)
1476 & (~FLAGS2_LONG_PATH_COMPONENTS));
1479 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1480 SSVAL(req->outbuf, smb_flg2,
1481 (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1484 directory = dptr_path(dptr_num);
1487 DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1488 smb_fn_name(CVAL(req->inbuf,smb_com)),
1490 directory ? directory : "./",
1495 END_PROFILE(SMBsearch);
1499 /****************************************************************************
1500 Reply to a fclose (stop directory search).
1501 ****************************************************************************/
1503 void reply_fclose(struct smb_request *req)
1511 bool path_contains_wcard = False;
1512 TALLOC_CTX *ctx = talloc_tos();
1514 START_PROFILE(SMBfclose);
1516 if (lp_posix_pathnames()) {
1517 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1518 END_PROFILE(SMBfclose);
1522 p = smb_buf(req->inbuf) + 1;
1523 p += srvstr_get_path_wcard(ctx,
1531 &path_contains_wcard);
1532 if (!NT_STATUS_IS_OK(err)) {
1533 reply_nterror(req, err);
1534 END_PROFILE(SMBfclose);
1538 status_len = SVAL(p,0);
1541 if (status_len == 0) {
1542 reply_doserror(req, ERRSRV, ERRsrverror);
1543 END_PROFILE(SMBfclose);
1547 memcpy(status,p,21);
1549 if(dptr_fetch(status+12,&dptr_num)) {
1550 /* Close the dptr - we know it's gone */
1551 dptr_close(&dptr_num);
1554 reply_outbuf(req, 1, 0);
1555 SSVAL(req->outbuf,smb_vwv0,0);
1557 DEBUG(3,("search close\n"));
1559 END_PROFILE(SMBfclose);
1563 /****************************************************************************
1565 ****************************************************************************/
1567 void reply_open(struct smb_request *req)
1569 connection_struct *conn = req->conn;
1575 SMB_STRUCT_STAT sbuf;
1582 uint32 create_disposition;
1583 uint32 create_options = 0;
1585 TALLOC_CTX *ctx = talloc_tos();
1587 START_PROFILE(SMBopen);
1590 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1591 END_PROFILE(SMBopen);
1595 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1596 deny_mode = SVAL(req->inbuf,smb_vwv0);
1597 dos_attr = SVAL(req->inbuf,smb_vwv1);
1599 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1600 smb_buf(req->inbuf)+1, 0,
1601 STR_TERMINATE, &status);
1602 if (!NT_STATUS_IS_OK(status)) {
1603 reply_nterror(req, status);
1604 END_PROFILE(SMBopen);
1608 if (!map_open_params_to_ntcreate(
1609 fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
1610 &share_mode, &create_disposition, &create_options)) {
1611 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1612 END_PROFILE(SMBopen);
1616 status = create_file(conn, /* conn */
1618 0, /* root_dir_fid */
1620 access_mask, /* access_mask */
1621 share_mode, /* share_access */
1622 create_disposition, /* create_disposition*/
1623 create_options, /* create_options */
1624 dos_attr, /* file_attributes */
1625 oplock_request, /* oplock_request */
1626 0, /* allocation_size */
1633 if (!NT_STATUS_IS_OK(status)) {
1634 if (open_was_deferred(req->mid)) {
1635 /* We have re-scheduled this call. */
1636 END_PROFILE(SMBopen);
1639 reply_openerror(req, status);
1640 END_PROFILE(SMBopen);
1644 size = sbuf.st_size;
1645 fattr = dos_mode(conn,fname,&sbuf);
1646 mtime = sbuf.st_mtime;
1649 DEBUG(3,("attempt to open a directory %s\n",fname));
1650 close_file(fsp,ERROR_CLOSE);
1651 reply_doserror(req, ERRDOS,ERRnoaccess);
1652 END_PROFILE(SMBopen);
1656 reply_outbuf(req, 7, 0);
1657 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1658 SSVAL(req->outbuf,smb_vwv1,fattr);
1659 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1660 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1662 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1664 SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1665 SSVAL(req->outbuf,smb_vwv6,deny_mode);
1667 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1668 SCVAL(req->outbuf,smb_flg,
1669 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1672 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1673 SCVAL(req->outbuf,smb_flg,
1674 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1676 END_PROFILE(SMBopen);
1680 /****************************************************************************
1681 Reply to an open and X.
1682 ****************************************************************************/
1684 void reply_open_and_X(struct smb_request *req)
1686 connection_struct *conn = req->conn;
1691 /* Breakout the oplock request bits so we can set the
1692 reply bits separately. */
1693 int ex_oplock_request;
1694 int core_oplock_request;
1697 int smb_sattr = SVAL(req->inbuf,smb_vwv4);
1698 uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6);
1703 SMB_STRUCT_STAT sbuf;
1707 SMB_BIG_UINT allocation_size;
1708 ssize_t retval = -1;
1711 uint32 create_disposition;
1712 uint32 create_options = 0;
1713 TALLOC_CTX *ctx = talloc_tos();
1715 START_PROFILE(SMBopenX);
1717 if (req->wct < 15) {
1718 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1719 END_PROFILE(SMBopenX);
1723 open_flags = SVAL(req->inbuf,smb_vwv2);
1724 deny_mode = SVAL(req->inbuf,smb_vwv3);
1725 smb_attr = SVAL(req->inbuf,smb_vwv5);
1726 ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1727 core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1728 oplock_request = ex_oplock_request | core_oplock_request;
1729 smb_ofun = SVAL(req->inbuf,smb_vwv8);
1730 allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv9);
1732 /* If it's an IPC, pass off the pipe handler. */
1734 if (lp_nt_pipe_support()) {
1735 reply_open_pipe_and_X(conn, req);
1737 reply_doserror(req, ERRSRV, ERRaccess);
1739 END_PROFILE(SMBopenX);
1743 /* XXXX we need to handle passed times, sattr and flags */
1744 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1745 smb_buf(req->inbuf), 0, STR_TERMINATE,
1747 if (!NT_STATUS_IS_OK(status)) {
1748 reply_nterror(req, status);
1749 END_PROFILE(SMBopenX);
1753 if (!map_open_params_to_ntcreate(
1754 fname, deny_mode, smb_ofun, &access_mask,
1755 &share_mode, &create_disposition, &create_options)) {
1756 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1757 END_PROFILE(SMBopenX);
1761 status = create_file(conn, /* conn */
1763 0, /* root_dir_fid */
1765 access_mask, /* access_mask */
1766 share_mode, /* share_access */
1767 create_disposition, /* create_disposition*/
1768 create_options, /* create_options */
1769 smb_attr, /* file_attributes */
1770 oplock_request, /* oplock_request */
1771 0, /* allocation_size */
1775 &smb_action, /* pinfo */
1778 if (!NT_STATUS_IS_OK(status)) {
1779 END_PROFILE(SMBopenX);
1780 if (open_was_deferred(req->mid)) {
1781 /* We have re-scheduled this call. */
1784 reply_openerror(req, status);
1788 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1789 if the file is truncated or created. */
1790 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1791 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1792 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1793 close_file(fsp,ERROR_CLOSE);
1794 reply_nterror(req, NT_STATUS_DISK_FULL);
1795 END_PROFILE(SMBopenX);
1798 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1800 close_file(fsp,ERROR_CLOSE);
1801 reply_nterror(req, NT_STATUS_DISK_FULL);
1802 END_PROFILE(SMBopenX);
1805 sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
1808 fattr = dos_mode(conn,fname,&sbuf);
1809 mtime = sbuf.st_mtime;
1811 close_file(fsp,ERROR_CLOSE);
1812 reply_doserror(req, ERRDOS, ERRnoaccess);
1813 END_PROFILE(SMBopenX);
1817 /* If the caller set the extended oplock request bit
1818 and we granted one (by whatever means) - set the
1819 correct bit for extended oplock reply.
1822 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1823 smb_action |= EXTENDED_OPLOCK_GRANTED;
1826 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1827 smb_action |= EXTENDED_OPLOCK_GRANTED;
1830 /* If the caller set the core oplock request bit
1831 and we granted one (by whatever means) - set the
1832 correct bit for core oplock reply.
1835 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1836 reply_outbuf(req, 19, 0);
1838 reply_outbuf(req, 15, 0);
1841 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1842 SCVAL(req->outbuf, smb_flg,
1843 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1846 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1847 SCVAL(req->outbuf, smb_flg,
1848 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1851 SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
1852 SSVAL(req->outbuf,smb_vwv3,fattr);
1853 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1854 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
1856 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
1858 SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size);
1859 SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
1860 SSVAL(req->outbuf,smb_vwv11,smb_action);
1862 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1863 SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
1866 END_PROFILE(SMBopenX);
1871 /****************************************************************************
1872 Reply to a SMBulogoffX.
1873 ****************************************************************************/
1875 void reply_ulogoffX(struct smb_request *req)
1879 START_PROFILE(SMBulogoffX);
1881 vuser = get_valid_user_struct(req->vuid);
1884 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
1888 /* in user level security we are supposed to close any files
1889 open by this user */
1890 if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
1891 file_close_user(req->vuid);
1894 invalidate_vuid(req->vuid);
1896 reply_outbuf(req, 2, 0);
1898 DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
1900 END_PROFILE(SMBulogoffX);
1904 /****************************************************************************
1905 Reply to a mknew or a create.
1906 ****************************************************************************/
1908 void reply_mknew(struct smb_request *req)
1910 connection_struct *conn = req->conn;
1914 struct timespec ts[2];
1916 int oplock_request = 0;
1917 SMB_STRUCT_STAT sbuf;
1919 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
1920 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1921 uint32 create_disposition;
1922 uint32 create_options = 0;
1923 TALLOC_CTX *ctx = talloc_tos();
1925 START_PROFILE(SMBcreate);
1928 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1929 END_PROFILE(SMBcreate);
1933 fattr = SVAL(req->inbuf,smb_vwv0);
1934 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1935 com = SVAL(req->inbuf,smb_com);
1937 ts[1] =convert_time_t_to_timespec(
1938 srv_make_unix_date3(req->inbuf + smb_vwv1));
1941 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1942 smb_buf(req->inbuf) + 1, 0,
1943 STR_TERMINATE, &status);
1944 if (!NT_STATUS_IS_OK(status)) {
1945 reply_nterror(req, status);
1946 END_PROFILE(SMBcreate);
1950 if (fattr & aVOLID) {
1951 DEBUG(0,("Attempt to create file (%s) with volid set - "
1952 "please report this\n", fname));
1955 if(com == SMBmknew) {
1956 /* We should fail if file exists. */
1957 create_disposition = FILE_CREATE;
1959 /* Create if file doesn't exist, truncate if it does. */
1960 create_disposition = FILE_OVERWRITE_IF;
1963 status = create_file(conn, /* conn */
1965 0, /* root_dir_fid */
1967 access_mask, /* access_mask */
1968 share_mode, /* share_access */
1969 create_disposition, /* create_disposition*/
1970 create_options, /* create_options */
1971 fattr, /* file_attributes */
1972 oplock_request, /* oplock_request */
1973 0, /* allocation_size */
1980 if (!NT_STATUS_IS_OK(status)) {
1981 END_PROFILE(SMBcreate);
1982 if (open_was_deferred(req->mid)) {
1983 /* We have re-scheduled this call. */
1986 reply_openerror(req, status);
1990 ts[0] = get_atimespec(&sbuf); /* atime. */
1991 file_ntimes(conn, fname, ts);
1993 reply_outbuf(req, 1, 0);
1994 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1996 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1997 SCVAL(req->outbuf,smb_flg,
1998 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2001 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2002 SCVAL(req->outbuf,smb_flg,
2003 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2006 DEBUG( 2, ( "reply_mknew: file %s\n", fname ) );
2007 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
2008 fname, fsp->fh->fd, (unsigned int)fattr ) );
2010 END_PROFILE(SMBcreate);
2014 /****************************************************************************
2015 Reply to a create temporary file.
2016 ****************************************************************************/
2018 void reply_ctemp(struct smb_request *req)
2020 connection_struct *conn = req->conn;
2026 SMB_STRUCT_STAT sbuf;
2029 TALLOC_CTX *ctx = talloc_tos();
2031 START_PROFILE(SMBctemp);
2034 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2035 END_PROFILE(SMBctemp);
2039 fattr = SVAL(req->inbuf,smb_vwv0);
2040 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2042 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
2043 smb_buf(req->inbuf)+1, 0, STR_TERMINATE,
2045 if (!NT_STATUS_IS_OK(status)) {
2046 reply_nterror(req, status);
2047 END_PROFILE(SMBctemp);
2051 fname = talloc_asprintf(ctx,
2055 fname = talloc_strdup(ctx, "TMXXXXXX");
2059 reply_nterror(req, NT_STATUS_NO_MEMORY);
2060 END_PROFILE(SMBctemp);
2064 status = resolve_dfspath(ctx, conn,
2065 req->flags2 & FLAGS2_DFS_PATHNAMES,
2068 if (!NT_STATUS_IS_OK(status)) {
2069 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2070 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2071 ERRSRV, ERRbadpath);
2072 END_PROFILE(SMBctemp);
2075 reply_nterror(req, status);
2076 END_PROFILE(SMBctemp);
2080 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
2081 if (!NT_STATUS_IS_OK(status)) {
2082 reply_nterror(req, status);
2083 END_PROFILE(SMBctemp);
2087 status = check_name(conn, CONST_DISCARD(char *,fname));
2088 if (!NT_STATUS_IS_OK(status)) {
2089 reply_nterror(req, status);
2090 END_PROFILE(SMBctemp);
2094 tmpfd = smb_mkstemp(fname);
2096 reply_unixerror(req, ERRDOS, ERRnoaccess);
2097 END_PROFILE(SMBctemp);
2101 SMB_VFS_STAT(conn,fname,&sbuf);
2103 /* We should fail if file does not exist. */
2104 status = open_file_ntcreate(conn, req, fname, &sbuf,
2105 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
2106 FILE_SHARE_READ|FILE_SHARE_WRITE,
2113 /* close fd from smb_mkstemp() */
2116 if (!NT_STATUS_IS_OK(status)) {
2117 if (open_was_deferred(req->mid)) {
2118 /* We have re-scheduled this call. */
2119 END_PROFILE(SMBctemp);
2122 reply_openerror(req, status);
2123 END_PROFILE(SMBctemp);
2127 reply_outbuf(req, 1, 0);
2128 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2130 /* the returned filename is relative to the directory */
2131 s = strrchr_m(fname, '/');
2139 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2140 thing in the byte section. JRA */
2141 SSVALS(p, 0, -1); /* what is this? not in spec */
2143 if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2145 reply_nterror(req, NT_STATUS_NO_MEMORY);
2146 END_PROFILE(SMBctemp);
2150 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2151 SCVAL(req->outbuf, smb_flg,
2152 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2155 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2156 SCVAL(req->outbuf, smb_flg,
2157 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2160 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) );
2161 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd,
2162 (unsigned int)sbuf.st_mode ) );
2164 END_PROFILE(SMBctemp);
2168 /*******************************************************************
2169 Check if a user is allowed to rename a file.
2170 ********************************************************************/
2172 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2173 uint16 dirtype, SMB_STRUCT_STAT *pst)
2177 if (!CAN_WRITE(conn)) {
2178 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2181 fmode = dos_mode(conn, fsp->fsp_name, pst);
2182 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
2183 return NT_STATUS_NO_SUCH_FILE;
2186 if (S_ISDIR(pst->st_mode)) {
2187 return NT_STATUS_OK;
2190 if (fsp->access_mask & DELETE_ACCESS) {
2191 return NT_STATUS_OK;
2194 return NT_STATUS_ACCESS_DENIED;
2197 /*******************************************************************
2198 * unlink a file with all relevant access checks
2199 *******************************************************************/
2201 static NTSTATUS do_unlink(connection_struct *conn,
2202 struct smb_request *req,
2206 SMB_STRUCT_STAT sbuf;
2209 uint32 dirtype_orig = dirtype;
2212 DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
2214 if (!CAN_WRITE(conn)) {
2215 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2218 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
2219 return map_nt_error_from_unix(errno);
2222 fattr = dos_mode(conn,fname,&sbuf);
2224 if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2225 dirtype = aDIR|aARCH|aRONLY;
2228 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
2230 return NT_STATUS_NO_SUCH_FILE;
2233 if (!dir_check_ftype(conn, fattr, dirtype)) {
2235 return NT_STATUS_FILE_IS_A_DIRECTORY;
2237 return NT_STATUS_NO_SUCH_FILE;
2240 if (dirtype_orig & 0x8000) {
2241 /* These will never be set for POSIX. */
2242 return NT_STATUS_NO_SUCH_FILE;
2246 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2247 return NT_STATUS_FILE_IS_A_DIRECTORY;
2250 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2251 return NT_STATUS_NO_SUCH_FILE;
2254 if (dirtype & 0xFF00) {
2255 /* These will never be set for POSIX. */
2256 return NT_STATUS_NO_SUCH_FILE;
2261 return NT_STATUS_NO_SUCH_FILE;
2264 /* Can't delete a directory. */
2266 return NT_STATUS_FILE_IS_A_DIRECTORY;
2271 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
2272 return NT_STATUS_OBJECT_NAME_INVALID;
2273 #endif /* JRATEST */
2275 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
2277 On a Windows share, a file with read-only dosmode can be opened with
2278 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
2279 fails with NT_STATUS_CANNOT_DELETE error.
2281 This semantic causes a problem that a user can not
2282 rename a file with read-only dosmode on a Samba share
2283 from a Windows command prompt (i.e. cmd.exe, but can rename
2284 from Windows Explorer).
2287 if (!lp_delete_readonly(SNUM(conn))) {
2288 if (fattr & aRONLY) {
2289 return NT_STATUS_CANNOT_DELETE;
2293 /* On open checks the open itself will check the share mode, so
2294 don't do it here as we'll get it wrong. */
2296 status = create_file_unixpath
2300 DELETE_ACCESS, /* access_mask */
2301 FILE_SHARE_NONE, /* share_access */
2302 FILE_OPEN, /* create_disposition*/
2303 FILE_NON_DIRECTORY_FILE, /* create_options */
2304 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2305 0, /* oplock_request */
2306 0, /* allocation_size */
2313 if (!NT_STATUS_IS_OK(status)) {
2314 DEBUG(10, ("open_file_ntcreate failed: %s\n",
2315 nt_errstr(status)));
2319 /* The set is across all open files on this dev/inode pair. */
2320 if (!set_delete_on_close(fsp, True, ¤t_user.ut)) {
2321 close_file(fsp, NORMAL_CLOSE);
2322 return NT_STATUS_ACCESS_DENIED;
2325 return close_file(fsp,NORMAL_CLOSE);
2328 /****************************************************************************
2329 The guts of the unlink command, split out so it may be called by the NT SMB
2331 ****************************************************************************/
2333 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2334 uint32 dirtype, const char *name_in, bool has_wild)
2336 const char *directory = NULL;
2341 NTSTATUS status = NT_STATUS_OK;
2342 SMB_STRUCT_STAT sbuf;
2343 TALLOC_CTX *ctx = talloc_tos();
2345 status = unix_convert(ctx, conn, name_in, has_wild, &name, NULL, &sbuf);
2346 if (!NT_STATUS_IS_OK(status)) {
2350 p = strrchr_m(name,'/');
2352 directory = talloc_strdup(ctx, ".");
2354 return NT_STATUS_NO_MEMORY;
2364 * We should only check the mangled cache
2365 * here if unix_convert failed. This means
2366 * that the path in 'mask' doesn't exist
2367 * on the file system and so we need to look
2368 * for a possible mangle. This patch from
2369 * Tine Smukavec <valentin.smukavec@hermes.si>.
2372 if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) {
2373 char *new_mask = NULL;
2374 mangle_lookup_name_from_8_3(ctx,
2384 directory = talloc_asprintf(ctx,
2389 return NT_STATUS_NO_MEMORY;
2392 dirtype = FILE_ATTRIBUTE_NORMAL;
2395 status = check_name(conn, directory);
2396 if (!NT_STATUS_IS_OK(status)) {
2400 status = do_unlink(conn, req, directory, dirtype);
2401 if (!NT_STATUS_IS_OK(status)) {
2407 struct smb_Dir *dir_hnd = NULL;
2411 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2412 return NT_STATUS_OBJECT_NAME_INVALID;
2415 if (strequal(mask,"????????.???")) {
2420 status = check_name(conn, directory);
2421 if (!NT_STATUS_IS_OK(status)) {
2425 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask,
2427 if (dir_hnd == NULL) {
2428 return map_nt_error_from_unix(errno);
2431 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2432 the pattern matches against the long name, otherwise the short name
2433 We don't implement this yet XXXX
2436 status = NT_STATUS_NO_SUCH_FILE;
2438 while ((dname = ReadDirName(dir_hnd, &offset))) {
2442 if (!is_visible_file(conn, directory, dname, &st, True)) {
2446 /* Quick check for "." and ".." */
2447 if (ISDOT(dname) || ISDOTDOT(dname)) {
2451 if(!mask_match(dname, mask, conn->case_sensitive)) {
2455 fname = talloc_asprintf(ctx, "%s/%s",
2459 return NT_STATUS_NO_MEMORY;
2462 status = check_name(conn, fname);
2463 if (!NT_STATUS_IS_OK(status)) {
2464 TALLOC_FREE(dir_hnd);
2468 status = do_unlink(conn, req, fname, dirtype);
2469 if (!NT_STATUS_IS_OK(status)) {
2475 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",
2480 TALLOC_FREE(dir_hnd);
2483 if (count == 0 && NT_STATUS_IS_OK(status)) {
2484 status = map_nt_error_from_unix(errno);
2490 /****************************************************************************
2492 ****************************************************************************/
2494 void reply_unlink(struct smb_request *req)
2496 connection_struct *conn = req->conn;
2500 bool path_contains_wcard = False;
2501 TALLOC_CTX *ctx = talloc_tos();
2503 START_PROFILE(SMBunlink);
2506 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2507 END_PROFILE(SMBunlink);
2511 dirtype = SVAL(req->inbuf,smb_vwv0);
2513 srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
2514 smb_buf(req->inbuf) + 1, 0,
2515 STR_TERMINATE, &status, &path_contains_wcard);
2516 if (!NT_STATUS_IS_OK(status)) {
2517 reply_nterror(req, status);
2518 END_PROFILE(SMBunlink);
2522 status = resolve_dfspath_wcard(ctx, conn,
2523 req->flags2 & FLAGS2_DFS_PATHNAMES,
2526 &path_contains_wcard);
2527 if (!NT_STATUS_IS_OK(status)) {
2528 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2529 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2530 ERRSRV, ERRbadpath);
2531 END_PROFILE(SMBunlink);
2534 reply_nterror(req, status);
2535 END_PROFILE(SMBunlink);
2539 DEBUG(3,("reply_unlink : %s\n",name));
2541 status = unlink_internals(conn, req, dirtype, name,
2542 path_contains_wcard);
2543 if (!NT_STATUS_IS_OK(status)) {
2544 if (open_was_deferred(req->mid)) {
2545 /* We have re-scheduled this call. */
2546 END_PROFILE(SMBunlink);
2549 reply_nterror(req, status);
2550 END_PROFILE(SMBunlink);
2554 reply_outbuf(req, 0, 0);
2555 END_PROFILE(SMBunlink);
2560 /****************************************************************************
2562 ****************************************************************************/
2564 static void fail_readraw(void)
2566 const char *errstr = talloc_asprintf(talloc_tos(),
2567 "FAIL ! reply_readbraw: socket write fail (%s)",
2572 exit_server_cleanly(errstr);
2575 /****************************************************************************
2576 Fake (read/write) sendfile. Returns -1 on read or write fail.
2577 ****************************************************************************/
2579 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
2583 size_t tosend = nread;
2590 bufsize = MIN(nread, 65536);
2592 if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2596 while (tosend > 0) {
2600 if (tosend > bufsize) {
2605 ret = read_file(fsp,buf,startpos,cur_read);
2611 /* If we had a short read, fill with zeros. */
2612 if (ret < cur_read) {
2613 memset(buf, '\0', cur_read - ret);
2616 if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
2621 startpos += cur_read;
2625 return (ssize_t)nread;
2628 /****************************************************************************
2629 Return a readbraw error (4 bytes of zero).
2630 ****************************************************************************/
2632 static void reply_readbraw_error(void)
2636 if (write_data(smbd_server_fd(),header,4) != 4) {
2641 /****************************************************************************
2642 Use sendfile in readbraw.
2643 ****************************************************************************/
2645 void send_file_readbraw(connection_struct *conn,
2651 char *outbuf = NULL;
2654 #if defined(WITH_SENDFILE)
2656 * We can only use sendfile on a non-chained packet
2657 * but we can use on a non-oplocked file. tridge proved this
2658 * on a train in Germany :-). JRA.
2659 * reply_readbraw has already checked the length.
2662 if ( (chain_size == 0) && (nread > 0) &&
2663 (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
2665 DATA_BLOB header_blob;
2667 _smb_setlen(header,nread);
2668 header_blob = data_blob_const(header, 4);
2670 if (SMB_VFS_SENDFILE(smbd_server_fd(), fsp,
2671 &header_blob, startpos, nread) == -1) {
2672 /* Returning ENOSYS means no data at all was sent.
2673 * Do this as a normal read. */
2674 if (errno == ENOSYS) {
2675 goto normal_readbraw;
2679 * Special hack for broken Linux with no working sendfile. If we
2680 * return EINTR we sent the header but not the rest of the data.
2681 * Fake this up by doing read/write calls.
2683 if (errno == EINTR) {
2684 /* Ensure we don't do this again. */
2685 set_use_sendfile(SNUM(conn), False);
2686 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2688 if (fake_sendfile(fsp, startpos, nread) == -1) {
2689 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2690 fsp->fsp_name, strerror(errno) ));
2691 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2696 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2697 fsp->fsp_name, strerror(errno) ));
2698 exit_server_cleanly("send_file_readbraw sendfile failed");
2707 outbuf = TALLOC_ARRAY(NULL, char, nread+4);
2709 DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
2710 (unsigned)(nread+4)));
2711 reply_readbraw_error();
2716 ret = read_file(fsp,outbuf+4,startpos,nread);
2717 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2726 _smb_setlen(outbuf,ret);
2727 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2730 TALLOC_FREE(outbuf);
2733 /****************************************************************************
2734 Reply to a readbraw (core+ protocol).
2735 ****************************************************************************/
2737 void reply_readbraw(struct smb_request *req)
2739 connection_struct *conn = req->conn;
2740 ssize_t maxcount,mincount;
2747 START_PROFILE(SMBreadbraw);
2749 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
2750 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
2751 "raw reads/writes are disallowed.");
2755 reply_readbraw_error();
2756 END_PROFILE(SMBreadbraw);
2761 * Special check if an oplock break has been issued
2762 * and the readraw request croses on the wire, we must
2763 * return a zero length response here.
2766 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
2769 * We have to do a check_fsp by hand here, as
2770 * we must always return 4 zero bytes on error,
2774 if (!fsp || !conn || conn != fsp->conn ||
2775 current_user.vuid != fsp->vuid ||
2776 fsp->is_directory || fsp->fh->fd == -1) {
2778 * fsp could be NULL here so use the value from the packet. JRA.
2780 DEBUG(3,("reply_readbraw: fnum %d not valid "
2782 (int)SVAL(req->inbuf,smb_vwv0)));
2783 reply_readbraw_error();
2784 END_PROFILE(SMBreadbraw);
2788 /* Do a "by hand" version of CHECK_READ. */
2789 if (!(fsp->can_read ||
2790 ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
2791 (fsp->access_mask & FILE_EXECUTE)))) {
2792 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
2793 (int)SVAL(req->inbuf,smb_vwv0)));
2794 reply_readbraw_error();
2795 END_PROFILE(SMBreadbraw);
2799 flush_write_cache(fsp, READRAW_FLUSH);
2801 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
2802 if(req->wct == 10) {
2804 * This is a large offset (64 bit) read.
2806 #ifdef LARGE_SMB_OFF_T
2808 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
2810 #else /* !LARGE_SMB_OFF_T */
2813 * Ensure we haven't been sent a >32 bit offset.
2816 if(IVAL(req->inbuf,smb_vwv8) != 0) {
2817 DEBUG(0,("reply_readbraw: large offset "
2818 "(%x << 32) used and we don't support "
2819 "64 bit offsets.\n",
2820 (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
2821 reply_readbraw_error();
2822 END_PROFILE(SMBreadbraw);
2826 #endif /* LARGE_SMB_OFF_T */
2829 DEBUG(0,("reply_readbraw: negative 64 bit "
2830 "readraw offset (%.0f) !\n",
2831 (double)startpos ));
2832 reply_readbraw_error();
2833 END_PROFILE(SMBreadbraw);
2838 maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
2839 mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
2841 /* ensure we don't overrun the packet size */
2842 maxcount = MIN(65535,maxcount);
2844 if (is_locked(fsp,(uint32)req->smbpid,
2845 (SMB_BIG_UINT)maxcount,
2846 (SMB_BIG_UINT)startpos,
2848 reply_readbraw_error();
2849 END_PROFILE(SMBreadbraw);
2853 if (SMB_VFS_FSTAT(fsp, &st) == 0) {
2857 if (startpos >= size) {
2860 nread = MIN(maxcount,(size - startpos));
2863 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2864 if (nread < mincount)
2868 DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
2869 "min=%lu nread=%lu\n",
2870 fsp->fnum, (double)startpos,
2871 (unsigned long)maxcount,
2872 (unsigned long)mincount,
2873 (unsigned long)nread ) );
2875 send_file_readbraw(conn, fsp, startpos, nread, mincount);
2877 DEBUG(5,("reply_readbraw finished\n"));
2878 END_PROFILE(SMBreadbraw);
2882 #define DBGC_CLASS DBGC_LOCKING
2884 /****************************************************************************
2885 Reply to a lockread (core+ protocol).
2886 ****************************************************************************/
2888 void reply_lockread(struct smb_request *req)
2890 connection_struct *conn = req->conn;
2897 struct byte_range_lock *br_lck = NULL;
2900 START_PROFILE(SMBlockread);
2903 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2904 END_PROFILE(SMBlockread);
2908 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
2910 if (!check_fsp(conn, req, fsp, ¤t_user)) {
2911 END_PROFILE(SMBlockread);
2915 if (!CHECK_READ(fsp,req->inbuf)) {
2916 reply_doserror(req, ERRDOS, ERRbadaccess);
2917 END_PROFILE(SMBlockread);
2921 release_level_2_oplocks_on_change(fsp);
2923 numtoread = SVAL(req->inbuf,smb_vwv1);
2924 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
2926 numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
2928 reply_outbuf(req, 5, numtoread + 3);
2930 data = smb_buf(req->outbuf) + 3;
2933 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2934 * protocol request that predates the read/write lock concept.
2935 * Thus instead of asking for a read lock here we need to ask
2936 * for a write lock. JRA.
2937 * Note that the requested lock size is unaffected by max_recv.
2940 br_lck = do_lock(smbd_messaging_context(),
2943 (SMB_BIG_UINT)numtoread,
2944 (SMB_BIG_UINT)startpos,
2947 False, /* Non-blocking lock. */
2950 TALLOC_FREE(br_lck);
2952 if (NT_STATUS_V(status)) {
2953 reply_nterror(req, status);
2954 END_PROFILE(SMBlockread);
2959 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
2962 if (numtoread > max_recv) {
2963 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
2964 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2965 (unsigned int)numtoread, (unsigned int)max_recv ));
2966 numtoread = MIN(numtoread,max_recv);
2968 nread = read_file(fsp,data,startpos,numtoread);
2971 reply_unixerror(req, ERRDOS, ERRnoaccess);
2972 END_PROFILE(SMBlockread);
2976 srv_set_message((char *)req->outbuf, 5, nread+3, False);
2978 SSVAL(req->outbuf,smb_vwv0,nread);
2979 SSVAL(req->outbuf,smb_vwv5,nread+3);
2980 p = smb_buf(req->outbuf);
2981 SCVAL(p,0,0); /* pad byte. */
2984 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
2985 fsp->fnum, (int)numtoread, (int)nread));
2987 END_PROFILE(SMBlockread);
2992 #define DBGC_CLASS DBGC_ALL
2994 /****************************************************************************
2996 ****************************************************************************/
2998 void reply_read(struct smb_request *req)
3000 connection_struct *conn = req->conn;
3008 START_PROFILE(SMBread);
3011 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3012 END_PROFILE(SMBread);
3016 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3018 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3019 END_PROFILE(SMBread);
3023 if (!CHECK_READ(fsp,req->inbuf)) {
3024 reply_doserror(req, ERRDOS, ERRbadaccess);
3025 END_PROFILE(SMBread);
3029 numtoread = SVAL(req->inbuf,smb_vwv1);
3030 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3032 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
3035 * The requested read size cannot be greater than max_recv. JRA.
3037 if (numtoread > max_recv) {
3038 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
3039 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3040 (unsigned int)numtoread, (unsigned int)max_recv ));
3041 numtoread = MIN(numtoread,max_recv);
3044 reply_outbuf(req, 5, numtoread+3);
3046 data = smb_buf(req->outbuf) + 3;
3048 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtoread,
3049 (SMB_BIG_UINT)startpos, READ_LOCK)) {
3050 reply_doserror(req, ERRDOS,ERRlock);
3051 END_PROFILE(SMBread);
3056 nread = read_file(fsp,data,startpos,numtoread);
3059 reply_unixerror(req, ERRDOS,ERRnoaccess);
3060 END_PROFILE(SMBread);
3064 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3066 SSVAL(req->outbuf,smb_vwv0,nread);
3067 SSVAL(req->outbuf,smb_vwv5,nread+3);
3068 SCVAL(smb_buf(req->outbuf),0,1);
3069 SSVAL(smb_buf(req->outbuf),1,nread);
3071 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
3072 fsp->fnum, (int)numtoread, (int)nread ) );
3074 END_PROFILE(SMBread);
3078 /****************************************************************************
3080 ****************************************************************************/
3082 static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
3087 outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
3088 data = smb_buf(outbuf);
3090 memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
3092 SCVAL(outbuf,smb_vwv0,0xFF);
3093 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
3094 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
3095 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
3096 SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
3097 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
3098 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
3099 _smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
3103 /****************************************************************************
3104 Reply to a read and X - possibly using sendfile.
3105 ****************************************************************************/
3107 static void send_file_readX(connection_struct *conn, struct smb_request *req,
3108 files_struct *fsp, SMB_OFF_T startpos,
3111 SMB_STRUCT_STAT sbuf;
3114 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
3115 reply_unixerror(req, ERRDOS, ERRnoaccess);
3119 if (startpos > sbuf.st_size) {
3121 } else if (smb_maxcnt > (sbuf.st_size - startpos)) {
3122 smb_maxcnt = (sbuf.st_size - startpos);
3125 if (smb_maxcnt == 0) {
3129 #if defined(WITH_SENDFILE)
3131 * We can only use sendfile on a non-chained packet
3132 * but we can use on a non-oplocked file. tridge proved this
3133 * on a train in Germany :-). JRA.
3136 if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
3137 !is_encrypted_packet(req->inbuf) &&
3138 lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
3139 uint8 headerbuf[smb_size + 12 * 2];
3143 * Set up the packet header before send. We
3144 * assume here the sendfile will work (get the
3145 * correct amount of data).
3148 header = data_blob_const(headerbuf, sizeof(headerbuf));
3150 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3151 setup_readX_header((char *)headerbuf, smb_maxcnt);
3153 if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
3154 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
3155 if (errno == ENOSYS) {
3160 * Special hack for broken Linux with no working sendfile. If we
3161 * return EINTR we sent the header but not the rest of the data.
3162 * Fake this up by doing read/write calls.
3165 if (errno == EINTR) {
3166 /* Ensure we don't do this again. */
3167 set_use_sendfile(SNUM(conn), False);
3168 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
3169 nread = fake_sendfile(fsp, startpos,
3172 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3173 fsp->fsp_name, strerror(errno) ));
3174 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3176 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
3177 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3178 /* No outbuf here means successful sendfile. */
3179 TALLOC_FREE(req->outbuf);
3183 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
3184 fsp->fsp_name, strerror(errno) ));
3185 exit_server_cleanly("send_file_readX sendfile failed");
3188 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
3189 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3190 /* No outbuf here means successful sendfile. */
3191 TALLOC_FREE(req->outbuf);
3198 if ((smb_maxcnt & 0xFF0000) > 0x10000) {
3199 uint8 headerbuf[smb_size + 2*12];
3201 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3202 setup_readX_header((char *)headerbuf, smb_maxcnt);
3204 /* Send out the header. */
3205 if (write_data(smbd_server_fd(), (char *)headerbuf,
3206 sizeof(headerbuf)) != sizeof(headerbuf)) {
3207 DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
3208 fsp->fsp_name, strerror(errno) ));
3209 exit_server_cleanly("send_file_readX sendfile failed");
3211 nread = fake_sendfile(fsp, startpos, smb_maxcnt);
3213 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
3214 fsp->fsp_name, strerror(errno) ));
3215 exit_server_cleanly("send_file_readX: fake_sendfile failed");
3217 TALLOC_FREE(req->outbuf);
3220 reply_outbuf(req, 12, smb_maxcnt);
3222 nread = read_file(fsp, smb_buf(req->outbuf), startpos,
3225 reply_unixerror(req, ERRDOS, ERRnoaccess);
3229 setup_readX_header((char *)req->outbuf, nread);
3231 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
3232 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
3240 /****************************************************************************
3241 Reply to a read and X.
3242 ****************************************************************************/
3244 void reply_read_and_X(struct smb_request *req)
3246 connection_struct *conn = req->conn;
3250 bool big_readX = False;
3252 size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
3255 START_PROFILE(SMBreadX);
3257 if ((req->wct != 10) && (req->wct != 12)) {
3258 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3262 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
3263 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3264 smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
3266 /* If it's an IPC, pass off the pipe handler. */
3268 reply_pipe_read_and_X(req);
3269 END_PROFILE(SMBreadX);
3273 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3274 END_PROFILE(SMBreadX);
3278 if (!CHECK_READ(fsp,req->inbuf)) {
3279 reply_doserror(req, ERRDOS,ERRbadaccess);
3280 END_PROFILE(SMBreadX);
3284 if (global_client_caps & CAP_LARGE_READX) {
3285 size_t upper_size = SVAL(req->inbuf,smb_vwv7);
3286 smb_maxcnt |= (upper_size<<16);
3287 if (upper_size > 1) {
3288 /* Can't do this on a chained packet. */
3289 if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) {
3290 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3291 END_PROFILE(SMBreadX);
3294 /* We currently don't do this on signed or sealed data. */
3295 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
3296 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
3297 END_PROFILE(SMBreadX);
3300 /* Is there room in the reply for this data ? */
3301 if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
3303 NT_STATUS_INVALID_PARAMETER);
3304 END_PROFILE(SMBreadX);
3311 if (req->wct == 12) {
3312 #ifdef LARGE_SMB_OFF_T
3314 * This is a large offset (64 bit) read.
3316 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32);
3318 #else /* !LARGE_SMB_OFF_T */
3321 * Ensure we haven't been sent a >32 bit offset.
3324 if(IVAL(req->inbuf,smb_vwv10) != 0) {
3325 DEBUG(0,("reply_read_and_X - large offset (%x << 32) "
3326 "used and we don't support 64 bit offsets.\n",
3327 (unsigned int)IVAL(req->inbuf,smb_vwv10) ));
3328 END_PROFILE(SMBreadX);
3329 reply_doserror(req, ERRDOS, ERRbadaccess);
3333 #endif /* LARGE_SMB_OFF_T */
3337 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)smb_maxcnt,
3338 (SMB_BIG_UINT)startpos, READ_LOCK)) {
3339 END_PROFILE(SMBreadX);
3340 reply_doserror(req, ERRDOS, ERRlock);
3344 /* It is possible for VFS modules to selectively decide whether Async I/O should be used
3345 for the file or not.
3347 if ((SMB_VFS_AIO_FORCE(fsp)) &&
3349 schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
3350 END_PROFILE(SMBreadX);
3354 send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
3356 END_PROFILE(SMBreadX);
3360 /****************************************************************************
3361 Error replies to writebraw must have smb_wct == 1. Fix this up.
3362 ****************************************************************************/
3364 void error_to_writebrawerr(struct smb_request *req)
3366 uint8 *old_outbuf = req->outbuf;
3368 reply_outbuf(req, 1, 0);
3370 memcpy(req->outbuf, old_outbuf, smb_size);
3371 TALLOC_FREE(old_outbuf);
3374 /****************************************************************************
3375 Reply to a writebraw (core+ or LANMAN1.0 protocol).
3376 ****************************************************************************/
3378 void reply_writebraw(struct smb_request *req)
3380 connection_struct *conn = req->conn;
3384 ssize_t total_written=0;
3385 size_t numtowrite=0;
3393 START_PROFILE(SMBwritebraw);
3396 * If we ever reply with an error, it must have the SMB command
3397 * type of SMBwritec, not SMBwriteBraw, as this tells the client
3400 SCVAL(req->inbuf,smb_com,SMBwritec);
3402 if (srv_is_signing_active()) {
3403 END_PROFILE(SMBwritebraw);
3404 exit_server_cleanly("reply_writebraw: SMB signing is active - "
3405 "raw reads/writes are disallowed.");
3408 if (req->wct < 12) {
3409 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3410 error_to_writebrawerr(req);
3411 END_PROFILE(SMBwritebraw);
3415 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3416 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3417 error_to_writebrawerr(req);
3418 END_PROFILE(SMBwritebraw);
3422 if (!CHECK_WRITE(fsp)) {
3423 reply_doserror(req, ERRDOS, ERRbadaccess);
3424 error_to_writebrawerr(req);
3425 END_PROFILE(SMBwritebraw);
3429 tcount = IVAL(req->inbuf,smb_vwv1);
3430 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3431 write_through = BITSETW(req->inbuf+smb_vwv7,0);
3433 /* We have to deal with slightly different formats depending
3434 on whether we are using the core+ or lanman1.0 protocol */
3436 if(Protocol <= PROTOCOL_COREPLUS) {
3437 numtowrite = SVAL(smb_buf(req->inbuf),-2);
3438 data = smb_buf(req->inbuf);
3440 numtowrite = SVAL(req->inbuf,smb_vwv10);
3441 data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11);
3444 /* Ensure we don't write bytes past the end of this packet. */
3445 if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) {
3446 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3447 error_to_writebrawerr(req);
3448 END_PROFILE(SMBwritebraw);
3452 if (is_locked(fsp,(uint32)req->smbpid,(SMB_BIG_UINT)tcount,
3453 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3454 reply_doserror(req, ERRDOS, ERRlock);
3455 error_to_writebrawerr(req);
3456 END_PROFILE(SMBwritebraw);
3461 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3464 DEBUG(3,("reply_writebraw: initial write fnum=%d start=%.0f num=%d "
3465 "wrote=%d sync=%d\n",
3466 fsp->fnum, (double)startpos, (int)numtowrite,
3467 (int)nwritten, (int)write_through));
3469 if (nwritten < (ssize_t)numtowrite) {
3470 reply_unixerror(req, ERRHRD, ERRdiskfull);
3471 error_to_writebrawerr(req);
3472 END_PROFILE(SMBwritebraw);
3476 total_written = nwritten;
3478 /* Allocate a buffer of 64k + length. */
3479 buf = TALLOC_ARRAY(NULL, char, 65540);
3481 reply_doserror(req, ERRDOS, ERRnomem);
3482 error_to_writebrawerr(req);
3483 END_PROFILE(SMBwritebraw);
3487 /* Return a SMBwritebraw message to the redirector to tell
3488 * it to send more bytes */
3490 memcpy(buf, req->inbuf, smb_size);
3491 outsize = srv_set_message(buf,
3492 Protocol>PROTOCOL_COREPLUS?1:0,0,True);
3493 SCVAL(buf,smb_com,SMBwritebraw);
3494 SSVALS(buf,smb_vwv0,0xFFFF);
3496 if (!srv_send_smb(smbd_server_fd(),
3498 IS_CONN_ENCRYPTED(conn))) {
3499 exit_server_cleanly("reply_writebraw: srv_send_smb "
3503 /* Now read the raw data into the buffer and write it */
3504 if (read_smb_length(smbd_server_fd(),buf,
3505 SMB_SECONDARY_WAIT, get_srv_read_error()) == -1) {
3506 exit_server_cleanly("secondary writebraw failed");
3510 * Even though this is not an smb message,
3511 * smb_len returns the generic length of a packet.
3514 numtowrite = smb_len(buf);
3516 /* Set up outbuf to return the correct size */
3517 reply_outbuf(req, 1, 0);
3519 if (numtowrite != 0) {
3521 if (numtowrite > 0xFFFF) {
3522 DEBUG(0,("reply_writebraw: Oversize secondary write "
3523 "raw requested (%u). Terminating\n",
3524 (unsigned int)numtowrite ));
3525 exit_server_cleanly("secondary writebraw failed");
3528 if (tcount > nwritten+numtowrite) {
3529 DEBUG(3,("reply_writebraw: Client overestimated the "
3531 (int)tcount,(int)nwritten,(int)numtowrite));
3534 if (read_data(smbd_server_fd(), buf+4, numtowrite,get_srv_read_error())
3536 DEBUG(0,("reply_writebraw: Oversize secondary write "
3537 "raw read failed (%s). Terminating\n",
3539 exit_server_cleanly("secondary writebraw failed");
3542 nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
3543 if (nwritten == -1) {
3545 reply_unixerror(req, ERRHRD, ERRdiskfull);
3546 error_to_writebrawerr(req);
3547 END_PROFILE(SMBwritebraw);
3551 if (nwritten < (ssize_t)numtowrite) {
3552 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3553 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3557 total_written += nwritten;
3562 SSVAL(req->outbuf,smb_vwv0,total_written);
3564 status = sync_file(conn, fsp, write_through);
3565 if (!NT_STATUS_IS_OK(status)) {
3566 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
3567 fsp->fsp_name, nt_errstr(status) ));
3568 reply_nterror(req, status);
3569 error_to_writebrawerr(req);
3570 END_PROFILE(SMBwritebraw);
3574 DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
3576 fsp->fnum, (double)startpos, (int)numtowrite,
3577 (int)total_written));
3579 /* We won't return a status if write through is not selected - this
3580 * follows what WfWg does */
3581 END_PROFILE(SMBwritebraw);
3583 if (!write_through && total_written==tcount) {
3585 #if RABBIT_PELLET_FIX
3587 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
3588 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this.
3591 if (!send_keepalive(smbd_server_fd())) {
3592 exit_server_cleanly("reply_writebraw: send of "
3593 "keepalive failed");
3596 TALLOC_FREE(req->outbuf);
3602 #define DBGC_CLASS DBGC_LOCKING
3604 /****************************************************************************
3605 Reply to a writeunlock (core+).
3606 ****************************************************************************/
3608 void reply_writeunlock(struct smb_request *req)
3610 connection_struct *conn = req->conn;
3611 ssize_t nwritten = -1;
3615 NTSTATUS status = NT_STATUS_OK;
3618 START_PROFILE(SMBwriteunlock);
3621 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3622 END_PROFILE(SMBwriteunlock);
3626 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3628 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3629 END_PROFILE(SMBwriteunlock);
3633 if (!CHECK_WRITE(fsp)) {
3634 reply_doserror(req, ERRDOS,ERRbadaccess);
3635 END_PROFILE(SMBwriteunlock);
3639 numtowrite = SVAL(req->inbuf,smb_vwv1);
3640 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3641 data = smb_buf(req->inbuf) + 3;
3644 && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
3645 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3646 reply_doserror(req, ERRDOS, ERRlock);
3647 END_PROFILE(SMBwriteunlock);
3651 /* The special X/Open SMB protocol handling of
3652 zero length writes is *NOT* done for
3654 if(numtowrite == 0) {
3657 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3660 status = sync_file(conn, fsp, False /* write through */);
3661 if (!NT_STATUS_IS_OK(status)) {
3662 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
3663 fsp->fsp_name, nt_errstr(status) ));
3664 reply_nterror(req, status);
3665 END_PROFILE(SMBwriteunlock);
3669 if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
3670 reply_unixerror(req, ERRHRD, ERRdiskfull);
3671 END_PROFILE(SMBwriteunlock);
3676 status = do_unlock(smbd_messaging_context(),
3679 (SMB_BIG_UINT)numtowrite,
3680 (SMB_BIG_UINT)startpos,
3683 if (NT_STATUS_V(status)) {
3684 reply_nterror(req, status);
3685 END_PROFILE(SMBwriteunlock);
3690 reply_outbuf(req, 1, 0);
3692 SSVAL(req->outbuf,smb_vwv0,nwritten);
3694 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
3695 fsp->fnum, (int)numtowrite, (int)nwritten));
3697 END_PROFILE(SMBwriteunlock);
3702 #define DBGC_CLASS DBGC_ALL
3704 /****************************************************************************
3706 ****************************************************************************/
3708 void reply_write(struct smb_request *req)
3710 connection_struct *conn = req->conn;
3712 ssize_t nwritten = -1;
3718 START_PROFILE(SMBwrite);
3721 END_PROFILE(SMBwrite);
3722 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3726 /* If it's an IPC, pass off the pipe handler. */
3728 reply_pipe_write(req);
3729 END_PROFILE(SMBwrite);
3733 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
3735 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3736 END_PROFILE(SMBwrite);
3740 if (!CHECK_WRITE(fsp)) {
3741 reply_doserror(req, ERRDOS, ERRbadaccess);
3742 END_PROFILE(SMBwrite);
3746 numtowrite = SVAL(req->inbuf,smb_vwv1);
3747 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3748 data = smb_buf(req->inbuf) + 3;
3750 if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
3751 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3752 reply_doserror(req, ERRDOS, ERRlock);
3753 END_PROFILE(SMBwrite);
3758 * X/Open SMB protocol says that if smb_vwv1 is
3759 * zero then the file size should be extended or
3760 * truncated to the size given in smb_vwv[2-3].
3763 if(numtowrite == 0) {
3765 * This is actually an allocate call, and set EOF. JRA.
3767 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
3769 reply_nterror(req, NT_STATUS_DISK_FULL);
3770 END_PROFILE(SMBwrite);
3773 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
3775 reply_nterror(req, NT_STATUS_DISK_FULL);
3776 END_PROFILE(SMBwrite);
3780 nwritten = write_file(req,fsp,data,startpos,numtowrite);
3782 status = sync_file(conn, fsp, False);
3783 if (!NT_STATUS_IS_OK(status)) {
3784 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
3785 fsp->fsp_name, nt_errstr(status) ));
3786 reply_nterror(req, status);
3787 END_PROFILE(SMBwrite);
3791 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3792 reply_unixerror(req, ERRHRD, ERRdiskfull);
3793 END_PROFILE(SMBwrite);
3797 reply_outbuf(req, 1, 0);
3799 SSVAL(req->outbuf,smb_vwv0,nwritten);
3801 if (nwritten < (ssize_t)numtowrite) {
3802 SCVAL(req->outbuf,smb_rcls,ERRHRD);
3803 SSVAL(req->outbuf,smb_err,ERRdiskfull);
3806 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
3808 END_PROFILE(SMBwrite);
3812 /****************************************************************************
3813 Ensure a buffer is a valid writeX for recvfile purposes.
3814 ****************************************************************************/
3816 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
3817 (2*14) + /* word count (including bcc) */ \
3820 bool is_valid_writeX_buffer(const uint8_t *inbuf)
3823 connection_struct *conn = NULL;
3824 unsigned int doff = 0;
3825 size_t len = smb_len_large(inbuf);
3827 if (is_encrypted_packet(inbuf)) {
3828 /* Can't do this on encrypted
3833 if (CVAL(inbuf,smb_com) != SMBwriteX) {
3837 if (CVAL(inbuf,smb_vwv0) != 0xFF ||
3838 CVAL(inbuf,smb_wct) != 14) {
3839 DEBUG(10,("is_valid_writeX_buffer: chained or "
3840 "invalid word length.\n"));
3844 conn = conn_find(SVAL(inbuf, smb_tid));
3846 DEBUG(10,("is_valid_writeX_buffer: bad tid\n"));
3850 DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
3853 doff = SVAL(inbuf,smb_vwv11);
3855 numtowrite = SVAL(inbuf,smb_vwv10);
3857 if (len > doff && len - doff > 0xFFFF) {
3858 numtowrite |= (((size_t)SVAL(inbuf,smb_vwv9))<<16);
3861 if (numtowrite == 0) {
3862 DEBUG(10,("is_valid_writeX_buffer: zero write\n"));
3866 /* Ensure the sizes match up. */
3867 if (doff < STANDARD_WRITE_AND_X_HEADER_SIZE) {
3868 /* no pad byte...old smbclient :-( */
3869 DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n",
3871 (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE));
3875 if (len - doff != numtowrite) {
3876 DEBUG(10,("is_valid_writeX_buffer: doff mismatch "
3877 "len = %u, doff = %u, numtowrite = %u\n",
3880 (unsigned int)numtowrite ));
3884 DEBUG(10,("is_valid_writeX_buffer: true "
3885 "len = %u, doff = %u, numtowrite = %u\n",
3888 (unsigned int)numtowrite ));
3893 /****************************************************************************
3894 Reply to a write and X.
3895 ****************************************************************************/
3897 void reply_write_and_X(struct smb_request *req)
3899 connection_struct *conn = req->conn;
3905 unsigned int smb_doff;
3906 unsigned int smblen;
3910 START_PROFILE(SMBwriteX);
3912 if ((req->wct != 12) && (req->wct != 14)) {
3913 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3914 END_PROFILE(SMBwriteX);
3918 numtowrite = SVAL(req->inbuf,smb_vwv10);
3919 smb_doff = SVAL(req->inbuf,smb_vwv11);
3920 smblen = smb_len(req->inbuf);
3922 if (req->unread_bytes > 0xFFFF ||
3923 (smblen > smb_doff &&
3924 smblen - smb_doff > 0xFFFF)) {
3925 numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
3928 if (req->unread_bytes) {
3929 /* Can't do a recvfile write on IPC$ */
3931 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3932 END_PROFILE(SMBwriteX);
3935 if (numtowrite != req->unread_bytes) {
3936 reply_doserror(req, ERRDOS, ERRbadmem);
3937 END_PROFILE(SMBwriteX);
3941 if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
3942 smb_doff + numtowrite > smblen) {
3943 reply_doserror(req, ERRDOS, ERRbadmem);
3944 END_PROFILE(SMBwriteX);
3949 /* If it's an IPC, pass off the pipe handler. */
3951 if (req->unread_bytes) {
3952 reply_doserror(req, ERRDOS, ERRbadmem);
3953 END_PROFILE(SMBwriteX);
3956 reply_pipe_write_and_X(req);
3957 END_PROFILE(SMBwriteX);
3961 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
3962 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
3963 write_through = BITSETW(req->inbuf+smb_vwv7,0);
3965 if (!check_fsp(conn, req, fsp, ¤t_user)) {
3966 END_PROFILE(SMBwriteX);
3970 if (!CHECK_WRITE(fsp)) {
3971 reply_doserror(req, ERRDOS, ERRbadaccess);
3972 END_PROFILE(SMBwriteX);
3976 data = smb_base(req->inbuf) + smb_doff;
3978 if(req->wct == 14) {
3979 #ifdef LARGE_SMB_OFF_T
3981 * This is a large offset (64 bit) write.
3983 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32);
3985 #else /* !LARGE_SMB_OFF_T */
3988 * Ensure we haven't been sent a >32 bit offset.
3991 if(IVAL(req->inbuf,smb_vwv12) != 0) {
3992 DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
3993 "used and we don't support 64 bit offsets.\n",
3994 (unsigned int)IVAL(req->inbuf,smb_vwv12) ));
3995 reply_doserror(req, ERRDOS, ERRbadaccess);
3996 END_PROFILE(SMBwriteX);
4000 #endif /* LARGE_SMB_OFF_T */
4003 if (is_locked(fsp,(uint32)req->smbpid,
4004 (SMB_BIG_UINT)numtowrite,
4005 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
4006 reply_doserror(req, ERRDOS, ERRlock);
4007 END_PROFILE(SMBwriteX);
4011 /* X/Open SMB protocol says that, unlike SMBwrite
4012 if the length is zero then NO truncation is
4013 done, just a write of zero. To truncate a file,
4016 if(numtowrite == 0) {
4020 /* It is possible for VFS modules to selectively decide whether Async I/O
4021 should be used for the file or not.
4023 if ((SMB_VFS_AIO_FORCE(fsp)) && (req->unread_bytes == 0) &&
4024 schedule_aio_write_and_X(conn, req, fsp, data, startpos,
4026 END_PROFILE(SMBwriteX);
4030 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4033 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4034 reply_unixerror(req, ERRHRD, ERRdiskfull);
4035 END_PROFILE(SMBwriteX);
4039 reply_outbuf(req, 6, 0);
4040 SSVAL(req->outbuf,smb_vwv2,nwritten);
4041 SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
4043 if (nwritten < (ssize_t)numtowrite) {
4044 SCVAL(req->outbuf,smb_rcls,ERRHRD);
4045 SSVAL(req->outbuf,smb_err,ERRdiskfull);
4048 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
4049 fsp->fnum, (int)numtowrite, (int)nwritten));
4051 status = sync_file(conn, fsp, write_through);
4052 if (!NT_STATUS_IS_OK(status)) {
4053 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
4054 fsp->fsp_name, nt_errstr(status) ));
4055 reply_nterror(req, status);
4056 END_PROFILE(SMBwriteX);
4060 END_PROFILE(SMBwriteX);
4065 /****************************************************************************
4067 ****************************************************************************/
4069 void reply_lseek(struct smb_request *req)
4071 connection_struct *conn = req->conn;
4077 START_PROFILE(SMBlseek);
4080 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4081 END_PROFILE(SMBlseek);
4085 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4087 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4091 flush_write_cache(fsp, SEEK_FLUSH);
4093 mode = SVAL(req->inbuf,smb_vwv1) & 3;
4094 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
4095 startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2);
4104 res = fsp->fh->pos + startpos;
4115 if (umode == SEEK_END) {
4116 if((res = SMB_VFS_LSEEK(fsp,startpos,umode)) == -1) {
4117 if(errno == EINVAL) {
4118 SMB_OFF_T current_pos = startpos;
4119 SMB_STRUCT_STAT sbuf;
4121 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
4122 reply_unixerror(req, ERRDOS,
4124 END_PROFILE(SMBlseek);
4128 current_pos += sbuf.st_size;
4130 res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
4135 reply_unixerror(req, ERRDOS, ERRnoaccess);
4136 END_PROFILE(SMBlseek);
4143 reply_outbuf(req, 2, 0);
4144 SIVAL(req->outbuf,smb_vwv0,res);
4146 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
4147 fsp->fnum, (double)startpos, (double)res, mode));
4149 END_PROFILE(SMBlseek);
4153 /****************************************************************************
4155 ****************************************************************************/
4157 void reply_flush(struct smb_request *req)
4159 connection_struct *conn = req->conn;
4163 START_PROFILE(SMBflush);
4166 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4170 fnum = SVAL(req->inbuf,smb_vwv0);
4171 fsp = file_fsp(fnum);
4173 if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp, ¤t_user)) {
4178 file_sync_all(conn);
4180 NTSTATUS status = sync_file(conn, fsp, True);
4181 if (!NT_STATUS_IS_OK(status)) {
4182 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
4183 fsp->fsp_name, nt_errstr(status) ));
4184 reply_nterror(req, status);
4185 END_PROFILE(SMBflush);
4190 reply_outbuf(req, 0, 0);
4192 DEBUG(3,("flush\n"));
4193 END_PROFILE(SMBflush);
4197 /****************************************************************************
4199 conn POINTER CAN BE NULL HERE !
4200 ****************************************************************************/
4202 void reply_exit(struct smb_request *req)
4204 START_PROFILE(SMBexit);
4206 file_close_pid(req->smbpid, req->vuid);
4208 reply_outbuf(req, 0, 0);
4210 DEBUG(3,("exit\n"));
4212 END_PROFILE(SMBexit);
4216 /****************************************************************************
4217 Reply to a close - has to deal with closing a directory opened by NT SMB's.
4218 ****************************************************************************/
4220 void reply_close(struct smb_request *req)
4222 connection_struct *conn = req->conn;
4223 NTSTATUS status = NT_STATUS_OK;
4224 files_struct *fsp = NULL;
4225 START_PROFILE(SMBclose);
4228 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4229 END_PROFILE(SMBclose);
4233 /* If it's an IPC, pass off to the pipe handler. */
4235 reply_pipe_close(conn, req);
4236 END_PROFILE(SMBclose);
4240 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4243 * We can only use CHECK_FSP if we know it's not a directory.
4246 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
4247 reply_doserror(req, ERRDOS, ERRbadfid);
4248 END_PROFILE(SMBclose);
4252 if(fsp->is_directory) {
4254 * Special case - close NT SMB directory handle.
4256 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
4257 status = close_file(fsp,NORMAL_CLOSE);
4260 * Close ordinary file.
4263 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
4264 fsp->fh->fd, fsp->fnum,
4265 conn->num_files_open));
4268 * Take care of any time sent in the close.
4271 fsp_set_pending_modtime(fsp, convert_time_t_to_timespec(
4272 srv_make_unix_date3(
4273 req->inbuf+smb_vwv1)));
4276 * close_file() returns the unix errno if an error
4277 * was detected on close - normally this is due to
4278 * a disk full error. If not then it was probably an I/O error.
4281 status = close_file(fsp,NORMAL_CLOSE);
4284 if (!NT_STATUS_IS_OK(status)) {
4285 reply_nterror(req, status);
4286 END_PROFILE(SMBclose);
4290 reply_outbuf(req, 0, 0);
4291 END_PROFILE(SMBclose);
4295 /****************************************************************************
4296 Reply to a writeclose (Core+ protocol).
4297 ****************************************************************************/
4299 void reply_writeclose(struct smb_request *req)
4301 connection_struct *conn = req->conn;
4303 ssize_t nwritten = -1;
4304 NTSTATUS close_status = NT_STATUS_OK;
4307 struct timespec mtime;
4310 START_PROFILE(SMBwriteclose);
4313 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4314 END_PROFILE(SMBwriteclose);
4318 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4320 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4321 END_PROFILE(SMBwriteclose);
4324 if (!CHECK_WRITE(fsp)) {
4325 reply_doserror(req, ERRDOS,ERRbadaccess);
4326 END_PROFILE(SMBwriteclose);
4330 numtowrite = SVAL(req->inbuf,smb_vwv1);
4331 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
4332 mtime = convert_time_t_to_timespec(srv_make_unix_date3(
4333 req->inbuf+smb_vwv4));
4334 data = smb_buf(req->inbuf) + 1;
4337 && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
4338 (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
4339 reply_doserror(req, ERRDOS,ERRlock);
4340 END_PROFILE(SMBwriteclose);
4344 nwritten = write_file(req,fsp,data,startpos,numtowrite);
4346 set_filetime(conn, fsp->fsp_name, mtime);
4349 * More insanity. W2K only closes the file if writelen > 0.
4354 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
4356 close_status = close_file(fsp,NORMAL_CLOSE);
4359 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
4360 fsp->fnum, (int)numtowrite, (int)nwritten,
4361 conn->num_files_open));
4363 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
4364 reply_doserror(req, ERRHRD, ERRdiskfull);
4365 END_PROFILE(SMBwriteclose);
4369 if(!NT_STATUS_IS_OK(close_status)) {
4370 reply_nterror(req, close_status);
4371 END_PROFILE(SMBwriteclose);
4375 reply_outbuf(req, 1, 0);
4377 SSVAL(req->outbuf,smb_vwv0,nwritten);
4378 END_PROFILE(SMBwriteclose);
4383 #define DBGC_CLASS DBGC_LOCKING
4385 /****************************************************************************
4387 ****************************************************************************/
4389 void reply_lock(struct smb_request *req)
4391 connection_struct *conn = req->conn;
4392 SMB_BIG_UINT count,offset;
4395 struct byte_range_lock *br_lck = NULL;
4397 START_PROFILE(SMBlock);
4400 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4401 END_PROFILE(SMBlock);
4405 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4407 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4408 END_PROFILE(SMBlock);
4412 release_level_2_oplocks_on_change(fsp);
4414 count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
4415 offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
4417 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4418 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
4420 br_lck = do_lock(smbd_messaging_context(),
4427 False, /* Non-blocking lock. */
4431 TALLOC_FREE(br_lck);
4433 if (NT_STATUS_V(status)) {
4434 reply_nterror(req, status);
4435 END_PROFILE(SMBlock);
4439 reply_outbuf(req, 0, 0);
4441 END_PROFILE(SMBlock);
4445 /****************************************************************************
4447 ****************************************************************************/
4449 void reply_unlock(struct smb_request *req)
4451 connection_struct *conn = req->conn;
4452 SMB_BIG_UINT count,offset;
4456 START_PROFILE(SMBunlock);
4459 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4460 END_PROFILE(SMBunlock);
4464 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4466 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4467 END_PROFILE(SMBunlock);
4471 count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
4472 offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
4474 status = do_unlock(smbd_messaging_context(),
4481 if (NT_STATUS_V(status)) {
4482 reply_nterror(req, status);
4483 END_PROFILE(SMBunlock);
4487 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
4488 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
4490 reply_outbuf(req, 0, 0);
4492 END_PROFILE(SMBunlock);
4497 #define DBGC_CLASS DBGC_ALL
4499 /****************************************************************************
4501 conn POINTER CAN BE NULL HERE !
4502 ****************************************************************************/
4504 void reply_tdis(struct smb_request *req)
4506 connection_struct *conn = req->conn;
4507 START_PROFILE(SMBtdis);
4510 DEBUG(4,("Invalid connection in tdis\n"));
4511 reply_doserror(req, ERRSRV, ERRinvnid);
4512 END_PROFILE(SMBtdis);
4518 close_cnum(conn,req->vuid);
4521 reply_outbuf(req, 0, 0);
4522 END_PROFILE(SMBtdis);
4526 /****************************************************************************
4528 conn POINTER CAN BE NULL HERE !
4529 ****************************************************************************/
4531 void reply_echo(struct smb_request *req)
4533 connection_struct *conn = req->conn;
4536 unsigned int data_len = smb_buflen(req->inbuf);
4538 START_PROFILE(SMBecho);
4541 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4542 END_PROFILE(SMBecho);
4546 if (data_len > BUFFER_SIZE) {
4547 DEBUG(0,("reply_echo: data_len too large.\n"));
4548 reply_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
4549 END_PROFILE(SMBecho);
4553 smb_reverb = SVAL(req->inbuf,smb_vwv0);
4555 reply_outbuf(req, 1, data_len);
4557 /* copy any incoming data back out */
4559 memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len);
4562 if (smb_reverb > 100) {
4563 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
4567 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
4568 SSVAL(req->outbuf,smb_vwv0,seq_num);
4570 show_msg((char *)req->outbuf);
4571 if (!srv_send_smb(smbd_server_fd(),
4572 (char *)req->outbuf,
4573 IS_CONN_ENCRYPTED(conn)||req->encrypted))
4574 exit_server_cleanly("reply_echo: srv_send_smb failed.");
4577 DEBUG(3,("echo %d times\n", smb_reverb));
4579 TALLOC_FREE(req->outbuf);
4583 END_PROFILE(SMBecho);
4587 /****************************************************************************
4588 Reply to a printopen.
4589 ****************************************************************************/
4591 void reply_printopen(struct smb_request *req)
4593 connection_struct *conn = req->conn;
4597 START_PROFILE(SMBsplopen);
4600 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4601 END_PROFILE(SMBsplopen);
4605 if (!CAN_PRINT(conn)) {
4606 reply_doserror(req, ERRDOS, ERRnoaccess);
4607 END_PROFILE(SMBsplopen);
4611 /* Open for exclusive use, write only. */
4612 status = print_fsp_open(conn, NULL, &fsp);
4614 if (!NT_STATUS_IS_OK(status)) {
4615 reply_nterror(req, status);
4616 END_PROFILE(SMBsplopen);
4620 reply_outbuf(req, 1, 0);
4621 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
4623 DEBUG(3,("openprint fd=%d fnum=%d\n",
4624 fsp->fh->fd, fsp->fnum));
4626 END_PROFILE(SMBsplopen);
4630 /****************************************************************************
4631 Reply to a printclose.
4632 ****************************************************************************/
4634 void reply_printclose(struct smb_request *req)
4636 connection_struct *conn = req->conn;
4640 START_PROFILE(SMBsplclose);
4643 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4644 END_PROFILE(SMBsplclose);
4648 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4650 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4651 END_PROFILE(SMBsplclose);
4655 if (!CAN_PRINT(conn)) {
4656 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
4657 END_PROFILE(SMBsplclose);
4661 DEBUG(3,("printclose fd=%d fnum=%d\n",
4662 fsp->fh->fd,fsp->fnum));
4664 status = close_file(fsp,NORMAL_CLOSE);
4666 if(!NT_STATUS_IS_OK(status)) {
4667 reply_nterror(req, status);
4668 END_PROFILE(SMBsplclose);
4672 END_PROFILE(SMBsplclose);
4676 /****************************************************************************
4677 Reply to a printqueue.
4678 ****************************************************************************/
4680 void reply_printqueue(struct smb_request *req)
4682 connection_struct *conn = req->conn;
4686 START_PROFILE(SMBsplretq);
4689 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4690 END_PROFILE(SMBsplretq);
4694 max_count = SVAL(req->inbuf,smb_vwv0);
4695 start_index = SVAL(req->inbuf,smb_vwv1);
4697 /* we used to allow the client to get the cnum wrong, but that
4698 is really quite gross and only worked when there was only
4699 one printer - I think we should now only accept it if they
4700 get it right (tridge) */
4701 if (!CAN_PRINT(conn)) {
4702 reply_doserror(req, ERRDOS, ERRnoaccess);
4703 END_PROFILE(SMBsplretq);
4707 reply_outbuf(req, 2, 3);
4708 SSVAL(req->outbuf,smb_vwv0,0);
4709 SSVAL(req->outbuf,smb_vwv1,0);
4710 SCVAL(smb_buf(req->outbuf),0,1);
4711 SSVAL(smb_buf(req->outbuf),1,0);
4713 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
4714 start_index, max_count));
4717 print_queue_struct *queue = NULL;
4718 print_status_struct status;
4719 int count = print_queue_status(SNUM(conn), &queue, &status);
4720 int num_to_get = ABS(max_count);
4721 int first = (max_count>0?start_index:start_index+max_count+1);
4727 num_to_get = MIN(num_to_get,count-first);
4730 for (i=first;i<first+num_to_get;i++) {
4734 srv_put_dos_date2(p,0,queue[i].time);
4735 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
4736 SSVAL(p,5, queue[i].job);
4737 SIVAL(p,7,queue[i].size);
4739 srvstr_push(blob, req->flags2, p+12,
4740 queue[i].fs_user, 16, STR_ASCII);
4742 if (message_push_blob(
4745 blob, sizeof(blob))) == -1) {
4746 reply_nterror(req, NT_STATUS_NO_MEMORY);
4747 END_PROFILE(SMBsplretq);
4753 SSVAL(req->outbuf,smb_vwv0,count);
4754 SSVAL(req->outbuf,smb_vwv1,
4755 (max_count>0?first+count:first-1));
4756 SCVAL(smb_buf(req->outbuf),0,1);
4757 SSVAL(smb_buf(req->outbuf),1,28*count);
4762 DEBUG(3,("%d entries returned in queue\n",count));
4765 END_PROFILE(SMBsplretq);
4769 /****************************************************************************
4770 Reply to a printwrite.
4771 ****************************************************************************/
4773 void reply_printwrite(struct smb_request *req)
4775 connection_struct *conn = req->conn;
4780 START_PROFILE(SMBsplwr);
4783 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4784 END_PROFILE(SMBsplwr);
4788 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
4790 if (!check_fsp(conn, req, fsp, ¤t_user)) {
4791 END_PROFILE(SMBsplwr);
4795 if (!CAN_PRINT(conn)) {
4796 reply_doserror(req, ERRDOS, ERRnoaccess);
4797 END_PROFILE(SMBsplwr);
4801 if (!CHECK_WRITE(fsp)) {
4802 reply_doserror(req, ERRDOS, ERRbadaccess);
4803 END_PROFILE(SMBsplwr);
4807 numtowrite = SVAL(smb_buf(req->inbuf),1);
4809 if (smb_buflen(req->inbuf) < numtowrite + 3) {
4810 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4811 END_PROFILE(SMBsplwr);
4815 data = smb_buf(req->inbuf) + 3;
4817 if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
4818 reply_unixerror(req, ERRHRD, ERRdiskfull);
4819 END_PROFILE(SMBsplwr);
4823 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
4825 END_PROFILE(SMBsplwr);
4829 /****************************************************************************
4831 ****************************************************************************/
4833 void reply_mkdir(struct smb_request *req)
4835 connection_struct *conn = req->conn;
4836 char *directory = NULL;
4838 SMB_STRUCT_STAT sbuf;
4839 TALLOC_CTX *ctx = talloc_tos();
4841 START_PROFILE(SMBmkdir);
4843 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
4844 smb_buf(req->inbuf) + 1, 0,
4845 STR_TERMINATE, &status);
4846 if (!NT_STATUS_IS_OK(status)) {
4847 reply_nterror(req, status);
4848 END_PROFILE(SMBmkdir);
4852 status = resolve_dfspath(ctx, conn,
4853 req->flags2 & FLAGS2_DFS_PATHNAMES,
4856 if (!NT_STATUS_IS_OK(status)) {
4857 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4858 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
4859 ERRSRV, ERRbadpath);
4860 END_PROFILE(SMBmkdir);
4863 reply_nterror(req, status);
4864 END_PROFILE(SMBmkdir);
4868 status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
4869 if (!NT_STATUS_IS_OK(status)) {
4870 reply_nterror(req, status);
4871 END_PROFILE(SMBmkdir);
4875 status = check_name(conn, directory);
4876 if (!NT_STATUS_IS_OK(status)) {
4877 reply_nterror(req, status);
4878 END_PROFILE(SMBmkdir);
4882 status = create_directory(conn, req, directory);
4884 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
4886 if (!NT_STATUS_IS_OK(status)) {
4888 if (!use_nt_status()
4889 && NT_STATUS_EQUAL(status,
4890 NT_STATUS_OBJECT_NAME_COLLISION)) {
4892 * Yes, in the DOS error code case we get a
4893 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
4894 * samba4 torture test.
4896 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
4899 reply_nterror(req, status);
4900 END_PROFILE(SMBmkdir);
4904 reply_outbuf(req, 0, 0);
4906 DEBUG( 3, ( "mkdir %s\n", directory ) );
4908 END_PROFILE(SMBmkdir);
4912 /****************************************************************************
4913 Static function used by reply_rmdir to delete an entire directory
4914 tree recursively. Return True on ok, False on fail.
4915 ****************************************************************************/
4917 static bool recursive_rmdir(TALLOC_CTX *ctx,
4918 connection_struct *conn,
4921 const char *dname = NULL;
4924 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, directory,
4930 while((dname = ReadDirName(dir_hnd, &offset))) {
4931 char *fullname = NULL;
4934 if (ISDOT(dname) || ISDOTDOT(dname)) {
4938 if (!is_visible_file(conn, directory, dname, &st, False)) {
4942 /* Construct the full name. */
4943 fullname = talloc_asprintf(ctx,
4953 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
4958 if(st.st_mode & S_IFDIR) {
4959 if(!recursive_rmdir(ctx, conn, fullname)) {
4963 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
4967 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
4971 TALLOC_FREE(fullname);
4973 TALLOC_FREE(dir_hnd);
4977 /****************************************************************************
4978 The internals of the rmdir code - called elsewhere.
4979 ****************************************************************************/
4981 NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
4982 connection_struct *conn,
4983 const char *directory)
4988 /* Might be a symlink. */
4989 if(SMB_VFS_LSTAT(conn, directory, &st) != 0) {
4990 return map_nt_error_from_unix(errno);
4993 if (S_ISLNK(st.st_mode)) {
4994 /* Is what it points to a directory ? */
4995 if(SMB_VFS_STAT(conn, directory, &st) != 0) {
4996 return map_nt_error_from_unix(errno);
4998 if (!(S_ISDIR(st.st_mode))) {
4999 return NT_STATUS_NOT_A_DIRECTORY;
5001 ret = SMB_VFS_UNLINK(conn,directory);
5003 ret = SMB_VFS_RMDIR(conn,directory);
5006 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5007 FILE_NOTIFY_CHANGE_DIR_NAME,
5009 return NT_STATUS_OK;
5012 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
5014 * Check to see if the only thing in this directory are
5015 * vetoed files/directories. If so then delete them and
5016 * retry. If we fail to delete any of them (and we *don't*
5017 * do a recursive delete) then fail the rmdir.
5021 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
5022 directory, NULL, 0);
5024 if(dir_hnd == NULL) {
5029 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5030 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
5032 if (!is_visible_file(conn, directory, dname, &st, False))
5034 if(!IS_VETO_PATH(conn, dname)) {
5035 TALLOC_FREE(dir_hnd);
5041 /* We only have veto files/directories. Recursive delete. */
5043 RewindDir(dir_hnd,&dirpos);
5044 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
5045 char *fullname = NULL;
5047 if (ISDOT(dname) || ISDOTDOT(dname)) {
5050 if (!is_visible_file(conn, directory, dname, &st, False)) {
5054 fullname = talloc_asprintf(ctx,
5064 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
5067 if(st.st_mode & S_IFDIR) {
5068 if(lp_recursive_veto_delete(SNUM(conn))) {
5069 if(!recursive_rmdir(ctx, conn, fullname))
5072 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
5075 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
5078 TALLOC_FREE(fullname);
5080 TALLOC_FREE(dir_hnd);
5081 /* Retry the rmdir */
5082 ret = SMB_VFS_RMDIR(conn,directory);
5088 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
5089 "%s\n", directory,strerror(errno)));
5090 return map_nt_error_from_unix(errno);
5093 notify_fname(conn, NOTIFY_ACTION_REMOVED,
5094 FILE_NOTIFY_CHANGE_DIR_NAME,
5097 return NT_STATUS_OK;
5100 /****************************************************************************
5102 ****************************************************************************/
5104 void reply_rmdir(struct smb_request *req)
5106 connection_struct *conn = req->conn;
5107 char *directory = NULL;
5108 SMB_STRUCT_STAT sbuf;
5110 TALLOC_CTX *ctx = talloc_tos();
5112 START_PROFILE(SMBrmdir);
5114 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
5115 smb_buf(req->inbuf) + 1, 0,
5116 STR_TERMINATE, &status);
5117 if (!NT_STATUS_IS_OK(status)) {
5118 reply_nterror(req, status);
5119 END_PROFILE(SMBrmdir);
5123 status = resolve_dfspath(ctx, conn,
5124 req->flags2 & FLAGS2_DFS_PATHNAMES,
5127 if (!NT_STATUS_IS_OK(status)) {
5128 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5129 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5130 ERRSRV, ERRbadpath);
5131 END_PROFILE(SMBrmdir);
5134 reply_nterror(req, status);
5135 END_PROFILE(SMBrmdir);
5139 status = unix_convert(ctx, conn, directory, False, &directory,
5141 if (!NT_STATUS_IS_OK(status)) {
5142 reply_nterror(req, status);
5143 END_PROFILE(SMBrmdir);
5147 status = check_name(conn, directory);
5148 if (!NT_STATUS_IS_OK(status)) {
5149 reply_nterror(req, status);
5150 END_PROFILE(SMBrmdir);
5154 dptr_closepath(directory, req->smbpid);
5155 status = rmdir_internals(ctx, conn, directory);
5156 if (!NT_STATUS_IS_OK(status)) {
5157 reply_nterror(req, status);
5158 END_PROFILE(SMBrmdir);
5162 reply_outbuf(req, 0, 0);
5164 DEBUG( 3, ( "rmdir %s\n", directory ) );
5166 END_PROFILE(SMBrmdir);
5170 /*******************************************************************
5171 Resolve wildcards in a filename rename.
5172 ********************************************************************/
5174 static bool resolve_wildcards(TALLOC_CTX *ctx,
5179 char *name2_copy = NULL;
5184 char *p,*p2, *pname1, *pname2;
5186 name2_copy = talloc_strdup(ctx, name2);
5191 pname1 = strrchr_m(name1,'/');
5192 pname2 = strrchr_m(name2_copy,'/');
5194 if (!pname1 || !pname2) {
5198 /* Truncate the copy of name2 at the last '/' */
5201 /* Now go past the '/' */
5205 root1 = talloc_strdup(ctx, pname1);
5206 root2 = talloc_strdup(ctx, pname2);
5208 if (!root1 || !root2) {
5212 p = strrchr_m(root1,'.');
5215 ext1 = talloc_strdup(ctx, p+1);
5217 ext1 = talloc_strdup(ctx, "");
5219 p = strrchr_m(root2,'.');
5222 ext2 = talloc_strdup(ctx, p+1);
5224 ext2 = talloc_strdup(ctx, "");
5227 if (!ext1 || !ext2) {
5235 /* Hmmm. Should this be mb-aware ? */
5238 } else if (*p2 == '*') {
5240 root2 = talloc_asprintf(ctx, "%s%s",
5259 /* Hmmm. Should this be mb-aware ? */
5262 } else if (*p2 == '*') {
5264 ext2 = talloc_asprintf(ctx, "%s%s",
5280 *pp_newname = talloc_asprintf(ctx, "%s/%s.%s",
5285 *pp_newname = talloc_asprintf(ctx, "%s/%s",
5297 /****************************************************************************
5298 Ensure open files have their names updated. Updated to notify other smbd's
5300 ****************************************************************************/
5302 static void rename_open_files(connection_struct *conn,
5303 struct share_mode_lock *lck,
5304 const char *newname)
5307 bool did_rename = False;
5309 for(fsp = file_find_di_first(lck->id); fsp;
5310 fsp = file_find_di_next(fsp)) {
5311 /* fsp_name is a relative path under the fsp. To change this for other
5312 sharepaths we need to manipulate relative paths. */
5313 /* TODO - create the absolute path and manipulate the newname
5314 relative to the sharepath. */
5315 if (fsp->conn != conn) {
5318 DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
5319 fsp->fnum, file_id_string_tos(&fsp->file_id),
5320 fsp->fsp_name, newname ));
5321 string_set(&fsp->fsp_name, newname);
5326 DEBUG(10,("rename_open_files: no open files on file_id %s for %s\n",
5327 file_id_string_tos(&lck->id), newname ));
5330 /* Send messages to all smbd's (not ourself) that the name has changed. */
5331 rename_share_filename(smbd_messaging_context(), lck, conn->connectpath,
5335 /****************************************************************************
5336 We need to check if the source path is a parent directory of the destination
5337 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
5338 refuse the rename with a sharing violation. Under UNIX the above call can
5339 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
5340 probably need to check that the client is a Windows one before disallowing
5341 this as a UNIX client (one with UNIX extensions) can know the source is a
5342 symlink and make this decision intelligently. Found by an excellent bug
5343 report from <AndyLiebman@aol.com>.
5344 ****************************************************************************/
5346 static bool rename_path_prefix_equal(const char *src, const char *dest)
5348 const char *psrc = src;
5349 const char *pdst = dest;
5352 if (psrc[0] == '.' && psrc[1] == '/') {
5355 if (pdst[0] == '.' && pdst[1] == '/') {
5358 if ((slen = strlen(psrc)) > strlen(pdst)) {
5361 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
5365 * Do the notify calls from a rename
5368 static void notify_rename(connection_struct *conn, bool is_dir,
5369 const char *oldpath, const char *newpath)
5371 char *olddir, *newdir;
5372 const char *oldname, *newname;
5375 mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
5376 : FILE_NOTIFY_CHANGE_FILE_NAME;
5378 if (!parent_dirname_talloc(NULL, oldpath, &olddir, &oldname)
5379 || !parent_dirname_talloc(NULL, newpath, &newdir, &newname)) {
5380 TALLOC_FREE(olddir);
5384 if (strcmp(olddir, newdir) == 0) {
5385 notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, oldpath);
5386 notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, newpath);
5389 notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, oldpath);
5390 notify_fname(conn, NOTIFY_ACTION_ADDED, mask, newpath);
5392 TALLOC_FREE(olddir);
5393 TALLOC_FREE(newdir);
5395 /* this is a strange one. w2k3 gives an additional event for
5396 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
5397 files, but not directories */
5399 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
5400 FILE_NOTIFY_CHANGE_ATTRIBUTES
5401 |FILE_NOTIFY_CHANGE_CREATION,
5406 /****************************************************************************
5407 Rename an open file - given an fsp.
5408 ****************************************************************************/
5410 NTSTATUS rename_internals_fsp(connection_struct *conn,
5413 const char *newname_last_component,
5415 bool replace_if_exists)
5417 TALLOC_CTX *ctx = talloc_tos();
5418 SMB_STRUCT_STAT sbuf, sbuf1;
5419 NTSTATUS status = NT_STATUS_OK;
5420 struct share_mode_lock *lck = NULL;
5425 status = check_name(conn, newname);
5426 if (!NT_STATUS_IS_OK(status)) {
5430 /* Ensure newname contains a '/' */
5431 if(strrchr_m(newname,'/') == 0) {
5432 newname = talloc_asprintf(ctx,
5436 return NT_STATUS_NO_MEMORY;
5441 * Check for special case with case preserving and not
5442 * case sensitive. If the old last component differs from the original
5443 * last component only by case, then we should allow
5444 * the rename (user is trying to change the case of the
5448 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
5449 strequal(newname, fsp->fsp_name)) {
5451 char *newname_modified_last_component = NULL;
5454 * Get the last component of the modified name.
5455 * Note that we guarantee that newname contains a '/'
5458 p = strrchr_m(newname,'/');
5459 newname_modified_last_component = talloc_strdup(ctx,
5461 if (!newname_modified_last_component) {
5462 return NT_STATUS_NO_MEMORY;
5465 if(strcsequal(newname_modified_last_component,
5466 newname_last_component) == False) {
5468 * Replace the modified last component with
5471 *p = '\0'; /* Truncate at the '/' */
5472 newname = talloc_asprintf(ctx,
5475 newname_last_component);
5480 * If the src and dest names are identical - including case,
5481 * don't do the rename, just return success.
5484 if (strcsequal(fsp->fsp_name, newname)) {
5485 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
5487 return NT_STATUS_OK;
5491 * Have vfs_object_exist also fill sbuf1
5493 dst_exists = vfs_object_exist(conn, newname, &sbuf1);
5495 if(!replace_if_exists && dst_exists) {
5496 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
5497 fsp->fsp_name,newname));
5498 return NT_STATUS_OBJECT_NAME_COLLISION;
5502 struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
5503 files_struct *dst_fsp = file_find_di_first(fileid);
5505 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
5506 return NT_STATUS_ACCESS_DENIED;
5510 /* Ensure we have a valid stat struct for the source. */
5511 if (fsp->fh->fd != -1) {
5512 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
5513 return map_nt_error_from_unix(errno);
5516 if (SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) == -1) {
5517 return map_nt_error_from_unix(errno);
5521 status = can_rename(conn, fsp, attrs, &sbuf);
5523 if (!NT_STATUS_IS_OK(status)) {
5524 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5525 nt_errstr(status), fsp->fsp_name,newname));
5526 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION))
5527 status = NT_STATUS_ACCESS_DENIED;
5531 if (rename_path_prefix_equal(fsp->fsp_name, newname)) {
5532 return NT_STATUS_ACCESS_DENIED;
5535 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL);
5538 * We have the file open ourselves, so not being able to get the
5539 * corresponding share mode lock is a fatal error.
5542 SMB_ASSERT(lck != NULL);
5544 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
5545 uint32 create_options = fsp->fh->private_options;
5547 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
5548 fsp->fsp_name,newname));
5550 rename_open_files(conn, lck, newname);
5552 notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname);
5555 * A rename acts as a new file create w.r.t. allowing an initial delete
5556 * on close, probably because in Windows there is a new handle to the
5557 * new file. If initial delete on close was requested but not
5558 * originally set, we need to set it here. This is probably not 100% correct,
5559 * but will work for the CIFSFS client which in non-posix mode
5560 * depends on these semantics. JRA.
5563 set_allow_initial_delete_on_close(lck, fsp, True);
5565 if (create_options & FILE_DELETE_ON_CLOSE) {
5566 status = can_set_delete_on_close(fsp, True, 0);
5568 if (NT_STATUS_IS_OK(status)) {
5569 /* Note that here we set the *inital* delete on close flag,
5570 * not the regular one. The magic gets handled in close. */
5571 fsp->initial_delete_on_close = True;
5575 return NT_STATUS_OK;
5580 if (errno == ENOTDIR || errno == EISDIR) {
5581 status = NT_STATUS_OBJECT_NAME_COLLISION;
5583 status = map_nt_error_from_unix(errno);
5586 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
5587 nt_errstr(status), fsp->fsp_name,newname));
5592 /****************************************************************************
5593 The guts of the rename command, split out so it may be called by the NT SMB
5595 ****************************************************************************/
5597 NTSTATUS rename_internals(TALLOC_CTX *ctx,
5598 connection_struct *conn,
5599 struct smb_request *req,
5600 const char *name_in,
5601 const char *newname_in,
5603 bool replace_if_exists,
5607 char *directory = NULL;
5609 char *last_component_src = NULL;
5610 char *last_component_dest = NULL;
5612 char *newname = NULL;
5615 NTSTATUS status = NT_STATUS_OK;
5616 SMB_STRUCT_STAT sbuf1, sbuf2;
5617 struct smb_Dir *dir_hnd = NULL;
5624 status = unix_convert(ctx, conn, name_in, src_has_wild, &name,
5625 &last_component_src, &sbuf1);
5626 if (!NT_STATUS_IS_OK(status)) {
5630 status = unix_convert(ctx, conn, newname_in, dest_has_wild, &newname,
5631 &last_component_dest, &sbuf2);
5632 if (!NT_STATUS_IS_OK(status)) {
5637 * Split the old name into directory and last component
5638 * strings. Note that unix_convert may have stripped off a
5639 * leading ./ from both name and newname if the rename is
5640 * at the root of the share. We need to make sure either both
5641 * name and newname contain a / character or neither of them do
5642 * as this is checked in resolve_wildcards().
5645 p = strrchr_m(name,'/');
5647 directory = talloc_strdup(ctx, ".");
5649 return NT_STATUS_NO_MEMORY;
5654 directory = talloc_strdup(ctx, name);
5656 return NT_STATUS_NO_MEMORY;
5659 *p = '/'; /* Replace needed for exceptional test below. */
5663 * We should only check the mangled cache
5664 * here if unix_convert failed. This means
5665 * that the path in 'mask' doesn't exist
5666 * on the file system and so we need to look
5667 * for a possible mangle. This patch from
5668 * Tine Smukavec <valentin.smukavec@hermes.si>.
5671 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
5672 char *new_mask = NULL;
5673 mangle_lookup_name_from_8_3(ctx,
5682 if (!src_has_wild) {
5686 * No wildcards - just process the one file.
5688 bool is_short_name = mangle_is_8_3(name, True, conn->params);
5690 /* Add a terminating '/' to the directory name. */
5691 directory = talloc_asprintf_append(directory,
5695 return NT_STATUS_NO_MEMORY;
5698 /* Ensure newname contains a '/' also */
5699 if(strrchr_m(newname,'/') == 0) {
5700 newname = talloc_asprintf(ctx,
5704 return NT_STATUS_NO_MEMORY;
5708 DEBUG(3, ("rename_internals: case_sensitive = %d, "
5709 "case_preserve = %d, short case preserve = %d, "
5710 "directory = %s, newname = %s, "
5711 "last_component_dest = %s, is_8_3 = %d\n",
5712 conn->case_sensitive, conn->case_preserve,
5713 conn->short_case_preserve, directory,
5714 newname, last_component_dest, is_short_name));
5716 /* The dest name still may have wildcards. */
5717 if (dest_has_wild) {
5718 char *mod_newname = NULL;
5719 if (!resolve_wildcards(ctx,
5720 directory,newname,&mod_newname)) {
5721 DEBUG(6, ("rename_internals: resolve_wildcards "
5725 return NT_STATUS_NO_MEMORY;
5727 newname = mod_newname;
5731 SMB_VFS_STAT(conn, directory, &sbuf1);
5733 status = S_ISDIR(sbuf1.st_mode) ?
5734 open_directory(conn, req, directory, &sbuf1,
5736 FILE_SHARE_READ|FILE_SHARE_WRITE,
5737 FILE_OPEN, 0, 0, NULL,
5739 : open_file_ntcreate(conn, req, directory, &sbuf1,
5741 FILE_SHARE_READ|FILE_SHARE_WRITE,
5742 FILE_OPEN, 0, 0, 0, NULL,
5745 if (!NT_STATUS_IS_OK(status)) {
5746 DEBUG(3, ("Could not open rename source %s: %s\n",
5747 directory, nt_errstr(status)));
5751 status = rename_internals_fsp(conn, fsp, newname,
5752 last_component_dest,
5753 attrs, replace_if_exists);
5755 close_file(fsp, NORMAL_CLOSE);
5757 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
5758 nt_errstr(status), directory,newname));
5764 * Wildcards - process each file that matches.
5766 if (strequal(mask,"????????.???")) {
5771 status = check_name(conn, directory);
5772 if (!NT_STATUS_IS_OK(status)) {
5776 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, attrs);
5777 if (dir_hnd == NULL) {
5778 return map_nt_error_from_unix(errno);
5781 status = NT_STATUS_NO_SUCH_FILE;
5783 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5784 * - gentest fix. JRA
5787 while ((dname = ReadDirName(dir_hnd, &offset))) {
5788 files_struct *fsp = NULL;
5790 char *destname = NULL;
5791 bool sysdir_entry = False;
5793 /* Quick check for "." and ".." */
5794 if (ISDOT(dname) || ISDOTDOT(dname)) {
5796 sysdir_entry = True;
5802 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
5806 if(!mask_match(dname, mask, conn->case_sensitive)) {
5811 status = NT_STATUS_OBJECT_NAME_INVALID;
5815 fname = talloc_asprintf(ctx,
5820 return NT_STATUS_NO_MEMORY;
5823 if (!resolve_wildcards(ctx,
5824 fname,newname,&destname)) {
5825 DEBUG(6, ("resolve_wildcards %s %s failed\n",
5831 return NT_STATUS_NO_MEMORY;
5835 SMB_VFS_STAT(conn, fname, &sbuf1);
5837 status = S_ISDIR(sbuf1.st_mode) ?
5838 open_directory(conn, req, fname, &sbuf1,
5840 FILE_SHARE_READ|FILE_SHARE_WRITE,
5841 FILE_OPEN, 0, 0, NULL,
5843 : open_file_ntcreate(conn, req, fname, &sbuf1,
5845 FILE_SHARE_READ|FILE_SHARE_WRITE,
5846 FILE_OPEN, 0, 0, 0, NULL,
5849 if (!NT_STATUS_IS_OK(status)) {
5850 DEBUG(3,("rename_internals: open_file_ntcreate "
5851 "returned %s rename %s -> %s\n",
5852 nt_errstr(status), directory, newname));
5856 status = rename_internals_fsp(conn, fsp, destname, dname,
5857 attrs, replace_if_exists);
5859 close_file(fsp, NORMAL_CLOSE);
5861 if (!NT_STATUS_IS_OK(status)) {
5862 DEBUG(3, ("rename_internals_fsp returned %s for "
5863 "rename %s -> %s\n", nt_errstr(status),
5864 directory, newname));
5870 DEBUG(3,("rename_internals: doing rename on %s -> "
5871 "%s\n",fname,destname));
5874 TALLOC_FREE(destname);
5876 TALLOC_FREE(dir_hnd);
5878 if (count == 0 && NT_STATUS_IS_OK(status)) {
5879 status = map_nt_error_from_unix(errno);
5885 /****************************************************************************
5887 ****************************************************************************/
5889 void reply_mv(struct smb_request *req)
5891 connection_struct *conn = req->conn;
5893 char *newname = NULL;
5897 bool src_has_wcard = False;
5898 bool dest_has_wcard = False;
5899 TALLOC_CTX *ctx = talloc_tos();
5901 START_PROFILE(SMBmv);
5904 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5909 attrs = SVAL(req->inbuf,smb_vwv0);
5911 p = smb_buf(req->inbuf) + 1;
5912 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
5913 0, STR_TERMINATE, &status,
5915 if (!NT_STATUS_IS_OK(status)) {
5916 reply_nterror(req, status);
5921 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
5922 0, STR_TERMINATE, &status,
5924 if (!NT_STATUS_IS_OK(status)) {
5925 reply_nterror(req, status);
5930 status = resolve_dfspath_wcard(ctx, conn,
5931 req->flags2 & FLAGS2_DFS_PATHNAMES,
5935 if (!NT_STATUS_IS_OK(status)) {
5936 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5937 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5938 ERRSRV, ERRbadpath);
5942 reply_nterror(req, status);
5947 status = resolve_dfspath_wcard(ctx, conn,
5948 req->flags2 & FLAGS2_DFS_PATHNAMES,
5952 if (!NT_STATUS_IS_OK(status)) {
5953 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5954 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
5955 ERRSRV, ERRbadpath);
5959 reply_nterror(req, status);
5964 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
5966 status = rename_internals(ctx, conn, req, name, newname, attrs, False,
5967 src_has_wcard, dest_has_wcard);
5968 if (!NT_STATUS_IS_OK(status)) {
5969 if (open_was_deferred(req->mid)) {
5970 /* We have re-scheduled this call. */
5974 reply_nterror(req, status);
5979 reply_outbuf(req, 0, 0);
5985 /*******************************************************************
5986 Copy a file as part of a reply_copy.
5987 ******************************************************************/
5990 * TODO: check error codes on all callers
5993 NTSTATUS copy_file(TALLOC_CTX *ctx,
5994 connection_struct *conn,
5999 bool target_is_directory)
6001 SMB_STRUCT_STAT src_sbuf, sbuf2;
6003 files_struct *fsp1,*fsp2;
6006 uint32 new_create_disposition;
6009 dest = talloc_strdup(ctx, dest1);
6011 return NT_STATUS_NO_MEMORY;
6013 if (target_is_directory) {
6014 const char *p = strrchr_m(src,'/');
6020 dest = talloc_asprintf_append(dest,
6024 return NT_STATUS_NO_MEMORY;
6028 if (!vfs_file_exist(conn,src,&src_sbuf)) {
6030 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6033 if (!target_is_directory && count) {
6034 new_create_disposition = FILE_OPEN;
6036 if (!map_open_params_to_ntcreate(dest1,0,ofun,
6037 NULL, NULL, &new_create_disposition, NULL)) {
6039 return NT_STATUS_INVALID_PARAMETER;
6043 status = open_file_ntcreate(conn, NULL, src, &src_sbuf,
6045 FILE_SHARE_READ|FILE_SHARE_WRITE,
6048 FILE_ATTRIBUTE_NORMAL,
6052 if (!NT_STATUS_IS_OK(status)) {
6057 dosattrs = dos_mode(conn, src, &src_sbuf);
6058 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) {
6059 ZERO_STRUCTP(&sbuf2);
6062 status = open_file_ntcreate(conn, NULL, dest, &sbuf2,
6064 FILE_SHARE_READ|FILE_SHARE_WRITE,
6065 new_create_disposition,
6073 if (!NT_STATUS_IS_OK(status)) {
6074 close_file(fsp1,ERROR_CLOSE);
6078 if ((ofun&3) == 1) {
6079 if(SMB_VFS_LSEEK(fsp2,0,SEEK_END) == -1) {
6080 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
6082 * Stop the copy from occurring.
6085 src_sbuf.st_size = 0;
6089 if (src_sbuf.st_size) {
6090 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
6093 close_file(fsp1,NORMAL_CLOSE);
6095 /* Ensure the modtime is set correctly on the destination file. */
6096 fsp_set_pending_modtime( fsp2, get_mtimespec(&src_sbuf));
6099 * As we are opening fsp1 read-only we only expect
6100 * an error on close on fsp2 if we are out of space.
6101 * Thus we don't look at the error return from the
6104 status = close_file(fsp2,NORMAL_CLOSE);
6106 if (!NT_STATUS_IS_OK(status)) {
6110 if (ret != (SMB_OFF_T)src_sbuf.st_size) {
6111 return NT_STATUS_DISK_FULL;
6114 return NT_STATUS_OK;
6117 /****************************************************************************
6118 Reply to a file copy.
6119 ****************************************************************************/
6121 void reply_copy(struct smb_request *req)
6123 connection_struct *conn = req->conn;
6125 char *newname = NULL;
6126 char *directory = NULL;
6130 int error = ERRnoaccess;
6135 bool target_is_directory=False;
6136 bool source_has_wild = False;
6137 bool dest_has_wild = False;
6138 SMB_STRUCT_STAT sbuf1, sbuf2;
6140 TALLOC_CTX *ctx = talloc_tos();
6142 START_PROFILE(SMBcopy);
6145 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6146 END_PROFILE(SMBcopy);
6150 tid2 = SVAL(req->inbuf,smb_vwv0);
6151 ofun = SVAL(req->inbuf,smb_vwv1);
6152 flags = SVAL(req->inbuf,smb_vwv2);
6154 p = smb_buf(req->inbuf);
6155 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
6156 0, STR_TERMINATE, &status,
6158 if (!NT_STATUS_IS_OK(status)) {
6159 reply_nterror(req, status);
6160 END_PROFILE(SMBcopy);
6163 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
6164 0, STR_TERMINATE, &status,
6166 if (!NT_STATUS_IS_OK(status)) {
6167 reply_nterror(req, status);
6168 END_PROFILE(SMBcopy);
6172 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
6174 if (tid2 != conn->cnum) {
6175 /* can't currently handle inter share copies XXXX */
6176 DEBUG(3,("Rejecting inter-share copy\n"));
6177 reply_doserror(req, ERRSRV, ERRinvdevice);
6178 END_PROFILE(SMBcopy);
6182 status = resolve_dfspath_wcard(ctx, conn,
6183 req->flags2 & FLAGS2_DFS_PATHNAMES,
6187 if (!NT_STATUS_IS_OK(status)) {
6188 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6189 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6190 ERRSRV, ERRbadpath);
6191 END_PROFILE(SMBcopy);
6194 reply_nterror(req, status);
6195 END_PROFILE(SMBcopy);
6199 status = resolve_dfspath_wcard(ctx, conn,
6200 req->flags2 & FLAGS2_DFS_PATHNAMES,
6204 if (!NT_STATUS_IS_OK(status)) {
6205 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6206 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
6207 ERRSRV, ERRbadpath);
6208 END_PROFILE(SMBcopy);
6211 reply_nterror(req, status);
6212 END_PROFILE(SMBcopy);
6216 status = unix_convert(ctx, conn, name, source_has_wild,
6217 &name, NULL, &sbuf1);
6218 if (!NT_STATUS_IS_OK(status)) {
6219 reply_nterror(req, status);
6220 END_PROFILE(SMBcopy);
6224 status = unix_convert(ctx, conn, newname, dest_has_wild,
6225 &newname, NULL, &sbuf2);
6226 if (!NT_STATUS_IS_OK(status)) {
6227 reply_nterror(req, status);
6228 END_PROFILE(SMBcopy);
6232 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
6234 if ((flags&1) && target_is_directory) {
6235 reply_doserror(req, ERRDOS, ERRbadfile);
6236 END_PROFILE(SMBcopy);
6240 if ((flags&2) && !target_is_directory) {
6241 reply_doserror(req, ERRDOS, ERRbadpath);
6242 END_PROFILE(SMBcopy);
6246 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
6247 /* wants a tree copy! XXXX */
6248 DEBUG(3,("Rejecting tree copy\n"));
6249 reply_doserror(req, ERRSRV, ERRerror);
6250 END_PROFILE(SMBcopy);
6254 p = strrchr_m(name,'/');
6256 directory = talloc_strdup(ctx, "./");
6258 reply_nterror(req, NT_STATUS_NO_MEMORY);
6259 END_PROFILE(SMBcopy);
6265 directory = talloc_strdup(ctx, name);
6267 reply_nterror(req, NT_STATUS_NO_MEMORY);
6268 END_PROFILE(SMBcopy);
6275 * We should only check the mangled cache
6276 * here if unix_convert failed. This means
6277 * that the path in 'mask' doesn't exist
6278 * on the file system and so we need to look
6279 * for a possible mangle. This patch from
6280 * Tine Smukavec <valentin.smukavec@hermes.si>.
6283 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
6284 char *new_mask = NULL;
6285 mangle_lookup_name_from_8_3(ctx,
6294 if (!source_has_wild) {
6295 directory = talloc_asprintf_append(directory,
6298 if (dest_has_wild) {
6299 char *mod_newname = NULL;
6300 if (!resolve_wildcards(ctx,
6301 directory,newname,&mod_newname)) {
6302 reply_nterror(req, NT_STATUS_NO_MEMORY);
6303 END_PROFILE(SMBcopy);
6306 newname = mod_newname;
6309 status = check_name(conn, directory);
6310 if (!NT_STATUS_IS_OK(status)) {
6311 reply_nterror(req, status);
6312 END_PROFILE(SMBcopy);
6316 status = check_name(conn, newname);
6317 if (!NT_STATUS_IS_OK(status)) {
6318 reply_nterror(req, status);
6319 END_PROFILE(SMBcopy);
6323 status = copy_file(ctx,conn,directory,newname,ofun,
6324 count,target_is_directory);
6326 if(!NT_STATUS_IS_OK(status)) {
6327 reply_nterror(req, status);
6328 END_PROFILE(SMBcopy);
6334 struct smb_Dir *dir_hnd = NULL;
6335 const char *dname = NULL;
6338 if (strequal(mask,"????????.???")) {
6343 status = check_name(conn, directory);
6344 if (!NT_STATUS_IS_OK(status)) {
6345 reply_nterror(req, status);
6346 END_PROFILE(SMBcopy);
6350 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, 0);
6351 if (dir_hnd == NULL) {
6352 status = map_nt_error_from_unix(errno);
6353 reply_nterror(req, status);
6354 END_PROFILE(SMBcopy);
6360 while ((dname = ReadDirName(dir_hnd, &offset))) {
6361 char *destname = NULL;
6364 if (ISDOT(dname) || ISDOTDOT(dname)) {
6368 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
6372 if(!mask_match(dname, mask, conn->case_sensitive)) {
6376 error = ERRnoaccess;
6377 fname = talloc_asprintf(ctx,
6382 TALLOC_FREE(dir_hnd);
6383 reply_nterror(req, NT_STATUS_NO_MEMORY);
6384 END_PROFILE(SMBcopy);
6388 if (!resolve_wildcards(ctx,
6389 fname,newname,&destname)) {
6393 TALLOC_FREE(dir_hnd);
6394 reply_nterror(req, NT_STATUS_NO_MEMORY);
6395 END_PROFILE(SMBcopy);
6399 status = check_name(conn, fname);
6400 if (!NT_STATUS_IS_OK(status)) {
6401 TALLOC_FREE(dir_hnd);
6402 reply_nterror(req, status);
6403 END_PROFILE(SMBcopy);
6407 status = check_name(conn, destname);
6408 if (!NT_STATUS_IS_OK(status)) {
6409 TALLOC_FREE(dir_hnd);
6410 reply_nterror(req, status);
6411 END_PROFILE(SMBcopy);
6415 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
6417 status = copy_file(ctx,conn,fname,destname,ofun,
6418 count,target_is_directory);
6419 if (NT_STATUS_IS_OK(status)) {
6423 TALLOC_FREE(destname);
6425 TALLOC_FREE(dir_hnd);
6430 /* Error on close... */
6432 reply_unixerror(req, ERRHRD, ERRgeneral);
6433 END_PROFILE(SMBcopy);
6437 reply_doserror(req, ERRDOS, error);
6438 END_PROFILE(SMBcopy);
6442 reply_outbuf(req, 1, 0);
6443 SSVAL(req->outbuf,smb_vwv0,count);
6445 END_PROFILE(SMBcopy);
6450 #define DBGC_CLASS DBGC_LOCKING
6452 /****************************************************************************
6453 Get a lock pid, dealing with large count requests.
6454 ****************************************************************************/
6456 uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
6458 if(!large_file_format)
6459 return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
6461 return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
6464 /****************************************************************************
6465 Get a lock count, dealing with large count requests.
6466 ****************************************************************************/
6468 SMB_BIG_UINT get_lock_count( char *data, int data_offset, bool large_file_format)
6470 SMB_BIG_UINT count = 0;
6472 if(!large_file_format) {
6473 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
6476 #if defined(HAVE_LONGLONG)
6477 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
6478 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
6479 #else /* HAVE_LONGLONG */
6482 * NT4.x seems to be broken in that it sends large file (64 bit)
6483 * lockingX calls even if the CAP_LARGE_FILES was *not*
6484 * negotiated. For boxes without large unsigned ints truncate the
6485 * lock count by dropping the top 32 bits.
6488 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
6489 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
6490 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
6491 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
6492 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
6495 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
6496 #endif /* HAVE_LONGLONG */
6502 #if !defined(HAVE_LONGLONG)
6503 /****************************************************************************
6504 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
6505 ****************************************************************************/
6507 static uint32 map_lock_offset(uint32 high, uint32 low)
6511 uint32 highcopy = high;
6514 * Try and find out how many significant bits there are in high.
6517 for(i = 0; highcopy; i++)
6521 * We use 31 bits not 32 here as POSIX
6522 * lock offsets may not be negative.
6525 mask = (~0) << (31 - i);
6528 return 0; /* Fail. */
6534 #endif /* !defined(HAVE_LONGLONG) */
6536 /****************************************************************************
6537 Get a lock offset, dealing with large offset requests.
6538 ****************************************************************************/
6540 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err)
6542 SMB_BIG_UINT offset = 0;
6546 if(!large_file_format) {
6547 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
6550 #if defined(HAVE_LONGLONG)
6551 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
6552 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
6553 #else /* HAVE_LONGLONG */
6556 * NT4.x seems to be broken in that it sends large file (64 bit)
6557 * lockingX calls even if the CAP_LARGE_FILES was *not*
6558 * negotiated. For boxes without large unsigned ints mangle the
6559 * lock offset by mapping the top 32 bits onto the lower 32.
6562 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
6563 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6564 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
6567 if((new_low = map_lock_offset(high, low)) == 0) {
6569 return (SMB_BIG_UINT)-1;
6572 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
6573 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
6574 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
6575 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
6578 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
6579 #endif /* HAVE_LONGLONG */
6585 /****************************************************************************
6586 Reply to a lockingX request.
6587 ****************************************************************************/
6589 void reply_lockingX(struct smb_request *req)
6591 connection_struct *conn = req->conn;
6593 unsigned char locktype;
6594 unsigned char oplocklevel;
6597 SMB_BIG_UINT count = 0, offset = 0;
6602 bool large_file_format;
6604 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
6606 START_PROFILE(SMBlockingX);
6609 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6610 END_PROFILE(SMBlockingX);
6614 fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
6615 locktype = CVAL(req->inbuf,smb_vwv3);
6616 oplocklevel = CVAL(req->inbuf,smb_vwv3+1);
6617 num_ulocks = SVAL(req->inbuf,smb_vwv6);
6618 num_locks = SVAL(req->inbuf,smb_vwv7);
6619 lock_timeout = IVAL(req->inbuf,smb_vwv4);
6620 large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
6622 if (!check_fsp(conn, req, fsp, ¤t_user)) {
6623 END_PROFILE(SMBlockingX);
6627 data = smb_buf(req->inbuf);
6629 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
6630 /* we don't support these - and CANCEL_LOCK makes w2k
6631 and XP reboot so I don't really want to be
6632 compatible! (tridge) */
6633 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
6634 END_PROFILE(SMBlockingX);
6638 /* Check if this is an oplock break on a file
6639 we have granted an oplock on.
6641 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
6642 /* Client can insist on breaking to none. */
6643 bool break_to_none = (oplocklevel == 0);
6646 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
6647 "for fnum = %d\n", (unsigned int)oplocklevel,
6651 * Make sure we have granted an exclusive or batch oplock on
6655 if (fsp->oplock_type == 0) {
6657 /* The Samba4 nbench simulator doesn't understand
6658 the difference between break to level2 and break
6659 to none from level2 - it sends oplock break
6660 replies in both cases. Don't keep logging an error
6661 message here - just ignore it. JRA. */
6663 DEBUG(5,("reply_lockingX: Error : oplock break from "
6664 "client for fnum = %d (oplock=%d) and no "
6665 "oplock granted on this file (%s).\n",
6666 fsp->fnum, fsp->oplock_type, fsp->fsp_name));
6668 /* if this is a pure oplock break request then don't
6670 if (num_locks == 0 && num_ulocks == 0) {
6671 END_PROFILE(SMBlockingX);
6674 END_PROFILE(SMBlockingX);
6675 reply_doserror(req, ERRDOS, ERRlock);
6680 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
6682 result = remove_oplock(fsp);
6684 result = downgrade_oplock(fsp);
6688 DEBUG(0, ("reply_lockingX: error in removing "
6689 "oplock on file %s\n", fsp->fsp_name));
6690 /* Hmmm. Is this panic justified? */
6691 smb_panic("internal tdb error");
6694 reply_to_oplock_break_requests(fsp);
6696 /* if this is a pure oplock break request then don't send a
6698 if (num_locks == 0 && num_ulocks == 0) {
6699 /* Sanity check - ensure a pure oplock break is not a
6701 if(CVAL(req->inbuf,smb_vwv0) != 0xff)
6702 DEBUG(0,("reply_lockingX: Error : pure oplock "
6703 "break is a chained %d request !\n",
6704 (unsigned int)CVAL(req->inbuf,
6706 END_PROFILE(SMBlockingX);
6712 * We do this check *after* we have checked this is not a oplock break
6713 * response message. JRA.
6716 release_level_2_oplocks_on_change(fsp);
6718 if (smb_buflen(req->inbuf) <
6719 (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
6720 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6721 END_PROFILE(SMBlockingX);
6725 /* Data now points at the beginning of the list
6726 of smb_unlkrng structs */
6727 for(i = 0; i < (int)num_ulocks; i++) {
6728 lock_pid = get_lock_pid( data, i, large_file_format);
6729 count = get_lock_count( data, i, large_file_format);
6730 offset = get_lock_offset( data, i, large_file_format, &err);
6733 * There is no error code marked "stupid client bug".... :-).
6736 END_PROFILE(SMBlockingX);
6737 reply_doserror(req, ERRDOS, ERRnoaccess);
6741 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
6742 "pid %u, file %s\n", (double)offset, (double)count,
6743 (unsigned int)lock_pid, fsp->fsp_name ));
6745 status = do_unlock(smbd_messaging_context(),
6752 if (NT_STATUS_V(status)) {
6753 END_PROFILE(SMBlockingX);
6754 reply_nterror(req, status);
6759 /* Setup the timeout in seconds. */
6761 if (!lp_blocking_locks(SNUM(conn))) {
6765 /* Now do any requested locks */
6766 data += ((large_file_format ? 20 : 10)*num_ulocks);
6768 /* Data now points at the beginning of the list
6769 of smb_lkrng structs */
6771 for(i = 0; i < (int)num_locks; i++) {
6772 enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
6773 READ_LOCK:WRITE_LOCK);
6774 lock_pid = get_lock_pid( data, i, large_file_format);
6775 count = get_lock_count( data, i, large_file_format);
6776 offset = get_lock_offset( data, i, large_file_format, &err);
6779 * There is no error code marked "stupid client bug".... :-).
6782 END_PROFILE(SMBlockingX);
6783 reply_doserror(req, ERRDOS, ERRnoaccess);
6787 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
6788 "%u, file %s timeout = %d\n", (double)offset,
6789 (double)count, (unsigned int)lock_pid,
6790 fsp->fsp_name, (int)lock_timeout ));
6792 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
6793 if (lp_blocking_locks(SNUM(conn))) {
6795 /* Schedule a message to ourselves to
6796 remove the blocking lock record and
6797 return the right error. */
6799 if (!blocking_lock_cancel(fsp,
6805 NT_STATUS_FILE_LOCK_CONFLICT)) {
6806 END_PROFILE(SMBlockingX);
6811 ERRcancelviolation));
6815 /* Remove a matching pending lock. */
6816 status = do_lock_cancel(fsp,
6822 bool blocking_lock = lock_timeout ? True : False;
6823 bool defer_lock = False;
6824 struct byte_range_lock *br_lck;
6825 uint32 block_smbpid;
6827 br_lck = do_lock(smbd_messaging_context(),
6838 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6839 /* Windows internal resolution for blocking locks seems
6840 to be about 200ms... Don't wait for less than that. JRA. */
6841 if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
6842 lock_timeout = lp_lock_spin_time();
6847 /* This heuristic seems to match W2K3 very well. If a
6848 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
6849 it pretends we asked for a timeout of between 150 - 300 milliseconds as
6850 far as I can tell. Replacement for do_lock_spin(). JRA. */
6852 if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
6853 NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
6855 lock_timeout = lp_lock_spin_time();
6858 if (br_lck && defer_lock) {
6860 * A blocking lock was requested. Package up
6861 * this smb into a queued request and push it
6862 * onto the blocking lock queue.
6864 if(push_blocking_lock_request(br_lck,
6875 TALLOC_FREE(br_lck);
6876 END_PROFILE(SMBlockingX);
6881 TALLOC_FREE(br_lck);
6884 if (NT_STATUS_V(status)) {
6885 END_PROFILE(SMBlockingX);
6886 reply_nterror(req, status);
6891 /* If any of the above locks failed, then we must unlock
6892 all of the previous locks (X/Open spec). */
6894 if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) &&
6898 * Ensure we don't do a remove on the lock that just failed,
6899 * as under POSIX rules, if we have a lock already there, we
6900 * will delete it (and we shouldn't) .....
6902 for(i--; i >= 0; i--) {
6903 lock_pid = get_lock_pid( data, i, large_file_format);
6904 count = get_lock_count( data, i, large_file_format);
6905 offset = get_lock_offset( data, i, large_file_format,
6909 * There is no error code marked "stupid client
6913 END_PROFILE(SMBlockingX);
6914 reply_doserror(req, ERRDOS, ERRnoaccess);
6918 do_unlock(smbd_messaging_context(),
6925 END_PROFILE(SMBlockingX);
6926 reply_nterror(req, status);
6930 reply_outbuf(req, 2, 0);
6932 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
6933 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
6935 END_PROFILE(SMBlockingX);
6940 #define DBGC_CLASS DBGC_ALL
6942 /****************************************************************************
6943 Reply to a SMBreadbmpx (read block multiplex) request.
6944 Always reply with an error, if someone has a platform really needs this,
6945 please contact vl@samba.org
6946 ****************************************************************************/
6948 void reply_readbmpx(struct smb_request *req)
6950 START_PROFILE(SMBreadBmpx);
6951 reply_doserror(req, ERRSRV, ERRuseSTD);
6952 END_PROFILE(SMBreadBmpx);
6956 /****************************************************************************
6957 Reply to a SMBreadbs (read block multiplex secondary) request.
6958 Always reply with an error, if someone has a platform really needs this,
6959 please contact vl@samba.org
6960 ****************************************************************************/
6962 void reply_readbs(struct smb_request *req)
6964 START_PROFILE(SMBreadBs);
6965 reply_doserror(req, ERRSRV, ERRuseSTD);
6966 END_PROFILE(SMBreadBs);
6970 /****************************************************************************
6971 Reply to a SMBsetattrE.
6972 ****************************************************************************/
6974 void reply_setattrE(struct smb_request *req)
6976 connection_struct *conn = req->conn;
6977 struct timespec ts[2];
6980 START_PROFILE(SMBsetattrE);
6983 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6984 END_PROFILE(SMBsetattrE);
6988 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
6990 if(!fsp || (fsp->conn != conn)) {
6991 reply_doserror(req, ERRDOS, ERRbadfid);
6992 END_PROFILE(SMBsetattrE);
6998 * Convert the DOS times into unix times. Ignore create
6999 * time as UNIX can't set this.
7002 ts[0] = convert_time_t_to_timespec(
7003 srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */
7004 ts[1] = convert_time_t_to_timespec(
7005 srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */
7007 reply_outbuf(req, 0, 0);
7010 * Patch from Ray Frush <frush@engr.colostate.edu>
7011 * Sometimes times are sent as zero - ignore them.
7014 if (null_timespec(ts[0]) && null_timespec(ts[1])) {
7015 /* Ignore request */
7016 if( DEBUGLVL( 3 ) ) {
7017 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
7018 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
7020 END_PROFILE(SMBsetattrE);
7022 } else if (!null_timespec(ts[0]) && null_timespec(ts[1])) {
7023 /* set modify time = to access time if modify time was unset */
7027 /* Set the date on this file */
7028 /* Should we set pending modtime here ? JRA */
7029 if(file_ntimes(conn, fsp->fsp_name, ts)) {
7030 reply_doserror(req, ERRDOS, ERRnoaccess);
7031 END_PROFILE(SMBsetattrE);
7035 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
7037 (unsigned int)ts[0].tv_sec,
7038 (unsigned int)ts[1].tv_sec));
7040 END_PROFILE(SMBsetattrE);
7045 /* Back from the dead for OS/2..... JRA. */
7047 /****************************************************************************
7048 Reply to a SMBwritebmpx (write block multiplex primary) request.
7049 Always reply with an error, if someone has a platform really needs this,
7050 please contact vl@samba.org
7051 ****************************************************************************/
7053 void reply_writebmpx(struct smb_request *req)
7055 START_PROFILE(SMBwriteBmpx);
7056 reply_doserror(req, ERRSRV, ERRuseSTD);
7057 END_PROFILE(SMBwriteBmpx);
7061 /****************************************************************************
7062 Reply to a SMBwritebs (write block multiplex secondary) 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_writebs(struct smb_request *req)
7069 START_PROFILE(SMBwriteBs);
7070 reply_doserror(req, ERRSRV, ERRuseSTD);
7071 END_PROFILE(SMBwriteBs);
7075 /****************************************************************************
7076 Reply to a SMBgetattrE.
7077 ****************************************************************************/
7079 void reply_getattrE(struct smb_request *req)
7081 connection_struct *conn = req->conn;
7082 SMB_STRUCT_STAT sbuf;
7086 START_PROFILE(SMBgetattrE);
7089 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7090 END_PROFILE(SMBgetattrE);
7094 fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
7096 if(!fsp || (fsp->conn != conn)) {
7097 reply_doserror(req, ERRDOS, ERRbadfid);
7098 END_PROFILE(SMBgetattrE);
7102 /* Do an fstat on this file */
7103 if(fsp_stat(fsp, &sbuf)) {
7104 reply_unixerror(req, ERRDOS, ERRnoaccess);
7105 END_PROFILE(SMBgetattrE);
7109 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
7112 * Convert the times into dos times. Set create
7113 * date to be last modify date as UNIX doesn't save
7117 reply_outbuf(req, 11, 0);
7119 srv_put_dos_date2((char *)req->outbuf, smb_vwv0,
7120 get_create_time(&sbuf,
7121 lp_fake_dir_create_times(SNUM(conn))));
7122 srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime);
7123 /* Should we check pending modtime here ? JRA */
7124 srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime);
7127 SIVAL(req->outbuf, smb_vwv6, 0);
7128 SIVAL(req->outbuf, smb_vwv8, 0);
7130 uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
7131 SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
7132 SIVAL(req->outbuf, smb_vwv8, allocation_size);
7134 SSVAL(req->outbuf,smb_vwv10, mode);
7136 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
7138 END_PROFILE(SMBgetattrE);