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.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 This file handles most of the reply_ calls that the server
23 makes to handle specific protocols
28 /* look in server.c for some explanation of these variables */
29 extern enum protocol_types Protocol;
32 unsigned int smb_echo_count = 0;
33 extern uint32 global_client_caps;
35 extern struct current_user current_user;
36 extern BOOL global_encrypted_passwords_negotiated;
38 /****************************************************************************
39 Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
40 path or anything including wildcards.
41 We're assuming here that '/' is not the second byte in any multibyte char
42 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
44 ****************************************************************************/
46 /* Custom version for processing POSIX paths. */
47 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
49 static NTSTATUS check_path_syntax_internal(char *path,
51 BOOL *p_last_component_contains_wcard)
55 NTSTATUS ret = NT_STATUS_OK;
56 BOOL start_of_name_component = True;
58 *p_last_component_contains_wcard = False;
61 if (IS_PATH_SEP(*s,posix_path)) {
63 * Safe to assume is not the second part of a mb char
64 * as this is handled below.
66 /* Eat multiple '/' or '\\' */
67 while (IS_PATH_SEP(*s,posix_path)) {
70 if ((d != path) && (*s != '\0')) {
71 /* We only care about non-leading or trailing '/' or '\\' */
75 start_of_name_component = True;
77 *p_last_component_contains_wcard = False;
81 if (start_of_name_component) {
82 if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
83 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
86 * No mb char starts with '.' so we're safe checking the directory separator here.
89 /* If we just added a '/' - delete it */
90 if ((d > path) && (*(d-1) == '/')) {
95 /* Are we at the start ? Can't go back further if so. */
97 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
100 /* Go back one level... */
101 /* We know this is safe as '/' cannot be part of a mb sequence. */
102 /* NOTE - if this assumption is invalid we are not in good shape... */
103 /* Decrement d first as d points to the *next* char to write into. */
104 for (d--; d > path; d--) {
108 s += 2; /* Else go past the .. */
109 /* We're still at the start of a name component, just the previous one. */
112 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
125 return NT_STATUS_OBJECT_NAME_INVALID;
133 *p_last_component_contains_wcard = True;
142 /* Get the size of the next MB character. */
143 next_codepoint(s,&siz);
161 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
163 return NT_STATUS_INVALID_PARAMETER;
166 start_of_name_component = False;
173 /****************************************************************************
174 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
175 No wildcards allowed.
176 ****************************************************************************/
178 NTSTATUS check_path_syntax(char *path)
181 return check_path_syntax_internal(path, False, &ignore);
184 /****************************************************************************
185 Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
186 Wildcards allowed - p_contains_wcard returns true if the last component contained
188 ****************************************************************************/
190 NTSTATUS check_path_syntax_wcard(char *path, BOOL *p_contains_wcard)
192 return check_path_syntax_internal(path, False, p_contains_wcard);
195 /****************************************************************************
196 Check the path for a POSIX client.
197 We're assuming here that '/' is not the second byte in any multibyte char
198 set (a safe assumption).
199 ****************************************************************************/
201 NTSTATUS check_path_syntax_posix(char *path)
204 return check_path_syntax_internal(path, True, &ignore);
207 /****************************************************************************
208 Pull a string and check the path allowing a wilcard - provide for error return.
209 ****************************************************************************/
211 size_t srvstr_get_path_wcard(char *inbuf, uint16 smb_flags2, char *dest,
212 const char *src, size_t dest_len, size_t src_len,
213 int flags, NTSTATUS *err, BOOL *contains_wcard)
217 SMB_ASSERT(dest_len == sizeof(pstring));
221 ret = srvstr_pull_buf(inbuf, smb_flags2, dest, src,
224 ret = srvstr_pull(inbuf, smb_flags2, dest, src,
225 dest_len, src_len, flags);
228 *contains_wcard = False;
230 if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
232 * For a DFS path the function parse_dfs_path()
233 * will do the path processing, just make a copy.
239 if (lp_posix_pathnames()) {
240 *err = check_path_syntax_posix(dest);
242 *err = check_path_syntax_wcard(dest, contains_wcard);
248 /****************************************************************************
249 Pull a string and check the path - provide for error return.
250 ****************************************************************************/
252 size_t srvstr_get_path(char *inbuf, uint16 smb_flags2, char *dest,
253 const char *src, size_t dest_len, size_t src_len,
254 int flags, NTSTATUS *err)
258 SMB_ASSERT(dest_len == sizeof(pstring));
262 ret = srvstr_pull_buf(inbuf, smb_flags2, dest, src,
265 ret = srvstr_pull(inbuf, smb_flags2, dest, src,
266 dest_len, src_len, flags);
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(dest);
281 *err = check_path_syntax(dest);
287 /****************************************************************************
288 Reply to a special message.
289 ****************************************************************************/
291 int reply_special(char *inbuf,char *outbuf)
294 int msg_type = CVAL(inbuf,0);
295 int msg_flags = CVAL(inbuf,1);
299 static BOOL already_got_session = False;
303 memset(outbuf,'\0',smb_size);
305 smb_setlen(inbuf,outbuf,0);
308 case 0x81: /* session request */
310 if (already_got_session) {
311 exit_server_cleanly("multiple session request not permitted");
314 SCVAL(outbuf,0,0x82);
316 if (name_len(inbuf+4) > 50 ||
317 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
318 DEBUG(0,("Invalid name length in session request\n"));
321 name_extract(inbuf,4,name1);
322 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
323 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
326 set_local_machine_name(name1, True);
327 set_remote_machine_name(name2, True);
329 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
330 get_local_machine_name(), get_remote_machine_name(),
333 if (name_type == 'R') {
334 /* We are being asked for a pathworks session ---
336 SCVAL(outbuf, 0,0x83);
340 /* only add the client's machine name to the list
341 of possibly valid usernames if we are operating
342 in share mode security */
343 if (lp_security() == SEC_SHARE) {
344 add_session_user(get_remote_machine_name());
347 reload_services(True);
350 already_got_session = True;
353 case 0x89: /* session keepalive request
354 (some old clients produce this?) */
355 SCVAL(outbuf,0,SMBkeepalive);
359 case 0x82: /* positive session response */
360 case 0x83: /* negative session response */
361 case 0x84: /* retarget session response */
362 DEBUG(0,("Unexpected session response\n"));
365 case SMBkeepalive: /* session keepalive */
370 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
371 msg_type, msg_flags));
376 /****************************************************************************
378 conn POINTER CAN BE NULL HERE !
379 ****************************************************************************/
381 int reply_tcon(connection_struct *conn,
382 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
389 uint16 vuid = SVAL(inbuf,smb_uid);
393 DATA_BLOB password_blob;
395 START_PROFILE(SMBtcon);
397 *service_buf = *password = *dev = 0;
399 p = smb_buf(inbuf)+1;
400 p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), service_buf, p,
401 sizeof(service_buf), STR_TERMINATE) + 1;
402 pwlen = srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), password, p,
403 sizeof(password), STR_TERMINATE) + 1;
405 p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), dev, p, sizeof(dev),
408 p = strrchr_m(service_buf,'\\');
412 service = service_buf;
415 password_blob = data_blob(password, pwlen+1);
417 conn = make_connection(service,password_blob,dev,vuid,&nt_status);
419 data_blob_clear_free(&password_blob);
422 END_PROFILE(SMBtcon);
423 return ERROR_NT(nt_status);
426 outsize = set_message(inbuf,outbuf,2,0,True);
427 SSVAL(outbuf,smb_vwv0,max_recv);
428 SSVAL(outbuf,smb_vwv1,conn->cnum);
429 SSVAL(outbuf,smb_tid,conn->cnum);
431 DEBUG(3,("tcon service=%s cnum=%d\n",
432 service, conn->cnum));
434 END_PROFILE(SMBtcon);
438 /****************************************************************************
439 Reply to a tcon and X.
440 conn POINTER CAN BE NULL HERE !
441 ****************************************************************************/
443 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
448 /* what the cleint thinks the device is */
449 fstring client_devicetype;
450 /* what the server tells the client the share represents */
451 const char *server_devicetype;
453 uint16 vuid = SVAL(inbuf,smb_uid);
454 int passlen = SVAL(inbuf,smb_vwv3);
457 uint16 tcon_flags = SVAL(inbuf,smb_vwv2);
459 START_PROFILE(SMBtconX);
461 *service = *client_devicetype = 0;
463 /* we might have to close an old one */
464 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
465 close_cnum(conn,vuid);
468 if (passlen > MAX_PASS_LEN) {
469 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
472 if (global_encrypted_passwords_negotiated) {
473 password = data_blob(smb_buf(inbuf),passlen);
474 if (lp_security() == SEC_SHARE) {
476 * Security = share always has a pad byte
477 * after the password.
479 p = smb_buf(inbuf) + passlen + 1;
481 p = smb_buf(inbuf) + passlen;
484 password = data_blob(smb_buf(inbuf),passlen+1);
485 /* Ensure correct termination */
486 password.data[passlen]=0;
487 p = smb_buf(inbuf) + passlen + 1;
490 p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), path, p,
491 sizeof(path), STR_TERMINATE);
494 * the service name can be either: \\server\share
495 * or share directly like on the DELL PowerVault 705
498 q = strchr_m(path+2,'\\');
500 END_PROFILE(SMBtconX);
501 return(ERROR_DOS(ERRDOS,ERRnosuchshare));
503 fstrcpy(service,q+1);
506 fstrcpy(service,path);
508 p += srvstr_pull(inbuf, SVAL(inbuf, smb_flg2), client_devicetype, p,
509 sizeof(client_devicetype), 6, STR_ASCII);
511 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
513 conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
515 data_blob_clear_free(&password);
518 END_PROFILE(SMBtconX);
519 return ERROR_NT(nt_status);
523 server_devicetype = "IPC";
524 else if ( IS_PRINT(conn) )
525 server_devicetype = "LPT1:";
527 server_devicetype = "A:";
529 if (Protocol < PROTOCOL_NT1) {
530 set_message(inbuf,outbuf,2,0,True);
532 p += srvstr_push(outbuf, p, server_devicetype, -1,
533 STR_TERMINATE|STR_ASCII);
534 set_message_end(inbuf,outbuf,p);
536 /* NT sets the fstype of IPC$ to the null string */
537 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
539 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
540 /* Return permissions. */
544 set_message(inbuf,outbuf,7,0,True);
547 perm1 = FILE_ALL_ACCESS;
548 perm2 = FILE_ALL_ACCESS;
550 perm1 = CAN_WRITE(conn) ?
555 SIVAL(outbuf, smb_vwv3, perm1);
556 SIVAL(outbuf, smb_vwv5, perm2);
558 set_message(inbuf,outbuf,3,0,True);
562 p += srvstr_push(outbuf, p, server_devicetype, -1,
563 STR_TERMINATE|STR_ASCII);
564 p += srvstr_push(outbuf, p, fstype, -1,
567 set_message_end(inbuf,outbuf,p);
569 /* what does setting this bit do? It is set by NT4 and
570 may affect the ability to autorun mounted cdroms */
571 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
572 (lp_csc_policy(SNUM(conn)) << 2));
574 init_dfsroot(conn, inbuf, outbuf);
578 DEBUG(3,("tconX service=%s \n",
581 /* set the incoming and outgoing tid to the just created one */
582 SSVAL(inbuf,smb_tid,conn->cnum);
583 SSVAL(outbuf,smb_tid,conn->cnum);
585 END_PROFILE(SMBtconX);
586 return chain_reply(inbuf,outbuf,length,bufsize);
589 /****************************************************************************
590 Reply to an unknown type.
591 ****************************************************************************/
593 int reply_unknown(char *inbuf,char *outbuf)
596 type = CVAL(inbuf,smb_com);
598 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
599 smb_fn_name(type), type, type));
601 return(ERROR_DOS(ERRSRV,ERRunknownsmb));
604 /****************************************************************************
606 conn POINTER CAN BE NULL HERE !
607 ****************************************************************************/
609 int reply_ioctl(connection_struct *conn,
610 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
612 uint16 device = SVAL(inbuf,smb_vwv1);
613 uint16 function = SVAL(inbuf,smb_vwv2);
614 uint32 ioctl_code = (device << 16) + function;
615 int replysize, outsize;
617 START_PROFILE(SMBioctl);
619 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
621 switch (ioctl_code) {
622 case IOCTL_QUERY_JOB_INFO:
626 END_PROFILE(SMBioctl);
627 return(ERROR_DOS(ERRSRV,ERRnosupport));
630 outsize = set_message(inbuf,outbuf,8,replysize+1,True);
631 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
632 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
633 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
634 p = smb_buf(outbuf) + 1; /* Allow for alignment */
636 switch (ioctl_code) {
637 case IOCTL_QUERY_JOB_INFO:
639 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
641 END_PROFILE(SMBioctl);
642 return(UNIXERROR(ERRDOS,ERRbadfid));
644 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
645 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
647 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
653 END_PROFILE(SMBioctl);
657 /****************************************************************************
658 Strange checkpath NTSTATUS mapping.
659 ****************************************************************************/
661 static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
663 /* Strange DOS error code semantics only for checkpath... */
664 if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
665 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
666 /* We need to map to ERRbadpath */
667 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
673 /****************************************************************************
674 Reply to a checkpath.
675 ****************************************************************************/
677 int reply_checkpath(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
681 SMB_STRUCT_STAT sbuf;
684 START_PROFILE(SMBcheckpath);
686 srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), name, smb_buf(inbuf) + 1,
687 sizeof(name), 0, STR_TERMINATE, &status);
688 if (!NT_STATUS_IS_OK(status)) {
689 END_PROFILE(SMBcheckpath);
690 status = map_checkpath_error(inbuf, status);
691 return ERROR_NT(status);
694 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name);
695 if (!NT_STATUS_IS_OK(status)) {
696 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
697 END_PROFILE(SMBcheckpath);
698 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
703 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(inbuf,smb_vwv0)));
705 status = unix_convert(conn, name, False, NULL, &sbuf);
706 if (!NT_STATUS_IS_OK(status)) {
710 status = check_name(conn, name);
711 if (!NT_STATUS_IS_OK(status)) {
712 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status)));
716 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
717 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
718 status = map_nt_error_from_unix(errno);
722 if (!S_ISDIR(sbuf.st_mode)) {
723 END_PROFILE(SMBcheckpath);
724 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath);
727 outsize = set_message(inbuf,outbuf,0,0,False);
729 END_PROFILE(SMBcheckpath);
734 END_PROFILE(SMBcheckpath);
736 /* We special case this - as when a Windows machine
737 is parsing a path is steps through the components
738 one at a time - if a component fails it expects
739 ERRbadpath, not ERRbadfile.
741 status = map_checkpath_error(inbuf, status);
742 if(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
744 * Windows returns different error codes if
745 * the parent directory is valid but not the
746 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
747 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
748 * if the path is invalid.
750 return ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpath);
753 return ERROR_NT(status);
756 /****************************************************************************
758 ****************************************************************************/
760 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
764 SMB_STRUCT_STAT sbuf;
771 START_PROFILE(SMBgetatr);
773 p = smb_buf(inbuf) + 1;
774 p += srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, p,
775 sizeof(fname), 0, STR_TERMINATE, &status);
776 if (!NT_STATUS_IS_OK(status)) {
777 END_PROFILE(SMBgetatr);
778 return ERROR_NT(status);
781 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
782 if (!NT_STATUS_IS_OK(status)) {
783 END_PROFILE(SMBgetatr);
784 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
785 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
787 return ERROR_NT(status);
790 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
791 under WfWg - weird! */
792 if (*fname == '\0') {
793 mode = aHIDDEN | aDIR;
794 if (!CAN_WRITE(conn)) {
800 status = unix_convert(conn, fname, False, NULL,&sbuf);
801 if (!NT_STATUS_IS_OK(status)) {
802 END_PROFILE(SMBgetatr);
803 return ERROR_NT(status);
805 status = check_name(conn, fname);
806 if (!NT_STATUS_IS_OK(status)) {
807 DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
808 END_PROFILE(SMBgetatr);
809 return ERROR_NT(status);
811 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
812 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
813 return UNIXERROR(ERRDOS,ERRbadfile);
816 mode = dos_mode(conn,fname,&sbuf);
818 mtime = sbuf.st_mtime;
824 outsize = set_message(inbuf,outbuf,10,0,True);
826 SSVAL(outbuf,smb_vwv0,mode);
827 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
828 srv_put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
830 srv_put_dos_date3(outbuf,smb_vwv1,mtime);
832 SIVAL(outbuf,smb_vwv3,(uint32)size);
834 if (Protocol >= PROTOCOL_NT1) {
835 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
838 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
840 END_PROFILE(SMBgetatr);
844 /****************************************************************************
846 ****************************************************************************/
848 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
854 SMB_STRUCT_STAT sbuf;
858 START_PROFILE(SMBsetatr);
860 p = smb_buf(inbuf) + 1;
861 p += srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, p,
862 sizeof(fname), 0, STR_TERMINATE, &status);
863 if (!NT_STATUS_IS_OK(status)) {
864 END_PROFILE(SMBsetatr);
865 return ERROR_NT(status);
868 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
869 if (!NT_STATUS_IS_OK(status)) {
870 END_PROFILE(SMBsetatr);
871 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
872 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
874 return ERROR_NT(status);
877 status = unix_convert(conn, fname, False, NULL, &sbuf);
878 if (!NT_STATUS_IS_OK(status)) {
879 END_PROFILE(SMBsetatr);
880 return ERROR_NT(status);
883 status = check_name(conn, fname);
884 if (!NT_STATUS_IS_OK(status)) {
885 END_PROFILE(SMBsetatr);
886 return ERROR_NT(status);
889 if (fname[0] == '.' && fname[1] == '\0') {
891 * Not sure here is the right place to catch this
892 * condition. Might be moved to somewhere else later -- vl
894 END_PROFILE(SMBsetatr);
895 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
898 mode = SVAL(inbuf,smb_vwv0);
899 mtime = srv_make_unix_date3(inbuf+smb_vwv1);
901 if (mode != FILE_ATTRIBUTE_NORMAL) {
902 if (VALID_STAT_OF_DIR(sbuf))
907 if (file_set_dosmode(conn,fname,mode,&sbuf,False) != 0) {
908 END_PROFILE(SMBsetatr);
909 return UNIXERROR(ERRDOS, ERRnoaccess);
913 if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) {
914 END_PROFILE(SMBsetatr);
915 return UNIXERROR(ERRDOS, ERRnoaccess);
918 outsize = set_message(inbuf,outbuf,0,0,False);
920 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
922 END_PROFILE(SMBsetatr);
926 /****************************************************************************
928 ****************************************************************************/
930 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
933 SMB_BIG_UINT dfree,dsize,bsize;
934 START_PROFILE(SMBdskattr);
936 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
937 END_PROFILE(SMBdskattr);
938 return(UNIXERROR(ERRHRD,ERRgeneral));
941 outsize = set_message(inbuf,outbuf,5,0,True);
943 if (Protocol <= PROTOCOL_LANMAN2) {
944 double total_space, free_space;
945 /* we need to scale this to a number that DOS6 can handle. We
946 use floating point so we can handle large drives on systems
947 that don't have 64 bit integers
949 we end up displaying a maximum of 2G to DOS systems
951 total_space = dsize * (double)bsize;
952 free_space = dfree * (double)bsize;
954 dsize = (total_space+63*512) / (64*512);
955 dfree = (free_space+63*512) / (64*512);
957 if (dsize > 0xFFFF) dsize = 0xFFFF;
958 if (dfree > 0xFFFF) dfree = 0xFFFF;
960 SSVAL(outbuf,smb_vwv0,dsize);
961 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
962 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
963 SSVAL(outbuf,smb_vwv3,dfree);
965 SSVAL(outbuf,smb_vwv0,dsize);
966 SSVAL(outbuf,smb_vwv1,bsize/512);
967 SSVAL(outbuf,smb_vwv2,512);
968 SSVAL(outbuf,smb_vwv3,dfree);
971 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
973 END_PROFILE(SMBdskattr);
977 /****************************************************************************
979 Can be called from SMBsearch, SMBffirst or SMBfunique.
980 ****************************************************************************/
982 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
992 unsigned int numentries = 0;
993 unsigned int maxentries = 0;
994 BOOL finished = False;
1000 BOOL check_descend = False;
1001 BOOL expect_close = False;
1003 BOOL mask_contains_wcard = False;
1004 BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1006 START_PROFILE(SMBsearch);
1008 if (lp_posix_pathnames()) {
1009 END_PROFILE(SMBsearch);
1010 return reply_unknown(inbuf, outbuf);
1013 *mask = *directory = *fname = 0;
1015 /* If we were called as SMBffirst then we must expect close. */
1016 if(CVAL(inbuf,smb_com) == SMBffirst) {
1017 expect_close = True;
1020 outsize = set_message(inbuf,outbuf,1,3,True);
1021 maxentries = SVAL(inbuf,smb_vwv0);
1022 dirtype = SVAL(inbuf,smb_vwv1);
1023 p = smb_buf(inbuf) + 1;
1024 p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), path, p,
1025 sizeof(path), 0, STR_TERMINATE, &nt_status,
1026 &mask_contains_wcard);
1027 if (!NT_STATUS_IS_OK(nt_status)) {
1028 END_PROFILE(SMBsearch);
1029 return ERROR_NT(nt_status);
1032 nt_status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, path, &mask_contains_wcard);
1033 if (!NT_STATUS_IS_OK(nt_status)) {
1034 END_PROFILE(SMBsearch);
1035 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1036 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
1038 return ERROR_NT(nt_status);
1042 status_len = SVAL(p, 0);
1045 /* dirtype &= ~aDIR; */
1047 if (status_len == 0) {
1048 SMB_STRUCT_STAT sbuf;
1050 pstrcpy(directory,path);
1051 nt_status = unix_convert(conn, directory, True, NULL, &sbuf);
1052 if (!NT_STATUS_IS_OK(nt_status)) {
1053 END_PROFILE(SMBsearch);
1054 return ERROR_NT(nt_status);
1057 nt_status = check_name(conn, directory);
1058 if (!NT_STATUS_IS_OK(nt_status)) {
1059 END_PROFILE(SMBsearch);
1060 return ERROR_NT(nt_status);
1063 p = strrchr_m(directory,'/');
1065 pstrcpy(mask,directory);
1066 pstrcpy(directory,".");
1072 if (*directory == '\0') {
1073 pstrcpy(directory,".");
1075 memset((char *)status,'\0',21);
1076 SCVAL(status,0,(dirtype & 0x1F));
1080 memcpy(status,p,21);
1081 status_dirtype = CVAL(status,0) & 0x1F;
1082 if (status_dirtype != (dirtype & 0x1F)) {
1083 dirtype = status_dirtype;
1086 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1087 if (!conn->dirptr) {
1090 string_set(&conn->dirpath,dptr_path(dptr_num));
1091 pstrcpy(mask, dptr_wcard(dptr_num));
1093 * For a 'continue' search we have no string. So
1094 * check from the initial saved string.
1096 mask_contains_wcard = ms_has_wild(mask);
1099 p = smb_buf(outbuf) + 3;
1101 if (status_len == 0) {
1102 nt_status = dptr_create(conn,
1106 SVAL(inbuf,smb_pid),
1108 mask_contains_wcard,
1111 if (!NT_STATUS_IS_OK(nt_status)) {
1112 return ERROR_NT(nt_status);
1114 dptr_num = dptr_dnum(conn->dirptr);
1116 dirtype = dptr_attr(dptr_num);
1119 DEBUG(4,("dptr_num is %d\n",dptr_num));
1121 if ((dirtype&0x1F) == aVOLID) {
1122 memcpy(p,status,21);
1123 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),
1124 0,aVOLID,0,!allow_long_path_components);
1125 dptr_fill(p+12,dptr_num);
1126 if (dptr_zero(p+12) && (status_len==0)) {
1131 p += DIR_STRUCT_SIZE;
1134 maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
1136 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1137 conn->dirpath,lp_dontdescend(SNUM(conn))));
1138 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) {
1139 check_descend = True;
1142 for (i=numentries;(i<maxentries) && !finished;i++) {
1143 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
1145 memcpy(p,status,21);
1146 make_dir_struct(p,mask,fname,size, mode,date,
1147 !allow_long_path_components);
1148 if (!dptr_fill(p+12,dptr_num)) {
1152 p += DIR_STRUCT_SIZE;
1159 /* If we were called as SMBffirst with smb_search_id == NULL
1160 and no entries were found then return error and close dirptr
1163 if (numentries == 0) {
1164 dptr_close(&dptr_num);
1165 } else if(expect_close && status_len == 0) {
1166 /* Close the dptr - we know it's gone */
1167 dptr_close(&dptr_num);
1170 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1171 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique) {
1172 dptr_close(&dptr_num);
1175 if ((numentries == 0) && !mask_contains_wcard) {
1176 return ERROR_BOTH(STATUS_NO_MORE_FILES,ERRDOS,ERRnofiles);
1179 SSVAL(outbuf,smb_vwv0,numentries);
1180 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1181 SCVAL(smb_buf(outbuf),0,5);
1182 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
1184 /* The replies here are never long name. */
1185 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1186 if (!allow_long_path_components) {
1187 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_LONG_PATH_COMPONENTS));
1190 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1191 SSVAL(outbuf,smb_flg2, (SVAL(outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1193 outsize += DIR_STRUCT_SIZE*numentries;
1194 smb_setlen(inbuf,outbuf,outsize - 4);
1196 if ((! *directory) && dptr_path(dptr_num))
1197 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1199 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1200 smb_fn_name(CVAL(inbuf,smb_com)),
1201 mask, directory, dirtype, numentries, maxentries ) );
1203 END_PROFILE(SMBsearch);
1207 /****************************************************************************
1208 Reply to a fclose (stop directory search).
1209 ****************************************************************************/
1211 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1220 BOOL path_contains_wcard = False;
1222 START_PROFILE(SMBfclose);
1224 if (lp_posix_pathnames()) {
1225 END_PROFILE(SMBfclose);
1226 return reply_unknown(inbuf, outbuf);
1229 outsize = set_message(inbuf,outbuf,1,0,True);
1230 p = smb_buf(inbuf) + 1;
1231 p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), path, p,
1232 sizeof(path), 0, STR_TERMINATE, &err,
1233 &path_contains_wcard);
1234 if (!NT_STATUS_IS_OK(err)) {
1235 END_PROFILE(SMBfclose);
1236 return ERROR_NT(err);
1239 status_len = SVAL(p,0);
1242 if (status_len == 0) {
1243 END_PROFILE(SMBfclose);
1244 return ERROR_DOS(ERRSRV,ERRsrverror);
1247 memcpy(status,p,21);
1249 if(dptr_fetch(status+12,&dptr_num)) {
1250 /* Close the dptr - we know it's gone */
1251 dptr_close(&dptr_num);
1254 SSVAL(outbuf,smb_vwv0,0);
1256 DEBUG(3,("search close\n"));
1258 END_PROFILE(SMBfclose);
1262 /****************************************************************************
1264 ****************************************************************************/
1266 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1274 SMB_STRUCT_STAT sbuf;
1276 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1278 uint32 dos_attr = SVAL(inbuf,smb_vwv1);
1281 uint32 create_disposition;
1282 uint32 create_options = 0;
1284 struct smb_request req;
1286 START_PROFILE(SMBopen);
1288 init_smb_request(&req, (uint8 *)inbuf);
1290 deny_mode = SVAL(inbuf,smb_vwv0);
1292 srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, smb_buf(inbuf)+1,
1293 sizeof(fname), 0, STR_TERMINATE, &status);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 END_PROFILE(SMBopen);
1296 return ERROR_NT(status);
1299 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 END_PROFILE(SMBopen);
1302 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1303 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
1305 return ERROR_NT(status);
1308 status = unix_convert(conn, fname, False, NULL, &sbuf);
1309 if (!NT_STATUS_IS_OK(status)) {
1310 END_PROFILE(SMBopen);
1311 return ERROR_NT(status);
1314 status = check_name(conn, fname);
1315 if (!NT_STATUS_IS_OK(status)) {
1316 END_PROFILE(SMBopen);
1317 return ERROR_NT(status);
1320 if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
1321 &access_mask, &share_mode, &create_disposition, &create_options)) {
1322 END_PROFILE(SMBopen);
1323 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1326 status = open_file_ntcreate(conn, &req, fname, &sbuf,
1335 if (!NT_STATUS_IS_OK(status)) {
1336 END_PROFILE(SMBopen);
1337 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1338 /* We have re-scheduled this call. */
1341 return ERROR_NT(status);
1344 size = sbuf.st_size;
1345 fattr = dos_mode(conn,fname,&sbuf);
1346 mtime = sbuf.st_mtime;
1349 DEBUG(3,("attempt to open a directory %s\n",fname));
1350 close_file(fsp,ERROR_CLOSE);
1351 END_PROFILE(SMBopen);
1352 return ERROR_DOS(ERRDOS,ERRnoaccess);
1355 outsize = set_message(inbuf,outbuf,7,0,True);
1356 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1357 SSVAL(outbuf,smb_vwv1,fattr);
1358 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1359 srv_put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
1361 srv_put_dos_date3(outbuf,smb_vwv2,mtime);
1363 SIVAL(outbuf,smb_vwv4,(uint32)size);
1364 SSVAL(outbuf,smb_vwv6,deny_mode);
1366 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1367 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1370 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1371 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1373 END_PROFILE(SMBopen);
1377 /****************************************************************************
1378 Reply to an open and X.
1379 ****************************************************************************/
1381 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1384 uint16 open_flags = SVAL(inbuf,smb_vwv2);
1385 int deny_mode = SVAL(inbuf,smb_vwv3);
1386 uint32 smb_attr = SVAL(inbuf,smb_vwv5);
1387 /* Breakout the oplock request bits so we can set the
1388 reply bits separately. */
1389 int ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
1390 int core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1391 int oplock_request = ex_oplock_request | core_oplock_request;
1393 int smb_sattr = SVAL(inbuf,smb_vwv4);
1394 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
1396 int smb_ofun = SVAL(inbuf,smb_vwv8);
1399 SMB_STRUCT_STAT sbuf;
1403 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
1404 ssize_t retval = -1;
1407 uint32 create_disposition;
1408 uint32 create_options = 0;
1409 struct smb_request req;
1411 START_PROFILE(SMBopenX);
1413 init_smb_request(&req, (uint8 *)inbuf);
1415 /* If it's an IPC, pass off the pipe handler. */
1417 if (lp_nt_pipe_support()) {
1418 END_PROFILE(SMBopenX);
1419 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
1421 END_PROFILE(SMBopenX);
1422 return ERROR_DOS(ERRSRV,ERRaccess);
1426 /* XXXX we need to handle passed times, sattr and flags */
1427 srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, smb_buf(inbuf),
1428 sizeof(fname), 0, STR_TERMINATE, &status);
1429 if (!NT_STATUS_IS_OK(status)) {
1430 END_PROFILE(SMBopenX);
1431 return ERROR_NT(status);
1434 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
1435 if (!NT_STATUS_IS_OK(status)) {
1436 END_PROFILE(SMBopenX);
1437 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1438 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
1440 return ERROR_NT(status);
1443 status = unix_convert(conn, fname, False, NULL, &sbuf);
1444 if (!NT_STATUS_IS_OK(status)) {
1445 END_PROFILE(SMBopenX);
1446 return ERROR_NT(status);
1449 status = check_name(conn, fname);
1450 if (!NT_STATUS_IS_OK(status)) {
1451 END_PROFILE(SMBopenX);
1452 return ERROR_NT(status);
1455 if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun,
1458 &create_disposition,
1460 END_PROFILE(SMBopenX);
1461 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
1464 status = open_file_ntcreate(conn, &req, fname, &sbuf,
1473 if (!NT_STATUS_IS_OK(status)) {
1474 END_PROFILE(SMBopenX);
1475 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1476 /* We have re-scheduled this call. */
1479 return ERROR_NT(status);
1482 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1483 if the file is truncated or created. */
1484 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1485 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1486 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1487 close_file(fsp,ERROR_CLOSE);
1488 END_PROFILE(SMBopenX);
1489 return ERROR_NT(NT_STATUS_DISK_FULL);
1491 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
1493 close_file(fsp,ERROR_CLOSE);
1494 END_PROFILE(SMBopenX);
1495 return ERROR_NT(NT_STATUS_DISK_FULL);
1497 sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
1500 fattr = dos_mode(conn,fname,&sbuf);
1501 mtime = sbuf.st_mtime;
1503 close_file(fsp,ERROR_CLOSE);
1504 END_PROFILE(SMBopenX);
1505 return ERROR_DOS(ERRDOS,ERRnoaccess);
1508 /* If the caller set the extended oplock request bit
1509 and we granted one (by whatever means) - set the
1510 correct bit for extended oplock reply.
1513 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1514 smb_action |= EXTENDED_OPLOCK_GRANTED;
1517 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1518 smb_action |= EXTENDED_OPLOCK_GRANTED;
1521 /* If the caller set the core oplock request bit
1522 and we granted one (by whatever means) - set the
1523 correct bit for core oplock reply.
1526 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1527 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1530 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1531 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1534 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1535 set_message(inbuf,outbuf,19,0,True);
1537 set_message(inbuf,outbuf,15,0,True);
1539 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1540 SSVAL(outbuf,smb_vwv3,fattr);
1541 if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1542 srv_put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1544 srv_put_dos_date3(outbuf,smb_vwv4,mtime);
1546 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
1547 SSVAL(outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
1548 SSVAL(outbuf,smb_vwv11,smb_action);
1550 if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
1551 SIVAL(outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
1554 END_PROFILE(SMBopenX);
1555 return chain_reply(inbuf,outbuf,length,bufsize);
1558 /****************************************************************************
1559 Reply to a SMBulogoffX.
1560 conn POINTER CAN BE NULL HERE !
1561 ****************************************************************************/
1563 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1565 uint16 vuid = SVAL(inbuf,smb_uid);
1566 user_struct *vuser = get_valid_user_struct(vuid);
1567 START_PROFILE(SMBulogoffX);
1570 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1572 /* in user level security we are supposed to close any files
1573 open by this user */
1574 if ((vuser != 0) && (lp_security() != SEC_SHARE))
1575 file_close_user(vuid);
1577 invalidate_vuid(vuid);
1579 set_message(inbuf,outbuf,2,0,True);
1581 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1583 END_PROFILE(SMBulogoffX);
1584 return chain_reply(inbuf,outbuf,length,bufsize);
1587 /****************************************************************************
1588 Reply to a mknew or a create.
1589 ****************************************************************************/
1591 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1596 uint32 fattr = SVAL(inbuf,smb_vwv0);
1597 struct timespec ts[2];
1599 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1600 SMB_STRUCT_STAT sbuf;
1602 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
1603 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1604 uint32 create_disposition;
1605 uint32 create_options = 0;
1606 struct smb_request req;
1608 START_PROFILE(SMBcreate);
1610 init_smb_request(&req, (uint8 *)inbuf);
1612 com = SVAL(inbuf,smb_com);
1614 ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(inbuf + smb_vwv1)); /* mtime. */
1616 srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, smb_buf(inbuf) + 1,
1617 sizeof(fname), 0, STR_TERMINATE, &status);
1618 if (!NT_STATUS_IS_OK(status)) {
1619 END_PROFILE(SMBcreate);
1620 return ERROR_NT(status);
1623 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
1624 if (!NT_STATUS_IS_OK(status)) {
1625 END_PROFILE(SMBcreate);
1626 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1627 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
1629 return ERROR_NT(status);
1632 status = unix_convert(conn, fname, False, NULL, &sbuf);
1633 if (!NT_STATUS_IS_OK(status)) {
1634 END_PROFILE(SMBcreate);
1635 return ERROR_NT(status);
1638 status = check_name(conn, fname);
1639 if (!NT_STATUS_IS_OK(status)) {
1640 END_PROFILE(SMBcreate);
1641 return ERROR_NT(status);
1644 if (fattr & aVOLID) {
1645 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1648 if(com == SMBmknew) {
1649 /* We should fail if file exists. */
1650 create_disposition = FILE_CREATE;
1652 /* Create if file doesn't exist, truncate if it does. */
1653 create_disposition = FILE_OVERWRITE_IF;
1656 /* Open file using ntcreate. */
1657 status = open_file_ntcreate(conn, &req, fname, &sbuf,
1666 if (!NT_STATUS_IS_OK(status)) {
1667 END_PROFILE(SMBcreate);
1668 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1669 /* We have re-scheduled this call. */
1672 return ERROR_NT(status);
1675 ts[0] = get_atimespec(&sbuf); /* atime. */
1676 file_ntimes(conn, fname, ts);
1678 outsize = set_message(inbuf,outbuf,1,0,True);
1679 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1681 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1682 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1685 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1686 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1689 DEBUG( 2, ( "reply_mknew: file %s\n", fname ) );
1690 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname, fsp->fh->fd, (unsigned int)fattr ) );
1692 END_PROFILE(SMBcreate);
1696 /****************************************************************************
1697 Reply to a create temporary file.
1698 ****************************************************************************/
1700 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1704 uint32 fattr = SVAL(inbuf,smb_vwv0);
1706 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1708 SMB_STRUCT_STAT sbuf;
1711 unsigned int namelen;
1712 struct smb_request req;
1714 START_PROFILE(SMBctemp);
1716 init_smb_request(&req, (uint8 *)inbuf);
1718 srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, smb_buf(inbuf)+1,
1719 sizeof(fname), 0, STR_TERMINATE, &status);
1720 if (!NT_STATUS_IS_OK(status)) {
1721 END_PROFILE(SMBctemp);
1722 return ERROR_NT(status);
1725 pstrcat(fname,"/TMXXXXXX");
1727 pstrcat(fname,"TMXXXXXX");
1730 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
1731 if (!NT_STATUS_IS_OK(status)) {
1732 END_PROFILE(SMBctemp);
1733 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1734 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
1736 return ERROR_NT(status);
1739 status = unix_convert(conn, fname, False, NULL, &sbuf);
1740 if (!NT_STATUS_IS_OK(status)) {
1741 END_PROFILE(SMBctemp);
1742 return ERROR_NT(status);
1745 status = check_name(conn, fname);
1746 if (!NT_STATUS_IS_OK(status)) {
1747 END_PROFILE(SMBctemp);
1748 return ERROR_NT(status);
1751 tmpfd = smb_mkstemp(fname);
1753 END_PROFILE(SMBctemp);
1754 return(UNIXERROR(ERRDOS,ERRnoaccess));
1757 SMB_VFS_STAT(conn,fname,&sbuf);
1759 /* We should fail if file does not exist. */
1760 status = open_file_ntcreate(conn, &req, fname, &sbuf,
1761 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
1762 FILE_SHARE_READ|FILE_SHARE_WRITE,
1769 /* close fd from smb_mkstemp() */
1772 if (!NT_STATUS_IS_OK(status)) {
1773 END_PROFILE(SMBctemp);
1774 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1775 /* We have re-scheduled this call. */
1778 return ERROR_NT(status);
1781 outsize = set_message(inbuf,outbuf,1,0,True);
1782 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1784 /* the returned filename is relative to the directory */
1785 s = strrchr_m(fname, '/');
1792 p = smb_buf(outbuf);
1794 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
1795 thing in the byte section. JRA */
1796 SSVALS(p, 0, -1); /* what is this? not in spec */
1798 namelen = srvstr_push(outbuf, p, s, -1, STR_ASCII|STR_TERMINATE);
1800 outsize = set_message_end(inbuf,outbuf, p);
1802 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1803 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1806 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1807 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1810 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) );
1811 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd,
1812 (unsigned int)sbuf.st_mode ) );
1814 END_PROFILE(SMBctemp);
1818 /*******************************************************************
1819 Check if a user is allowed to rename a file.
1820 ********************************************************************/
1822 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
1823 uint16 dirtype, SMB_STRUCT_STAT *pst)
1827 if (!CAN_WRITE(conn)) {
1828 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1831 fmode = dos_mode(conn, fsp->fsp_name, pst);
1832 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
1833 return NT_STATUS_NO_SUCH_FILE;
1836 if (S_ISDIR(pst->st_mode)) {
1837 return NT_STATUS_OK;
1840 if (fsp->access_mask & DELETE_ACCESS) {
1841 return NT_STATUS_OK;
1844 return NT_STATUS_ACCESS_DENIED;
1847 /*******************************************************************
1848 * unlink a file with all relevant access checks
1849 *******************************************************************/
1851 static NTSTATUS do_unlink(connection_struct *conn, struct smb_request *req,
1852 char *fname, uint32 dirtype)
1854 SMB_STRUCT_STAT sbuf;
1857 uint32 dirtype_orig = dirtype;
1860 DEBUG(10,("do_unlink: %s, dirtype = %d\n", fname, dirtype ));
1862 if (!CAN_WRITE(conn)) {
1863 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1866 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
1867 return map_nt_error_from_unix(errno);
1870 fattr = dos_mode(conn,fname,&sbuf);
1872 if (dirtype & FILE_ATTRIBUTE_NORMAL) {
1873 dirtype = aDIR|aARCH|aRONLY;
1876 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM);
1878 return NT_STATUS_NO_SUCH_FILE;
1881 if (!dir_check_ftype(conn, fattr, dirtype)) {
1883 return NT_STATUS_FILE_IS_A_DIRECTORY;
1885 return NT_STATUS_NO_SUCH_FILE;
1888 if (dirtype_orig & 0x8000) {
1889 /* These will never be set for POSIX. */
1890 return NT_STATUS_NO_SUCH_FILE;
1894 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
1895 return NT_STATUS_FILE_IS_A_DIRECTORY;
1898 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
1899 return NT_STATUS_NO_SUCH_FILE;
1902 if (dirtype & 0xFF00) {
1903 /* These will never be set for POSIX. */
1904 return NT_STATUS_NO_SUCH_FILE;
1909 return NT_STATUS_NO_SUCH_FILE;
1912 /* Can't delete a directory. */
1914 return NT_STATUS_FILE_IS_A_DIRECTORY;
1919 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
1920 return NT_STATUS_OBJECT_NAME_INVALID;
1921 #endif /* JRATEST */
1923 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
1925 On a Windows share, a file with read-only dosmode can be opened with
1926 DELETE_ACCESS. But on a Samba share (delete readonly = no), it
1927 fails with NT_STATUS_CANNOT_DELETE error.
1929 This semantic causes a problem that a user can not
1930 rename a file with read-only dosmode on a Samba share
1931 from a Windows command prompt (i.e. cmd.exe, but can rename
1932 from Windows Explorer).
1935 if (!lp_delete_readonly(SNUM(conn))) {
1936 if (fattr & aRONLY) {
1937 return NT_STATUS_CANNOT_DELETE;
1941 /* On open checks the open itself will check the share mode, so
1942 don't do it here as we'll get it wrong. */
1944 status = open_file_ntcreate(conn, req, fname, &sbuf,
1949 FILE_ATTRIBUTE_NORMAL,
1950 req != NULL ? 0 : INTERNAL_OPEN_ONLY,
1953 if (!NT_STATUS_IS_OK(status)) {
1954 DEBUG(10, ("open_file_ntcreate failed: %s\n",
1955 nt_errstr(status)));
1959 /* The set is across all open files on this dev/inode pair. */
1960 if (!set_delete_on_close(fsp, True, ¤t_user.ut)) {
1961 close_file(fsp, NORMAL_CLOSE);
1962 return NT_STATUS_ACCESS_DENIED;
1965 return close_file(fsp,NORMAL_CLOSE);
1968 /****************************************************************************
1969 The guts of the unlink command, split out so it may be called by the NT SMB
1971 ****************************************************************************/
1973 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
1974 uint32 dirtype, char *name, BOOL has_wild)
1980 NTSTATUS status = NT_STATUS_OK;
1981 SMB_STRUCT_STAT sbuf;
1983 *directory = *mask = 0;
1985 status = unix_convert(conn, name, has_wild, NULL, &sbuf);
1986 if (!NT_STATUS_IS_OK(status)) {
1990 p = strrchr_m(name,'/');
1992 pstrcpy(directory,".");
1996 pstrcpy(directory,name);
2001 * We should only check the mangled cache
2002 * here if unix_convert failed. This means
2003 * that the path in 'mask' doesn't exist
2004 * on the file system and so we need to look
2005 * for a possible mangle. This patch from
2006 * Tine Smukavec <valentin.smukavec@hermes.si>.
2009 if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params))
2010 mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
2013 pstrcat(directory,"/");
2014 pstrcat(directory,mask);
2016 dirtype = FILE_ATTRIBUTE_NORMAL;
2019 status = check_name(conn, directory);
2020 if (!NT_STATUS_IS_OK(status)) {
2024 status = do_unlink(conn, req, directory, dirtype);
2025 if (!NT_STATUS_IS_OK(status)) {
2031 struct smb_Dir *dir_hnd = NULL;
2035 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
2036 return NT_STATUS_OBJECT_NAME_INVALID;
2039 if (strequal(mask,"????????.???")) {
2043 status = check_name(conn, directory);
2044 if (!NT_STATUS_IS_OK(status)) {
2048 dir_hnd = OpenDir(conn, directory, mask, dirtype);
2049 if (dir_hnd == NULL) {
2050 return map_nt_error_from_unix(errno);
2053 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2054 the pattern matches against the long name, otherwise the short name
2055 We don't implement this yet XXXX
2058 status = NT_STATUS_NO_SUCH_FILE;
2060 while ((dname = ReadDirName(dir_hnd, &offset))) {
2063 pstrcpy(fname,dname);
2065 if (!is_visible_file(conn, directory, dname, &st, True)) {
2069 /* Quick check for "." and ".." */
2070 if (fname[0] == '.') {
2071 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
2076 if(!mask_match(fname, mask, conn->case_sensitive)) {
2080 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
2082 status = check_name(conn, fname);
2083 if (!NT_STATUS_IS_OK(status)) {
2088 status = do_unlink(conn, req, fname, dirtype);
2089 if (!NT_STATUS_IS_OK(status)) {
2094 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",
2100 if (count == 0 && NT_STATUS_IS_OK(status)) {
2101 status = map_nt_error_from_unix(errno);
2107 /****************************************************************************
2109 ****************************************************************************/
2111 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
2118 BOOL path_contains_wcard = False;
2119 struct smb_request req;
2121 START_PROFILE(SMBunlink);
2123 init_smb_request(&req, (uint8 *)inbuf);
2125 dirtype = SVAL(inbuf,smb_vwv0);
2127 srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), name,
2128 smb_buf(inbuf) + 1, sizeof(name), 0,
2129 STR_TERMINATE, &status, &path_contains_wcard);
2130 if (!NT_STATUS_IS_OK(status)) {
2131 END_PROFILE(SMBunlink);
2132 return ERROR_NT(status);
2135 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &path_contains_wcard);
2136 if (!NT_STATUS_IS_OK(status)) {
2137 END_PROFILE(SMBunlink);
2138 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2139 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
2141 return ERROR_NT(status);
2144 DEBUG(3,("reply_unlink : %s\n",name));
2146 status = unlink_internals(conn, &req, dirtype, name,
2147 path_contains_wcard);
2148 if (!NT_STATUS_IS_OK(status)) {
2149 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
2150 /* We have re-scheduled this call. */
2153 return ERROR_NT(status);
2156 outsize = set_message(inbuf,outbuf,0,0,False);
2158 END_PROFILE(SMBunlink);
2162 /****************************************************************************
2164 ****************************************************************************/
2166 static void fail_readraw(void)
2169 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
2171 exit_server_cleanly(errstr);
2174 /****************************************************************************
2175 Fake (read/write) sendfile. Returns -1 on read or write fail.
2176 ****************************************************************************/
2178 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, size_t bufsize)
2180 size_t tosend = nread;
2182 while (tosend > 0) {
2186 if (tosend > bufsize) {
2191 ret = read_file(fsp,buf,startpos,cur_read);
2196 /* If we had a short read, fill with zeros. */
2197 if (ret < cur_read) {
2198 memset(buf, '\0', cur_read - ret);
2201 if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
2205 startpos += cur_read;
2208 return (ssize_t)nread;
2211 /****************************************************************************
2212 Use sendfile in readbraw.
2213 ****************************************************************************/
2215 void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
2216 ssize_t mincount, char *outbuf, int out_buffsize)
2220 #if defined(WITH_SENDFILE)
2222 * We can only use sendfile on a non-chained packet
2223 * but we can use on a non-oplocked file. tridge proved this
2224 * on a train in Germany :-). JRA.
2225 * reply_readbraw has already checked the length.
2228 if ( (chain_size == 0) && (nread > 0) &&
2229 (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
2232 _smb_setlen(outbuf,nread);
2233 header.data = (uint8 *)outbuf;
2237 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, nread) == -1) {
2238 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2239 if (errno == ENOSYS) {
2240 goto normal_readbraw;
2244 * Special hack for broken Linux with no working sendfile. If we
2245 * return EINTR we sent the header but not the rest of the data.
2246 * Fake this up by doing read/write calls.
2248 if (errno == EINTR) {
2249 /* Ensure we don't do this again. */
2250 set_use_sendfile(SNUM(conn), False);
2251 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
2253 if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) {
2254 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
2255 fsp->fsp_name, strerror(errno) ));
2256 exit_server_cleanly("send_file_readbraw fake_sendfile failed");
2261 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
2262 fsp->fsp_name, strerror(errno) ));
2263 exit_server_cleanly("send_file_readbraw sendfile failed");
2273 ret = read_file(fsp,outbuf+4,startpos,nread);
2274 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2283 _smb_setlen(outbuf,ret);
2284 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
2288 /****************************************************************************
2289 Reply to a readbraw (core+ protocol).
2290 ****************************************************************************/
2292 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
2294 ssize_t maxcount,mincount;
2297 char *header = outbuf;
2299 START_PROFILE(SMBreadbraw);
2301 if (srv_is_signing_active()) {
2302 exit_server_cleanly("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
2306 * Special check if an oplock break has been issued
2307 * and the readraw request croses on the wire, we must
2308 * return a zero length response here.
2311 fsp = file_fsp(inbuf,smb_vwv0);
2313 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
2315 * fsp could be NULL here so use the value from the packet. JRA.
2317 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
2318 _smb_setlen(header,0);
2319 if (write_data(smbd_server_fd(),header,4) != 4)
2321 END_PROFILE(SMBreadbraw);
2325 CHECK_FSP(fsp,conn);
2327 flush_write_cache(fsp, READRAW_FLUSH);
2329 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
2330 if(CVAL(inbuf,smb_wct) == 10) {
2332 * This is a large offset (64 bit) read.
2334 #ifdef LARGE_SMB_OFF_T
2336 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
2338 #else /* !LARGE_SMB_OFF_T */
2341 * Ensure we haven't been sent a >32 bit offset.
2344 if(IVAL(inbuf,smb_vwv8) != 0) {
2345 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
2346 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
2347 _smb_setlen(header,0);
2348 if (write_data(smbd_server_fd(),header,4) != 4)
2350 END_PROFILE(SMBreadbraw);
2354 #endif /* LARGE_SMB_OFF_T */
2357 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
2358 _smb_setlen(header,0);
2359 if (write_data(smbd_server_fd(),header,4) != 4)
2361 END_PROFILE(SMBreadbraw);
2365 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
2366 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
2368 /* ensure we don't overrun the packet size */
2369 maxcount = MIN(65535,maxcount);
2371 if (!is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2375 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
2379 if (startpos >= size) {
2382 nread = MIN(maxcount,(size - startpos));
2386 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
2387 if (nread < mincount)
2391 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp->fnum, (double)startpos,
2392 (unsigned long)maxcount, (unsigned long)mincount, (unsigned long)nread ) );
2394 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
2396 DEBUG(5,("readbraw finished\n"));
2397 END_PROFILE(SMBreadbraw);
2402 #define DBGC_CLASS DBGC_LOCKING
2404 /****************************************************************************
2405 Reply to a lockread (core+ protocol).
2406 ****************************************************************************/
2408 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
2416 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2417 struct byte_range_lock *br_lck = NULL;
2418 START_PROFILE(SMBlockread);
2420 CHECK_FSP(fsp,conn);
2421 if (!CHECK_READ(fsp,inbuf)) {
2422 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2425 release_level_2_oplocks_on_change(fsp);
2427 numtoread = SVAL(inbuf,smb_vwv1);
2428 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2430 outsize = set_message(inbuf,outbuf,5,3,True);
2431 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2432 data = smb_buf(outbuf) + 3;
2435 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2436 * protocol request that predates the read/write lock concept.
2437 * Thus instead of asking for a read lock here we need to ask
2438 * for a write lock. JRA.
2439 * Note that the requested lock size is unaffected by max_recv.
2442 br_lck = do_lock(smbd_messaging_context(),
2444 (uint32)SVAL(inbuf,smb_pid),
2445 (SMB_BIG_UINT)numtoread,
2446 (SMB_BIG_UINT)startpos,
2449 False, /* Non-blocking lock. */
2452 TALLOC_FREE(br_lck);
2454 if (NT_STATUS_V(status)) {
2455 END_PROFILE(SMBlockread);
2456 return ERROR_NT(status);
2460 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
2463 if (numtoread > max_recv) {
2464 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
2465 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2466 (unsigned int)numtoread, (unsigned int)max_recv ));
2467 numtoread = MIN(numtoread,max_recv);
2469 nread = read_file(fsp,data,startpos,numtoread);
2472 END_PROFILE(SMBlockread);
2473 return(UNIXERROR(ERRDOS,ERRnoaccess));
2477 SSVAL(outbuf,smb_vwv0,nread);
2478 SSVAL(outbuf,smb_vwv5,nread+3);
2479 SSVAL(smb_buf(outbuf),1,nread);
2481 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
2482 fsp->fnum, (int)numtoread, (int)nread));
2484 END_PROFILE(SMBlockread);
2489 #define DBGC_CLASS DBGC_ALL
2491 /****************************************************************************
2493 ****************************************************************************/
2495 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2502 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2503 START_PROFILE(SMBread);
2505 CHECK_FSP(fsp,conn);
2506 if (!CHECK_READ(fsp,inbuf)) {
2507 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2510 numtoread = SVAL(inbuf,smb_vwv1);
2511 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2513 outsize = set_message(inbuf,outbuf,5,3,True);
2514 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2516 * The requested read size cannot be greater than max_recv. JRA.
2518 if (numtoread > max_recv) {
2519 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
2520 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2521 (unsigned int)numtoread, (unsigned int)max_recv ));
2522 numtoread = MIN(numtoread,max_recv);
2525 data = smb_buf(outbuf) + 3;
2527 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2528 END_PROFILE(SMBread);
2529 return ERROR_DOS(ERRDOS,ERRlock);
2533 nread = read_file(fsp,data,startpos,numtoread);
2536 END_PROFILE(SMBread);
2537 return(UNIXERROR(ERRDOS,ERRnoaccess));
2541 SSVAL(outbuf,smb_vwv0,nread);
2542 SSVAL(outbuf,smb_vwv5,nread+3);
2543 SCVAL(smb_buf(outbuf),0,1);
2544 SSVAL(smb_buf(outbuf),1,nread);
2546 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
2547 fsp->fnum, (int)numtoread, (int)nread ) );
2549 END_PROFILE(SMBread);
2553 /****************************************************************************
2555 ****************************************************************************/
2557 static int setup_readX_header(char *inbuf, char *outbuf, size_t smb_maxcnt)
2560 char *data = smb_buf(outbuf);
2562 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2563 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
2564 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2565 SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
2566 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
2567 SCVAL(outbuf,smb_vwv0,0xFF);
2568 outsize = set_message(inbuf, outbuf,12,smb_maxcnt,False);
2569 /* Reset the outgoing length, set_message truncates at 0x1FFFF. */
2570 _smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
2574 /****************************************************************************
2575 Reply to a read and X - possibly using sendfile.
2576 ****************************************************************************/
2578 int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, int len_outbuf,
2579 files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
2581 SMB_STRUCT_STAT sbuf;
2584 char *data = smb_buf(outbuf);
2586 if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) {
2587 return(UNIXERROR(ERRDOS,ERRnoaccess));
2590 if (startpos > sbuf.st_size) {
2592 } else if (smb_maxcnt > (sbuf.st_size - startpos)) {
2593 smb_maxcnt = (sbuf.st_size - startpos);
2596 if (smb_maxcnt == 0) {
2600 #if defined(WITH_SENDFILE)
2602 * We can only use sendfile on a non-chained packet
2603 * but we can use on a non-oplocked file. tridge proved this
2604 * on a train in Germany :-). JRA.
2607 if ((chain_size == 0) && (CVAL(inbuf,smb_vwv0) == 0xFF) &&
2608 lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
2612 * Set up the packet header before send. We
2613 * assume here the sendfile will work (get the
2614 * correct amount of data).
2617 setup_readX_header(inbuf,outbuf,smb_maxcnt);
2618 set_message(inbuf,outbuf,12,smb_maxcnt,False);
2619 header.data = (uint8 *)outbuf;
2620 header.length = data - outbuf;
2623 if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) {
2624 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2625 if (errno == ENOSYS) {
2630 * Special hack for broken Linux with no working sendfile. If we
2631 * return EINTR we sent the header but not the rest of the data.
2632 * Fake this up by doing read/write calls.
2635 if (errno == EINTR) {
2636 /* Ensure we don't do this again. */
2637 set_use_sendfile(SNUM(conn), False);
2638 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
2640 if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
2641 len_outbuf - (data-outbuf))) == -1) {
2642 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
2643 fsp->fsp_name, strerror(errno) ));
2644 exit_server_cleanly("send_file_readX: fake_sendfile failed");
2646 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
2647 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2648 /* Returning -1 here means successful sendfile. */
2652 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
2653 fsp->fsp_name, strerror(errno) ));
2654 exit_server_cleanly("send_file_readX sendfile failed");
2657 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
2658 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2659 /* Returning -1 here means successful sendfile. */
2667 if ((smb_maxcnt & 0xFF0000) > 0x10000) {
2668 int sendlen = setup_readX_header(inbuf,outbuf,smb_maxcnt) - smb_maxcnt;
2669 /* Send out the header. */
2670 if (write_data(smbd_server_fd(),outbuf,sendlen) != sendlen) {
2671 DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
2672 fsp->fsp_name, strerror(errno) ));
2673 exit_server_cleanly("send_file_readX sendfile failed");
2675 if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
2676 len_outbuf - (data-outbuf))) == -1) {
2677 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
2678 fsp->fsp_name, strerror(errno) ));
2679 exit_server_cleanly("send_file_readX: fake_sendfile failed");
2683 nread = read_file(fsp,data,startpos,smb_maxcnt);
2686 return(UNIXERROR(ERRDOS,ERRnoaccess));
2689 outsize = setup_readX_header(inbuf, outbuf,nread);
2691 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
2692 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2694 /* Returning the number of bytes we want to send back - including header. */
2699 /****************************************************************************
2700 Reply to a read and X.
2701 ****************************************************************************/
2703 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2705 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2706 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2708 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
2709 BOOL big_readX = False;
2711 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
2714 START_PROFILE(SMBreadX);
2716 /* If it's an IPC, pass off the pipe handler. */
2718 END_PROFILE(SMBreadX);
2719 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
2722 CHECK_FSP(fsp,conn);
2723 if (!CHECK_READ(fsp,inbuf)) {
2724 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2727 set_message(inbuf,outbuf,12,0,True);
2729 if (global_client_caps & CAP_LARGE_READX) {
2730 size_t upper_size = SVAL(inbuf,smb_vwv7);
2731 smb_maxcnt |= (upper_size<<16);
2732 if (upper_size > 1) {
2733 /* Can't do this on a chained packet. */
2734 if ((CVAL(inbuf,smb_vwv0) != 0xFF)) {
2735 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
2737 /* We currently don't do this on signed or sealed data. */
2738 if (srv_is_signing_active() || srv_encryption_on()) {
2739 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
2741 /* Is there room in the reply for this data ? */
2742 if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
2743 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2749 if(CVAL(inbuf,smb_wct) == 12) {
2750 #ifdef LARGE_SMB_OFF_T
2752 * This is a large offset (64 bit) read.
2754 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
2756 #else /* !LARGE_SMB_OFF_T */
2759 * Ensure we haven't been sent a >32 bit offset.
2762 if(IVAL(inbuf,smb_vwv10) != 0) {
2763 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2764 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
2765 END_PROFILE(SMBreadX);
2766 return ERROR_DOS(ERRDOS,ERRbadaccess);
2769 #endif /* LARGE_SMB_OFF_T */
2773 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2774 END_PROFILE(SMBreadX);
2775 return ERROR_DOS(ERRDOS,ERRlock);
2778 if (!big_readX && schedule_aio_read_and_X(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt)) {
2779 END_PROFILE(SMBreadX);
2783 nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
2784 /* Only call chain_reply if not an error. */
2785 if (nread != -1 && SVAL(outbuf,smb_rcls) == 0) {
2786 nread = chain_reply(inbuf,outbuf,length,bufsize);
2789 END_PROFILE(SMBreadX);
2793 /****************************************************************************
2794 Reply to a writebraw (core+ or LANMAN1.0 protocol).
2795 ****************************************************************************/
2797 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2800 ssize_t total_written=0;
2801 size_t numtowrite=0;
2806 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2809 START_PROFILE(SMBwritebraw);
2811 if (srv_is_signing_active()) {
2812 exit_server_cleanly("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
2815 CHECK_FSP(fsp,conn);
2816 if (!CHECK_WRITE(fsp)) {
2817 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2820 tcount = IVAL(inbuf,smb_vwv1);
2821 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2822 write_through = BITSETW(inbuf+smb_vwv7,0);
2824 /* We have to deal with slightly different formats depending
2825 on whether we are using the core+ or lanman1.0 protocol */
2827 if(Protocol <= PROTOCOL_COREPLUS) {
2828 numtowrite = SVAL(smb_buf(inbuf),-2);
2829 data = smb_buf(inbuf);
2831 numtowrite = SVAL(inbuf,smb_vwv10);
2832 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
2835 /* force the error type */
2836 SCVAL(inbuf,smb_com,SMBwritec);
2837 SCVAL(outbuf,smb_com,SMBwritec);
2839 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2840 END_PROFILE(SMBwritebraw);
2841 return(ERROR_DOS(ERRDOS,ERRlock));
2845 nwritten = write_file(fsp,data,startpos,numtowrite);
2847 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2848 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
2850 if (nwritten < (ssize_t)numtowrite) {
2851 END_PROFILE(SMBwritebraw);
2852 return(UNIXERROR(ERRHRD,ERRdiskfull));
2855 total_written = nwritten;
2857 /* Return a message to the redirector to tell it to send more bytes */
2858 SCVAL(outbuf,smb_com,SMBwritebraw);
2859 SSVALS(outbuf,smb_vwv0,-1);
2860 outsize = set_message(inbuf,outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
2862 if (!send_smb(smbd_server_fd(),outbuf))
2863 exit_server_cleanly("reply_writebraw: send_smb failed.");
2865 /* Now read the raw data into the buffer and write it */
2866 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
2867 exit_server_cleanly("secondary writebraw failed");
2870 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
2871 numtowrite = smb_len(inbuf);
2873 /* Set up outbuf to return the correct return */
2874 outsize = set_message(inbuf,outbuf,1,0,True);
2875 SCVAL(outbuf,smb_com,SMBwritec);
2877 if (numtowrite != 0) {
2879 if (numtowrite > BUFFER_SIZE) {
2880 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2881 (unsigned int)numtowrite ));
2882 exit_server_cleanly("secondary writebraw failed");
2885 if (tcount > nwritten+numtowrite) {
2886 DEBUG(3,("Client overestimated the write %d %d %d\n",
2887 (int)tcount,(int)nwritten,(int)numtowrite));
2890 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
2891 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2893 exit_server_cleanly("secondary writebraw failed");
2896 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
2897 if (nwritten == -1) {
2898 END_PROFILE(SMBwritebraw);
2899 return(UNIXERROR(ERRHRD,ERRdiskfull));
2902 if (nwritten < (ssize_t)numtowrite) {
2903 SCVAL(outbuf,smb_rcls,ERRHRD);
2904 SSVAL(outbuf,smb_err,ERRdiskfull);
2908 total_written += nwritten;
2911 SSVAL(outbuf,smb_vwv0,total_written);
2913 status = sync_file(conn, fsp, write_through);
2914 if (!NT_STATUS_IS_OK(status)) {
2915 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
2916 fsp->fsp_name, nt_errstr(status) ));
2917 END_PROFILE(SMBwritebraw);
2918 return ERROR_NT(status);
2921 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2922 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2924 /* we won't return a status if write through is not selected - this follows what WfWg does */
2925 END_PROFILE(SMBwritebraw);
2926 if (!write_through && total_written==tcount) {
2928 #if RABBIT_PELLET_FIX
2930 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2931 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2933 if (!send_keepalive(smbd_server_fd()))
2934 exit_server_cleanly("reply_writebraw: send of keepalive failed");
2943 #define DBGC_CLASS DBGC_LOCKING
2945 /****************************************************************************
2946 Reply to a writeunlock (core+).
2947 ****************************************************************************/
2949 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
2950 int size, int dum_buffsize)
2952 ssize_t nwritten = -1;
2956 NTSTATUS status = NT_STATUS_OK;
2957 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2959 START_PROFILE(SMBwriteunlock);
2961 CHECK_FSP(fsp,conn);
2962 if (!CHECK_WRITE(fsp)) {
2963 return(ERROR_DOS(ERRDOS,ERRbadaccess));
2966 numtowrite = SVAL(inbuf,smb_vwv1);
2967 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2968 data = smb_buf(inbuf) + 3;
2970 if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2971 END_PROFILE(SMBwriteunlock);
2972 return ERROR_DOS(ERRDOS,ERRlock);
2975 /* The special X/Open SMB protocol handling of
2976 zero length writes is *NOT* done for
2978 if(numtowrite == 0) {
2981 nwritten = write_file(fsp,data,startpos,numtowrite);
2984 status = sync_file(conn, fsp, False /* write through */);
2985 if (!NT_STATUS_IS_OK(status)) {
2986 END_PROFILE(SMBwriteunlock);
2987 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
2988 fsp->fsp_name, nt_errstr(status) ));
2989 return ERROR_NT(status);
2992 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2993 END_PROFILE(SMBwriteunlock);
2994 return(UNIXERROR(ERRHRD,ERRdiskfull));
2998 status = do_unlock(smbd_messaging_context(),
3000 (uint32)SVAL(inbuf,smb_pid),
3001 (SMB_BIG_UINT)numtowrite,
3002 (SMB_BIG_UINT)startpos,
3005 if (NT_STATUS_V(status)) {
3006 END_PROFILE(SMBwriteunlock);
3007 return ERROR_NT(status);
3011 outsize = set_message(inbuf,outbuf,1,0,True);
3013 SSVAL(outbuf,smb_vwv0,nwritten);
3015 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
3016 fsp->fnum, (int)numtowrite, (int)nwritten));
3018 END_PROFILE(SMBwriteunlock);
3023 #define DBGC_CLASS DBGC_ALL
3025 /****************************************************************************
3027 ****************************************************************************/
3029 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
3032 ssize_t nwritten = -1;
3035 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3038 START_PROFILE(SMBwrite);
3040 /* If it's an IPC, pass off the pipe handler. */
3042 END_PROFILE(SMBwrite);
3043 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
3046 CHECK_FSP(fsp,conn);
3047 if (!CHECK_WRITE(fsp)) {
3048 END_PROFILE(SMBwrite);
3049 return(ERROR_DOS(ERRDOS,ERRbadaccess));
3052 numtowrite = SVAL(inbuf,smb_vwv1);
3053 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
3054 data = smb_buf(inbuf) + 3;
3056 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3057 END_PROFILE(SMBwrite);
3058 return ERROR_DOS(ERRDOS,ERRlock);
3062 * X/Open SMB protocol says that if smb_vwv1 is
3063 * zero then the file size should be extended or
3064 * truncated to the size given in smb_vwv[2-3].
3067 if(numtowrite == 0) {
3069 * This is actually an allocate call, and set EOF. JRA.
3071 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
3073 END_PROFILE(SMBwrite);
3074 return ERROR_NT(NT_STATUS_DISK_FULL);
3076 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
3078 END_PROFILE(SMBwrite);
3079 return ERROR_NT(NT_STATUS_DISK_FULL);
3082 nwritten = write_file(fsp,data,startpos,numtowrite);
3084 status = sync_file(conn, fsp, False);
3085 if (!NT_STATUS_IS_OK(status)) {
3086 END_PROFILE(SMBwrite);
3087 DEBUG(5,("reply_write: sync_file for %s returned %s\n",
3088 fsp->fsp_name, nt_errstr(status) ));
3089 return ERROR_NT(status);
3092 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3093 END_PROFILE(SMBwrite);
3094 return(UNIXERROR(ERRHRD,ERRdiskfull));
3097 outsize = set_message(inbuf,outbuf,1,0,True);
3099 SSVAL(outbuf,smb_vwv0,nwritten);
3101 if (nwritten < (ssize_t)numtowrite) {
3102 SCVAL(outbuf,smb_rcls,ERRHRD);
3103 SSVAL(outbuf,smb_err,ERRdiskfull);
3106 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
3108 END_PROFILE(SMBwrite);
3112 /****************************************************************************
3113 Reply to a write and X.
3114 ****************************************************************************/
3116 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
3118 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
3119 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
3120 size_t numtowrite = SVAL(inbuf,smb_vwv10);
3121 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
3122 ssize_t nwritten = -1;
3123 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
3124 unsigned int smblen = smb_len(inbuf);
3126 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
3128 START_PROFILE(SMBwriteX);
3130 /* If it's an IPC, pass off the pipe handler. */
3132 END_PROFILE(SMBwriteX);
3133 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
3136 CHECK_FSP(fsp,conn);
3137 if (!CHECK_WRITE(fsp)) {
3138 return(ERROR_DOS(ERRDOS,ERRbadaccess));
3141 set_message(inbuf,outbuf,6,0,True);
3143 /* Deal with possible LARGE_WRITEX */
3145 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
3148 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
3149 END_PROFILE(SMBwriteX);
3150 return ERROR_DOS(ERRDOS,ERRbadmem);
3153 data = smb_base(inbuf) + smb_doff;
3155 if(CVAL(inbuf,smb_wct) == 14) {
3156 #ifdef LARGE_SMB_OFF_T
3158 * This is a large offset (64 bit) write.
3160 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
3162 #else /* !LARGE_SMB_OFF_T */
3165 * Ensure we haven't been sent a >32 bit offset.
3168 if(IVAL(inbuf,smb_vwv12) != 0) {
3169 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
3170 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
3171 END_PROFILE(SMBwriteX);
3172 return ERROR_DOS(ERRDOS,ERRbadaccess);
3175 #endif /* LARGE_SMB_OFF_T */
3178 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3179 END_PROFILE(SMBwriteX);
3180 return ERROR_DOS(ERRDOS,ERRlock);
3183 /* X/Open SMB protocol says that, unlike SMBwrite
3184 if the length is zero then NO truncation is
3185 done, just a write of zero. To truncate a file,
3188 if(numtowrite == 0) {
3192 if (schedule_aio_write_and_X(conn, inbuf, outbuf, length, bufsize,
3193 fsp,data,startpos,numtowrite)) {
3194 END_PROFILE(SMBwriteX);
3198 nwritten = write_file(fsp,data,startpos,numtowrite);
3201 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3202 END_PROFILE(SMBwriteX);
3203 return(UNIXERROR(ERRHRD,ERRdiskfull));
3206 SSVAL(outbuf,smb_vwv2,nwritten);
3208 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
3210 if (nwritten < (ssize_t)numtowrite) {
3211 SCVAL(outbuf,smb_rcls,ERRHRD);
3212 SSVAL(outbuf,smb_err,ERRdiskfull);
3215 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
3216 fsp->fnum, (int)numtowrite, (int)nwritten));
3218 status = sync_file(conn, fsp, write_through);
3219 if (!NT_STATUS_IS_OK(status)) {
3220 END_PROFILE(SMBwriteX);
3221 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
3222 fsp->fsp_name, nt_errstr(status) ));
3223 return ERROR_NT(status);
3226 END_PROFILE(SMBwriteX);
3227 return chain_reply(inbuf,outbuf,length,bufsize);
3230 /****************************************************************************
3232 ****************************************************************************/
3234 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
3240 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3241 START_PROFILE(SMBlseek);
3243 CHECK_FSP(fsp,conn);
3245 flush_write_cache(fsp, SEEK_FLUSH);
3247 mode = SVAL(inbuf,smb_vwv1) & 3;
3248 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
3249 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
3258 res = fsp->fh->pos + startpos;
3269 if (umode == SEEK_END) {
3270 if((res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,startpos,umode)) == -1) {
3271 if(errno == EINVAL) {
3272 SMB_OFF_T current_pos = startpos;
3273 SMB_STRUCT_STAT sbuf;
3275 if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) {
3276 END_PROFILE(SMBlseek);
3277 return(UNIXERROR(ERRDOS,ERRnoaccess));
3280 current_pos += sbuf.st_size;
3282 res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,0,SEEK_SET);
3287 END_PROFILE(SMBlseek);
3288 return(UNIXERROR(ERRDOS,ERRnoaccess));
3294 outsize = set_message(inbuf,outbuf,2,0,True);
3295 SIVAL(outbuf,smb_vwv0,res);
3297 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
3298 fsp->fnum, (double)startpos, (double)res, mode));
3300 END_PROFILE(SMBlseek);
3304 /****************************************************************************
3306 ****************************************************************************/
3308 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
3310 int outsize = set_message(inbuf,outbuf,0,0,False);
3311 uint16 fnum = SVAL(inbuf,smb_vwv0);
3312 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3313 START_PROFILE(SMBflush);
3316 CHECK_FSP(fsp,conn);
3319 file_sync_all(conn);
3321 NTSTATUS status = sync_file(conn, fsp, True);
3322 if (!NT_STATUS_IS_OK(status)) {
3323 END_PROFILE(SMBflush);
3324 DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
3325 fsp->fsp_name, nt_errstr(status) ));
3326 return ERROR_NT(status);
3330 DEBUG(3,("flush\n"));
3331 END_PROFILE(SMBflush);
3335 /****************************************************************************
3337 conn POINTER CAN BE NULL HERE !
3338 ****************************************************************************/
3340 int reply_exit(connection_struct *conn,
3341 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3344 START_PROFILE(SMBexit);
3346 file_close_pid(SVAL(inbuf,smb_pid),SVAL(inbuf,smb_uid));
3348 outsize = set_message(inbuf,outbuf,0,0,False);
3350 DEBUG(3,("exit\n"));
3352 END_PROFILE(SMBexit);
3356 /****************************************************************************
3357 Reply to a close - has to deal with closing a directory opened by NT SMB's.
3358 ****************************************************************************/
3360 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
3363 NTSTATUS status = NT_STATUS_OK;
3365 files_struct *fsp = NULL;
3366 START_PROFILE(SMBclose);
3368 outsize = set_message(inbuf,outbuf,0,0,False);
3370 /* If it's an IPC, pass off to the pipe handler. */
3372 END_PROFILE(SMBclose);
3373 return reply_pipe_close(conn, inbuf,outbuf);
3376 fsp = file_fsp(inbuf,smb_vwv0);
3379 * We can only use CHECK_FSP if we know it's not a directory.
3382 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
3383 END_PROFILE(SMBclose);
3384 return ERROR_DOS(ERRDOS,ERRbadfid);
3387 if(fsp->is_directory) {
3389 * Special case - close NT SMB directory handle.
3391 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
3392 status = close_file(fsp,NORMAL_CLOSE);
3395 * Close ordinary file.
3398 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
3399 fsp->fh->fd, fsp->fnum,
3400 conn->num_files_open));
3403 * Take care of any time sent in the close.
3406 fsp_set_pending_modtime(fsp,
3407 convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv1)));
3410 * close_file() returns the unix errno if an error
3411 * was detected on close - normally this is due to
3412 * a disk full error. If not then it was probably an I/O error.
3415 status = close_file(fsp,NORMAL_CLOSE);
3418 if(!NT_STATUS_IS_OK(status)) {
3419 END_PROFILE(SMBclose);
3420 return ERROR_NT(status);
3423 END_PROFILE(SMBclose);
3427 /****************************************************************************
3428 Reply to a writeclose (Core+ protocol).
3429 ****************************************************************************/
3431 int reply_writeclose(connection_struct *conn,
3432 char *inbuf,char *outbuf, int size, int dum_buffsize)
3435 ssize_t nwritten = -1;
3437 NTSTATUS close_status = NT_STATUS_OK;
3440 struct timespec mtime;
3441 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3442 START_PROFILE(SMBwriteclose);
3444 CHECK_FSP(fsp,conn);
3445 if (!CHECK_WRITE(fsp)) {
3446 return(ERROR_DOS(ERRDOS,ERRbadaccess));
3449 numtowrite = SVAL(inbuf,smb_vwv1);
3450 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
3451 mtime = convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv4));
3452 data = smb_buf(inbuf) + 1;
3454 if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
3455 END_PROFILE(SMBwriteclose);
3456 return ERROR_DOS(ERRDOS,ERRlock);
3459 nwritten = write_file(fsp,data,startpos,numtowrite);
3461 set_filetime(conn, fsp->fsp_name, mtime);
3464 * More insanity. W2K only closes the file if writelen > 0.
3469 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
3471 close_status = close_file(fsp,NORMAL_CLOSE);
3474 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
3475 fsp->fnum, (int)numtowrite, (int)nwritten,
3476 conn->num_files_open));
3478 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
3479 END_PROFILE(SMBwriteclose);
3480 return(UNIXERROR(ERRHRD,ERRdiskfull));
3483 if(!NT_STATUS_IS_OK(close_status)) {
3484 END_PROFILE(SMBwriteclose);
3485 return ERROR_NT(close_status);
3488 outsize = set_message(inbuf,outbuf,1,0,True);
3490 SSVAL(outbuf,smb_vwv0,nwritten);
3491 END_PROFILE(SMBwriteclose);
3496 #define DBGC_CLASS DBGC_LOCKING
3498 /****************************************************************************
3500 ****************************************************************************/
3502 int reply_lock(connection_struct *conn,
3503 char *inbuf,char *outbuf, int length, int dum_buffsize)
3505 int outsize = set_message(inbuf,outbuf,0,0,False);
3506 SMB_BIG_UINT count,offset;
3508 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3509 struct byte_range_lock *br_lck = NULL;
3511 START_PROFILE(SMBlock);
3513 CHECK_FSP(fsp,conn);
3515 release_level_2_oplocks_on_change(fsp);
3517 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
3518 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
3520 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3521 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
3523 br_lck = do_lock(smbd_messaging_context(),
3525 (uint32)SVAL(inbuf,smb_pid),
3530 False, /* Non-blocking lock. */
3534 TALLOC_FREE(br_lck);
3536 if (NT_STATUS_V(status)) {
3537 END_PROFILE(SMBlock);
3538 return ERROR_NT(status);
3541 END_PROFILE(SMBlock);
3545 /****************************************************************************
3547 ****************************************************************************/
3549 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
3552 int outsize = set_message(inbuf,outbuf,0,0,False);
3553 SMB_BIG_UINT count,offset;
3555 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3556 START_PROFILE(SMBunlock);
3558 CHECK_FSP(fsp,conn);
3560 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
3561 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
3563 status = do_unlock(smbd_messaging_context(),
3565 (uint32)SVAL(inbuf,smb_pid),
3570 if (NT_STATUS_V(status)) {
3571 END_PROFILE(SMBunlock);
3572 return ERROR_NT(status);
3575 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3576 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
3578 END_PROFILE(SMBunlock);
3583 #define DBGC_CLASS DBGC_ALL
3585 /****************************************************************************
3587 conn POINTER CAN BE NULL HERE !
3588 ****************************************************************************/
3590 int reply_tdis(connection_struct *conn,
3591 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3593 int outsize = set_message(inbuf,outbuf,0,0,False);
3595 START_PROFILE(SMBtdis);
3597 vuid = SVAL(inbuf,smb_uid);
3600 DEBUG(4,("Invalid connection in tdis\n"));
3601 END_PROFILE(SMBtdis);
3602 return ERROR_DOS(ERRSRV,ERRinvnid);
3607 close_cnum(conn,vuid);
3609 END_PROFILE(SMBtdis);
3613 /****************************************************************************
3615 conn POINTER CAN BE NULL HERE !
3616 ****************************************************************************/
3618 int reply_echo(connection_struct *conn,
3619 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3621 int smb_reverb = SVAL(inbuf,smb_vwv0);
3623 unsigned int data_len = smb_buflen(inbuf);
3624 int outsize = set_message(inbuf,outbuf,1,data_len,True);
3625 START_PROFILE(SMBecho);
3627 if (data_len > BUFFER_SIZE) {
3628 DEBUG(0,("reply_echo: data_len too large.\n"));
3629 END_PROFILE(SMBecho);
3633 /* copy any incoming data back out */
3635 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
3637 if (smb_reverb > 100) {
3638 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
3642 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
3643 SSVAL(outbuf,smb_vwv0,seq_num);
3645 smb_setlen(inbuf,outbuf,outsize - 4);
3648 if (!send_smb(smbd_server_fd(),outbuf))
3649 exit_server_cleanly("reply_echo: send_smb failed.");
3652 DEBUG(3,("echo %d times\n", smb_reverb));
3656 END_PROFILE(SMBecho);
3660 /****************************************************************************
3661 Reply to a printopen.
3662 ****************************************************************************/
3664 int reply_printopen(connection_struct *conn,
3665 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3671 START_PROFILE(SMBsplopen);
3673 if (!CAN_PRINT(conn)) {
3674 END_PROFILE(SMBsplopen);
3675 return ERROR_DOS(ERRDOS,ERRnoaccess);
3678 /* Open for exclusive use, write only. */
3679 status = print_fsp_open(conn, NULL, &fsp);
3681 if (!NT_STATUS_IS_OK(status)) {
3682 END_PROFILE(SMBsplopen);
3683 return(ERROR_NT(status));
3686 outsize = set_message(inbuf,outbuf,1,0,True);
3687 SSVAL(outbuf,smb_vwv0,fsp->fnum);
3689 DEBUG(3,("openprint fd=%d fnum=%d\n",
3690 fsp->fh->fd, fsp->fnum));
3692 END_PROFILE(SMBsplopen);
3696 /****************************************************************************
3697 Reply to a printclose.
3698 ****************************************************************************/
3700 int reply_printclose(connection_struct *conn,
3701 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3703 int outsize = set_message(inbuf,outbuf,0,0,False);
3704 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3706 START_PROFILE(SMBsplclose);
3708 CHECK_FSP(fsp,conn);
3710 if (!CAN_PRINT(conn)) {
3711 END_PROFILE(SMBsplclose);
3712 return ERROR_NT(NT_STATUS_DOS(ERRSRV, ERRerror));
3715 DEBUG(3,("printclose fd=%d fnum=%d\n",
3716 fsp->fh->fd,fsp->fnum));
3718 status = close_file(fsp,NORMAL_CLOSE);
3720 if(!NT_STATUS_IS_OK(status)) {
3721 END_PROFILE(SMBsplclose);
3722 return ERROR_NT(status);
3725 END_PROFILE(SMBsplclose);
3729 /****************************************************************************
3730 Reply to a printqueue.
3731 ****************************************************************************/
3733 int reply_printqueue(connection_struct *conn,
3734 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3736 int outsize = set_message(inbuf,outbuf,2,3,True);
3737 int max_count = SVAL(inbuf,smb_vwv0);
3738 int start_index = SVAL(inbuf,smb_vwv1);
3739 START_PROFILE(SMBsplretq);
3741 /* we used to allow the client to get the cnum wrong, but that
3742 is really quite gross and only worked when there was only
3743 one printer - I think we should now only accept it if they
3744 get it right (tridge) */
3745 if (!CAN_PRINT(conn)) {
3746 END_PROFILE(SMBsplretq);
3747 return ERROR_DOS(ERRDOS,ERRnoaccess);
3750 SSVAL(outbuf,smb_vwv0,0);
3751 SSVAL(outbuf,smb_vwv1,0);
3752 SCVAL(smb_buf(outbuf),0,1);
3753 SSVAL(smb_buf(outbuf),1,0);
3755 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
3756 start_index, max_count));
3759 print_queue_struct *queue = NULL;
3760 print_status_struct status;
3761 char *p = smb_buf(outbuf) + 3;
3762 int count = print_queue_status(SNUM(conn), &queue, &status);
3763 int num_to_get = ABS(max_count);
3764 int first = (max_count>0?start_index:start_index+max_count+1);
3770 num_to_get = MIN(num_to_get,count-first);
3773 for (i=first;i<first+num_to_get;i++) {
3774 srv_put_dos_date2(p,0,queue[i].time);
3775 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
3776 SSVAL(p,5, queue[i].job);
3777 SIVAL(p,7,queue[i].size);
3779 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
3784 outsize = set_message(inbuf,outbuf,2,28*count+3,False);
3785 SSVAL(outbuf,smb_vwv0,count);
3786 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
3787 SCVAL(smb_buf(outbuf),0,1);
3788 SSVAL(smb_buf(outbuf),1,28*count);
3793 DEBUG(3,("%d entries returned in queue\n",count));
3796 END_PROFILE(SMBsplretq);
3800 /****************************************************************************
3801 Reply to a printwrite.
3802 ****************************************************************************/
3804 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3807 int outsize = set_message(inbuf,outbuf,0,0,False);
3809 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3811 START_PROFILE(SMBsplwr);
3813 if (!CAN_PRINT(conn)) {
3814 END_PROFILE(SMBsplwr);
3815 return ERROR_DOS(ERRDOS,ERRnoaccess);
3818 CHECK_FSP(fsp,conn);
3819 if (!CHECK_WRITE(fsp)) {
3820 return(ERROR_DOS(ERRDOS,ERRbadaccess));
3823 numtowrite = SVAL(smb_buf(inbuf),1);
3824 data = smb_buf(inbuf) + 3;
3826 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
3827 END_PROFILE(SMBsplwr);
3828 return(UNIXERROR(ERRHRD,ERRdiskfull));
3831 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
3833 END_PROFILE(SMBsplwr);
3837 /****************************************************************************
3839 ****************************************************************************/
3841 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3846 SMB_STRUCT_STAT sbuf;
3848 START_PROFILE(SMBmkdir);
3850 srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), directory,
3851 smb_buf(inbuf) + 1, sizeof(directory), 0,
3852 STR_TERMINATE, &status);
3853 if (!NT_STATUS_IS_OK(status)) {
3854 END_PROFILE(SMBmkdir);
3855 return ERROR_NT(status);
3858 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory);
3859 if (!NT_STATUS_IS_OK(status)) {
3860 END_PROFILE(SMBmkdir);
3861 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
3862 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
3864 return ERROR_NT(status);
3867 status = unix_convert(conn, directory, False, NULL, &sbuf);
3868 if (!NT_STATUS_IS_OK(status)) {
3869 END_PROFILE(SMBmkdir);
3870 return ERROR_NT(status);
3873 status = check_name(conn, directory);
3874 if (!NT_STATUS_IS_OK(status)) {
3875 END_PROFILE(SMBmkdir);
3876 return ERROR_NT(status);
3879 status = create_directory(conn, directory);
3881 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
3883 if (!NT_STATUS_IS_OK(status)) {
3885 if (!use_nt_status()
3886 && NT_STATUS_EQUAL(status,
3887 NT_STATUS_OBJECT_NAME_COLLISION)) {
3889 * Yes, in the DOS error code case we get a
3890 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
3891 * samba4 torture test.
3893 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
3896 END_PROFILE(SMBmkdir);
3897 return ERROR_NT(status);
3900 outsize = set_message(inbuf,outbuf,0,0,False);
3902 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
3904 END_PROFILE(SMBmkdir);
3908 /****************************************************************************
3909 Static function used by reply_rmdir to delete an entire directory
3910 tree recursively. Return True on ok, False on fail.
3911 ****************************************************************************/
3913 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
3915 const char *dname = NULL;
3918 struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
3923 while((dname = ReadDirName(dir_hnd, &offset))) {
3927 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3930 if (!is_visible_file(conn, directory, dname, &st, False))
3933 /* Construct the full name. */
3934 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3940 pstrcpy(fullname, directory);
3941 pstrcat(fullname, "/");
3942 pstrcat(fullname, dname);
3944 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
3949 if(st.st_mode & S_IFDIR) {
3950 if(!recursive_rmdir(conn, fullname)) {
3954 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
3958 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
3967 /****************************************************************************
3968 The internals of the rmdir code - called elsewhere.
3969 ****************************************************************************/
3971 NTSTATUS rmdir_internals(connection_struct *conn, const char *directory)
3976 /* Might be a symlink. */
3977 if(SMB_VFS_LSTAT(conn, directory, &st) != 0) {
3978 return map_nt_error_from_unix(errno);
3981 if (S_ISLNK(st.st_mode)) {
3982 /* Is what it points to a directory ? */
3983 if(SMB_VFS_STAT(conn, directory, &st) != 0) {
3984 return map_nt_error_from_unix(errno);
3986 if (!(S_ISDIR(st.st_mode))) {
3987 return NT_STATUS_NOT_A_DIRECTORY;
3989 ret = SMB_VFS_UNLINK(conn,directory);
3991 ret = SMB_VFS_RMDIR(conn,directory);
3994 notify_fname(conn, NOTIFY_ACTION_REMOVED,
3995 FILE_NOTIFY_CHANGE_DIR_NAME,
3997 return NT_STATUS_OK;
4000 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
4002 * Check to see if the only thing in this directory are
4003 * vetoed files/directories. If so then delete them and
4004 * retry. If we fail to delete any of them (and we *don't*
4005 * do a recursive delete) then fail the rmdir.
4009 struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
4011 if(dir_hnd == NULL) {
4016 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
4017 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
4019 if (!is_visible_file(conn, directory, dname, &st, False))
4021 if(!IS_VETO_PATH(conn, dname)) {
4028 /* We only have veto files/directories. Recursive delete. */
4030 RewindDir(dir_hnd,&dirpos);
4031 while ((dname = ReadDirName(dir_hnd,&dirpos))) {
4034 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
4036 if (!is_visible_file(conn, directory, dname, &st, False))
4039 /* Construct the full name. */
4040 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
4045 pstrcpy(fullname, directory);
4046 pstrcat(fullname, "/");
4047 pstrcat(fullname, dname);
4049 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
4051 if(st.st_mode & S_IFDIR) {
4052 if(lp_recursive_veto_delete(SNUM(conn))) {
4053 if(!recursive_rmdir(conn, fullname))
4056 if(SMB_VFS_RMDIR(conn,fullname) != 0)
4058 } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
4062 /* Retry the rmdir */
4063 ret = SMB_VFS_RMDIR(conn,directory);
4069 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
4070 "%s\n", directory,strerror(errno)));
4071 return map_nt_error_from_unix(errno);
4074 notify_fname(conn, NOTIFY_ACTION_REMOVED,
4075 FILE_NOTIFY_CHANGE_DIR_NAME,
4078 return NT_STATUS_OK;
4081 /****************************************************************************
4083 ****************************************************************************/
4085 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4089 SMB_STRUCT_STAT sbuf;
4091 START_PROFILE(SMBrmdir);
4093 srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), directory,
4094 smb_buf(inbuf) + 1, sizeof(directory), 0,
4095 STR_TERMINATE, &status);
4096 if (!NT_STATUS_IS_OK(status)) {
4097 END_PROFILE(SMBrmdir);
4098 return ERROR_NT(status);
4101 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory);
4102 if (!NT_STATUS_IS_OK(status)) {
4103 END_PROFILE(SMBrmdir);
4104 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4105 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
4107 return ERROR_NT(status);
4110 status = unix_convert(conn, directory, False, NULL, &sbuf);
4111 if (!NT_STATUS_IS_OK(status)) {
4112 END_PROFILE(SMBrmdir);
4113 return ERROR_NT(status);
4116 status = check_name(conn, directory);
4117 if (!NT_STATUS_IS_OK(status)) {
4118 END_PROFILE(SMBrmdir);
4119 return ERROR_NT(status);
4122 dptr_closepath(directory,SVAL(inbuf,smb_pid));
4123 status = rmdir_internals(conn, directory);
4124 if (!NT_STATUS_IS_OK(status)) {
4125 END_PROFILE(SMBrmdir);
4126 return ERROR_NT(status);
4129 outsize = set_message(inbuf,outbuf,0,0,False);
4131 DEBUG( 3, ( "rmdir %s\n", directory ) );
4133 END_PROFILE(SMBrmdir);
4137 /*******************************************************************
4138 Resolve wildcards in a filename rename.
4139 Note that name is in UNIX charset and thus potentially can be more
4140 than fstring buffer (255 bytes) especially in default UTF-8 case.
4141 Therefore, we use pstring inside and all calls should ensure that
4142 name2 is at least pstring-long (they do already)
4143 ********************************************************************/
4145 static BOOL resolve_wildcards(const char *name1, char *name2)
4147 pstring root1,root2;
4149 char *p,*p2, *pname1, *pname2;
4150 int available_space, actual_space;
4152 pname1 = strrchr_m(name1,'/');
4153 pname2 = strrchr_m(name2,'/');
4155 if (!pname1 || !pname2)
4158 pstrcpy(root1,pname1);
4159 pstrcpy(root2,pname2);
4160 p = strrchr_m(root1,'.');
4167 p = strrchr_m(root2,'.');
4181 } else if (*p2 == '*') {
4197 } else if (*p2 == '*') {
4207 available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
4210 actual_space = snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
4211 if (actual_space >= available_space - 1) {
4212 DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n",
4213 actual_space - available_space));
4216 pstrcpy_base(pname2, root2, name2);
4222 /****************************************************************************
4223 Ensure open files have their names updated. Updated to notify other smbd's
4225 ****************************************************************************/
4227 static void rename_open_files(connection_struct *conn,
4228 struct share_mode_lock *lck,
4229 const char *newname)
4232 BOOL did_rename = False;
4234 for(fsp = file_find_di_first(lck->id); fsp;
4235 fsp = file_find_di_next(fsp)) {
4236 /* fsp_name is a relative path under the fsp. To change this for other
4237 sharepaths we need to manipulate relative paths. */
4238 /* TODO - create the absolute path and manipulate the newname
4239 relative to the sharepath. */
4240 if (fsp->conn != conn) {
4243 DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
4244 fsp->fnum, file_id_static_string(&fsp->file_id),
4245 fsp->fsp_name, newname ));
4246 string_set(&fsp->fsp_name, newname);
4251 DEBUG(10,("rename_open_files: no open files on file_id %s for %s\n",
4252 file_id_static_string(&lck->id), newname ));
4255 /* Send messages to all smbd's (not ourself) that the name has changed. */
4256 rename_share_filename(smbd_messaging_context(), lck, conn->connectpath,
4260 /****************************************************************************
4261 We need to check if the source path is a parent directory of the destination
4262 (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
4263 refuse the rename with a sharing violation. Under UNIX the above call can
4264 *succeed* if /foo/bar/baz is a symlink to another area in the share. We
4265 probably need to check that the client is a Windows one before disallowing
4266 this as a UNIX client (one with UNIX extensions) can know the source is a
4267 symlink and make this decision intelligently. Found by an excellent bug
4268 report from <AndyLiebman@aol.com>.
4269 ****************************************************************************/
4271 static BOOL rename_path_prefix_equal(const char *src, const char *dest)
4273 const char *psrc = src;
4274 const char *pdst = dest;
4277 if (psrc[0] == '.' && psrc[1] == '/') {
4280 if (pdst[0] == '.' && pdst[1] == '/') {
4283 if ((slen = strlen(psrc)) > strlen(pdst)) {
4286 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
4290 * Do the notify calls from a rename
4293 static void notify_rename(connection_struct *conn, BOOL is_dir,
4294 const char *oldpath, const char *newpath)
4296 char *olddir, *newdir;
4297 const char *oldname, *newname;
4300 mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
4301 : FILE_NOTIFY_CHANGE_FILE_NAME;
4303 if (!parent_dirname_talloc(NULL, oldpath, &olddir, &oldname)
4304 || !parent_dirname_talloc(NULL, newpath, &newdir, &newname)) {
4305 TALLOC_FREE(olddir);
4309 if (strcmp(olddir, newdir) == 0) {
4310 notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, oldpath);
4311 notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, newpath);
4314 notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, oldpath);
4315 notify_fname(conn, NOTIFY_ACTION_ADDED, mask, newpath);
4317 TALLOC_FREE(olddir);
4318 TALLOC_FREE(newdir);
4320 /* this is a strange one. w2k3 gives an additional event for
4321 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming
4322 files, but not directories */
4324 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
4325 FILE_NOTIFY_CHANGE_ATTRIBUTES
4326 |FILE_NOTIFY_CHANGE_CREATION,
4331 /****************************************************************************
4332 Rename an open file - given an fsp.
4333 ****************************************************************************/
4335 NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstring newname, uint32 attrs, BOOL replace_if_exists)
4337 SMB_STRUCT_STAT sbuf, sbuf1;
4338 pstring newname_last_component;
4339 NTSTATUS status = NT_STATUS_OK;
4340 struct share_mode_lock *lck = NULL;
4345 status = unix_convert(conn, newname, False, newname_last_component, &sbuf);
4347 /* If an error we expect this to be NT_STATUS_OBJECT_PATH_NOT_FOUND */
4349 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND, status)) {
4353 status = check_name(conn, newname);
4354 if (!NT_STATUS_IS_OK(status)) {
4358 /* Ensure newname contains a '/' */
4359 if(strrchr_m(newname,'/') == 0) {
4362 pstrcpy(tmpstr, "./");
4363 pstrcat(tmpstr, newname);
4364 pstrcpy(newname, tmpstr);
4368 * Check for special case with case preserving and not
4369 * case sensitive. If the old last component differs from the original
4370 * last component only by case, then we should allow
4371 * the rename (user is trying to change the case of the
4375 if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
4376 strequal(newname, fsp->fsp_name)) {
4378 pstring newname_modified_last_component;
4381 * Get the last component of the modified name.
4382 * Note that we guarantee that newname contains a '/'
4385 p = strrchr_m(newname,'/');
4386 pstrcpy(newname_modified_last_component,p+1);
4388 if(strcsequal(newname_modified_last_component,
4389 newname_last_component) == False) {
4391 * Replace the modified last component with
4394 pstrcpy(p+1, newname_last_component);
4399 * If the src and dest names are identical - including case,
4400 * don't do the rename, just return success.
4403 if (strcsequal(fsp->fsp_name, newname)) {
4404 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
4406 return NT_STATUS_OK;
4410 * Have vfs_object_exist also fill sbuf1
4412 dst_exists = vfs_object_exist(conn, newname, &sbuf1);
4414 if(!replace_if_exists && dst_exists) {
4415 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
4416 fsp->fsp_name,newname));
4417 return NT_STATUS_OBJECT_NAME_COLLISION;
4420 if (dst_exists && file_find_di_first(file_id_sbuf(&sbuf1)) != NULL) {
4421 DEBUG(3, ("rename_internals_fsp: Target file open\n"));
4422 return NT_STATUS_ACCESS_DENIED;
4425 /* Ensure we have a valid stat struct for the source. */
4426 if (fsp->fh->fd != -1) {
4427 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) == -1) {
4428 return map_nt_error_from_unix(errno);
4431 if (SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) == -1) {
4432 return map_nt_error_from_unix(errno);
4436 status = can_rename(conn, fsp, attrs, &sbuf);
4438 if (!NT_STATUS_IS_OK(status)) {
4439 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
4440 nt_errstr(status), fsp->fsp_name,newname));
4441 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION))
4442 status = NT_STATUS_ACCESS_DENIED;
4446 if (rename_path_prefix_equal(fsp->fsp_name, newname)) {
4447 return NT_STATUS_ACCESS_DENIED;
4450 lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL);
4453 * We have the file open ourselves, so not being able to get the
4454 * corresponding share mode lock is a fatal error.
4457 SMB_ASSERT(lck != NULL);
4459 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
4460 uint32 create_options = fsp->fh->private_options;
4462 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
4463 fsp->fsp_name,newname));
4465 rename_open_files(conn, lck, newname);
4467 notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname);
4470 * A rename acts as a new file create w.r.t. allowing an initial delete
4471 * on close, probably because in Windows there is a new handle to the
4472 * new file. If initial delete on close was requested but not
4473 * originally set, we need to set it here. This is probably not 100% correct,
4474 * but will work for the CIFSFS client which in non-posix mode
4475 * depends on these semantics. JRA.
4478 set_allow_initial_delete_on_close(lck, fsp, True);
4480 if (create_options & FILE_DELETE_ON_CLOSE) {
4481 status = can_set_delete_on_close(fsp, True, 0);
4483 if (NT_STATUS_IS_OK(status)) {
4484 /* Note that here we set the *inital* delete on close flag,
4485 * not the regular one. The magic gets handled in close. */
4486 fsp->initial_delete_on_close = True;
4490 return NT_STATUS_OK;
4495 if (errno == ENOTDIR || errno == EISDIR) {
4496 status = NT_STATUS_OBJECT_NAME_COLLISION;
4498 status = map_nt_error_from_unix(errno);
4501 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
4502 nt_errstr(status), fsp->fsp_name,newname));
4507 /****************************************************************************
4508 The guts of the rename command, split out so it may be called by the NT SMB
4510 ****************************************************************************/
4512 NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
4516 BOOL replace_if_exists,
4522 pstring last_component_src;
4523 pstring last_component_dest;
4526 NTSTATUS status = NT_STATUS_OK;
4527 SMB_STRUCT_STAT sbuf1, sbuf2;
4528 struct smb_Dir *dir_hnd = NULL;
4533 *directory = *mask = 0;
4538 status = unix_convert(conn, name, src_has_wild, last_component_src, &sbuf1);
4539 if (!NT_STATUS_IS_OK(status)) {
4543 status = unix_convert(conn, newname, dest_has_wild, last_component_dest, &sbuf2);
4544 if (!NT_STATUS_IS_OK(status)) {
4549 * Split the old name into directory and last component
4550 * strings. Note that unix_convert may have stripped off a
4551 * leading ./ from both name and newname if the rename is
4552 * at the root of the share. We need to make sure either both
4553 * name and newname contain a / character or neither of them do
4554 * as this is checked in resolve_wildcards().
4557 p = strrchr_m(name,'/');
4559 pstrcpy(directory,".");
4563 pstrcpy(directory,name);
4565 *p = '/'; /* Replace needed for exceptional test below. */
4569 * We should only check the mangled cache
4570 * here if unix_convert failed. This means
4571 * that the path in 'mask' doesn't exist
4572 * on the file system and so we need to look
4573 * for a possible mangle. This patch from
4574 * Tine Smukavec <valentin.smukavec@hermes.si>.
4577 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
4578 mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
4581 if (!src_has_wild) {
4585 * No wildcards - just process the one file.
4587 BOOL is_short_name = mangle_is_8_3(name, True, conn->params);
4589 /* Add a terminating '/' to the directory name. */
4590 pstrcat(directory,"/");
4591 pstrcat(directory,mask);
4593 /* Ensure newname contains a '/' also */
4594 if(strrchr_m(newname,'/') == 0) {
4597 pstrcpy(tmpstr, "./");
4598 pstrcat(tmpstr, newname);
4599 pstrcpy(newname, tmpstr);
4602 DEBUG(3, ("rename_internals: case_sensitive = %d, "
4603 "case_preserve = %d, short case preserve = %d, "
4604 "directory = %s, newname = %s, "
4605 "last_component_dest = %s, is_8_3 = %d\n",
4606 conn->case_sensitive, conn->case_preserve,
4607 conn->short_case_preserve, directory,
4608 newname, last_component_dest, is_short_name));
4610 /* The dest name still may have wildcards. */
4611 if (dest_has_wild) {
4612 if (!resolve_wildcards(directory,newname)) {
4613 DEBUG(6, ("rename_internals: resolve_wildcards %s %s failed\n",
4614 directory,newname));
4615 return NT_STATUS_NO_MEMORY;
4620 SMB_VFS_STAT(conn, directory, &sbuf1);
4622 status = S_ISDIR(sbuf1.st_mode) ?
4623 open_directory(conn, req, directory, &sbuf1,
4625 FILE_SHARE_READ|FILE_SHARE_WRITE,
4626 FILE_OPEN, 0, 0, NULL,
4628 : open_file_ntcreate(conn, req, directory, &sbuf1,
4630 FILE_SHARE_READ|FILE_SHARE_WRITE,
4631 FILE_OPEN, 0, 0, 0, NULL,
4634 if (!NT_STATUS_IS_OK(status)) {
4635 DEBUG(3, ("Could not open rename source %s: %s\n",
4636 directory, nt_errstr(status)));
4640 status = rename_internals_fsp(conn, fsp, newname, attrs,
4643 close_file(fsp, NORMAL_CLOSE);
4645 DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
4646 nt_errstr(status), directory,newname));
4652 * Wildcards - process each file that matches.
4654 if (strequal(mask,"????????.???")) {
4658 status = check_name(conn, directory);
4659 if (!NT_STATUS_IS_OK(status)) {
4663 dir_hnd = OpenDir(conn, directory, mask, attrs);
4664 if (dir_hnd == NULL) {
4665 return map_nt_error_from_unix(errno);
4668 status = NT_STATUS_NO_SUCH_FILE;
4670 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
4671 * - gentest fix. JRA
4674 while ((dname = ReadDirName(dir_hnd, &offset))) {
4677 BOOL sysdir_entry = False;
4679 pstrcpy(fname,dname);
4681 /* Quick check for "." and ".." */
4682 if (fname[0] == '.') {
4683 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
4685 sysdir_entry = True;
4692 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
4696 if(!mask_match(fname, mask, conn->case_sensitive)) {
4701 status = NT_STATUS_OBJECT_NAME_INVALID;
4705 slprintf(fname, sizeof(fname)-1, "%s/%s", directory, dname);
4707 pstrcpy(destname,newname);
4709 if (!resolve_wildcards(fname,destname)) {
4710 DEBUG(6, ("resolve_wildcards %s %s failed\n",
4716 SMB_VFS_STAT(conn, fname, &sbuf1);
4718 status = S_ISDIR(sbuf1.st_mode) ?
4719 open_directory(conn, req, fname, &sbuf1,
4721 FILE_SHARE_READ|FILE_SHARE_WRITE,
4722 FILE_OPEN, 0, 0, NULL,
4724 : open_file_ntcreate(conn, req, fname, &sbuf1,
4726 FILE_SHARE_READ|FILE_SHARE_WRITE,
4727 FILE_OPEN, 0, 0, 0, NULL,
4730 if (!NT_STATUS_IS_OK(status)) {
4731 DEBUG(3,("rename_internals: open_file_ntcreate "
4732 "returned %s rename %s -> %s\n",
4733 nt_errstr(status), directory, newname));
4737 status = rename_internals_fsp(conn, fsp, destname, attrs,
4740 close_file(fsp, NORMAL_CLOSE);
4742 if (!NT_STATUS_IS_OK(status)) {
4743 DEBUG(3, ("rename_internals_fsp returned %s for "
4744 "rename %s -> %s\n", nt_errstr(status),
4745 directory, newname));
4751 DEBUG(3,("rename_internals: doing rename on %s -> "
4752 "%s\n",fname,destname));
4756 if (count == 0 && NT_STATUS_IS_OK(status)) {
4757 status = map_nt_error_from_unix(errno);
4763 /****************************************************************************
4765 ****************************************************************************/
4767 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
4774 uint32 attrs = SVAL(inbuf,smb_vwv0);
4776 BOOL src_has_wcard = False;
4777 BOOL dest_has_wcard = False;
4778 struct smb_request req;
4780 START_PROFILE(SMBmv);
4782 init_smb_request(&req, (uint8 *)inbuf);
4784 p = smb_buf(inbuf) + 1;
4785 p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), name, p,
4786 sizeof(name), 0, STR_TERMINATE, &status,
4788 if (!NT_STATUS_IS_OK(status)) {
4790 return ERROR_NT(status);
4793 p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), newname, p,
4794 sizeof(newname), 0, STR_TERMINATE, &status,
4796 if (!NT_STATUS_IS_OK(status)) {
4798 return ERROR_NT(status);
4801 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &src_has_wcard);
4802 if (!NT_STATUS_IS_OK(status)) {
4804 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4805 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
4807 return ERROR_NT(status);
4810 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wcard);
4811 if (!NT_STATUS_IS_OK(status)) {
4813 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
4814 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
4816 return ERROR_NT(status);
4819 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
4821 status = rename_internals(conn, &req, name, newname, attrs, False,
4822 src_has_wcard, dest_has_wcard);
4823 if (!NT_STATUS_IS_OK(status)) {
4825 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4826 /* We have re-scheduled this call. */
4829 return ERROR_NT(status);
4832 outsize = set_message(inbuf,outbuf,0,0,False);
4838 /*******************************************************************
4839 Copy a file as part of a reply_copy.
4840 ******************************************************************/
4843 * TODO: check error codes on all callers
4846 NTSTATUS copy_file(connection_struct *conn,
4851 BOOL target_is_directory)
4853 SMB_STRUCT_STAT src_sbuf, sbuf2;
4855 files_struct *fsp1,*fsp2;
4858 uint32 new_create_disposition;
4861 pstrcpy(dest,dest1);
4862 if (target_is_directory) {
4863 char *p = strrchr_m(src,'/');
4873 if (!vfs_file_exist(conn,src,&src_sbuf)) {
4874 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4877 if (!target_is_directory && count) {
4878 new_create_disposition = FILE_OPEN;
4880 if (!map_open_params_to_ntcreate(dest1,0,ofun,
4881 NULL, NULL, &new_create_disposition, NULL)) {
4882 return NT_STATUS_INVALID_PARAMETER;
4886 status = open_file_ntcreate(conn, NULL, src, &src_sbuf,
4888 FILE_SHARE_READ|FILE_SHARE_WRITE,
4891 FILE_ATTRIBUTE_NORMAL,
4895 if (!NT_STATUS_IS_OK(status)) {
4899 dosattrs = dos_mode(conn, src, &src_sbuf);
4900 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) {
4901 ZERO_STRUCTP(&sbuf2);
4904 status = open_file_ntcreate(conn, NULL, dest, &sbuf2,
4906 FILE_SHARE_READ|FILE_SHARE_WRITE,
4907 new_create_disposition,
4913 if (!NT_STATUS_IS_OK(status)) {
4914 close_file(fsp1,ERROR_CLOSE);
4918 if ((ofun&3) == 1) {
4919 if(SMB_VFS_LSEEK(fsp2,fsp2->fh->fd,0,SEEK_END) == -1) {
4920 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
4922 * Stop the copy from occurring.
4925 src_sbuf.st_size = 0;
4929 if (src_sbuf.st_size) {
4930 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
4933 close_file(fsp1,NORMAL_CLOSE);
4935 /* Ensure the modtime is set correctly on the destination file. */
4936 fsp_set_pending_modtime( fsp2, get_mtimespec(&src_sbuf));
4939 * As we are opening fsp1 read-only we only expect
4940 * an error on close on fsp2 if we are out of space.
4941 * Thus we don't look at the error return from the
4944 status = close_file(fsp2,NORMAL_CLOSE);
4946 if (!NT_STATUS_IS_OK(status)) {
4950 if (ret != (SMB_OFF_T)src_sbuf.st_size) {
4951 return NT_STATUS_DISK_FULL;
4954 return NT_STATUS_OK;
4957 /****************************************************************************
4958 Reply to a file copy.
4959 ****************************************************************************/
4961 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4966 pstring mask,newname;
4969 int error = ERRnoaccess;
4971 int tid2 = SVAL(inbuf,smb_vwv0);
4972 int ofun = SVAL(inbuf,smb_vwv1);
4973 int flags = SVAL(inbuf,smb_vwv2);
4974 BOOL target_is_directory=False;
4975 BOOL source_has_wild = False;
4976 BOOL dest_has_wild = False;
4977 SMB_STRUCT_STAT sbuf1, sbuf2;
4979 START_PROFILE(SMBcopy);
4981 *directory = *mask = 0;
4984 p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), name, p,
4985 sizeof(name), 0, STR_TERMINATE, &status,
4987 if (!NT_STATUS_IS_OK(status)) {
4988 END_PROFILE(SMBcopy);
4989 return ERROR_NT(status);
4991 p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), newname, p,
4992 sizeof(newname), 0, STR_TERMINATE, &status,
4994 if (!NT_STATUS_IS_OK(status)) {
4995 END_PROFILE(SMBcopy);
4996 return ERROR_NT(status);
4999 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
5001 if (tid2 != conn->cnum) {
5002 /* can't currently handle inter share copies XXXX */
5003 DEBUG(3,("Rejecting inter-share copy\n"));
5004 END_PROFILE(SMBcopy);
5005 return ERROR_DOS(ERRSRV,ERRinvdevice);
5008 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &source_has_wild);
5009 if (!NT_STATUS_IS_OK(status)) {
5010 END_PROFILE(SMBcopy);
5011 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5012 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
5014 return ERROR_NT(status);
5017 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wild);
5018 if (!NT_STATUS_IS_OK(status)) {
5019 END_PROFILE(SMBcopy);
5020 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5021 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
5023 return ERROR_NT(status);
5026 status = unix_convert(conn, name, source_has_wild, NULL, &sbuf1);
5027 if (!NT_STATUS_IS_OK(status)) {
5028 END_PROFILE(SMBcopy);
5029 return ERROR_NT(status);
5032 status = unix_convert(conn, newname, dest_has_wild, NULL, &sbuf2);
5033 if (!NT_STATUS_IS_OK(status)) {
5034 END_PROFILE(SMBcopy);
5035 return ERROR_NT(status);
5038 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
5040 if ((flags&1) && target_is_directory) {
5041 END_PROFILE(SMBcopy);
5042 return ERROR_DOS(ERRDOS,ERRbadfile);
5045 if ((flags&2) && !target_is_directory) {
5046 END_PROFILE(SMBcopy);
5047 return ERROR_DOS(ERRDOS,ERRbadpath);
5050 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
5051 /* wants a tree copy! XXXX */
5052 DEBUG(3,("Rejecting tree copy\n"));
5053 END_PROFILE(SMBcopy);
5054 return ERROR_DOS(ERRSRV,ERRerror);
5057 p = strrchr_m(name,'/');
5059 pstrcpy(directory,"./");
5063 pstrcpy(directory,name);
5068 * We should only check the mangled cache
5069 * here if unix_convert failed. This means
5070 * that the path in 'mask' doesn't exist
5071 * on the file system and so we need to look
5072 * for a possible mangle. This patch from
5073 * Tine Smukavec <valentin.smukavec@hermes.si>.
5076 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
5077 mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
5080 if (!source_has_wild) {
5081 pstrcat(directory,"/");
5082 pstrcat(directory,mask);
5083 if (dest_has_wild) {
5084 if (!resolve_wildcards(directory,newname)) {
5085 END_PROFILE(SMBcopy);
5086 return ERROR_NT(NT_STATUS_NO_MEMORY);
5090 status = check_name(conn, directory);
5091 if (!NT_STATUS_IS_OK(status)) {
5092 return ERROR_NT(status);
5095 status = check_name(conn, newname);
5096 if (!NT_STATUS_IS_OK(status)) {
5097 return ERROR_NT(status);
5100 status = copy_file(conn,directory,newname,ofun,
5101 count,target_is_directory);
5103 if(!NT_STATUS_IS_OK(status)) {
5104 END_PROFILE(SMBcopy);
5105 return ERROR_NT(status);
5110 struct smb_Dir *dir_hnd = NULL;
5115 if (strequal(mask,"????????.???"))
5118 status = check_name(conn, directory);
5119 if (!NT_STATUS_IS_OK(status)) {
5120 return ERROR_NT(status);
5123 dir_hnd = OpenDir(conn, directory, mask, 0);
5124 if (dir_hnd == NULL) {
5125 status = map_nt_error_from_unix(errno);
5126 return ERROR_NT(status);
5131 while ((dname = ReadDirName(dir_hnd, &offset))) {
5133 pstrcpy(fname,dname);
5135 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
5139 if(!mask_match(fname, mask, conn->case_sensitive)) {
5143 error = ERRnoaccess;
5144 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
5145 pstrcpy(destname,newname);
5146 if (!resolve_wildcards(fname,destname)) {
5150 status = check_name(conn, fname);
5151 if (!NT_STATUS_IS_OK(status)) {
5152 return ERROR_NT(status);
5155 status = check_name(conn, destname);
5156 if (!NT_STATUS_IS_OK(status)) {
5157 return ERROR_NT(status);
5160 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
5162 status = copy_file(conn,fname,destname,ofun,
5163 count,target_is_directory);
5164 if (NT_STATUS_IS_OK(status)) {
5173 /* Error on close... */
5175 END_PROFILE(SMBcopy);
5176 return(UNIXERROR(ERRHRD,ERRgeneral));
5179 END_PROFILE(SMBcopy);
5180 return ERROR_DOS(ERRDOS,error);
5183 outsize = set_message(inbuf,outbuf,1,0,True);
5184 SSVAL(outbuf,smb_vwv0,count);
5186 END_PROFILE(SMBcopy);
5190 /****************************************************************************
5192 ****************************************************************************/
5194 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
5201 START_PROFILE(pathworks_setdir);
5204 if (!CAN_SETDIR(snum)) {
5205 END_PROFILE(pathworks_setdir);
5206 return ERROR_DOS(ERRDOS,ERRnoaccess);
5209 srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), newdir,
5210 smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE,
5212 if (!NT_STATUS_IS_OK(status)) {
5213 END_PROFILE(pathworks_setdir);
5214 return ERROR_NT(status);
5217 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newdir);
5218 if (!NT_STATUS_IS_OK(status)) {
5219 END_PROFILE(pathworks_setdir);
5220 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5221 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
5223 return ERROR_NT(status);
5226 if (strlen(newdir) != 0) {
5227 if (!vfs_directory_exist(conn,newdir,NULL)) {
5228 END_PROFILE(pathworks_setdir);
5229 return ERROR_DOS(ERRDOS,ERRbadpath);
5231 set_conn_connectpath(conn,newdir);
5234 outsize = set_message(inbuf,outbuf,0,0,False);
5235 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
5237 DEBUG(3,("setdir %s\n", newdir));
5239 END_PROFILE(pathworks_setdir);
5244 #define DBGC_CLASS DBGC_LOCKING
5246 /****************************************************************************
5247 Get a lock pid, dealing with large count requests.
5248 ****************************************************************************/
5250 uint32 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
5252 if(!large_file_format)
5253 return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
5255 return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
5258 /****************************************************************************
5259 Get a lock count, dealing with large count requests.
5260 ****************************************************************************/
5262 SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
5264 SMB_BIG_UINT count = 0;
5266 if(!large_file_format) {
5267 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
5270 #if defined(HAVE_LONGLONG)
5271 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
5272 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
5273 #else /* HAVE_LONGLONG */
5276 * NT4.x seems to be broken in that it sends large file (64 bit)
5277 * lockingX calls even if the CAP_LARGE_FILES was *not*
5278 * negotiated. For boxes without large unsigned ints truncate the
5279 * lock count by dropping the top 32 bits.
5282 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
5283 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
5284 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
5285 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
5286 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
5289 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
5290 #endif /* HAVE_LONGLONG */
5296 #if !defined(HAVE_LONGLONG)
5297 /****************************************************************************
5298 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
5299 ****************************************************************************/
5301 static uint32 map_lock_offset(uint32 high, uint32 low)
5305 uint32 highcopy = high;
5308 * Try and find out how many significant bits there are in high.
5311 for(i = 0; highcopy; i++)
5315 * We use 31 bits not 32 here as POSIX
5316 * lock offsets may not be negative.
5319 mask = (~0) << (31 - i);
5322 return 0; /* Fail. */
5328 #endif /* !defined(HAVE_LONGLONG) */
5330 /****************************************************************************
5331 Get a lock offset, dealing with large offset requests.
5332 ****************************************************************************/
5334 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
5336 SMB_BIG_UINT offset = 0;
5340 if(!large_file_format) {
5341 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
5344 #if defined(HAVE_LONGLONG)
5345 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
5346 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
5347 #else /* HAVE_LONGLONG */
5350 * NT4.x seems to be broken in that it sends large file (64 bit)
5351 * lockingX calls even if the CAP_LARGE_FILES was *not*
5352 * negotiated. For boxes without large unsigned ints mangle the
5353 * lock offset by mapping the top 32 bits onto the lower 32.
5356 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
5357 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
5358 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
5361 if((new_low = map_lock_offset(high, low)) == 0) {
5363 return (SMB_BIG_UINT)-1;
5366 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
5367 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
5368 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
5369 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
5372 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
5373 #endif /* HAVE_LONGLONG */
5379 /****************************************************************************
5380 Reply to a lockingX request.
5381 ****************************************************************************/
5383 int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
5384 int length, int bufsize)
5386 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
5387 unsigned char locktype = CVAL(inbuf,smb_vwv3);
5388 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
5389 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
5390 uint16 num_locks = SVAL(inbuf,smb_vwv7);
5391 SMB_BIG_UINT count = 0, offset = 0;
5393 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
5396 BOOL large_file_format =
5397 (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
5399 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5401 START_PROFILE(SMBlockingX);
5403 CHECK_FSP(fsp,conn);
5405 data = smb_buf(inbuf);
5407 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
5408 /* we don't support these - and CANCEL_LOCK makes w2k
5409 and XP reboot so I don't really want to be
5410 compatible! (tridge) */
5411 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
5414 /* Check if this is an oplock break on a file
5415 we have granted an oplock on.
5417 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
5418 /* Client can insist on breaking to none. */
5419 BOOL break_to_none = (oplocklevel == 0);
5422 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
5423 "for fnum = %d\n", (unsigned int)oplocklevel,
5427 * Make sure we have granted an exclusive or batch oplock on
5431 if (fsp->oplock_type == 0) {
5433 /* The Samba4 nbench simulator doesn't understand
5434 the difference between break to level2 and break
5435 to none from level2 - it sends oplock break
5436 replies in both cases. Don't keep logging an error
5437 message here - just ignore it. JRA. */
5439 DEBUG(5,("reply_lockingX: Error : oplock break from "
5440 "client for fnum = %d (oplock=%d) and no "
5441 "oplock granted on this file (%s).\n",
5442 fsp->fnum, fsp->oplock_type, fsp->fsp_name));
5444 /* if this is a pure oplock break request then don't
5446 if (num_locks == 0 && num_ulocks == 0) {
5447 END_PROFILE(SMBlockingX);
5450 END_PROFILE(SMBlockingX);
5451 return ERROR_DOS(ERRDOS,ERRlock);
5455 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
5457 result = remove_oplock(fsp);
5459 result = downgrade_oplock(fsp);
5463 DEBUG(0, ("reply_lockingX: error in removing "
5464 "oplock on file %s\n", fsp->fsp_name));
5465 /* Hmmm. Is this panic justified? */
5466 smb_panic("internal tdb error");
5469 reply_to_oplock_break_requests(fsp);
5471 /* if this is a pure oplock break request then don't send a
5473 if (num_locks == 0 && num_ulocks == 0) {
5474 /* Sanity check - ensure a pure oplock break is not a
5476 if(CVAL(inbuf,smb_vwv0) != 0xff)
5477 DEBUG(0,("reply_lockingX: Error : pure oplock "
5478 "break is a chained %d request !\n",
5479 (unsigned int)CVAL(inbuf,smb_vwv0) ));
5480 END_PROFILE(SMBlockingX);
5486 * We do this check *after* we have checked this is not a oplock break
5487 * response message. JRA.
5490 release_level_2_oplocks_on_change(fsp);
5492 /* Data now points at the beginning of the list
5493 of smb_unlkrng structs */
5494 for(i = 0; i < (int)num_ulocks; i++) {
5495 lock_pid = get_lock_pid( data, i, large_file_format);
5496 count = get_lock_count( data, i, large_file_format);
5497 offset = get_lock_offset( data, i, large_file_format, &err);
5500 * There is no error code marked "stupid client bug".... :-).
5503 END_PROFILE(SMBlockingX);
5504 return ERROR_DOS(ERRDOS,ERRnoaccess);
5507 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
5508 "pid %u, file %s\n", (double)offset, (double)count,
5509 (unsigned int)lock_pid, fsp->fsp_name ));
5511 status = do_unlock(smbd_messaging_context(),
5518 if (NT_STATUS_V(status)) {
5519 END_PROFILE(SMBlockingX);
5520 return ERROR_NT(status);
5524 /* Setup the timeout in seconds. */
5526 if (!lp_blocking_locks(SNUM(conn))) {
5530 /* Now do any requested locks */
5531 data += ((large_file_format ? 20 : 10)*num_ulocks);
5533 /* Data now points at the beginning of the list
5534 of smb_lkrng structs */
5536 for(i = 0; i < (int)num_locks; i++) {
5537 enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
5538 READ_LOCK:WRITE_LOCK);
5539 lock_pid = get_lock_pid( data, i, large_file_format);
5540 count = get_lock_count( data, i, large_file_format);
5541 offset = get_lock_offset( data, i, large_file_format, &err);
5544 * There is no error code marked "stupid client bug".... :-).
5547 END_PROFILE(SMBlockingX);
5548 return ERROR_DOS(ERRDOS,ERRnoaccess);
5551 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
5552 "%u, file %s timeout = %d\n", (double)offset,
5553 (double)count, (unsigned int)lock_pid,
5554 fsp->fsp_name, (int)lock_timeout ));
5556 if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
5557 if (lp_blocking_locks(SNUM(conn))) {
5559 /* Schedule a message to ourselves to
5560 remove the blocking lock record and
5561 return the right error. */
5563 if (!blocking_lock_cancel(fsp,
5569 NT_STATUS_FILE_LOCK_CONFLICT)) {
5570 END_PROFILE(SMBlockingX);
5571 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRcancelviolation));
5574 /* Remove a matching pending lock. */
5575 status = do_lock_cancel(fsp,
5581 BOOL blocking_lock = lock_timeout ? True : False;
5582 BOOL defer_lock = False;
5583 struct byte_range_lock *br_lck;
5584 uint32 block_smbpid;
5586 br_lck = do_lock(smbd_messaging_context(),
5597 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
5598 /* Windows internal resolution for blocking locks seems
5599 to be about 200ms... Don't wait for less than that. JRA. */
5600 if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
5601 lock_timeout = lp_lock_spin_time();
5606 /* This heuristic seems to match W2K3 very well. If a
5607 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
5608 it pretends we asked for a timeout of between 150 - 300 milliseconds as
5609 far as I can tell. Replacement for do_lock_spin(). JRA. */
5611 if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
5612 NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
5614 lock_timeout = lp_lock_spin_time();
5617 if (br_lck && defer_lock) {
5619 * A blocking lock was requested. Package up
5620 * this smb into a queued request and push it
5621 * onto the blocking lock queue.
5623 if(push_blocking_lock_request(br_lck,
5634 TALLOC_FREE(br_lck);
5635 END_PROFILE(SMBlockingX);
5640 TALLOC_FREE(br_lck);
5643 if (NT_STATUS_V(status)) {
5644 END_PROFILE(SMBlockingX);
5645 return ERROR_NT(status);
5649 /* If any of the above locks failed, then we must unlock
5650 all of the previous locks (X/Open spec). */
5652 if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) &&
5656 * Ensure we don't do a remove on the lock that just failed,
5657 * as under POSIX rules, if we have a lock already there, we
5658 * will delete it (and we shouldn't) .....
5660 for(i--; i >= 0; i--) {
5661 lock_pid = get_lock_pid( data, i, large_file_format);
5662 count = get_lock_count( data, i, large_file_format);
5663 offset = get_lock_offset( data, i, large_file_format,
5667 * There is no error code marked "stupid client
5671 END_PROFILE(SMBlockingX);
5672 return ERROR_DOS(ERRDOS,ERRnoaccess);
5675 do_unlock(smbd_messaging_context(),
5682 END_PROFILE(SMBlockingX);
5683 return ERROR_NT(status);
5686 set_message(inbuf,outbuf,2,0,True);
5688 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
5689 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
5691 END_PROFILE(SMBlockingX);
5692 return chain_reply(inbuf,outbuf,length,bufsize);
5696 #define DBGC_CLASS DBGC_ALL
5698 /****************************************************************************
5699 Reply to a SMBreadbmpx (read block multiplex) request.
5700 ****************************************************************************/
5702 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
5713 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5714 START_PROFILE(SMBreadBmpx);
5716 /* this function doesn't seem to work - disable by default */
5717 if (!lp_readbmpx()) {
5718 END_PROFILE(SMBreadBmpx);
5719 return ERROR_DOS(ERRSRV,ERRuseSTD);
5722 outsize = set_message(inbuf,outbuf,8,0,True);
5724 CHECK_FSP(fsp,conn);
5725 if (!CHECK_READ(fsp,inbuf)) {
5726 return(ERROR_DOS(ERRDOS,ERRbadaccess));
5729 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
5730 maxcount = SVAL(inbuf,smb_vwv3);
5732 data = smb_buf(outbuf);
5733 pad = ((long)data)%4;
5738 max_per_packet = bufsize-(outsize+pad);
5742 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
5743 END_PROFILE(SMBreadBmpx);
5744 return ERROR_DOS(ERRDOS,ERRlock);
5748 size_t N = MIN(max_per_packet,tcount-total_read);
5750 nread = read_file(fsp,data,startpos,N);
5755 if (nread < (ssize_t)N)
5756 tcount = total_read + nread;
5758 set_message(inbuf,outbuf,8,nread+pad,False);
5759 SIVAL(outbuf,smb_vwv0,startpos);
5760 SSVAL(outbuf,smb_vwv2,tcount);
5761 SSVAL(outbuf,smb_vwv6,nread);
5762 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
5765 if (!send_smb(smbd_server_fd(),outbuf))
5766 exit_server_cleanly("reply_readbmpx: send_smb failed.");
5768 total_read += nread;
5770 } while (total_read < (ssize_t)tcount);
5772 END_PROFILE(SMBreadBmpx);
5776 /****************************************************************************
5777 Reply to a SMBsetattrE.
5778 ****************************************************************************/
5780 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
5782 struct timespec ts[2];
5784 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5785 START_PROFILE(SMBsetattrE);
5787 outsize = set_message(inbuf,outbuf,0,0,False);
5789 if(!fsp || (fsp->conn != conn)) {
5790 END_PROFILE(SMBsetattrE);
5791 return ERROR_DOS(ERRDOS,ERRbadfid);
5795 * Convert the DOS times into unix times. Ignore create
5796 * time as UNIX can't set this.
5799 ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv3)); /* atime. */
5800 ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv5)); /* mtime. */
5803 * Patch from Ray Frush <frush@engr.colostate.edu>
5804 * Sometimes times are sent as zero - ignore them.
5807 if (null_timespec(ts[0]) && null_timespec(ts[1])) {
5808 /* Ignore request */
5809 if( DEBUGLVL( 3 ) ) {
5810 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
5811 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
5813 END_PROFILE(SMBsetattrE);
5815 } else if (!null_timespec(ts[0]) && null_timespec(ts[1])) {
5816 /* set modify time = to access time if modify time was unset */
5820 /* Set the date on this file */
5821 /* Should we set pending modtime here ? JRA */
5822 if(file_ntimes(conn, fsp->fsp_name, ts)) {
5823 END_PROFILE(SMBsetattrE);
5824 return ERROR_DOS(ERRDOS,ERRnoaccess);
5827 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
5829 (unsigned int)ts[0].tv_sec,
5830 (unsigned int)ts[1].tv_sec));
5832 END_PROFILE(SMBsetattrE);
5837 /* Back from the dead for OS/2..... JRA. */
5839 /****************************************************************************
5840 Reply to a SMBwritebmpx (write block multiplex primary) request.
5841 ****************************************************************************/
5843 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
5846 ssize_t nwritten = -1;
5853 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5855 START_PROFILE(SMBwriteBmpx);
5857 CHECK_FSP(fsp,conn);
5858 if (!CHECK_WRITE(fsp)) {
5859 return(ERROR_DOS(ERRDOS,ERRbadaccess));
5861 if (HAS_CACHED_ERROR(fsp)) {
5862 return(CACHED_ERROR(fsp));
5865 tcount = SVAL(inbuf,smb_vwv1);
5866 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
5867 write_through = BITSETW(inbuf+smb_vwv7,0);
5868 numtowrite = SVAL(inbuf,smb_vwv10);
5869 smb_doff = SVAL(inbuf,smb_vwv11);
5871 data = smb_base(inbuf) + smb_doff;
5873 /* If this fails we need to send an SMBwriteC response,
5874 not an SMBwritebmpx - set this up now so we don't forget */
5875 SCVAL(outbuf,smb_com,SMBwritec);
5877 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
5878 END_PROFILE(SMBwriteBmpx);
5879 return(ERROR_DOS(ERRDOS,ERRlock));
5882 nwritten = write_file(fsp,data,startpos,numtowrite);
5884 status = sync_file(conn, fsp, write_through);
5885 if (!NT_STATUS_IS_OK(status)) {
5886 END_PROFILE(SMBwriteBmpx);
5887 DEBUG(5,("reply_writebmpx: sync_file for %s returned %s\n",
5888 fsp->fsp_name, nt_errstr(status) ));
5889 return ERROR_NT(status);
5892 if(nwritten < (ssize_t)numtowrite) {
5893 END_PROFILE(SMBwriteBmpx);
5894 return(UNIXERROR(ERRHRD,ERRdiskfull));
5897 /* If the maximum to be written to this file
5898 is greater than what we just wrote then set
5899 up a secondary struct to be attached to this
5900 fd, we will use this to cache error messages etc. */
5902 if((ssize_t)tcount > nwritten) {
5903 write_bmpx_struct *wbms;
5904 if(fsp->wbmpx_ptr != NULL)
5905 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
5907 wbms = SMB_MALLOC_P(write_bmpx_struct);
5909 DEBUG(0,("Out of memory in reply_readmpx\n"));
5910 END_PROFILE(SMBwriteBmpx);
5911 return(ERROR_DOS(ERRSRV,ERRnoresource));
5913 wbms->wr_mode = write_through;
5914 wbms->wr_discard = False; /* No errors yet */
5915 wbms->wr_total_written = nwritten;
5916 wbms->wr_errclass = 0;
5918 fsp->wbmpx_ptr = wbms;
5921 /* We are returning successfully, set the message type back to
5923 SCVAL(outbuf,smb_com,SMBwriteBmpx);
5925 outsize = set_message(inbuf,outbuf,1,0,True);
5927 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
5929 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
5930 fsp->fnum, (int)numtowrite, (int)nwritten ) );
5932 if (write_through && tcount==nwritten) {
5933 /* We need to send both a primary and a secondary response */
5934 smb_setlen(inbuf,outbuf,outsize - 4);
5936 if (!send_smb(smbd_server_fd(),outbuf))
5937 exit_server_cleanly("reply_writebmpx: send_smb failed.");
5939 /* Now the secondary */
5940 outsize = set_message(inbuf,outbuf,1,0,True);
5941 SCVAL(outbuf,smb_com,SMBwritec);
5942 SSVAL(outbuf,smb_vwv0,nwritten);
5945 END_PROFILE(SMBwriteBmpx);
5949 /****************************************************************************
5950 Reply to a SMBwritebs (write block multiplex secondary) request.
5951 ****************************************************************************/
5953 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
5956 ssize_t nwritten = -1;
5963 write_bmpx_struct *wbms;
5964 BOOL send_response = False;
5965 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
5967 START_PROFILE(SMBwriteBs);
5969 CHECK_FSP(fsp,conn);
5970 if (!CHECK_WRITE(fsp)) {
5971 return(ERROR_DOS(ERRDOS,ERRbadaccess));
5974 tcount = SVAL(inbuf,smb_vwv1);
5975 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
5976 numtowrite = SVAL(inbuf,smb_vwv6);
5977 smb_doff = SVAL(inbuf,smb_vwv7);
5979 data = smb_base(inbuf) + smb_doff;
5981 /* We need to send an SMBwriteC response, not an SMBwritebs */
5982 SCVAL(outbuf,smb_com,SMBwritec);
5984 /* This fd should have an auxiliary struct attached,
5985 check that it does */
5986 wbms = fsp->wbmpx_ptr;
5988 END_PROFILE(SMBwriteBs);
5992 /* If write through is set we can return errors, else we must cache them */
5993 write_through = wbms->wr_mode;
5995 /* Check for an earlier error */
5996 if(wbms->wr_discard) {
5997 END_PROFILE(SMBwriteBs);
5998 return -1; /* Just discard the packet */
6001 nwritten = write_file(fsp,data,startpos,numtowrite);
6003 status = sync_file(conn, fsp, write_through);
6005 if (nwritten < (ssize_t)numtowrite || !NT_STATUS_IS_OK(status)) {
6007 /* We are returning an error - we can delete the aux struct */
6010 fsp->wbmpx_ptr = NULL;
6011 END_PROFILE(SMBwriteBs);
6012 return(ERROR_DOS(ERRHRD,ERRdiskfull));
6014 wbms->wr_errclass = ERRHRD;
6015 wbms->wr_error = ERRdiskfull;
6016 wbms->wr_status = NT_STATUS_DISK_FULL;
6017 wbms->wr_discard = True;
6018 END_PROFILE(SMBwriteBs);
6022 /* Increment the total written, if this matches tcount
6023 we can discard the auxiliary struct (hurrah !) and return a writeC */
6024 wbms->wr_total_written += nwritten;
6025 if(wbms->wr_total_written >= tcount) {
6026 if (write_through) {
6027 outsize = set_message(inbuf,outbuf,1,0,True);
6028 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
6029 send_response = True;
6033 fsp->wbmpx_ptr = NULL;
6037 END_PROFILE(SMBwriteBs);
6041 END_PROFILE(SMBwriteBs);
6045 /****************************************************************************
6046 Reply to a SMBgetattrE.
6047 ****************************************************************************/
6049 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
6051 SMB_STRUCT_STAT sbuf;
6054 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
6055 START_PROFILE(SMBgetattrE);
6057 outsize = set_message(inbuf,outbuf,11,0,True);
6059 if(!fsp || (fsp->conn != conn)) {
6060 END_PROFILE(SMBgetattrE);
6061 return ERROR_DOS(ERRDOS,ERRbadfid);
6064 /* Do an fstat on this file */
6065 if(fsp_stat(fsp, &sbuf)) {
6066 END_PROFILE(SMBgetattrE);
6067 return(UNIXERROR(ERRDOS,ERRnoaccess));
6070 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
6073 * Convert the times into dos times. Set create
6074 * date to be last modify date as UNIX doesn't save
6078 srv_put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
6079 srv_put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
6080 /* Should we check pending modtime here ? JRA */
6081 srv_put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
6084 SIVAL(outbuf,smb_vwv6,0);
6085 SIVAL(outbuf,smb_vwv8,0);
6087 uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
6088 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
6089 SIVAL(outbuf,smb_vwv8,allocation_size);
6091 SSVAL(outbuf,smb_vwv10, mode);
6093 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
6095 END_PROFILE(SMBgetattrE);