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
28 #include "smbd/globals.h"
30 extern enum protocol_types Protocol;
32 /****************************************************************************
33 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
34 path or anything including wildcards.
35 We're assuming here that '/' is not the second byte in any multibyte char
36 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
38 ****************************************************************************/
40 /* Custom version for processing POSIX paths. */
41 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
43 static NTSTATUS check_path_syntax_internal(char *path,
45 bool *p_last_component_contains_wcard)
49 NTSTATUS ret = NT_STATUS_OK;
50 bool start_of_name_component = True;
51 bool stream_started = false;
53 *p_last_component_contains_wcard = False;
60 return NT_STATUS_OBJECT_NAME_INVALID;
63 return NT_STATUS_OBJECT_NAME_INVALID;
65 if (strchr_m(&s[1], ':')) {
66 return NT_STATUS_OBJECT_NAME_INVALID;
68 if (StrCaseCmp(s, ":$DATA") != 0) {
69 return NT_STATUS_INVALID_PARAMETER;
75 if (!posix_path && !stream_started && *s == ':') {
76 if (*p_last_component_contains_wcard) {
77 return NT_STATUS_OBJECT_NAME_INVALID;
79 /* Stream names allow more characters than file names.
80 We're overloading posix_path here to allow a wider
81 range of characters. If stream_started is true this
82 is still a Windows path even if posix_path is true.
85 stream_started = true;
86 start_of_name_component = false;
90 return NT_STATUS_OBJECT_NAME_INVALID;
94 if (!stream_started && IS_PATH_SEP(*s,posix_path)) {
96 * Safe to assume is not the second part of a mb char
97 * as this is handled below.
99 /* Eat multiple '/' or '\\' */
100 while (IS_PATH_SEP(*s,posix_path)) {
103 if ((d != path) && (*s != '\0')) {
104 /* We only care about non-leading or trailing '/' or '\\' */
108 start_of_name_component = True;
110 *p_last_component_contains_wcard = False;
114 if (start_of_name_component) {
115 if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
116 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
119 * No mb char starts with '.' so we're safe checking the directory separator here.
122 /* If we just added a '/' - delete it */
123 if ((d > path) && (*(d-1) == '/')) {
128 /* Are we at the start ? Can't go back further if so. */
130 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
133 /* Go back one level... */
134 /* We know this is safe as '/' cannot be part of a mb sequence. */
135 /* NOTE - if this assumption is invalid we are not in good shape... */
136 /* Decrement d first as d points to the *next* char to write into. */
137 for (d--; d > path; d--) {
141 s += 2; /* Else go past the .. */
142 /* We're still at the start of a name component, just the previous one. */
145 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
157 if (*s <= 0x1f || *s == '|') {
158 return NT_STATUS_OBJECT_NAME_INVALID;
166 *p_last_component_contains_wcard = True;
175 /* Get the size of the next MB character. */
176 next_codepoint(s,&siz);
194 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
196 return NT_STATUS_INVALID_PARAMETER;
199 start_of_name_component = False;
207 /****************************************************************************
208 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
209 No wildcards allowed.
210 ****************************************************************************/
212 NTSTATUS check_path_syntax(char *path)
215 return check_path_syntax_internal(path, False, &ignore);
218 /****************************************************************************
219 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
220 Wildcards allowed - p_contains_wcard returns true if the last component contained
222 ****************************************************************************/
224 NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
226 return check_path_syntax_internal(path, False, p_contains_wcard);
229 /****************************************************************************
230 Check the path for a POSIX client.
231 We're assuming here that '/' is not the second byte in any multibyte char
232 set (a safe assumption).
233 ****************************************************************************/
235 NTSTATUS check_path_syntax_posix(char *path)
238 return check_path_syntax_internal(path, True, &ignore);
241 /****************************************************************************
242 Pull a string and check the path allowing a wilcard - provide for error return.
243 ****************************************************************************/
245 size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
246 const char *base_ptr,
253 bool *contains_wcard)
259 ret = srvstr_pull_talloc(ctx, base_ptr, smb_flags2, pp_dest, src,
263 *err = NT_STATUS_INVALID_PARAMETER;
267 *contains_wcard = False;
269 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
271 * For a DFS path the function parse_dfs_path()
272 * will do the path processing, just make a copy.
278 if (lp_posix_pathnames()) {
279 *err = check_path_syntax_posix(*pp_dest);
281 *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
287 /****************************************************************************
288 Pull a string and check the path - provide for error return.
289 ****************************************************************************/
291 size_t srvstr_get_path(TALLOC_CTX *ctx,
292 const char *base_ptr,
301 return srvstr_get_path_wcard(ctx, base_ptr, smb_flags2, pp_dest, src,
302 src_len, flags, err, &ignore);
305 size_t srvstr_get_path_req_wcard(TALLOC_CTX *mem_ctx, struct smb_request *req,
306 char **pp_dest, const char *src, int flags,
307 NTSTATUS *err, bool *contains_wcard)
309 return srvstr_get_path_wcard(mem_ctx, (char *)req->inbuf, req->flags2,
310 pp_dest, src, smbreq_bufrem(req, src),
311 flags, err, contains_wcard);
314 size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req,
315 char **pp_dest, const char *src, int flags,
319 return srvstr_get_path_req_wcard(mem_ctx, req, pp_dest, src,
320 flags, err, &ignore);
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 static bool netbios_session_retarget(const char *name, int name_type)
413 char *trim_name_type;
414 const char *retarget_parm;
417 int retarget_type = 0x20;
418 int retarget_port = 139;
419 struct sockaddr_storage retarget_addr;
420 struct sockaddr_in *in_addr;
424 if (get_socket_port(smbd_server_fd()) != 139) {
428 trim_name = talloc_strdup(talloc_tos(), name);
429 if (trim_name == NULL) {
432 trim_char(trim_name, ' ', ' ');
434 trim_name_type = talloc_asprintf(trim_name, "%s#%2.2x", trim_name,
436 if (trim_name_type == NULL) {
440 retarget_parm = lp_parm_const_string(-1, "netbios retarget",
441 trim_name_type, NULL);
442 if (retarget_parm == NULL) {
443 retarget_parm = lp_parm_const_string(-1, "netbios retarget",
446 if (retarget_parm == NULL) {
450 retarget = talloc_strdup(trim_name, retarget_parm);
451 if (retarget == NULL) {
455 DEBUG(10, ("retargeting %s to %s\n", trim_name_type, retarget));
457 p = strchr(retarget, ':');
460 retarget_port = atoi(p);
463 p = strchr_m(retarget, '#');
466 sscanf(p, "%x", &retarget_type);
469 ret = resolve_name(retarget, &retarget_addr, retarget_type);
471 DEBUG(10, ("could not resolve %s\n", retarget));
475 if (retarget_addr.ss_family != AF_INET) {
476 DEBUG(10, ("Retarget target not an IPv4 addr\n"));
480 in_addr = (struct sockaddr_in *)(void *)&retarget_addr;
482 _smb_setlen(outbuf, 6);
483 SCVAL(outbuf, 0, 0x84);
484 *(uint32_t *)(outbuf+4) = in_addr->sin_addr.s_addr;
485 *(uint16_t *)(outbuf+8) = htons(retarget_port);
487 if (!srv_send_smb(smbd_server_fd(), (char *)outbuf, false, 0, false,
489 exit_server_cleanly("netbios_session_regarget: srv_send_smb "
495 TALLOC_FREE(trim_name);
499 /****************************************************************************
500 Reply to a (netbios-level) special message.
501 ****************************************************************************/
503 void reply_special(char *inbuf)
505 int msg_type = CVAL(inbuf,0);
506 int msg_flags = CVAL(inbuf,1);
508 char name_type1, name_type2;
509 struct smbd_server_connection *sconn = smbd_server_conn;
512 * We only really use 4 bytes of the outbuf, but for the smb_setlen
513 * calculation & friends (srv_send_smb uses that) we need the full smb
516 char outbuf[smb_size];
520 memset(outbuf, '\0', sizeof(outbuf));
522 smb_setlen(outbuf,0);
525 case 0x81: /* session request */
527 if (sconn->nbt.got_session) {
528 exit_server_cleanly("multiple session request not permitted");
531 SCVAL(outbuf,0,0x82);
533 if (name_len(inbuf+4) > 50 ||
534 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
535 DEBUG(0,("Invalid name length in session request\n"));
538 name_type1 = name_extract(inbuf,4,name1);
539 name_type2 = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
540 DEBUG(2,("netbios connect: name1=%s0x%x name2=%s0x%x\n",
541 name1, name_type1, name2, name_type2));
543 if (netbios_session_retarget(name1, name_type1)) {
544 exit_server_cleanly("retargeted client");
547 set_local_machine_name(name1, True);
548 set_remote_machine_name(name2, True);
550 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
551 get_local_machine_name(), get_remote_machine_name(),
554 if (name_type2 == 'R') {
555 /* We are being asked for a pathworks session ---
557 SCVAL(outbuf, 0,0x83);
561 /* only add the client's machine name to the list
562 of possibly valid usernames if we are operating
563 in share mode security */
564 if (lp_security() == SEC_SHARE) {
565 add_session_user(sconn, get_remote_machine_name());
568 reload_services(True);
571 sconn->nbt.got_session = true;
574 case 0x89: /* session keepalive request
575 (some old clients produce this?) */
576 SCVAL(outbuf,0,SMBkeepalive);
580 case 0x82: /* positive session response */
581 case 0x83: /* negative session response */
582 case 0x84: /* retarget session response */
583 DEBUG(0,("Unexpected session response\n"));
586 case SMBkeepalive: /* session keepalive */
591 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
592 msg_type, msg_flags));
594 srv_send_smb(smbd_server_fd(), outbuf, false, 0, false, NULL);
598 /****************************************************************************
600 conn POINTER CAN BE NULL HERE !
601 ****************************************************************************/
603 void reply_tcon(struct smb_request *req)
605 connection_struct *conn = req->conn;
607 char *service_buf = NULL;
608 char *password = NULL;
613 DATA_BLOB password_blob;
614 TALLOC_CTX *ctx = talloc_tos();
615 struct smbd_server_connection *sconn = smbd_server_conn;
617 START_PROFILE(SMBtcon);
619 if (req->buflen < 4) {
620 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
621 END_PROFILE(SMBtcon);
625 p = (const char *)req->buf + 1;
626 p += srvstr_pull_req_talloc(ctx, req, &service_buf, p, STR_TERMINATE);
628 pwlen = srvstr_pull_req_talloc(ctx, req, &password, p, STR_TERMINATE);
630 p += srvstr_pull_req_talloc(ctx, req, &dev, p, STR_TERMINATE);
633 if (service_buf == NULL || password == NULL || dev == NULL) {
634 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
635 END_PROFILE(SMBtcon);
638 p = strrchr_m(service_buf,'\\');
642 service = service_buf;
645 password_blob = data_blob(password, pwlen+1);
647 conn = make_connection(sconn,service,password_blob,dev,
648 req->vuid,&nt_status);
651 data_blob_clear_free(&password_blob);
654 reply_nterror(req, nt_status);
655 END_PROFILE(SMBtcon);
659 reply_outbuf(req, 2, 0);
660 SSVAL(req->outbuf,smb_vwv0,sconn->smb1.negprot.max_recv);
661 SSVAL(req->outbuf,smb_vwv1,conn->cnum);
662 SSVAL(req->outbuf,smb_tid,conn->cnum);
664 DEBUG(3,("tcon service=%s cnum=%d\n",
665 service, conn->cnum));
667 END_PROFILE(SMBtcon);
671 /****************************************************************************
672 Reply to a tcon and X.
673 conn POINTER CAN BE NULL HERE !
674 ****************************************************************************/
676 void reply_tcon_and_X(struct smb_request *req)
678 connection_struct *conn = req->conn;
679 const char *service = NULL;
681 TALLOC_CTX *ctx = talloc_tos();
682 /* what the cleint thinks the device is */
683 char *client_devicetype = NULL;
684 /* what the server tells the client the share represents */
685 const char *server_devicetype;
691 struct smbd_server_connection *sconn = smbd_server_conn;
693 START_PROFILE(SMBtconX);
696 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
697 END_PROFILE(SMBtconX);
701 passlen = SVAL(req->vwv+3, 0);
702 tcon_flags = SVAL(req->vwv+2, 0);
704 /* we might have to close an old one */
705 if ((tcon_flags & 0x1) && conn) {
706 close_cnum(sconn, conn,req->vuid);
711 if ((passlen > MAX_PASS_LEN) || (passlen >= req->buflen)) {
712 reply_doserror(req, ERRDOS, ERRbuftoosmall);
713 END_PROFILE(SMBtconX);
717 if (sconn->smb1.negprot.encrypted_passwords) {
718 password = data_blob_talloc(talloc_tos(), req->buf, passlen);
719 if (lp_security() == SEC_SHARE) {
721 * Security = share always has a pad byte
722 * after the password.
724 p = (const char *)req->buf + passlen + 1;
726 p = (const char *)req->buf + passlen;
729 password = data_blob_talloc(talloc_tos(), req->buf, passlen+1);
730 /* Ensure correct termination */
731 password.data[passlen]=0;
732 p = (const char *)req->buf + passlen + 1;
735 p += srvstr_pull_req_talloc(ctx, req, &path, p, STR_TERMINATE);
738 data_blob_clear_free(&password);
739 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
740 END_PROFILE(SMBtconX);
745 * the service name can be either: \\server\share
746 * or share directly like on the DELL PowerVault 705
749 q = strchr_m(path+2,'\\');
751 data_blob_clear_free(&password);
752 reply_doserror(req, ERRDOS, ERRnosuchshare);
753 END_PROFILE(SMBtconX);
761 p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
762 &client_devicetype, p,
763 MIN(6, smbreq_bufrem(req, p)), STR_ASCII);
765 if (client_devicetype == NULL) {
766 data_blob_clear_free(&password);
767 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
768 END_PROFILE(SMBtconX);
772 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
774 conn = make_connection(sconn, service, password, client_devicetype,
775 req->vuid, &nt_status);
778 data_blob_clear_free(&password);
781 reply_nterror(req, nt_status);
782 END_PROFILE(SMBtconX);
787 server_devicetype = "IPC";
788 else if ( IS_PRINT(conn) )
789 server_devicetype = "LPT1:";
791 server_devicetype = "A:";
793 if (Protocol < PROTOCOL_NT1) {
794 reply_outbuf(req, 2, 0);
795 if (message_push_string(&req->outbuf, server_devicetype,
796 STR_TERMINATE|STR_ASCII) == -1) {
797 reply_nterror(req, NT_STATUS_NO_MEMORY);
798 END_PROFILE(SMBtconX);
802 /* NT sets the fstype of IPC$ to the null string */
803 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
805 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
806 /* Return permissions. */
810 reply_outbuf(req, 7, 0);
813 perm1 = FILE_ALL_ACCESS;
814 perm2 = FILE_ALL_ACCESS;
816 perm1 = CAN_WRITE(conn) ?
821 SIVAL(req->outbuf, smb_vwv3, perm1);
822 SIVAL(req->outbuf, smb_vwv5, perm2);
824 reply_outbuf(req, 3, 0);
827 if ((message_push_string(&req->outbuf, server_devicetype,
828 STR_TERMINATE|STR_ASCII) == -1)
829 || (message_push_string(&req->outbuf, fstype,
830 STR_TERMINATE) == -1)) {
831 reply_nterror(req, NT_STATUS_NO_MEMORY);
832 END_PROFILE(SMBtconX);
836 /* what does setting this bit do? It is set by NT4 and
837 may affect the ability to autorun mounted cdroms */
838 SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
839 (lp_csc_policy(SNUM(conn)) << 2));
841 if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) {
842 DEBUG(2,("Serving %s as a Dfs root\n",
843 lp_servicename(SNUM(conn)) ));
844 SSVAL(req->outbuf, smb_vwv2,
845 SMB_SHARE_IN_DFS | SVAL(req->outbuf, smb_vwv2));
850 DEBUG(3,("tconX service=%s \n",
853 /* set the incoming and outgoing tid to the just created one */
854 SSVAL(req->inbuf,smb_tid,conn->cnum);
855 SSVAL(req->outbuf,smb_tid,conn->cnum);
857 END_PROFILE(SMBtconX);
863 /****************************************************************************
864 Reply to an unknown type.
865 ****************************************************************************/
867 void reply_unknown_new(struct smb_request *req, uint8 type)
869 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
870 smb_fn_name(type), type, type));
871 reply_doserror(req, ERRSRV, ERRunknownsmb);
875 /****************************************************************************
877 conn POINTER CAN BE NULL HERE !
878 ****************************************************************************/
880 void reply_ioctl(struct smb_request *req)
882 connection_struct *conn = req->conn;
889 START_PROFILE(SMBioctl);
892 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
893 END_PROFILE(SMBioctl);
897 device = SVAL(req->vwv+1, 0);
898 function = SVAL(req->vwv+2, 0);
899 ioctl_code = (device << 16) + function;
901 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
903 switch (ioctl_code) {
904 case IOCTL_QUERY_JOB_INFO:
908 reply_doserror(req, ERRSRV, ERRnosupport);
909 END_PROFILE(SMBioctl);
913 reply_outbuf(req, 8, replysize+1);
914 SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
915 SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
916 SSVAL(req->outbuf,smb_vwv6,52); /* Offset to data */
917 p = smb_buf(req->outbuf);
918 memset(p, '\0', replysize+1); /* valgrind-safe. */
919 p += 1; /* Allow for alignment */
921 switch (ioctl_code) {
922 case IOCTL_QUERY_JOB_INFO:
924 files_struct *fsp = file_fsp(
925 req, SVAL(req->vwv+0, 0));
927 reply_doserror(req, ERRDOS, ERRbadfid);
928 END_PROFILE(SMBioctl);
931 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
932 srvstr_push((char *)req->outbuf, req->flags2, p+2,
934 STR_TERMINATE|STR_ASCII);
936 srvstr_push((char *)req->outbuf, req->flags2,
937 p+18, lp_servicename(SNUM(conn)),
938 13, STR_TERMINATE|STR_ASCII);
946 END_PROFILE(SMBioctl);
950 /****************************************************************************
951 Strange checkpath NTSTATUS mapping.
952 ****************************************************************************/
954 static NTSTATUS map_checkpath_error(uint16_t flags2, NTSTATUS status)
956 /* Strange DOS error code semantics only for checkpath... */
957 if (!(flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
958 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
959 /* We need to map to ERRbadpath */
960 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
966 /****************************************************************************
967 Reply to a checkpath.
968 ****************************************************************************/
970 void reply_checkpath(struct smb_request *req)
972 connection_struct *conn = req->conn;
973 struct smb_filename *smb_fname = NULL;
976 TALLOC_CTX *ctx = talloc_tos();
978 START_PROFILE(SMBcheckpath);
980 srvstr_get_path_req(ctx, req, &name, (const char *)req->buf + 1,
981 STR_TERMINATE, &status);
983 if (!NT_STATUS_IS_OK(status)) {
984 status = map_checkpath_error(req->flags2, status);
985 reply_nterror(req, status);
986 END_PROFILE(SMBcheckpath);
990 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
992 status = filename_convert(ctx,
994 req->flags2 & FLAGS2_DFS_PATHNAMES,
999 if (!NT_STATUS_IS_OK(status)) {
1000 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1001 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1002 ERRSRV, ERRbadpath);
1003 END_PROFILE(SMBcheckpath);
1009 if (!VALID_STAT(smb_fname->st) &&
1010 (SMB_VFS_STAT(conn, smb_fname) != 0)) {
1011 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",
1012 smb_fname_str_dbg(smb_fname), strerror(errno)));
1013 status = map_nt_error_from_unix(errno);
1017 if (!S_ISDIR(smb_fname->st.st_ex_mode)) {
1018 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
1019 ERRDOS, ERRbadpath);
1023 reply_outbuf(req, 0, 0);
1026 /* We special case this - as when a Windows machine
1027 is parsing a path is steps through the components
1028 one at a time - if a component fails it expects
1029 ERRbadpath, not ERRbadfile.
1031 status = map_checkpath_error(req->flags2, status);
1032 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1034 * Windows returns different error codes if
1035 * the parent directory is valid but not the
1036 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
1037 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
1038 * if the path is invalid.
1040 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1041 ERRDOS, ERRbadpath);
1045 reply_nterror(req, status);
1048 TALLOC_FREE(smb_fname);
1049 END_PROFILE(SMBcheckpath);
1053 /****************************************************************************
1055 ****************************************************************************/
1057 void reply_getatr(struct smb_request *req)
1059 connection_struct *conn = req->conn;
1060 struct smb_filename *smb_fname = NULL;
1067 TALLOC_CTX *ctx = talloc_tos();
1069 START_PROFILE(SMBgetatr);
1071 p = (const char *)req->buf + 1;
1072 p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
1073 if (!NT_STATUS_IS_OK(status)) {
1074 reply_nterror(req, status);
1078 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1079 under WfWg - weird! */
1080 if (*fname == '\0') {
1081 mode = aHIDDEN | aDIR;
1082 if (!CAN_WRITE(conn)) {
1088 status = filename_convert(ctx,
1090 req->flags2 & FLAGS2_DFS_PATHNAMES,
1094 if (!NT_STATUS_IS_OK(status)) {
1095 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1096 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1097 ERRSRV, ERRbadpath);
1100 reply_nterror(req, status);
1103 if (!VALID_STAT(smb_fname->st) &&
1104 (SMB_VFS_STAT(conn, smb_fname) != 0)) {
1105 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",
1106 smb_fname_str_dbg(smb_fname),
1108 reply_unixerror(req, ERRDOS,ERRbadfile);
1112 mode = dos_mode(conn, fname, &smb_fname->st);
1113 size = smb_fname->st.st_ex_size;
1114 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1120 reply_outbuf(req, 10, 0);
1122 SSVAL(req->outbuf,smb_vwv0,mode);
1123 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1124 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1126 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1128 SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1130 if (Protocol >= PROTOCOL_NT1) {
1131 SSVAL(req->outbuf, smb_flg2,
1132 SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1135 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n",
1136 smb_fname_str_dbg(smb_fname), mode, (unsigned int)size));
1139 TALLOC_FREE(smb_fname);
1141 END_PROFILE(SMBgetatr);
1145 /****************************************************************************
1147 ****************************************************************************/
1149 void reply_setatr(struct smb_request *req)
1151 struct smb_file_time ft;
1152 connection_struct *conn = req->conn;
1153 struct smb_filename *smb_fname = NULL;
1159 TALLOC_CTX *ctx = talloc_tos();
1161 START_PROFILE(SMBsetatr);
1166 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1170 p = (const char *)req->buf + 1;
1171 p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
1172 if (!NT_STATUS_IS_OK(status)) {
1173 reply_nterror(req, status);
1177 status = filename_convert(ctx,
1179 req->flags2 & FLAGS2_DFS_PATHNAMES,
1183 if (!NT_STATUS_IS_OK(status)) {
1184 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1185 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1186 ERRSRV, ERRbadpath);
1189 reply_nterror(req, status);
1193 if (smb_fname->base_name[0] == '.' &&
1194 smb_fname->base_name[1] == '\0') {
1196 * Not sure here is the right place to catch this
1197 * condition. Might be moved to somewhere else later -- vl
1199 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1203 mode = SVAL(req->vwv+0, 0);
1204 mtime = srv_make_unix_date3(req->vwv+1);
1206 ft.mtime = convert_time_t_to_timespec(mtime);
1207 status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 reply_unixerror(req, ERRDOS, ERRnoaccess);
1213 if (mode != FILE_ATTRIBUTE_NORMAL) {
1214 if (VALID_STAT_OF_DIR(smb_fname->st))
1219 if (file_set_dosmode(conn, smb_fname, mode, NULL,
1221 reply_unixerror(req, ERRDOS, ERRnoaccess);
1226 reply_outbuf(req, 0, 0);
1228 DEBUG(3, ("setatr name=%s mode=%d\n", smb_fname_str_dbg(smb_fname),
1231 TALLOC_FREE(smb_fname);
1232 END_PROFILE(SMBsetatr);
1236 /****************************************************************************
1238 ****************************************************************************/
1240 void reply_dskattr(struct smb_request *req)
1242 connection_struct *conn = req->conn;
1243 uint64_t dfree,dsize,bsize;
1244 START_PROFILE(SMBdskattr);
1246 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
1247 reply_unixerror(req, ERRHRD, ERRgeneral);
1248 END_PROFILE(SMBdskattr);
1252 reply_outbuf(req, 5, 0);
1254 if (Protocol <= PROTOCOL_LANMAN2) {
1255 double total_space, free_space;
1256 /* we need to scale this to a number that DOS6 can handle. We
1257 use floating point so we can handle large drives on systems
1258 that don't have 64 bit integers
1260 we end up displaying a maximum of 2G to DOS systems
1262 total_space = dsize * (double)bsize;
1263 free_space = dfree * (double)bsize;
1265 dsize = (uint64_t)((total_space+63*512) / (64*512));
1266 dfree = (uint64_t)((free_space+63*512) / (64*512));
1268 if (dsize > 0xFFFF) dsize = 0xFFFF;
1269 if (dfree > 0xFFFF) dfree = 0xFFFF;
1271 SSVAL(req->outbuf,smb_vwv0,dsize);
1272 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1273 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1274 SSVAL(req->outbuf,smb_vwv3,dfree);
1276 SSVAL(req->outbuf,smb_vwv0,dsize);
1277 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1278 SSVAL(req->outbuf,smb_vwv2,512);
1279 SSVAL(req->outbuf,smb_vwv3,dfree);
1282 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1284 END_PROFILE(SMBdskattr);
1289 * Utility function to split the filename from the directory.
1291 static NTSTATUS split_fname_dir_mask(TALLOC_CTX *ctx, const char *fname_in,
1292 char **fname_dir_out,
1293 char **fname_mask_out)
1295 const char *p = NULL;
1296 char *fname_dir = NULL;
1297 char *fname_mask = NULL;
1299 p = strrchr_m(fname_in, '/');
1301 fname_dir = talloc_strdup(ctx, ".");
1302 fname_mask = talloc_strdup(ctx, fname_in);
1304 fname_dir = talloc_strndup(ctx, fname_in,
1305 PTR_DIFF(p, fname_in));
1306 fname_mask = talloc_strdup(ctx, p+1);
1309 if (!fname_dir || !fname_mask) {
1310 TALLOC_FREE(fname_dir);
1311 TALLOC_FREE(fname_mask);
1312 return NT_STATUS_NO_MEMORY;
1315 *fname_dir_out = fname_dir;
1316 *fname_mask_out = fname_mask;
1317 return NT_STATUS_OK;
1320 /****************************************************************************
1322 Can be called from SMBsearch, SMBffirst or SMBfunique.
1323 ****************************************************************************/
1325 void reply_search(struct smb_request *req)
1327 connection_struct *conn = req->conn;
1329 const char *mask = NULL;
1330 char *directory = NULL;
1334 struct timespec date;
1336 unsigned int numentries = 0;
1337 unsigned int maxentries = 0;
1338 bool finished = False;
1343 bool check_descend = False;
1344 bool expect_close = False;
1346 bool mask_contains_wcard = False;
1347 bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1348 TALLOC_CTX *ctx = talloc_tos();
1349 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1351 START_PROFILE(SMBsearch);
1354 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1355 END_PROFILE(SMBsearch);
1359 if (lp_posix_pathnames()) {
1360 reply_unknown_new(req, req->cmd);
1361 END_PROFILE(SMBsearch);
1365 /* If we were called as SMBffirst then we must expect close. */
1366 if(req->cmd == SMBffirst) {
1367 expect_close = True;
1370 reply_outbuf(req, 1, 3);
1371 maxentries = SVAL(req->vwv+0, 0);
1372 dirtype = SVAL(req->vwv+1, 0);
1373 p = (const char *)req->buf + 1;
1374 p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
1375 &nt_status, &mask_contains_wcard);
1376 if (!NT_STATUS_IS_OK(nt_status)) {
1377 reply_nterror(req, nt_status);
1378 END_PROFILE(SMBsearch);
1383 status_len = SVAL(p, 0);
1386 /* dirtype &= ~aDIR; */
1388 if (status_len == 0) {
1389 struct smb_filename *smb_fname = NULL;
1391 nt_status = resolve_dfspath_wcard(ctx, conn,
1392 req->flags2 & FLAGS2_DFS_PATHNAMES,
1395 &mask_contains_wcard);
1396 if (!NT_STATUS_IS_OK(nt_status)) {
1397 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1398 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1399 ERRSRV, ERRbadpath);
1400 END_PROFILE(SMBsearch);
1403 reply_nterror(req, nt_status);
1404 END_PROFILE(SMBsearch);
1408 nt_status = unix_convert(ctx, conn, path, &smb_fname,
1409 UCF_ALLOW_WCARD_LCOMP);
1410 if (!NT_STATUS_IS_OK(nt_status)) {
1411 reply_nterror(req, nt_status);
1412 END_PROFILE(SMBsearch);
1416 nt_status = get_full_smb_filename(ctx, smb_fname, &directory);
1417 TALLOC_FREE(smb_fname);
1418 if (!NT_STATUS_IS_OK(nt_status)) {
1419 reply_nterror(req, nt_status);
1420 END_PROFILE(SMBsearch);
1424 nt_status = check_name(conn, directory);
1425 if (!NT_STATUS_IS_OK(nt_status)) {
1426 reply_nterror(req, nt_status);
1427 END_PROFILE(SMBsearch);
1431 p = strrchr_m(directory,'/');
1432 if ((p != NULL) && (*directory != '/')) {
1434 directory = talloc_strndup(ctx, directory,
1435 PTR_DIFF(p, directory));
1438 directory = talloc_strdup(ctx,".");
1442 reply_nterror(req, NT_STATUS_NO_MEMORY);
1443 END_PROFILE(SMBsearch);
1447 memset((char *)status,'\0',21);
1448 SCVAL(status,0,(dirtype & 0x1F));
1450 nt_status = dptr_create(conn,
1456 mask_contains_wcard,
1459 if (!NT_STATUS_IS_OK(nt_status)) {
1460 reply_nterror(req, nt_status);
1461 END_PROFILE(SMBsearch);
1464 dptr_num = dptr_dnum(conn->dirptr);
1468 memcpy(status,p,21);
1469 status_dirtype = CVAL(status,0) & 0x1F;
1470 if (status_dirtype != (dirtype & 0x1F)) {
1471 dirtype = status_dirtype;
1474 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1475 if (!conn->dirptr) {
1478 string_set(&conn->dirpath,dptr_path(dptr_num));
1479 mask = dptr_wcard(dptr_num);
1484 * For a 'continue' search we have no string. So
1485 * check from the initial saved string.
1487 mask_contains_wcard = ms_has_wild(mask);
1488 dirtype = dptr_attr(dptr_num);
1491 DEBUG(4,("dptr_num is %d\n",dptr_num));
1493 /* Initialize per SMBsearch/SMBffirst/SMBfunique operation data */
1494 dptr_init_search_op(conn->dirptr);
1496 if ((dirtype&0x1F) == aVOLID) {
1497 char buf[DIR_STRUCT_SIZE];
1498 memcpy(buf,status,21);
1499 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1500 0,aVOLID,0,!allow_long_path_components)) {
1501 reply_nterror(req, NT_STATUS_NO_MEMORY);
1502 END_PROFILE(SMBsearch);
1505 dptr_fill(buf+12,dptr_num);
1506 if (dptr_zero(buf+12) && (status_len==0)) {
1511 if (message_push_blob(&req->outbuf,
1512 data_blob_const(buf, sizeof(buf)))
1514 reply_nterror(req, NT_STATUS_NO_MEMORY);
1515 END_PROFILE(SMBsearch);
1523 ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1526 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1527 conn->dirpath,lp_dontdescend(SNUM(conn))));
1528 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) {
1529 check_descend = True;
1532 for (i=numentries;(i<maxentries) && !finished;i++) {
1533 finished = !get_dir_entry(ctx,
1544 char buf[DIR_STRUCT_SIZE];
1545 memcpy(buf,status,21);
1546 if (!make_dir_struct(ctx,
1552 convert_timespec_to_time_t(date),
1553 !allow_long_path_components)) {
1554 reply_nterror(req, NT_STATUS_NO_MEMORY);
1555 END_PROFILE(SMBsearch);
1558 if (!dptr_fill(buf+12,dptr_num)) {
1561 if (message_push_blob(&req->outbuf,
1562 data_blob_const(buf, sizeof(buf)))
1564 reply_nterror(req, NT_STATUS_NO_MEMORY);
1565 END_PROFILE(SMBsearch);
1575 /* If we were called as SMBffirst with smb_search_id == NULL
1576 and no entries were found then return error and close dirptr
1579 if (numentries == 0) {
1580 dptr_close(&dptr_num);
1581 } else if(expect_close && status_len == 0) {
1582 /* Close the dptr - we know it's gone */
1583 dptr_close(&dptr_num);
1586 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1587 if(dptr_num >= 0 && req->cmd == SMBfunique) {
1588 dptr_close(&dptr_num);
1591 if ((numentries == 0) && !mask_contains_wcard) {
1592 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1593 END_PROFILE(SMBsearch);
1597 SSVAL(req->outbuf,smb_vwv0,numentries);
1598 SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1599 SCVAL(smb_buf(req->outbuf),0,5);
1600 SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1602 /* The replies here are never long name. */
1603 SSVAL(req->outbuf, smb_flg2,
1604 SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1605 if (!allow_long_path_components) {
1606 SSVAL(req->outbuf, smb_flg2,
1607 SVAL(req->outbuf, smb_flg2)
1608 & (~FLAGS2_LONG_PATH_COMPONENTS));
1611 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1612 SSVAL(req->outbuf, smb_flg2,
1613 (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1616 directory = dptr_path(dptr_num);
1619 DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1620 smb_fn_name(req->cmd),
1622 directory ? directory : "./",
1627 END_PROFILE(SMBsearch);
1631 /****************************************************************************
1632 Reply to a fclose (stop directory search).
1633 ****************************************************************************/
1635 void reply_fclose(struct smb_request *req)
1643 bool path_contains_wcard = False;
1644 TALLOC_CTX *ctx = talloc_tos();
1646 START_PROFILE(SMBfclose);
1648 if (lp_posix_pathnames()) {
1649 reply_unknown_new(req, req->cmd);
1650 END_PROFILE(SMBfclose);
1654 p = (const char *)req->buf + 1;
1655 p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
1656 &err, &path_contains_wcard);
1657 if (!NT_STATUS_IS_OK(err)) {
1658 reply_nterror(req, err);
1659 END_PROFILE(SMBfclose);
1663 status_len = SVAL(p,0);
1666 if (status_len == 0) {
1667 reply_doserror(req, ERRSRV, ERRsrverror);
1668 END_PROFILE(SMBfclose);
1672 memcpy(status,p,21);
1674 if(dptr_fetch(status+12,&dptr_num)) {
1675 /* Close the dptr - we know it's gone */
1676 dptr_close(&dptr_num);
1679 reply_outbuf(req, 1, 0);
1680 SSVAL(req->outbuf,smb_vwv0,0);
1682 DEBUG(3,("search close\n"));
1684 END_PROFILE(SMBfclose);
1688 /****************************************************************************
1690 ****************************************************************************/
1692 void reply_open(struct smb_request *req)
1694 connection_struct *conn = req->conn;
1695 struct smb_filename *smb_fname = NULL;
1707 uint32 create_disposition;
1708 uint32 create_options = 0;
1710 TALLOC_CTX *ctx = talloc_tos();
1712 START_PROFILE(SMBopen);
1715 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1719 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1720 deny_mode = SVAL(req->vwv+0, 0);
1721 dos_attr = SVAL(req->vwv+1, 0);
1723 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
1724 STR_TERMINATE, &status);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 reply_nterror(req, status);
1730 status = filename_convert(ctx,
1732 req->flags2 & FLAGS2_DFS_PATHNAMES,
1736 if (!NT_STATUS_IS_OK(status)) {
1737 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1738 reply_botherror(req,
1739 NT_STATUS_PATH_NOT_COVERED,
1740 ERRSRV, ERRbadpath);
1743 reply_nterror(req, status);
1747 if (!map_open_params_to_ntcreate(
1748 fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
1749 &share_mode, &create_disposition, &create_options)) {
1750 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1754 status = SMB_VFS_CREATE_FILE(
1757 0, /* root_dir_fid */
1758 smb_fname, /* fname */
1759 access_mask, /* access_mask */
1760 share_mode, /* share_access */
1761 create_disposition, /* create_disposition*/
1762 create_options, /* create_options */
1763 dos_attr, /* file_attributes */
1764 oplock_request, /* oplock_request */
1765 0, /* allocation_size */
1771 if (!NT_STATUS_IS_OK(status)) {
1772 if (open_was_deferred(req->mid)) {
1773 /* We have re-scheduled this call. */
1776 reply_openerror(req, status);
1780 size = smb_fname->st.st_ex_size;
1781 fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
1782 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1785 DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
1786 close_file(req, fsp, ERROR_CLOSE);
1787 reply_doserror(req, ERRDOS,ERRnoaccess);
1791 reply_outbuf(req, 7, 0);
1792 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1793 SSVAL(req->outbuf,smb_vwv1,fattr);
1794 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1795 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1797 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1799 SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1800 SSVAL(req->outbuf,smb_vwv6,deny_mode);
1802 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1803 SCVAL(req->outbuf,smb_flg,
1804 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1807 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1808 SCVAL(req->outbuf,smb_flg,
1809 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1812 TALLOC_FREE(smb_fname);
1813 END_PROFILE(SMBopen);
1817 /****************************************************************************
1818 Reply to an open and X.
1819 ****************************************************************************/
1821 void reply_open_and_X(struct smb_request *req)
1823 connection_struct *conn = req->conn;
1824 struct smb_filename *smb_fname = NULL;
1829 /* Breakout the oplock request bits so we can set the
1830 reply bits separately. */
1831 int ex_oplock_request;
1832 int core_oplock_request;
1835 int smb_sattr = SVAL(req->vwv+4, 0);
1836 uint32 smb_time = make_unix_date3(req->vwv+6);
1844 uint64_t allocation_size;
1845 ssize_t retval = -1;
1848 uint32 create_disposition;
1849 uint32 create_options = 0;
1850 TALLOC_CTX *ctx = talloc_tos();
1852 START_PROFILE(SMBopenX);
1854 if (req->wct < 15) {
1855 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1859 open_flags = SVAL(req->vwv+2, 0);
1860 deny_mode = SVAL(req->vwv+3, 0);
1861 smb_attr = SVAL(req->vwv+5, 0);
1862 ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1863 core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1864 oplock_request = ex_oplock_request | core_oplock_request;
1865 smb_ofun = SVAL(req->vwv+8, 0);
1866 allocation_size = (uint64_t)IVAL(req->vwv+9, 0);
1868 /* If it's an IPC, pass off the pipe handler. */
1870 if (lp_nt_pipe_support()) {
1871 reply_open_pipe_and_X(conn, req);
1873 reply_doserror(req, ERRSRV, ERRaccess);
1878 /* XXXX we need to handle passed times, sattr and flags */
1879 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
1880 STR_TERMINATE, &status);
1881 if (!NT_STATUS_IS_OK(status)) {
1882 reply_nterror(req, status);
1886 status = filename_convert(ctx,
1888 req->flags2 & FLAGS2_DFS_PATHNAMES,
1892 if (!NT_STATUS_IS_OK(status)) {
1893 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1894 reply_botherror(req,
1895 NT_STATUS_PATH_NOT_COVERED,
1896 ERRSRV, ERRbadpath);
1899 reply_nterror(req, status);
1903 if (!map_open_params_to_ntcreate(
1904 fname, deny_mode, smb_ofun, &access_mask,
1905 &share_mode, &create_disposition, &create_options)) {
1906 reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1910 status = SMB_VFS_CREATE_FILE(
1913 0, /* root_dir_fid */
1914 smb_fname, /* fname */
1915 access_mask, /* access_mask */
1916 share_mode, /* share_access */
1917 create_disposition, /* create_disposition*/
1918 create_options, /* create_options */
1919 smb_attr, /* file_attributes */
1920 oplock_request, /* oplock_request */
1921 0, /* allocation_size */
1925 &smb_action); /* pinfo */
1927 if (!NT_STATUS_IS_OK(status)) {
1928 if (open_was_deferred(req->mid)) {
1929 /* We have re-scheduled this call. */
1932 reply_openerror(req, status);
1936 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1937 if the file is truncated or created. */
1938 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1939 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1940 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1941 close_file(req, fsp, ERROR_CLOSE);
1942 reply_nterror(req, NT_STATUS_DISK_FULL);
1945 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1947 close_file(req, fsp, ERROR_CLOSE);
1948 reply_nterror(req, NT_STATUS_DISK_FULL);
1951 smb_fname->st.st_ex_size =
1952 SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st);
1955 fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
1956 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1958 close_file(req, fsp, ERROR_CLOSE);
1959 reply_doserror(req, ERRDOS, ERRnoaccess);
1963 /* If the caller set the extended oplock request bit
1964 and we granted one (by whatever means) - set the
1965 correct bit for extended oplock reply.
1968 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1969 smb_action |= EXTENDED_OPLOCK_GRANTED;
1972 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1973 smb_action |= EXTENDED_OPLOCK_GRANTED;
1976 /* If the caller set the core oplock request bit
1977 and we granted one (by whatever means) - set the
1978 correct bit for core oplock reply.
1981 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1982 reply_outbuf(req, 19, 0);
1984 reply_outbuf(req, 15, 0);
1987 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1988 SCVAL(req->outbuf, smb_flg,
1989 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1992 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1993 SCVAL(req->outbuf, smb_flg,
1994 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1997 SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
1998 SSVAL(req->outbuf,smb_vwv3,fattr);
1999 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
2000 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
2002 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
2004 SIVAL(req->outbuf,smb_vwv6,(uint32)smb_fname->st.st_ex_size);
2005 SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
2006 SSVAL(req->outbuf,smb_vwv11,smb_action);
2008 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
2009 SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
2014 TALLOC_FREE(smb_fname);
2015 END_PROFILE(SMBopenX);
2019 /****************************************************************************
2020 Reply to a SMBulogoffX.
2021 ****************************************************************************/
2023 void reply_ulogoffX(struct smb_request *req)
2025 struct smbd_server_connection *sconn = smbd_server_conn;
2028 START_PROFILE(SMBulogoffX);
2030 vuser = get_valid_user_struct(sconn, req->vuid);
2033 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
2037 /* in user level security we are supposed to close any files
2038 open by this user */
2039 if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
2040 file_close_user(req->vuid);
2043 invalidate_vuid(sconn, req->vuid);
2045 reply_outbuf(req, 2, 0);
2047 DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
2049 END_PROFILE(SMBulogoffX);
2053 /****************************************************************************
2054 Reply to a mknew or a create.
2055 ****************************************************************************/
2057 void reply_mknew(struct smb_request *req)
2059 connection_struct *conn = req->conn;
2060 struct smb_filename *smb_fname = NULL;
2063 struct smb_file_time ft;
2065 int oplock_request = 0;
2067 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
2068 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2069 uint32 create_disposition;
2070 uint32 create_options = 0;
2071 TALLOC_CTX *ctx = talloc_tos();
2073 START_PROFILE(SMBcreate);
2077 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2081 fattr = SVAL(req->vwv+0, 0);
2082 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2085 ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
2087 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1,
2088 STR_TERMINATE, &status);
2089 if (!NT_STATUS_IS_OK(status)) {
2090 reply_nterror(req, status);
2094 status = filename_convert(ctx,
2096 req->flags2 & FLAGS2_DFS_PATHNAMES,
2100 if (!NT_STATUS_IS_OK(status)) {
2101 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2102 reply_botherror(req,
2103 NT_STATUS_PATH_NOT_COVERED,
2104 ERRSRV, ERRbadpath);
2107 reply_nterror(req, status);
2111 if (fattr & aVOLID) {
2112 DEBUG(0,("Attempt to create file (%s) with volid set - "
2113 "please report this\n",
2114 smb_fname_str_dbg(smb_fname)));
2117 if(req->cmd == SMBmknew) {
2118 /* We should fail if file exists. */
2119 create_disposition = FILE_CREATE;
2121 /* Create if file doesn't exist, truncate if it does. */
2122 create_disposition = FILE_OVERWRITE_IF;
2125 status = SMB_VFS_CREATE_FILE(
2128 0, /* root_dir_fid */
2129 smb_fname, /* fname */
2130 access_mask, /* access_mask */
2131 share_mode, /* share_access */
2132 create_disposition, /* create_disposition*/
2133 create_options, /* create_options */
2134 fattr, /* file_attributes */
2135 oplock_request, /* oplock_request */
2136 0, /* allocation_size */
2142 if (!NT_STATUS_IS_OK(status)) {
2143 if (open_was_deferred(req->mid)) {
2144 /* We have re-scheduled this call. */
2147 reply_openerror(req, status);
2151 ft.atime = smb_fname->st.st_ex_atime; /* atime. */
2152 status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
2153 if (!NT_STATUS_IS_OK(status)) {
2154 END_PROFILE(SMBcreate);
2158 reply_outbuf(req, 1, 0);
2159 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2161 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2162 SCVAL(req->outbuf,smb_flg,
2163 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2166 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2167 SCVAL(req->outbuf,smb_flg,
2168 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2171 DEBUG(2, ("reply_mknew: file %s\n", smb_fname_str_dbg(smb_fname)));
2172 DEBUG(3, ("reply_mknew %s fd=%d dmode=0x%x\n",
2173 smb_fname_str_dbg(smb_fname), fsp->fh->fd,
2174 (unsigned int)fattr));
2177 TALLOC_FREE(smb_fname);
2178 END_PROFILE(SMBcreate);
2182 /****************************************************************************
2183 Reply to a create temporary file.
2184 ****************************************************************************/
2186 void reply_ctemp(struct smb_request *req)
2188 connection_struct *conn = req->conn;
2189 struct smb_filename *smb_fname = NULL;
2197 TALLOC_CTX *ctx = talloc_tos();
2199 START_PROFILE(SMBctemp);
2202 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2206 fattr = SVAL(req->vwv+0, 0);
2207 oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2209 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
2210 STR_TERMINATE, &status);
2211 if (!NT_STATUS_IS_OK(status)) {
2212 reply_nterror(req, status);
2216 fname = talloc_asprintf(ctx,
2220 fname = talloc_strdup(ctx, "TMXXXXXX");
2224 reply_nterror(req, NT_STATUS_NO_MEMORY);
2228 status = filename_convert(ctx, conn,
2229 req->flags2 & FLAGS2_DFS_PATHNAMES,
2233 if (!NT_STATUS_IS_OK(status)) {
2234 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2235 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2236 ERRSRV, ERRbadpath);
2239 reply_nterror(req, status);
2243 tmpfd = mkstemp(smb_fname->base_name);
2245 reply_unixerror(req, ERRDOS, ERRnoaccess);
2249 SMB_VFS_STAT(conn, smb_fname);
2251 /* We should fail if file does not exist. */
2252 status = SMB_VFS_CREATE_FILE(
2255 0, /* root_dir_fid */
2256 smb_fname, /* fname */
2257 FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */
2258 FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
2259 FILE_OPEN, /* create_disposition*/
2260 0, /* create_options */
2261 fattr, /* file_attributes */
2262 oplock_request, /* oplock_request */
2263 0, /* allocation_size */
2269 /* close fd from mkstemp() */
2272 if (!NT_STATUS_IS_OK(status)) {
2273 if (open_was_deferred(req->mid)) {
2274 /* We have re-scheduled this call. */
2277 reply_openerror(req, status);
2281 reply_outbuf(req, 1, 0);
2282 SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2284 /* the returned filename is relative to the directory */
2285 s = strrchr_m(fsp->fsp_name, '/');
2293 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2294 thing in the byte section. JRA */
2295 SSVALS(p, 0, -1); /* what is this? not in spec */
2297 if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2299 reply_nterror(req, NT_STATUS_NO_MEMORY);
2303 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2304 SCVAL(req->outbuf, smb_flg,
2305 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2308 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2309 SCVAL(req->outbuf, smb_flg,
2310 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2313 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
2314 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
2315 fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
2317 TALLOC_FREE(smb_fname);
2318 END_PROFILE(SMBctemp);
2322 /*******************************************************************
2323 Check if a user is allowed to rename a file.
2324 ********************************************************************/
2326 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2327 uint16 dirtype, SMB_STRUCT_STAT *pst)
2331 if (!CAN_WRITE(conn)) {
2332 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2335 fmode = dos_mode(conn, fsp->fsp_name, pst);
2336 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
2337 return NT_STATUS_NO_SUCH_FILE;
2340 if (S_ISDIR(pst->st_ex_mode)) {
2341 if (fsp->posix_open) {
2342 return NT_STATUS_OK;
2345 /* If no pathnames are open below this
2346 directory, allow the rename. */
2348 if (file_find_subpath(fsp)) {
2349 return NT_STATUS_ACCESS_DENIED;
2351 return NT_STATUS_OK;
2354 if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
2355 return NT_STATUS_OK;
2358 return NT_STATUS_ACCESS_DENIED;
2361 /*******************************************************************
2362 * unlink a file with all relevant access checks
2363 *******************************************************************/
2365 static NTSTATUS do_unlink(connection_struct *conn,
2366 struct smb_request *req,
2367 struct smb_filename *smb_fname,
2373 uint32 dirtype_orig = dirtype;
2376 DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
2378 if (!CAN_WRITE(conn)) {
2379 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2382 if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
2383 return map_nt_error_from_unix(errno);
2386 status = get_full_smb_filename(smb_fname, smb_fname, &fname);
2387 if (!NT_STATUS_IS_OK(status)) {
2390 fattr = dos_mode(conn, fname, &smb_fname->st);
2393 if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2394 dirtype = aDIR|aARCH|aRONLY;
2397 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
2399 return NT_STATUS_NO_SUCH_FILE;
2402 if (!dir_check_ftype(conn, fattr, dirtype)) {
2404 return NT_STATUS_FILE_IS_A_DIRECTORY;
2406 return NT_STATUS_NO_SUCH_FILE;
2409 if (dirtype_orig & 0x8000) {
2410 /* These will never be set for POSIX. */
2411 return NT_STATUS_NO_SUCH_FILE;
2415 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2416 return NT_STATUS_FILE_IS_A_DIRECTORY;
2419 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2420 return NT_STATUS_NO_SUCH_FILE;
2423 if (dirtype & 0xFF00) {
2424 /* These will never be set for POSIX. */
2425 return NT_STATUS_NO_SUCH_FILE;
2430 return NT_STATUS_NO_SUCH_FILE;
2433 /* Can't delete a directory. */
2435 return NT_STATUS_FILE_IS_A_DIRECTORY;
2440 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
2441 return NT_STATUS_OBJECT_NAME_INVALID;
2442 #endif /* JRATEST */
2444 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
2446 On a Windows share, a file with read-only dosmode can be opened with
2447 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
2448 fails with NT_STATUS_CANNOT_DELETE error.
2450 This semantic causes a problem that a user can not
2451 rename a file with read-only dosmode on a Samba share
2452 from a Windows command prompt (i.e. cmd.exe, but can rename
2453 from Windows Explorer).
2456 if (!lp_delete_readonly(SNUM(conn))) {
2457 if (fattr & aRONLY) {
2458 return NT_STATUS_CANNOT_DELETE;
2462 /* On open checks the open itself will check the share mode, so
2463 don't do it here as we'll get it wrong. */
2465 status = SMB_VFS_CREATE_FILE
2468 0, /* root_dir_fid */
2469 smb_fname, /* fname */
2470 DELETE_ACCESS, /* access_mask */
2471 FILE_SHARE_NONE, /* share_access */
2472 FILE_OPEN, /* create_disposition*/
2473 FILE_NON_DIRECTORY_FILE, /* create_options */
2474 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2475 0, /* oplock_request */
2476 0, /* allocation_size */
2482 if (!NT_STATUS_IS_OK(status)) {
2483 DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n",
2484 nt_errstr(status)));
2488 /* The set is across all open files on this dev/inode pair. */
2489 if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) {
2490 close_file(req, fsp, NORMAL_CLOSE);
2491 return NT_STATUS_ACCESS_DENIED;
2494 return close_file(req, fsp, NORMAL_CLOSE);
2497 /****************************************************************************
2498 The guts of the unlink command, split out so it may be called by the NT SMB
2500 ****************************************************************************/
2502 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2503 uint32 dirtype, const char *name_in, bool has_wild)
2505 struct smb_filename *smb_fname = NULL;
2506 char *fname_dir = NULL;
2507 char *fname_mask = NULL;
2509 NTSTATUS status = NT_STATUS_OK;
2510 TALLOC_CTX *ctx = talloc_tos();
2512 status = unix_convert(ctx, conn, name_in, &smb_fname,
2513 has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
2514 if (!NT_STATUS_IS_OK(status)) {
2518 /* Split up the directory from the filename/mask. */
2519 status = split_fname_dir_mask(ctx, smb_fname->base_name,
2520 &fname_dir, &fname_mask);
2521 if (!NT_STATUS_IS_OK(status)) {
2526 * We should only check the mangled cache
2527 * here if unix_convert failed. This means
2528 * that the path in 'mask' doesn't exist
2529 * on the file system and so we need to look
2530 * for a possible mangle. This patch from
2531 * Tine Smukavec <valentin.smukavec@hermes.si>.
2534 if (!VALID_STAT(smb_fname->st) &&
2535 mangle_is_mangled(fname_mask, conn->params)) {
2536 char *new_mask = NULL;
2537 mangle_lookup_name_from_8_3(ctx, fname_mask,
2538 &new_mask, conn->params);
2540 TALLOC_FREE(fname_mask);
2541 fname_mask = new_mask;
2548 * Only one file needs to be unlinked. Append the mask back
2549 * onto the directory.
2551 TALLOC_FREE(smb_fname->base_name);
2552 smb_fname->base_name = talloc_asprintf(smb_fname,
2556 if (!smb_fname->base_name) {
2557 status = NT_STATUS_NO_MEMORY;
2561 dirtype = FILE_ATTRIBUTE_NORMAL;
2564 status = check_name(conn, smb_fname->base_name);
2565 if (!NT_STATUS_IS_OK(status)) {
2569 status = do_unlink(conn, req, smb_fname, dirtype);
2570 if (!NT_STATUS_IS_OK(status)) {
2576 struct smb_Dir *dir_hnd = NULL;
2580 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2581 status = NT_STATUS_OBJECT_NAME_INVALID;
2585 if (strequal(fname_mask,"????????.???")) {
2586 TALLOC_FREE(fname_mask);
2587 fname_mask = talloc_strdup(ctx, "*");
2589 status = NT_STATUS_NO_MEMORY;
2594 status = check_name(conn, fname_dir);
2595 if (!NT_STATUS_IS_OK(status)) {
2599 dir_hnd = OpenDir(talloc_tos(), conn, fname_dir, fname_mask,
2601 if (dir_hnd == NULL) {
2602 status = map_nt_error_from_unix(errno);
2606 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2607 the pattern matches against the long name, otherwise the short name
2608 We don't implement this yet XXXX
2611 status = NT_STATUS_NO_SUCH_FILE;
2613 while ((dname = ReadDirName(dir_hnd, &offset,
2615 if (!is_visible_file(conn, fname_dir, dname,
2616 &smb_fname->st, true)) {
2620 /* Quick check for "." and ".." */
2621 if (ISDOT(dname) || ISDOTDOT(dname)) {
2625 if(!mask_match(dname, fname_mask,
2626 conn->case_sensitive)) {
2630 TALLOC_FREE(smb_fname->base_name);
2631 smb_fname->base_name =
2632 talloc_asprintf(smb_fname, "%s/%s",
2635 if (!smb_fname->base_name) {
2636 TALLOC_FREE(dir_hnd);
2637 status = NT_STATUS_NO_MEMORY;
2641 status = check_name(conn, smb_fname->base_name);
2642 if (!NT_STATUS_IS_OK(status)) {
2643 TALLOC_FREE(dir_hnd);
2647 status = do_unlink(conn, req, smb_fname, dirtype);
2648 if (!NT_STATUS_IS_OK(status)) {
2653 DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2654 smb_fname->base_name));
2656 TALLOC_FREE(dir_hnd);
2659 if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
2660 status = map_nt_error_from_unix(errno);
2664 TALLOC_FREE(smb_fname);
2665 TALLOC_FREE(fname_dir);
2666 TALLOC_FREE(fname_mask);
2670 /****************************************************************************
2672 ****************************************************************************/
2674 void reply_unlink(struct smb_request *req)
2676 connection_struct *conn = req->conn;
2680 bool path_contains_wcard = False;
2681 TALLOC_CTX *ctx = talloc_tos();
2683 START_PROFILE(SMBunlink);
2686 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2687 END_PROFILE(SMBunlink);
2691 dirtype = SVAL(req->vwv+0, 0);
2693 srvstr_get_path_req_wcard(ctx, req, &name, (const char *)req->buf + 1,
2694 STR_TERMINATE, &status,
2695 &path_contains_wcard);
2696 if (!NT_STATUS_IS_OK(status)) {
2697 reply_nterror(req, status);
2698 END_PROFILE(SMBunlink);
2702 status = resolve_dfspath_wcard(ctx, conn,
2703 req->flags2 & FLAGS2_DFS_PATHNAMES,
2706 &path_contains_wcard);
2707 if (!NT_STATUS_IS_OK(status)) {
2708 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2709 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2710 ERRSRV, ERRbadpath);
2711 END_PROFILE(SMBunlink);
2714 reply_nterror(req, status);
2715 END_PROFILE(SMBunlink);
2719 DEBUG(3,("reply_unlink : %s\n",name));
2721 status = unlink_internals(conn, req, dirtype, name,
2722 path_contains_wcard);
2723 if (!NT_STATUS_IS_OK(status)) {
2724 if (open_was_deferred(req->mid)) {
2725 /* We have re-scheduled this call. */
2726 END_PROFILE(SMBunlink);
2729 reply_nterror(req, status);
2730 END_PROFILE(SMBunlink);
2734 reply_outbuf(req, 0, 0);
2735 END_PROFILE(SMBunlink);
2740 /****************************************************************************
2742 ****************************************************************************/
2744 static void fail_readraw(void)
2746 const char *errstr = talloc_asprintf(talloc_tos(),
2747 "FAIL ! reply_readbraw: socket write fail (%s)",
2752 exit_server_cleanly(errstr);
2755 /****************************************************************************
2756 Fake (read/write) sendfile. Returns -1 on read or write fail.
2757 ****************************************************************************/
2759 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
2763 size_t tosend = nread;
2770 bufsize = MIN(nread, 65536);
2772 if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2776 while (tosend > 0) {
2780 if (tosend > bufsize) {
2785 ret = read_file(fsp,buf,startpos,cur_read);
2791 /* If we had a short read, fill with zeros. */
2792 if (ret < cur_read) {
2793 memset(buf + ret, '\0', cur_read - ret);
2796 if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
2801 startpos += cur_read;
2805 return (ssize_t)nread;
2808 #if defined(WITH_SENDFILE)
2809 /****************************************************************************
2810 Deal with the case of sendfile reading less bytes from the file than
2811 requested. Fill with zeros (all we can do).
2812 ****************************************************************************/
2814 static void sendfile_short_send(files_struct *fsp,
2819 #define SHORT_SEND_BUFSIZE 1024
2820 if (nread < headersize) {
2821 DEBUG(0,("sendfile_short_send: sendfile failed to send "
2822 "header for file %s (%s). Terminating\n",
2823 fsp->fsp_name, strerror(errno) ));
2824 exit_server_cleanly("sendfile_short_send failed");
2827 nread -= headersize;
2829 if (nread < smb_maxcnt) {
2830 char *buf = SMB_CALLOC_ARRAY(char, SHORT_SEND_BUFSIZE);
2832 exit_server_cleanly("sendfile_short_send: "
2836 DEBUG(0,("sendfile_short_send: filling truncated file %s "
2837 "with zeros !\n", fsp->fsp_name));
2839 while (nread < smb_maxcnt) {
2841 * We asked for the real file size and told sendfile
2842 * to not go beyond the end of the file. But it can
2843 * happen that in between our fstat call and the
2844 * sendfile call the file was truncated. This is very
2845 * bad because we have already announced the larger
2846 * number of bytes to the client.
2848 * The best we can do now is to send 0-bytes, just as
2849 * a read from a hole in a sparse file would do.
2851 * This should happen rarely enough that I don't care
2852 * about efficiency here :-)
2856 to_write = MIN(SHORT_SEND_BUFSIZE, smb_maxcnt - nread);
2857 if (write_data(smbd_server_fd(), buf, to_write) != to_write) {
2858 exit_server_cleanly("sendfile_short_send: "
2859 "write_data failed");
2866 #endif /* defined WITH_SENDFILE */
2868 /****************************************************************************
2869 Return a readbraw error (4 bytes of zero).
2870 ****************************************************************************/
2872 static void reply_readbraw_error(void)
2876 if (write_data(smbd_server_fd(),header,4) != 4) {
2881 /****************************************************************************
2882 Use sendfile in readbraw.
2883 ****************************************************************************/
2885 static void send_file_readbraw(connection_struct *conn,
2886 struct smb_request *req,
2892 char *outbuf = NULL;
2895 #if defined(WITH_SENDFILE)
2897 * We can only use sendfile on a non-chained packet
2898 * but we can use on a non-oplocked file. tridge proved this
2899 * on a train in Germany :-). JRA.
2900 * reply_readbraw has already checked the length.
2903 if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
2904 (fsp->wcp == NULL) &&
2905 lp_use_sendfile(SNUM(conn), smbd_server_conn->smb1.signing_state) ) {
2906 ssize_t sendfile_read = -1;
2908 DATA_BLOB header_blob;
2910 _smb_setlen(header,nread);
2911 header_blob = data_blob_const(header, 4);
2913 if ((sendfile_read = SMB_VFS_SENDFILE(smbd_server_fd(), fsp,
2914 &header_blob, startpos, nread)) == -1) {
2915 /* Returning ENOSYS means no data at all was sent.
2916 * Do this as a normal read. */
2917 if (errno == ENOSYS) {
2918 goto normal_readbraw;
2922 * Special hack for broken Linux with no working sendfile. If we
2923 * return EINTR we sent the header but not the rest of the data.
2924 * Fake this up by doing read/write calls.
2926 if (errno == EINTR) {
2927 /* Ensure we don't do this again. */
2928 set_use_sendfile(SNUM(conn), False);
2929 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2931 if (fake_sendfile(fsp, startpos, nread) == -1) {
2932 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2933 fsp->fsp_name, strerror(errno) ));
2934 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2939 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2940 fsp->fsp_name, strerror(errno) ));
2941 exit_server_cleanly("send_file_readbraw sendfile failed");
2942 } else if (sendfile_read == 0) {
2944 * Some sendfile implementations return 0 to indicate
2945 * that there was a short read, but nothing was
2946 * actually written to the socket. In this case,
2947 * fallback to the normal read path so the header gets
2948 * the correct byte count.
2950 DEBUG(3, ("send_file_readbraw: sendfile sent zero "
2951 "bytes falling back to the normal read: "
2952 "%s\n", fsp->fsp_name));
2953 goto normal_readbraw;
2956 /* Deal with possible short send. */
2957 if (sendfile_read != 4+nread) {
2958 sendfile_short_send(fsp, sendfile_read, 4, nread);
2966 outbuf = TALLOC_ARRAY(NULL, char, nread+4);
2968 DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
2969 (unsigned)(nread+4)));
2970 reply_readbraw_error();
2975 ret = read_file(fsp,outbuf+4,startpos,nread);
2976 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2985 _smb_setlen(outbuf,ret);
2986 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2989 TALLOC_FREE(outbuf);
2992 /****************************************************************************
2993 Reply to a readbraw (core+ protocol).
2994 ****************************************************************************/
2996 void reply_readbraw(struct smb_request *req)
2998 connection_struct *conn = req->conn;
2999 ssize_t maxcount,mincount;
3003 struct lock_struct lock;
3007 START_PROFILE(SMBreadbraw);
3009 if (srv_is_signing_active(smbd_server_conn) ||
3010 is_encrypted_packet(req->inbuf)) {
3011 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
3012 "raw reads/writes are disallowed.");
3016 reply_readbraw_error();
3017 END_PROFILE(SMBreadbraw);
3022 * Special check if an oplock break has been issued
3023 * and the readraw request croses on the wire, we must
3024 * return a zero length response here.
3027 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
3030 * We have to do a check_fsp by hand here, as
3031 * we must always return 4 zero bytes on error,
3035 if (!fsp || !conn || conn != fsp->conn ||
3036 req->vuid != fsp->vuid ||
3037 fsp->is_directory || fsp->fh->fd == -1) {
3039 * fsp could be NULL here so use the value from the packet. JRA.
3041 DEBUG(3,("reply_readbraw: fnum %d not valid "
3043 (int)SVAL(req->vwv+0, 0)));
3044 reply_readbraw_error();
3045 END_PROFILE(SMBreadbraw);
3049 /* Do a "by hand" version of CHECK_READ. */
3050 if (!(fsp->can_read ||
3051 ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
3052 (fsp->access_mask & FILE_EXECUTE)))) {
3053 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
3054 (int)SVAL(req->vwv+0, 0)));
3055 reply_readbraw_error();
3056 END_PROFILE(SMBreadbraw);
3060 flush_write_cache(fsp, READRAW_FLUSH);
3062 startpos = IVAL_TO_SMB_OFF_T(req->vwv+1, 0);
3063 if(req->wct == 10) {
3065 * This is a large offset (64 bit) read.
3067 #ifdef LARGE_SMB_OFF_T
3069 startpos |= (((SMB_OFF_T)IVAL(req->vwv+8, 0)) << 32);
3071 #else /* !LARGE_SMB_OFF_T */
3074 * Ensure we haven't been sent a >32 bit offset.
3077 if(IVAL(req->vwv+8, 0) != 0) {
3078 DEBUG(0,("reply_readbraw: large offset "
3079 "(%x << 32) used and we don't support "
3080 "64 bit offsets.\n",
3081 (unsigned int)IVAL(req->vwv+8, 0) ));
3082 reply_readbraw_error();
3083 END_PROFILE(SMBreadbraw);
3087 #endif /* LARGE_SMB_OFF_T */
3090 DEBUG(0,("reply_readbraw: negative 64 bit "
3091 "readraw offset (%.0f) !\n",
3092 (double)startpos ));
3093 reply_readbraw_error();
3094 END_PROFILE(SMBreadbraw);
3099 maxcount = (SVAL(req->vwv+3, 0) & 0xFFFF);
3100 mincount = (SVAL(req->vwv+4, 0) & 0xFFFF);
3102 /* ensure we don't overrun the packet size */
3103 maxcount = MIN(65535,maxcount);
3105 init_strict_lock_struct(fsp, (uint32)req->smbpid,
3106 (uint64_t)startpos, (uint64_t)maxcount, READ_LOCK,
3109 if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
3110 reply_readbraw_error();
3111 END_PROFILE(SMBreadbraw);
3115 if (SMB_VFS_FSTAT(fsp, &st) == 0) {
3116 size = st.st_ex_size;
3119 if (startpos >= size) {
3122 nread = MIN(maxcount,(size - startpos));
3125 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
3126 if (nread < mincount)
3130 DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
3131 "min=%lu nread=%lu\n",
3132 fsp->fnum, (double)startpos,
3133 (unsigned long)maxcount,
3134 (unsigned long)mincount,
3135 (unsigned long)nread ) );
3137 send_file_readbraw(conn, req, fsp, startpos, nread, mincount);
3139 DEBUG(5,("reply_readbraw finished\n"));
3141 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
3143 END_PROFILE(SMBreadbraw);
3148 #define DBGC_CLASS DBGC_LOCKING
3150 /****************************************************************************
3151 Reply to a lockread (core+ protocol).
3152 ****************************************************************************/
3154 void reply_lockread(struct smb_request *req)
3156 connection_struct *conn = req->conn;
3163 struct byte_range_lock *br_lck = NULL;
3165 struct smbd_server_connection *sconn = smbd_server_conn;
3167 START_PROFILE(SMBlockread);
3170 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3171 END_PROFILE(SMBlockread);
3175 fsp = file_fsp(req, SVAL(req->vwv+0, 0));
3177 if (!check_fsp(conn, req, fsp)) {
3178 END_PROFILE(SMBlockread);