2 Unix SMB/CIFS implementation.
3 Main SMB reply routines
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jeremy Allison 1992-2007.
7 Copyright (C) Volker Lendecke 2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This file handles most of the reply_ calls that the server
24 makes to handle specific protocols
29 /* look in server.c for some explanation of these variables */
30 extern enum protocol_types Protocol;
32 extern uint32 global_client_caps;
34 extern bool global_encrypted_passwords_negotiated;
36 /****************************************************************************
37 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
38 path or anything including wildcards.
39 We're assuming here that '/' is not the second byte in any multibyte char
40 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
42 ****************************************************************************/
44 /* Custom version for processing POSIX paths. */
45 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
47 static NTSTATUS check_path_syntax_internal(char *path,
49 bool *p_last_component_contains_wcard)
53 NTSTATUS ret = NT_STATUS_OK;
54 bool start_of_name_component = True;
56 *p_last_component_contains_wcard = False;
59 if (IS_PATH_SEP(*s,posix_path)) {
61 * Safe to assume is not the second part of a mb char
62 * as this is handled below.
64 /* Eat multiple '/' or '\\' */
65 while (IS_PATH_SEP(*s,posix_path)) {
68 if ((d != path) && (*s != '\0')) {
69 /* We only care about non-leading or trailing '/' or '\\' */
73 start_of_name_component = True;
75 *p_last_component_contains_wcard = False;
79 if (start_of_name_component) {
80 if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
81 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
84 * No mb char starts with '.' so we're safe checking the directory separator here.
87 /* If we just added a '/' - delete it */
88 if ((d > path) && (*(d-1) == '/')) {
93 /* Are we at the start ? Can't go back further if so. */
95 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
98 /* Go back one level... */
99 /* We know this is safe as '/' cannot be part of a mb sequence. */
100 /* NOTE - if this assumption is invalid we are not in good shape... */
101 /* Decrement d first as d points to the *next* char to write into. */
102 for (d--; d > path; d--) {
106 s += 2; /* Else go past the .. */
107 /* We're still at the start of a name component, just the previous one. */
110 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
123 return NT_STATUS_OBJECT_NAME_INVALID;
131 *p_last_component_contains_wcard = True;
140 /* Get the size of the next MB character. */
141 next_codepoint(s,&siz);
159 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
161 return NT_STATUS_INVALID_PARAMETER;
164 start_of_name_component = False;
172 /****************************************************************************
173 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
174 No wildcards allowed.
175 ****************************************************************************/
177 NTSTATUS check_path_syntax(char *path)
180 return check_path_syntax_internal(path, False, &ignore);
183 /****************************************************************************
184 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
185 Wildcards allowed - p_contains_wcard returns true if the last component contained
187 ****************************************************************************/
189 NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
191 return check_path_syntax_internal(path, False, p_contains_wcard);
194 /****************************************************************************
195 Check the path for a POSIX client.
196 We're assuming here that '/' is not the second byte in any multibyte char
197 set (a safe assumption).
198 ****************************************************************************/
200 NTSTATUS check_path_syntax_posix(char *path)
203 return check_path_syntax_internal(path, True, &ignore);
206 /****************************************************************************
207 Pull a string and check the path allowing a wilcard - provide for error return.
208 ****************************************************************************/
210 size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
218 bool *contains_wcard)
225 ret = srvstr_pull_buf_talloc(ctx,
232 ret = srvstr_pull_talloc(ctx,
242 *err = NT_STATUS_INVALID_PARAMETER;
246 *contains_wcard = False;
248 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
250 * For a DFS path the function parse_dfs_path()
251 * will do the path processing, just make a copy.
257 if (lp_posix_pathnames()) {
258 *err = check_path_syntax_posix(*pp_dest);
260 *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
266 /****************************************************************************
267 Pull a string and check the path - provide for error return.
268 ****************************************************************************/
270 size_t srvstr_get_path(TALLOC_CTX *ctx,
284 ret = srvstr_pull_buf_talloc(ctx,
291 ret = srvstr_pull_talloc(ctx,
301 *err = NT_STATUS_INVALID_PARAMETER;
305 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
307 * For a DFS path the function parse_dfs_path()
308 * will do the path processing, just make a copy.
314 if (lp_posix_pathnames()) {
315 *err = check_path_syntax_posix(*pp_dest);
317 *err = check_path_syntax(*pp_dest);
323 /****************************************************************************
324 Check if we have a correct fsp pointing to a file. Basic check for open fsp.
325 ****************************************************************************/
327 bool check_fsp_open(connection_struct *conn, struct smb_request *req,
330 if (!(fsp) || !(conn)) {
331 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
334 if (((conn) != (fsp)->conn) || req->vuid != (fsp)->vuid) {
335 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
341 /****************************************************************************
342 Check if we have a correct fsp pointing to a file.
343 ****************************************************************************/
345 bool check_fsp(connection_struct *conn, struct smb_request *req,
348 if (!check_fsp_open(conn, req, fsp)) {
351 if ((fsp)->is_directory) {
352 reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
355 if ((fsp)->fh->fd == -1) {
356 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
359 (fsp)->num_smb_operations++;
363 /****************************************************************************
364 Check if we have a correct fsp pointing to a quota fake file. Replacement for
365 the CHECK_NTQUOTA_HANDLE_OK macro.
366 ****************************************************************************/
368 bool check_fsp_ntquota_handle(connection_struct *conn, struct smb_request *req,
371 if (!check_fsp_open(conn, req, fsp)) {
375 if (fsp->is_directory) {
379 if (fsp->fake_file_handle == NULL) {
383 if (fsp->fake_file_handle->type != FAKE_FILE_TYPE_QUOTA) {
387 if (fsp->fake_file_handle->private_data == NULL) {
394 /****************************************************************************
395 Check if we have a correct fsp. Replacement for the FSP_BELONGS_CONN macro
396 ****************************************************************************/
398 bool fsp_belongs_conn(connection_struct *conn, struct smb_request *req,
401 if ((fsp) && (conn) && ((conn)==(fsp)->conn)
402 && (req->vuid == (fsp)->vuid)) {
406 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
410 /****************************************************************************
411 Reply to a (netbios-level) special message.
412 ****************************************************************************/
414 void reply_special(char *inbuf)
416 int msg_type = CVAL(inbuf,0);
417 int msg_flags = CVAL(inbuf,1);
422 * We only really use 4 bytes of the outbuf, but for the smb_setlen
423 * calculation & friends (srv_send_smb uses that) we need the full smb
426 char outbuf[smb_size];
428 static bool already_got_session = False;
432 memset(outbuf, '\0', sizeof(outbuf));
434 smb_setlen(outbuf,0);
437 case 0x81: /* session request */
439 if (already_got_session) {
440 exit_server_cleanly("multiple session request not permitted");
443 SCVAL(outbuf,0,0x82);
445 if (name_len(inbuf+4) > 50 ||
446 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
447 DEBUG(0,("Invalid name length in session request\n"));
450 name_extract(inbuf,4,name1);
451 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
452 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
455 set_local_machine_name(name1, True);
456 set_remote_machine_name(name2, True);
458 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
459 get_local_machine_name(), get_remote_machine_name(),
462 if (name_type == 'R') {
463 /* We are being asked for a pathworks session ---
465 SCVAL(outbuf, 0,0x83);
469 /* only add the client's machine name to the list
470 of possibly valid usernames if we are operating
471 in share mode security */
472 if (lp_security() == SEC_SHARE) {
473 add_session_user(get_remote_machine_name());
476 reload_services(True);
479 already_got_session = True;
482 case 0x89: /* session keepalive request
483 (some old clients produce this?) */
484 SCVAL(outbuf,0,SMBkeepalive);
488 case 0x82: /* positive session response */
489 case 0x83: /* negative session response */
490 case 0x84: /* retarget session response */
491 DEBUG(0,("Unexpected session response\n"));
494 case SMBkeepalive: /* session keepalive */
499 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
500 msg_type, msg_flags));
502 srv_send_smb(smbd_server_fd(), outbuf, false);
506 /****************************************************************************
508 conn POINTER CAN BE NULL HERE !
509 ****************************************************************************/
511 void reply_tcon(struct smb_request *req)
513 connection_struct *conn = req->conn;
515 char *service_buf = NULL;
516 char *password = NULL;
521 DATA_BLOB password_blob;
522 TALLOC_CTX *ctx = talloc_tos();
524 START_PROFILE(SMBtcon);
526 if (smb_buflen(req->inbuf) < 4) {
527 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
528 END_PROFILE(SMBtcon);
532 p = smb_buf(req->inbuf)+1;
533 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
534 &service_buf, p, STR_TERMINATE) + 1;
535 pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
536 &password, p, STR_TERMINATE) + 1;
538 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
539 &dev, p, STR_TERMINATE) + 1;
541 if (service_buf == NULL || password == NULL || dev == NULL) {
542 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
543 END_PROFILE(SMBtcon);
546 p = strrchr_m(service_buf,'\\');
550 service = service_buf;
553 password_blob = data_blob(password, pwlen+1);
555 conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
558 data_blob_clear_free(&password_blob);
561 reply_nterror(req, nt_status);
562 END_PROFILE(SMBtcon);
566 reply_outbuf(req, 2, 0);
567 SSVAL(req->outbuf,smb_vwv0,max_recv);
568 SSVAL(req->outbuf,smb_vwv1,conn->cnum);
569 SSVAL(req->outbuf,smb_tid,conn->cnum);
571 DEBUG(3,("tcon service=%s cnum=%d\n",
572 service, conn->cnum));
574 END_PROFILE(SMBtcon);
578 /****************************************************************************
579 Reply to a tcon and X.
580 conn POINTER CAN BE NULL HERE !
581 ****************************************************************************/
583 void reply_tcon_and_X(struct smb_request *req)
585 connection_struct *conn = req->conn;
586 char *service = NULL;
588 TALLOC_CTX *ctx = talloc_tos();
589 /* what the cleint thinks the device is */
590 char *client_devicetype = NULL;
591 /* what the server tells the client the share represents */
592 const char *server_devicetype;
599 START_PROFILE(SMBtconX);
602 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
603 END_PROFILE(SMBtconX);
607 passlen = SVAL(req->inbuf,smb_vwv3);
608 tcon_flags = SVAL(req->inbuf,smb_vwv2);
610 /* we might have to close an old one */
611 if ((tcon_flags & 0x1) && conn) {
612 close_cnum(conn,req->vuid);
617 if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
618 reply_doserror(req, ERRDOS, ERRbuftoosmall);
619 END_PROFILE(SMBtconX);
623 if (global_encrypted_passwords_negotiated) {
624 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
626 if (lp_security() == SEC_SHARE) {
628 * Security = share always has a pad byte
629 * after the password.
631 p = smb_buf(req->inbuf) + passlen + 1;
633 p = smb_buf(req->inbuf) + passlen;
636 password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
638 /* Ensure correct termination */
639 password.data[passlen]=0;
640 p = smb_buf(req->inbuf) + passlen + 1;
643 p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
647 data_blob_clear_free(&password);
648 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
649 END_PROFILE(SMBtconX);
654 * the service name can be either: \\server\share
655 * or share directly like on the DELL PowerVault 705
658 q = strchr_m(path+2,'\\');
660 data_blob_clear_free(&password);
661 reply_doserror(req, ERRDOS, ERRnosuchshare);
662 END_PROFILE(SMBtconX);
670 p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
671 &client_devicetype, p,
672 MIN(6,smb_bufrem(req->inbuf, p)), STR_ASCII);
674 if (client_devicetype == NULL) {
675 data_blob_clear_free(&password);
676 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
677 END_PROFILE(SMBtconX);
681 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
683 conn = make_connection(service, password, client_devicetype,
684 req->vuid, &nt_status);
687 data_blob_clear_free(&password);
690 reply_nterror(req, nt_status);
691 END_PROFILE(SMBtconX);
696 server_devicetype = "IPC";
697 else if ( IS_PRINT(conn) )
698 server_devicetype = "LPT1:";
700 server_devicetype = "A:";
702 if (Protocol < PROTOCOL_NT1) {
703 reply_outbuf(req, 2, 0);
704 if (message_push_string(&req->outbuf, server_devicetype,
705 STR_TERMINATE|STR_ASCII) == -1) {
706 reply_nterror(req, NT_STATUS_NO_MEMORY);
707 END_PROFILE(SMBtconX);
711 /* NT sets the fstype of IPC$ to the null string */
712 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
714 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
715 /* Return permissions. */
719 reply_outbuf(req, 7, 0);
722 perm1 = FILE_ALL_ACCESS;
723 perm2 = FILE_ALL_ACCESS;
725 perm1 = CAN_WRITE(conn) ?
730 SIVAL(req->outbuf, smb_vwv3, perm1);
731 SIVAL(req->outbuf, smb_vwv5, perm2);
733 reply_outbuf(req, 3, 0);
736 if ((message_push_string(&req->outbuf, server_devicetype,
737 STR_TERMINATE|STR_ASCII) == -1)
738 || (message_push_string(&req->outbuf, fstype,
739 STR_TERMINATE) == -1)) {
740 reply_nterror(req, NT_STATUS_NO_MEMORY);
741 END_PROFILE(SMBtconX);
745 /* what does setting this bit do? It is set by NT4 and
746 may affect the ability to autorun mounted cdroms */
747 SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
748 (lp_csc_policy(SNUM(conn)) << 2));
750 if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) {
751 DEBUG(2,("Serving %s as a Dfs root\n",
752 lp_servicename(SNUM(conn)) ));
753 SSVAL(req->outbuf, smb_vwv2,
754 SMB_SHARE_IN_DFS | SVAL(req->outbuf, smb_vwv2));
759 DEBUG(3,("tconX service=%s \n",
762 /* set the incoming and outgoing tid to the just created one */
763 SSVAL(req->inbuf,smb_tid,conn->cnum);
764 SSVAL(req->outbuf,smb_tid,conn->cnum);
766 END_PROFILE(SMBtconX);
772 /****************************************************************************
773 Reply to an unknown type.
774 ****************************************************************************/
776 void reply_unknown_new(struct smb_request *req, uint8 type)
778 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
779 smb_fn_name(type), type, type));
780 reply_doserror(req, ERRSRV, ERRunknownsmb);
784 /****************************************************************************
786 conn POINTER CAN BE NULL HERE !
787 ****************************************************************************/
789 void reply_ioctl(struct smb_request *req)
791 connection_struct *conn = req->conn;
798 START_PROFILE(SMBioctl);
801 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
802 END_PROFILE(SMBioctl);
806 device = SVAL(req->inbuf,smb_vwv1);
807 function = SVAL(req->inbuf,smb_vwv2);
808 ioctl_code = (device << 16) + function;
810 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
812 switch (ioctl_code) {
813 case IOCTL_QUERY_JOB_INFO:
817 reply_doserror(req, ERRSRV, ERRnosupport);
818 END_PROFILE(SMBioctl);
822 reply_outbuf(req, 8, replysize+1);
823 SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
824 SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
825 SSVAL(req->outbuf,smb_vwv6,52); /* Offset to data */
826 p = smb_buf(req->outbuf);
827 memset(p, '\0', replysize+1); /* valgrind-safe. */
828 p += 1; /* Allow for alignment */
830 switch (ioctl_code) {
831 case IOCTL_QUERY_JOB_INFO:
833 files_struct *fsp = file_fsp(
834 req, SVAL(req->inbuf, smb_vwv0));
836 reply_doserror(req, ERRDOS, ERRbadfid);
837 END_PROFILE(SMBioctl);
840 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
841 srvstr_push((char *)req->outbuf, req->flags2, p+2,
843 STR_TERMINATE|STR_ASCII);
845 srvstr_push((char *)req->outbuf, req->flags2,
846 p+18, lp_servicename(SNUM(conn)),
847 13, STR_TERMINATE|STR_ASCII);
855 END_PROFILE(SMBioctl);
859 /****************************************************************************
860 Strange checkpath NTSTATUS mapping.
861 ****************************************************************************/
863 static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
865 /* Strange DOS error code semantics only for checkpath... */
866 if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
867 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
868 /* We need to map to ERRbadpath */
869 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
875 /****************************************************************************
876 Reply to a checkpath.
877 ****************************************************************************/
879 void reply_checkpath(struct smb_request *req)
881 connection_struct *conn = req->conn;
883 SMB_STRUCT_STAT sbuf;
885 TALLOC_CTX *ctx = talloc_tos();
887 START_PROFILE(SMBcheckpath);
889 srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
890 smb_buf(req->inbuf) + 1, 0,
891 STR_TERMINATE, &status);
892 if (!NT_STATUS_IS_OK(status)) {
893 status = map_checkpath_error((char *)req->inbuf, status);
894 reply_nterror(req, status);
895 END_PROFILE(SMBcheckpath);
899 status = resolve_dfspath(ctx, conn,
900 req->flags2 & FLAGS2_DFS_PATHNAMES,
903 if (!NT_STATUS_IS_OK(status)) {
904 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
905 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
907 END_PROFILE(SMBcheckpath);
913 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
915 status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
916 if (!NT_STATUS_IS_OK(status)) {
920 status = check_name(conn, name);
921 if (!NT_STATUS_IS_OK(status)) {
922 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status)));
926 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
927 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
928 status = map_nt_error_from_unix(errno);
932 if (!S_ISDIR(sbuf.st_mode)) {
933 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
935 END_PROFILE(SMBcheckpath);
939 reply_outbuf(req, 0, 0);
941 END_PROFILE(SMBcheckpath);
946 END_PROFILE(SMBcheckpath);
948 /* We special case this - as when a Windows machine
949 is parsing a path is steps through the components
950 one at a time - if a component fails it expects
951 ERRbadpath, not ERRbadfile.
953 status = map_checkpath_error((char *)req->inbuf, status);
954 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
956 * Windows returns different error codes if
957 * the parent directory is valid but not the
958 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
959 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
960 * if the path is invalid.
962 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
967 reply_nterror(req, status);
970 /****************************************************************************
972 ****************************************************************************/
974 void reply_getatr(struct smb_request *req)
976 connection_struct *conn = req->conn;
978 SMB_STRUCT_STAT sbuf;
984 TALLOC_CTX *ctx = talloc_tos();
986 START_PROFILE(SMBgetatr);
988 p = smb_buf(req->inbuf) + 1;
989 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
990 0, STR_TERMINATE, &status);
991 if (!NT_STATUS_IS_OK(status)) {
992 reply_nterror(req, status);
993 END_PROFILE(SMBgetatr);
997 status = resolve_dfspath(ctx, conn,
998 req->flags2 & FLAGS2_DFS_PATHNAMES,
1001 if (!NT_STATUS_IS_OK(status)) {
1002 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1003 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1004 ERRSRV, ERRbadpath);
1005 END_PROFILE(SMBgetatr);
1008 reply_nterror(req, status);
1009 END_PROFILE(SMBgetatr);
1013 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1014 under WfWg - weird! */
1015 if (*fname == '\0') {
1016 mode = aHIDDEN | aDIR;
1017 if (!CAN_WRITE(conn)) {
1023 status = unix_convert(ctx, conn, fname, False, &fname, NULL,&sbuf);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 reply_nterror(req, status);
1026 END_PROFILE(SMBgetatr);
1029 status = check_name(conn, fname);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
1032 reply_nterror(req, status);
1033 END_PROFILE(SMBgetatr);
1036 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
1037 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
1038 reply_unixerror(req, ERRDOS,ERRbadfile);
1039 END_PROFILE(SMBgetatr);
1043 mode = dos_mode(conn,fname,&sbuf);
1044 size = sbuf.st_size;
1045 mtime = sbuf.st_mtime;
1051 reply_outbuf(req, 10, 0);
1053 SSVAL(req->outbuf,smb_vwv0,mode);
1054 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1055 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1057 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1059 SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1061 if (Protocol >= PROTOCOL_NT1) {
1062 SSVAL(req->outbuf, smb_flg2,
1063 SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1066 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
1068 END_PROFILE(SMBgetatr);
1072 /****************************************************************************
1074 ****************************************************************************/
1076 void reply_setatr(struct smb_request *req)
1078 struct timespec ts[2];
1079 connection_struct *conn = req->conn;
1083 SMB_STRUCT_STAT sbuf;
1086 TALLOC_CTX *ctx = talloc_tos();
1088 START_PROFILE(SMBsetatr);
1093 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1097 p = smb_buf(req->inbuf) + 1;
1098 p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
1099 0, STR_TERMINATE, &status);
1100 if (!NT_STATUS_IS_OK(status)) {
1101 reply_nterror(req, status);
1102 END_PROFILE(SMBsetatr);
1106 status = resolve_dfspath(ctx, conn,
1107 req->flags2 & FLAGS2_DFS_PATHNAMES,
1110 if (!NT_STATUS_IS_OK(status)) {
1111 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1112 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1113 ERRSRV, ERRbadpath);
1114 END_PROFILE(SMBsetatr);
1117 reply_nterror(req, status);
1118 END_PROFILE(SMBsetatr);
1122 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
1123 if (!NT_STATUS_IS_OK(status)) {
1124 reply_nterror(req, status);
1125 END_PROFILE(SMBsetatr);
1129 status = check_name(conn, fname);
1130 if (!NT_STATUS_IS_OK(status)) {
1131 reply_nterror(req, status);
1132 END_PROFILE(SMBsetatr);
1136 if (fname[0] == '.' && fname[1] == '\0') {
1138 * Not sure here is the right place to catch this
1139 * condition. Might be moved to somewhere else later -- vl
1141 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1142 END_PROFILE(SMBsetatr);
1146 mode = SVAL(req->inbuf,smb_vwv0);
1147 mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
1149 ts[1] = convert_time_t_to_timespec(mtime);
1150 status = smb_set_file_time(conn, NULL, fname,
1152 if (!NT_STATUS_IS_OK(status)) {
1153 reply_unixerror(req, ERRDOS, ERRnoaccess);
1154 END_PROFILE(SMBsetatr);
1158 if (mode != FILE_ATTRIBUTE_NORMAL) {
1159 if (VALID_STAT_OF_DIR(sbuf))
1164 if (file_set_dosmode(conn,fname,mode,&sbuf,NULL,false) != 0) {
1165 reply_unixerror(req, ERRDOS, ERRnoaccess);
1166 END_PROFILE(SMBsetatr);
1171 reply_outbuf(req, 0, 0);
1173 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1175 END_PROFILE(SMBsetatr);
1179 /****************************************************************************
1181 ****************************************************************************/
1183 void reply_dskattr(struct smb_request *req)
1185 connection_struct *conn = req->conn;
1186 uint64_t dfree,dsize,bsize;
1187 START_PROFILE(SMBdskattr);
1189 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
1190 reply_unixerror(req, ERRHRD, ERRgeneral);
1191 END_PROFILE(SMBdskattr);
1195 reply_outbuf(req, 5, 0);
1197 if (Protocol <= PROTOCOL_LANMAN2) {
1198 double total_space, free_space;
1199 /* we need to scale this to a number that DOS6 can handle. We
1200 use floating point so we can handle large drives on systems
1201 that don't have 64 bit integers
1203 we end up displaying a maximum of 2G to DOS systems
1205 total_space = dsize * (double)bsize;
1206 free_space = dfree * (double)bsize;
1208 dsize = (uint64_t)((total_space+63*512) / (64*512));
1209 dfree = (uint64_t)((free_space+63*512) / (64*512));
1211 if (dsize > 0xFFFF) dsize = 0xFFFF;
1212 if (dfree > 0xFFFF) dfree = 0xFFFF;
1214 SSVAL(req->outbuf,smb_vwv0,dsize);
1215 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1216 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1217 SSVAL(req->outbuf,smb_vwv3,dfree);
1219 SSVAL(req->outbuf,smb_vwv0,dsize);
1220 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1221 SSVAL(req->outbuf,smb_vwv2,512);
1222 SSVAL(req->outbuf,smb_vwv3,dfree);
1225 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1227 END_PROFILE(SMBdskattr);
1231 /****************************************************************************
1233 Can be called from SMBsearch, SMBffirst or SMBfunique.
1234 ****************************************************************************/
1236 void reply_search(struct smb_request *req)
1238 connection_struct *conn = req->conn;
1240 char *directory = NULL;
1246 unsigned int numentries = 0;
1247 unsigned int maxentries = 0;
1248 bool finished = False;
1254 bool check_descend = False;
1255 bool expect_close = False;
1257 bool mask_contains_wcard = False;
1258 bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1259 TALLOC_CTX *ctx = talloc_tos();
1260 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1262 START_PROFILE(SMBsearch);
1265 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1266 END_PROFILE(SMBsearch);
1270 if (lp_posix_pathnames()) {
1271 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1272 END_PROFILE(SMBsearch);
1276 /* If we were called as SMBffirst then we must expect close. */
1277 if(CVAL(req->inbuf,smb_com) == SMBffirst) {
1278 expect_close = True;
1281 reply_outbuf(req, 1, 3);
1282 maxentries = SVAL(req->inbuf,smb_vwv0);
1283 dirtype = SVAL(req->inbuf,smb_vwv1);
1284 p = smb_buf(req->inbuf) + 1;
1285 p += srvstr_get_path_wcard(ctx,
1293 &mask_contains_wcard);
1294 if (!NT_STATUS_IS_OK(nt_status)) {
1295 reply_nterror(req, nt_status);
1296 END_PROFILE(SMBsearch);
1300 nt_status = resolve_dfspath_wcard(ctx, conn,
1301 req->flags2 & FLAGS2_DFS_PATHNAMES,
1304 &mask_contains_wcard);
1305 if (!NT_STATUS_IS_OK(nt_status)) {
1306 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1307 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1308 ERRSRV, ERRbadpath);
1309 END_PROFILE(SMBsearch);
1312 reply_nterror(req, nt_status);
1313 END_PROFILE(SMBsearch);
1318 status_len = SVAL(p, 0);
1321 /* dirtype &= ~aDIR; */
1323 if (status_len == 0) {
1324 SMB_STRUCT_STAT sbuf;
1326 nt_status = unix_convert(ctx, conn, path, True,
1327 &directory, NULL, &sbuf);
1328 if (!NT_STATUS_IS_OK(nt_status)) {
1329 reply_nterror(req, nt_status);
1330 END_PROFILE(SMBsearch);
1334 nt_status = check_name(conn, directory);
1335 if (!NT_STATUS_IS_OK(nt_status)) {
1336 reply_nterror(req, nt_status);
1337 END_PROFILE(SMBsearch);
1341 p = strrchr_m(directory,'/');
1344 directory = talloc_strdup(ctx,".");
1346 reply_nterror(req, NT_STATUS_NO_MEMORY);
1347 END_PROFILE(SMBsearch);
1355 if (*directory == '\0') {
1356 directory = talloc_strdup(ctx,".");
1358 reply_nterror(req, NT_STATUS_NO_MEMORY);
1359 END_PROFILE(SMBsearch);
1363 memset((char *)status,'\0',21);
1364 SCVAL(status,0,(dirtype & 0x1F));
1366 nt_status = dptr_create(conn,
1372 mask_contains_wcard,
1375 if (!NT_STATUS_IS_OK(nt_status)) {
1376 reply_nterror(req, nt_status);
1377 END_PROFILE(SMBsearch);
1380 dptr_num = dptr_dnum(conn->dirptr);
1384 memcpy(status,p,21);
1385 status_dirtype = CVAL(status,0) & 0x1F;
1386 if (status_dirtype != (dirtype & 0x1F)) {
1387 dirtype = status_dirtype;
1390 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1391 if (!conn->dirptr) {
1394 string_set(&conn->dirpath,dptr_path(dptr_num));
1395 mask = dptr_wcard(dptr_num);
1400 * For a 'continue' search we have no string. So
1401 * check from the initial saved string.
1403 mask_contains_wcard = ms_has_wild(mask);
1404 dirtype = dptr_attr(dptr_num);
1407 DEBUG(4,("dptr_num is %d\n",dptr_num));
1409 if ((dirtype&0x1F) == aVOLID) {
1410 char buf[DIR_STRUCT_SIZE];
1411 memcpy(buf,status,21);
1412 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1413 0,aVOLID,0,!allow_long_path_components)) {
1414 reply_nterror(req, NT_STATUS_NO_MEMORY);
1415 END_PROFILE(SMBsearch);
1418 dptr_fill(buf+12,dptr_num);
1419 if (dptr_zero(buf+12) && (status_len==0)) {
1424 if (message_push_blob(&req->outbuf,
1425 data_blob_const(buf, sizeof(buf)))
1427 reply_nterror(req, NT_STATUS_NO_MEMORY);
1428 END_PROFILE(SMBsearch);
1436 ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1439 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1440 conn->dirpath,lp_dontdescend(SNUM(conn))));
1441 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) {
1442 check_descend = True;
1445 for (i=numentries;(i<maxentries) && !finished;i++) {
1446 finished = !get_dir_entry(ctx,
1457 char buf[DIR_STRUCT_SIZE];
1458 memcpy(buf,status,21);
1459 if (!make_dir_struct(ctx,
1466 !allow_long_path_components)) {
1467 reply_nterror(req, NT_STATUS_NO_MEMORY);
1468 END_PROFILE(SMBsearch);
1471 if (!dptr_fill(buf+12,dptr_num)) {
1474 if (message_push_blob(&req->outbuf,
1475 data_blob_const(buf, sizeof(buf)))
1477 reply_nterror(req, NT_STATUS_NO_MEMORY);
1478 END_PROFILE(SMBsearch);
1488 /* If we were called as SMBffirst with smb_search_id == NULL
1489 and no entries were found then return error and close dirptr
1492 if (numentries == 0) {
1493 dptr_close(&dptr_num);
1494 } else if(expect_close && status_len == 0) {
1495 /* Close the dptr - we know it's gone */
1496 dptr_close(&dptr_num);
1499 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1500 if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
1501 dptr_close(&dptr_num);
1504 if ((numentries == 0) && !mask_contains_wcard) {
1505 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1506 END_PROFILE(SMBsearch);
1510 SSVAL(req->outbuf,smb_vwv0,numentries);
1511 SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1512 SCVAL(smb_buf(req->outbuf),0,5);
1513 SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1515 /* The replies here are never long name. */
1516 SSVAL(req->outbuf, smb_flg2,
1517 SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1518 if (!allow_long_path_components) {
1519 SSVAL(req->outbuf, smb_flg2,
1520 SVAL(req->outbuf, smb_flg2)
1521 & (~FLAGS2_LONG_PATH_COMPONENTS));
1524 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1525 SSVAL(req->outbuf, smb_flg2,
1526 (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1529 directory = dptr_path(dptr_num);
1532 DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1533 smb_fn_name(CVAL(req->inbuf,smb_com)),
1535 directory ? directory : "./",
1540 END_PROFILE(SMBsearch);
1544 /****************************************************************************
1545 Reply to a fclose (stop directory search).
1546 ****************************************************************************/
1548 void reply_fclose(struct smb_request *req)
1556 bool path_contains_wcard = False;
1557 TALLOC_CTX *ctx = talloc_tos();
1559 START_PROFILE(SMBfclose);
1561 if (lp_posix_pathnames()) {
1562 reply_unknown_new(req, CVAL(req->inbuf, smb_com));
1563 END_PROFILE(SMBfclose);
1567 p = smb_buf(req->inbuf) + 1;
1568 p += srvstr_get_path_wcard(ctx,
1576 &path_contains_wcard);
1577 if (!NT_STATUS_IS_OK(err)) {
1578 reply_nterror(req, err);
1579 END_PROFILE(SMBfclose);
1583 status_len = SVAL(p,0);
1586 if (status_len == 0) {
1587 reply_doserror(req, ERRSRV, ERRsrverror);
1588 END_PROFILE(SMBfclose);
1592 memcpy(status,p,21);
1594 if(dptr_fetch(status+12,&dptr_num)) {
1595 /* Close the dptr - we know it's gone */
1596 dptr_close(&dptr_num);
1599 reply_outbuf(req, 1, 0);
1600 SSVAL(req->outbuf,smb_vwv0,0);
1602 DEBUG(3,("search close\n"));
1604 END_PROFILE(SMBfclose);
1608 /****************************************************************************
1610 ****************************************************************************/
1612 void reply_open(struct smb_request *req)
1614 connection_struct *conn = req->conn;
1620 SMB_STRUCT_STAT sbuf;
1627 uint32 create_disposition;
1628 uint32 create_options = 0;
1630 TALLOC_CTX *ctx = talloc_tos();
1632 START_PROFILE(SMBopen);
1635 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1636 END_PROFILE(SMBopen);
1640 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1641 deny_mode = SVAL(req->inbuf,smb_vwv0);
1642 dos_attr = SVAL(req->inbuf,smb_vwv1);
1644 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1645 smb_buf(req->inbuf)+1, 0,
1646 STR_TERMINATE, &status);
1647 if (!NT_STATUS_IS_OK(status)) {
1648 reply_nterror(req, status);
1649 END_PROFILE(SMBopen);
1653 if (!map_open_params_to_ntcreate(
1654 fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
1655 &share_mode, &create_disposition, &create_options)) {
1656 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1657 END_PROFILE(SMBopen);
1661 status = create_file(conn, /* conn */
1663 0, /* root_dir_fid */
1665 access_mask, /* access_mask */
1666 share_mode, /* share_access */
1667 create_disposition, /* create_disposition*/
1668 create_options, /* create_options */
1669 dos_attr, /* file_attributes */
1670 oplock_request, /* oplock_request */
1671 0, /* allocation_size */
1678 if (!NT_STATUS_IS_OK(status)) {
1679 if (open_was_deferred(req->mid)) {
1680 /* We have re-scheduled this call. */
1681 END_PROFILE(SMBopen);
1684 reply_openerror(req, status);
1685 END_PROFILE(SMBopen);
1689 size = sbuf.st_size;
1690 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1691 mtime = sbuf.st_mtime;
1694 DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
1695 close_file(req, fsp, ERROR_CLOSE);
1696 reply_doserror(req, ERRDOS,ERRnoaccess);
1697 END_PROFILE(SMBopen);
1701 reply_outbuf(req, 7, 0);
1702 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1703 SSVAL(req->outbuf,smb_vwv1,fattr);
1704 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1705 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1707 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1709 SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1710 SSVAL(req->outbuf,smb_vwv6,deny_mode);
1712 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1713 SCVAL(req->outbuf,smb_flg,
1714 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1717 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1718 SCVAL(req->outbuf,smb_flg,
1719 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1721 END_PROFILE(SMBopen);
1725 /****************************************************************************
1726 Reply to an open and X.
1727 ****************************************************************************/
1729 void reply_open_and_X(struct smb_request *req)
1731 connection_struct *conn = req->conn;
1736 /* Breakout the oplock request bits so we can set the
1737 reply bits separately. */
1738 int ex_oplock_request;
1739 int core_oplock_request;
1742 int smb_sattr = SVAL(req->inbuf,smb_vwv4);
1743 uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6);
1748 SMB_STRUCT_STAT sbuf;
1752 uint64_t allocation_size;
1753 ssize_t retval = -1;
1756 uint32 create_disposition;
1757 uint32 create_options = 0;
1758 TALLOC_CTX *ctx = talloc_tos();
1760 START_PROFILE(SMBopenX);
1762 if (req->wct < 15) {
1763 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1764 END_PROFILE(SMBopenX);
1768 open_flags = SVAL(req->inbuf,smb_vwv2);
1769 deny_mode = SVAL(req->inbuf,smb_vwv3);
1770 smb_attr = SVAL(req->inbuf,smb_vwv5);
1771 ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1772 core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1773 oplock_request = ex_oplock_request | core_oplock_request;
1774 smb_ofun = SVAL(req->inbuf,smb_vwv8);
1775 allocation_size = (uint64_t)IVAL(req->inbuf,smb_vwv9);
1777 /* If it's an IPC, pass off the pipe handler. */
1779 if (lp_nt_pipe_support()) {
1780 reply_open_pipe_and_X(conn, req);
1782 reply_doserror(req, ERRSRV, ERRaccess);
1784 END_PROFILE(SMBopenX);
1788 /* XXXX we need to handle passed times, sattr and flags */
1789 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1790 smb_buf(req->inbuf), 0, STR_TERMINATE,
1792 if (!NT_STATUS_IS_OK(status)) {
1793 reply_nterror(req, status);
1794 END_PROFILE(SMBopenX);
1798 if (!map_open_params_to_ntcreate(
1799 fname, deny_mode, smb_ofun, &access_mask,
1800 &share_mode, &create_disposition, &create_options)) {
1801 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1802 END_PROFILE(SMBopenX);
1806 status = create_file(conn, /* conn */
1808 0, /* root_dir_fid */
1810 access_mask, /* access_mask */
1811 share_mode, /* share_access */
1812 create_disposition, /* create_disposition*/
1813 create_options, /* create_options */
1814 smb_attr, /* file_attributes */
1815 oplock_request, /* oplock_request */
1816 0, /* allocation_size */
1820 &smb_action, /* pinfo */
1823 if (!NT_STATUS_IS_OK(status)) {
1824 END_PROFILE(SMBopenX);
1825 if (open_was_deferred(req->mid)) {
1826 /* We have re-scheduled this call. */
1829 reply_openerror(req, status);
1833 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1834 if the file is truncated or created. */
1835 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1836 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1837 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1838 close_file(req, fsp, ERROR_CLOSE);
1839 reply_nterror(req, NT_STATUS_DISK_FULL);
1840 END_PROFILE(SMBopenX);
1843 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1845 close_file(req, fsp, ERROR_CLOSE);
1846 reply_nterror(req, NT_STATUS_DISK_FULL);
1847 END_PROFILE(SMBopenX);
1850 sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
1853 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1854 mtime = sbuf.st_mtime;
1856 close_file(req, fsp, ERROR_CLOSE);
1857 reply_doserror(req, ERRDOS, ERRnoaccess);
1858 END_PROFILE(SMBopenX);
1862 /* If the caller set the extended oplock request bit
1863 and we granted one (by whatever means) - set the
1864 correct bit for extended oplock reply.
1867 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1868 smb_action |= EXTENDED_OPLOCK_GRANTED;
1871 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1872 smb_action |= EXTENDED_OPLOCK_GRANTED;
1875 /* If the caller set the core oplock request bit
1876 and we granted one (by whatever means) - set the
1877 correct bit for core oplock reply.
1880 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1881 reply_outbuf(req, 19, 0);
1883 reply_outbuf(req, 15, 0);
1886 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1887 SCVAL(req->outbuf, smb_flg,
1888 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1891 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1892 SCVAL(req->outbuf, smb_flg,
1893 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1896 SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
1897 SSVAL(req->outbuf,smb_vwv3,fattr);
1898 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1899 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
1901 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
1903 SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size);
1904 SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
1905 SSVAL(req->outbuf,smb_vwv11,smb_action);
1907 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1908 SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
1911 END_PROFILE(SMBopenX);
1916 /****************************************************************************
1917 Reply to a SMBulogoffX.
1918 ****************************************************************************/
1920 void reply_ulogoffX(struct smb_request *req)
1924 START_PROFILE(SMBulogoffX);
1926 vuser = get_valid_user_struct(req->vuid);
1929 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
1933 /* in user level security we are supposed to close any files
1934 open by this user */
1935 if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
1936 file_close_user(req->vuid);
1939 invalidate_vuid(req->vuid);
1941 reply_outbuf(req, 2, 0);
1943 DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
1945 END_PROFILE(SMBulogoffX);
1949 /****************************************************************************
1950 Reply to a mknew or a create.
1951 ****************************************************************************/
1953 void reply_mknew(struct smb_request *req)
1955 connection_struct *conn = req->conn;
1959 struct timespec ts[2];
1961 int oplock_request = 0;
1962 SMB_STRUCT_STAT sbuf;
1964 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
1965 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1966 uint32 create_disposition;
1967 uint32 create_options = 0;
1968 TALLOC_CTX *ctx = talloc_tos();
1970 START_PROFILE(SMBcreate);
1973 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1974 END_PROFILE(SMBcreate);
1978 fattr = SVAL(req->inbuf,smb_vwv0);
1979 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1980 com = SVAL(req->inbuf,smb_com);
1982 ts[1] =convert_time_t_to_timespec(
1983 srv_make_unix_date3(req->inbuf + smb_vwv1));
1986 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
1987 smb_buf(req->inbuf) + 1, 0,
1988 STR_TERMINATE, &status);
1989 if (!NT_STATUS_IS_OK(status)) {
1990 reply_nterror(req, status);
1991 END_PROFILE(SMBcreate);
1995 if (fattr & aVOLID) {
1996 DEBUG(0,("Attempt to create file (%s) with volid set - "
1997 "please report this\n", fname));
2000 if(com == SMBmknew) {
2001 /* We should fail if file exists. */
2002 create_disposition = FILE_CREATE;
2004 /* Create if file doesn't exist, truncate if it does. */
2005 create_disposition = FILE_OVERWRITE_IF;
2008 status = create_file(conn, /* conn */
2010 0, /* root_dir_fid */
2012 access_mask, /* access_mask */
2013 share_mode, /* share_access */
2014 create_disposition, /* create_disposition*/
2015 create_options, /* create_options */
2016 fattr, /* file_attributes */
2017 oplock_request, /* oplock_request */
2018 0, /* allocation_size */
2025 if (!NT_STATUS_IS_OK(status)) {
2026 END_PROFILE(SMBcreate);
2027 if (open_was_deferred(req->mid)) {
2028 /* We have re-scheduled this call. */
2031 reply_openerror(req, status);
2035 ts[0] = get_atimespec(&sbuf); /* atime. */
2036 status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true);
2037 if (!NT_STATUS_IS_OK(status)) {
2038 END_PROFILE(SMBcreate);
2039 reply_openerror(req, status);
2043 reply_outbuf(req, 1, 0);
2044 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2046 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2047 SCVAL(req->outbuf,smb_flg,
2048 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2051 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2052 SCVAL(req->outbuf,smb_flg,
2053 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2056 DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) );
2057 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
2058 fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
2060 END_PROFILE(SMBcreate);
2064 /****************************************************************************
2065 Reply to a create temporary file.
2066 ****************************************************************************/
2068 void reply_ctemp(struct smb_request *req)
2070 connection_struct *conn = req->conn;
2076 SMB_STRUCT_STAT sbuf;
2079 TALLOC_CTX *ctx = talloc_tos();
2081 START_PROFILE(SMBctemp);
2084 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2085 END_PROFILE(SMBctemp);
2089 fattr = SVAL(req->inbuf,smb_vwv0);
2090 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2092 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
2093 smb_buf(req->inbuf)+1, 0, STR_TERMINATE,
2095 if (!NT_STATUS_IS_OK(status)) {
2096 reply_nterror(req, status);
2097 END_PROFILE(SMBctemp);
2101 fname = talloc_asprintf(ctx,
2105 fname = talloc_strdup(ctx, "TMXXXXXX");
2109 reply_nterror(req, NT_STATUS_NO_MEMORY);
2110 END_PROFILE(SMBctemp);
2114 status = resolve_dfspath(ctx, conn,
2115 req->flags2 & FLAGS2_DFS_PATHNAMES,
2118 if (!NT_STATUS_IS_OK(status)) {
2119 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2120 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2121 ERRSRV, ERRbadpath);
2122 END_PROFILE(SMBctemp);
2125 reply_nterror(req, status);
2126 END_PROFILE(SMBctemp);
2130 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
2131 if (!NT_STATUS_IS_OK(status)) {
2132 reply_nterror(req, status);
2133 END_PROFILE(SMBctemp);
2137 status = check_name(conn, fname);
2138 if (!NT_STATUS_IS_OK(status)) {
2139 reply_nterror(req, status);
2140 END_PROFILE(SMBctemp);
2144 tmpfd = smb_mkstemp(fname);
2146 reply_unixerror(req, ERRDOS, ERRnoaccess);
2147 END_PROFILE(SMBctemp);
2151 SMB_VFS_STAT(conn,fname,&sbuf);
2153 /* We should fail if file does not exist. */
2154 status = open_file_ntcreate(conn, req, fname, &sbuf,
2155 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
2156 FILE_SHARE_READ|FILE_SHARE_WRITE,
2163 /* close fd from smb_mkstemp() */
2166 if (!NT_STATUS_IS_OK(status)) {
2167 if (open_was_deferred(req->mid)) {
2168 /* We have re-scheduled this call. */
2169 END_PROFILE(SMBctemp);
2172 reply_openerror(req, status);
2173 END_PROFILE(SMBctemp);
2177 reply_outbuf(req, 1, 0);
2178 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2180 /* the returned filename is relative to the directory */
2181 s = strrchr_m(fsp->fsp_name, '/');
2189 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2190 thing in the byte section. JRA */
2191 SSVALS(p, 0, -1); /* what is this? not in spec */
2193 if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2195 reply_nterror(req, NT_STATUS_NO_MEMORY);
2196 END_PROFILE(SMBctemp);
2200 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2201 SCVAL(req->outbuf, smb_flg,
2202 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2205 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2206 SCVAL(req->outbuf, smb_flg,
2207 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2210 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
2211 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
2212 fsp->fh->fd, (unsigned int)sbuf.st_mode ) );
2214 END_PROFILE(SMBctemp);
2218 /*******************************************************************
2219 Check if a user is allowed to rename a file.
2220 ********************************************************************/
2222 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2223 uint16 dirtype, SMB_STRUCT_STAT *pst)
2227 if (!CAN_WRITE(conn)) {
2228 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2231 fmode = dos_mode(conn, fsp->fsp_name, pst);
2232 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
2233 return NT_STATUS_NO_SUCH_FILE;
2236 if (S_ISDIR(pst->st_mode)) {
2237 return NT_STATUS_OK;
2240 if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
2241 return NT_STATUS_OK;
2244 return NT_STATUS_ACCESS_DENIED;
2247 /*******************************************************************
2248 * unlink a file with all relevant access checks
2249 *******************************************************************/
2251 static NTSTATUS do_unlink(connection_struct *conn,
2252 struct smb_request *req,
2256 SMB_STRUCT_STAT sbuf;
2259 uint32 dirtype_orig = dirtype;
2262 DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
2264 if (!CAN_WRITE(conn)) {
2265 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2268 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
2269 return map_nt_error_from_unix(errno);
2272 fattr = dos_mode(conn,fname,&sbuf);
2274 if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2275 dirtype = aDIR|aARCH|aRONLY;
2278 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
2280 return NT_STATUS_NO_SUCH_FILE;
2283 if (!dir_check_ftype(conn, fattr, dirtype)) {
2285 return NT_STATUS_FILE_IS_A_DIRECTORY;
2287 return NT_STATUS_NO_SUCH_FILE;
2290 if (dirtype_orig & 0x8000) {
2291 /* These will never be set for POSIX. */
2292 return NT_STATUS_NO_SUCH_FILE;
2296 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2297 return NT_STATUS_FILE_IS_A_DIRECTORY;
2300 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2301 return NT_STATUS_NO_SUCH_FILE;
2304 if (dirtype & 0xFF00) {
2305 /* These will never be set for POSIX. */
2306 return NT_STATUS_NO_SUCH_FILE;
2311 return NT_STATUS_NO_SUCH_FILE;
2314 /* Can't delete a directory. */
2316 return NT_STATUS_FILE_IS_A_DIRECTORY;
2321 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
2322 return NT_STATUS_OBJECT_NAME_INVALID;
2323 #endif /* JRATEST */
2325 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
2327 On a Windows share, a file with read-only dosmode can be opened with
2328 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
2329 fails with NT_STATUS_CANNOT_DELETE error.
2331 This semantic causes a problem that a user can not
2332 rename a file with read-only dosmode on a Samba share
2333 from a Windows command prompt (i.e. cmd.exe, but can rename
2334 from Windows Explorer).
2337 if (!lp_delete_readonly(SNUM(conn))) {
2338 if (fattr & aRONLY) {
2339 return NT_STATUS_CANNOT_DELETE;
2343 /* On open checks the open itself will check the share mode, so
2344 don't do it here as we'll get it wrong. */
2346 status = create_file_unixpath
2350 DELETE_ACCESS, /* access_mask */
2351 FILE_SHARE_NONE, /* share_access */
2352 FILE_OPEN, /* create_disposition*/
2353 FILE_NON_DIRECTORY_FILE, /* create_options */
2354 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2355 0, /* oplock_request */
2356 0, /* allocation_size */
2363 if (!NT_STATUS_IS_OK(status)) {
2364 DEBUG(10, ("create_file_unixpath failed: %s\n",
2365 nt_errstr(status)));
2369 /* The set is across all open files on this dev/inode pair. */
2370 if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) {
2371 close_file(req, fsp, NORMAL_CLOSE);
2372 return NT_STATUS_ACCESS_DENIED;
2375 return close_file(req, fsp, NORMAL_CLOSE);
2378 /****************************************************************************
2379 The guts of the unlink command, split out so it may be called by the NT SMB
2381 ****************************************************************************/
2383 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2384 uint32 dirtype, const char *name_in, bool has_wild)
2386 const char *directory = NULL;
2391 NTSTATUS status = NT_STATUS_OK;
2392 SMB_STRUCT_STAT sbuf;
2393 TALLOC_CTX *ctx = talloc_tos();
2395 status = unix_convert(ctx, conn, name_in, has_wild, &name, NULL, &sbuf);
2396 if (!NT_STATUS_IS_OK(status)) {
2400 p = strrchr_m(name,'/');
2402 directory = talloc_strdup(ctx, ".");
2404 return NT_STATUS_NO_MEMORY;
2414 * We should only check the mangled cache
2415 * here if unix_convert failed. This means
2416 * that the path in 'mask' doesn't exist
2417 * on the file system and so we need to look
2418 * for a possible mangle. This patch from
2419 * Tine Smukavec <valentin.smukavec@hermes.si>.
2422 if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) {
2423 char *new_mask = NULL;
2424 mangle_lookup_name_from_8_3(ctx,
2434 directory = talloc_asprintf(ctx,
2439 return NT_STATUS_NO_MEMORY;
2442 dirtype = FILE_ATTRIBUTE_NORMAL;
2445 status = check_name(conn, directory);
2446 if (!NT_STATUS_IS_OK(status)) {
2450 status = do_unlink(conn, req, directory, dirtype);
2451 if (!NT_STATUS_IS_OK(status)) {
2457 struct smb_Dir *dir_hnd = NULL;
2461 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2462 return NT_STATUS_OBJECT_NAME_INVALID;
2465 if (strequal(mask,"????????.???")) {
2470 status = check_name(conn, directory);
2471 if (!NT_STATUS_IS_OK(status)) {
2475 dir_hnd = OpenDir(talloc_tos(), conn, directory, mask,
2477 if (dir_hnd == NULL) {
2478 return map_nt_error_from_unix(errno);
2481 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2482 the pattern matches against the long name, otherwise the short name
2483 We don't implement this yet XXXX
2486 status = NT_STATUS_NO_SUCH_FILE;
2488 while ((dname = ReadDirName(dir_hnd, &offset))) {
2492 if (!is_visible_file(conn, directory, dname, &st, True)) {
2496 /* Quick check for "." and ".." */
2497 if (ISDOT(dname) || ISDOTDOT(dname)) {
2501 if(!mask_match(dname, mask, conn->case_sensitive)) {
2505 fname = talloc_asprintf(ctx, "%s/%s",
2509 return NT_STATUS_NO_MEMORY;
2512 status = check_name(conn, fname);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 TALLOC_FREE(dir_hnd);
2518 status = do_unlink(conn, req, fname, dirtype);
2519 if (!NT_STATUS_IS_OK(status)) {
2525 DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2530 TALLOC_FREE(dir_hnd);
2533 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
2534 status = map_nt_error_from_unix(errno);
2540 /****************************************************************************
2542 ****************************************************************************/
2544 void reply_unlink(struct smb_request *req)
2546 connection_struct *conn = req->conn;
2550 bool path_contains_wcard = False;
2551 TALLOC_CTX *ctx = talloc_tos();
2553 START_PROFILE(SMBunlink);
2556 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2557 END_PROFILE(SMBunlink);
2561 dirtype = SVAL(req->inbuf,smb_vwv0);
2563 srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
2564 smb_buf(req->inbuf) + 1, 0,
2565 STR_TERMINATE, &status, &path_contains_wcard);
2566 if (!NT_STATUS_IS_OK(status)) {
2567 reply_nterror(req, status);
2568 END_PROFILE(SMBunlink);
2572 status = resolve_dfspath_wcard(ctx, conn,
2573 req->flags2 & FLAGS2_DFS_PATHNAMES,
2576 &path_contains_wcard);
2577 if (!NT_STATUS_IS_OK(status)) {
2578 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2579 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2580 ERRSRV, ERRbadpath);
2581 END_PROFILE(SMBunlink);
2584 reply_nterror(req, status);
2585 END_PROFILE(SMBunlink);
2589 DEBUG(3,("reply_unlink : %s\n",name));
2591 status = unlink_internals(conn, req, dirtype, name,
2592 path_contains_wcard);
2593 if (!NT_STATUS_IS_OK(status)) {
2594 if (open_was_deferred(req->mid)) {
2595 /* We have re-scheduled this call. */
2596 END_PROFILE(SMBunlink);
2599 reply_nterror(req, status);
2600 END_PROFILE(SMBunlink);
2604 reply_outbuf(req, 0, 0);
2605 END_PROFILE(SMBunlink);
2610 /****************************************************************************
2612 ****************************************************************************/
2614 static void fail_readraw(void)
2616 const char *errstr = talloc_asprintf(talloc_tos(),
2617 "FAIL ! reply_readbraw: socket write fail (%s)",
2622 exit_server_cleanly(errstr);
2625 /****************************************************************************
2626 Fake (read/write) sendfile. Returns -1 on read or write fail.
2627 ****************************************************************************/
2629 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
2633 size_t tosend = nread;
2640 bufsize = MIN(nread, 65536);
2642 if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2646 while (tosend > 0) {
2650 if (tosend > bufsize) {
2655 ret = read_file(fsp,buf,startpos,cur_read);
2661 /* If we had a short read, fill with zeros. */
2662 if (ret < cur_read) {
2663 memset(buf, '\0', cur_read - ret);
2666 if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
2671 startpos += cur_read;
2675 return (ssize_t)nread;
2678 /****************************************************************************
2679 Return a readbraw error (4 bytes of zero).
2680 ****************************************************************************/
2682 static void reply_readbraw_error(void)
2686 if (write_data(smbd_server_fd(),header,4) != 4) {
2691 /****************************************************************************
2692 Use sendfile in readbraw.
2693 ****************************************************************************/
2695 void send_file_readbraw(connection_struct *conn,
2701 char *outbuf = NULL;
2704 #if defined(WITH_SENDFILE)
2706 * We can only use sendfile on a non-chained packet
2707 * but we can use on a non-oplocked file. tridge proved this
2708 * on a train in Germany :-). JRA.
2709 * reply_readbraw has already checked the length.
2712 if ( (chain_size == 0) && (nread > 0) && (fsp->base_fsp == NULL) &&
2713 (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
2715 DATA_BLOB header_blob;
2717 _smb_setlen(header,nread);
2718 header_blob = data_blob_const(header, 4);
2720 if (SMB_VFS_SENDFILE(smbd_server_fd(), fsp,
2721 &header_blob, startpos, nread) == -1) {
2722 /* Returning ENOSYS means no data at all was sent.
2723 * Do this as a normal read. */
2724 if (errno == ENOSYS) {
2725 goto normal_readbraw;
2729 * Special hack for broken Linux with no working sendfile. If we
2730 * return EINTR we sent the header but not the rest of the data.
2731 * Fake this up by doing read/write calls.
2733 if (errno == EINTR) {
2734 /* Ensure we don't do this again. */
2735 set_use_sendfile(SNUM(conn), False);
2736 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2738 if (fake_sendfile(fsp, startpos, nread) == -1) {
2739 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2740 fsp->fsp_name, strerror(errno) ));
2741 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2746 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2747 fsp->fsp_name, strerror(errno) ));
2748 exit_server_cleanly("send_file_readbraw sendfile failed");
2757 outbuf = TALLOC_ARRAY(NULL, char, nread+4);
2759 DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
2760 (unsigned)(nread+4)));
2761 reply_readbraw_error();
2766 ret = read_file(fsp,outbuf+4,startpos,nread);
2767 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2776 _smb_setlen(outbuf,ret);
2777 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2780 TALLOC_FREE(outbuf);
2783 /****************************************************************************
2784 Reply to a readbraw (core+ protocol).
2785 ****************************************************************************/
2787 void reply_readbraw(struct smb_request *req)
2789 connection_struct *conn = req->conn;
2790 ssize_t maxcount,mincount;
2797 START_PROFILE(SMBreadbraw);
2799 if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
2800 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
2801 "raw reads/writes are disallowed.");
2805 reply_readbraw_error();
2806 END_PROFILE(SMBreadbraw);
2811 * Special check if an oplock break has been issued
2812 * and the readraw request croses on the wire, we must
2813 * return a zero length response here.
2816 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
2819 * We have to do a check_fsp by hand here, as
2820 * we must always return 4 zero bytes on error,
2824 if (!fsp || !conn || conn != fsp->conn ||
2825 req->vuid != fsp->vuid ||
2826 fsp->is_directory || fsp->fh->fd == -1) {
2828 * fsp could be NULL here so use the value from the packet. JRA.
2830 DEBUG(3,("reply_readbraw: fnum %d not valid "
2832 (int)SVAL(req->inbuf,smb_vwv0)));
2833 reply_readbraw_error();
2834 END_PROFILE(SMBreadbraw);
2838 /* Do a "by hand" version of CHECK_READ. */
2839 if (!(fsp->can_read ||
2840 ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
2841 (fsp->access_mask & FILE_EXECUTE)))) {
2842 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
2843 (int)SVAL(req->inbuf,smb_vwv0)));
2844 reply_readbraw_error();
2845 END_PROFILE(SMBreadbraw);
2849 flush_write_cache(fsp, READRAW_FLUSH);
2851 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
2852 if(req->wct == 10) {
2854 * This is a large offset (64 bit) read.
2856 #ifdef LARGE_SMB_OFF_T
2858 startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
2860 #else /* !LARGE_SMB_OFF_T */
2863 * Ensure we haven't been sent a >32 bit offset.
2866 if(IVAL(req->inbuf,smb_vwv8) != 0) {
2867 DEBUG(0,("reply_readbraw: large offset "
2868 "(%x << 32) used and we don't support "
2869 "64 bit offsets.\n",
2870 (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
2871 reply_readbraw_error();
2872 END_PROFILE(SMBreadbraw);
2876 #endif /* LARGE_SMB_OFF_T */
2879 DEBUG(0,("reply_readbraw: negative 64 bit "
2880 "readraw offset (%.0f) !\n",
2881 (double)startpos ));
2882 reply_readbraw_error();
2883 END_PROFILE(SMBreadbraw);
2888 maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
2889 mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
2891 /* ensure we don't overrun the packet size */
2892 maxcount = MIN(65535,maxcount);
2894 if (is_locked(fsp,(uint32)req->smbpid,
2898 reply_readbraw_error();
2899 END_PROFILE(SMBreadbraw);
2903 if (SMB_VFS_FSTAT(fsp, &st) == 0) {
2907 if (startpos >= size) {
2910 nread = MIN(maxcount,(size - startpos));
2913 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2914 if (nread < mincount)
2918 DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
2919 "min=%lu nread=%lu\n",
2920 fsp->fnum, (double)startpos,
2921 (unsigned long)maxcount,
2922 (unsigned long)mincount,
2923 (unsigned long)nread ) );
2925 send_file_readbraw(conn, fsp, startpos, nread, mincount);
2927 DEBUG(5,("reply_readbraw finished\n"));
2928 END_PROFILE(SMBreadbraw);
2932 #define DBGC_CLASS DBGC_LOCKING
2934 /****************************************************************************
2935 Reply to a lockread (core+ protocol).
2936 ****************************************************************************/
2938 void reply_lockread(struct smb_request *req)
2940 connection_struct *conn = req->conn;
2947 struct byte_range_lock *br_lck = NULL;
2950 START_PROFILE(SMBlockread);
2953 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2954 END_PROFILE(SMBlockread);
2958 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
2960 if (!check_fsp(conn, req, fsp)) {
2961 END_PROFILE(SMBlockread);
2965 if (!CHECK_READ(fsp,req->inbuf)) {
2966 reply_doserror(req, ERRDOS, ERRbadaccess);
2967 END_PROFILE(SMBlockread);
2971 release_level_2_oplocks_on_change(fsp);
2973 numtoread = SVAL(req->inbuf,smb_vwv1);
2974 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
2976 numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
2978 reply_outbuf(req, 5, numtoread + 3);
2980 data = smb_buf(req->outbuf) + 3;
2983 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2984 * protocol request that predates the read/write lock concept.
2985 * Thus instead of asking for a read lock here we need to ask
2986 * for a write lock. JRA.
2987 * Note that the requested lock size is unaffected by max_recv.
2990 br_lck = do_lock(smbd_messaging_context(),
2993 (uint64_t)numtoread,
2997 False, /* Non-blocking lock. */
3000 TALLOC_FREE(br_lck);
3002 if (NT_STATUS_V(status)) {
3003 reply_nterror(req, status);
3004 END_PROFILE(SMBlockread);
3009 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
3012 if (numtoread > max_recv) {
3013 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
3014 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3015 (unsigned int)numtoread, (unsigned int)max_recv ));
3016 numtoread = MIN(numtoread,max_recv);
3018 nread = read_file(fsp,data,startpos,numtoread);
3021 reply_unixerror(req, ERRDOS, ERRnoaccess);
3022 END_PROFILE(SMBlockread);
3026 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3028 SSVAL(req->outbuf,smb_vwv0,nread);
3029 SSVAL(req->outbuf,smb_vwv5,nread+3);
3030 p = smb_buf(req->outbuf);
3031 SCVAL(p,0,0); /* pad byte. */
3034 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
3035 fsp->fnum, (int)numtoread, (int)nread));
3037 END_PROFILE(SMBlockread);
3042 #define DBGC_CLASS DBGC_ALL
3044 /****************************************************************************
3046 ****************************************************************************/
3048 void reply_read(struct smb_request *req)
3050 connection_struct *conn = req->conn;
3058 START_PROFILE(SMBread);
3061 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3062 END_PROFILE(SMBread);
3066 fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
3068 if (!check_fsp(conn, req, fsp)) {
3069 END_PROFILE(SMBread);
3073 if (!CHECK_READ(fsp,req->inbuf)) {
3074 reply_doserror(req, ERRDOS, ERRbadaccess);
3075 END_PROFILE(SMBread);
3079 numtoread = SVAL(req->inbuf,smb_vwv1);
3080 startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
3082 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
3085 * The requested read size cannot be greater than max_recv. JRA.
3087 if (numtoread > max_recv) {
3088 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
3089 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
3090 (unsigned int)numtoread, (unsigned int)max_recv ));
3091 numtoread = MIN(numtoread,max_recv);
3094 reply_outbuf(req, 5, numtoread+3);
3096 data = smb_buf(req->outbuf) + 3;
3098 if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtoread,
3099 (uint64_t)startpos, READ_LOCK)) {
3100 reply_doserror(req, ERRDOS,ERRlock);
3101 END_PROFILE(SMBread);
3106 nread = read_file(fsp,data,startpos,numtoread);
3109 reply_unixerror(req, ERRDOS,ERRnoaccess);
3110 END_PROFILE(SMBread);
3114 srv_set_message((char *)req->outbuf, 5, nread+3, False);
3116 SSVAL(req->outbuf,smb_vwv0,nread);
3117 SSVAL(req->outbuf,smb_vwv5,nread+3);
3118 SCVAL(smb_buf(req->outbuf),0,1);
3119 SSVAL(smb_buf(req->outbuf),1,nread);
3121 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
3122 fsp->fnum, (int)numtoread, (int)nread ) );
3124 END_PROFILE(SMBread);
3128 /****************************************************************************
3130 ****************************************************************************/
3132 static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
3137 outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
3138 data = smb_buf(outbuf);
3140 memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
3142 SCVAL(outbuf,smb_vwv0,0xFF);
3143 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
3144 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
3145 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
3146 SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
3147 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
3148 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
3149 _smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
3153 /****************************************************************************
3154 Reply to a read and X - possibly using sendfile.
3155 ****************************************************************************/
3157 static void send_file_readX(connection_struct *conn, struct smb_request *req,
3158 files_struct *fsp, SMB_OFF_T startpos,
3161 SMB_STRUCT_STAT sbuf;
3164 if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
3165 reply_unixerror(req, ERRDOS, ERRnoaccess);
3169 if (startpos > sbuf.st_size) {
3171 } else if (smb_maxcnt > (sbuf.st_size - startpos)) {
3172 smb_maxcnt = (sbuf.st_size - startpos);
3175 if (smb_maxcnt == 0) {
3179 #if defined(WITH_SENDFILE)
3181 * We can only use sendfile on a non-chained packet
3182 * but we can use on a non-oplocked file. tridge proved this
3183 * on a train in Germany :-). JRA.
3186 if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
3187 !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
3188 lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
3189 uint8 headerbuf[smb_size + 12 * 2];
3193 * Set up the packet header before send. We
3194 * assume here the sendfile will work (get the
3195 * correct amount of data).
3198 header = data_blob_const(headerbuf, sizeof(headerbuf));
3200 construct_reply_common((char *)req->inbuf, (char *)headerbuf);
3201 setup_readX_header((char *)headerbuf, smb_maxcnt);
3203 if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
3204 /* Returning ENOSYS or EINVAL means no data at all was sent.
3205 Do this as a normal read. */
3206 if (errno == ENOSYS || errno == EINVAL) {
3211 * Special hack for broken Linux with no working sendfile. If we
3212 * return EINTR we sent the header but not the rest of the data.
3213 * Fake this up by doing read/write calls.