2 Unix SMB/CIFS implementation.
3 Main SMB reply routines
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 */
32 extern char magic_char;
33 extern BOOL case_sensitive;
34 extern BOOL case_preserve;
35 extern BOOL short_case_preserve;
36 extern int global_oplock_break;
37 unsigned int smb_echo_count = 0;
39 extern BOOL global_encrypted_passwords_negotiated;
41 /****************************************************************************
42 Ensure we check the path in *exactly* the same way as W2K.
43 We're assuming here that '/' is not the second byte in any multibyte char
44 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
46 ****************************************************************************/
48 NTSTATUS check_path_syntax(pstring destname, const pstring srcname)
51 const char *s = srcname;
52 NTSTATUS ret = NT_STATUS_OK;
55 if (IS_DIRECTORY_SEP(*s)) {
57 * Safe to assume is not the second part of a mb char as this is handled below.
59 /* Eat multiple '/' or '\\' */
60 while (IS_DIRECTORY_SEP(*s)) {
63 if ((d != destname) && (*s != '\0')) {
64 /* We only care about non-leading or trailing '/' or '\\' */
67 } else if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
68 /* Uh oh - "../" or "..\\" or "..\0" ! */
71 * No mb char starts with '.' so we're safe checking the directory separator here.
74 /* If we just added a '/', delete it. */
76 if ((d > destname) && (*(d-1) == '/')) {
78 if (d == (destname + 1)) {
84 /* Are we at the start ? Can't go back further if so. */
86 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
88 /* Go back one level... */
89 while (d > destname) {
95 } else if ((s[0] == '.') && IS_DIRECTORY_SEP(s[1])) {
98 * No mb char starts with '.' so we're safe checking the directory separator here.
101 /* "./" or ".\\" fails with a different error depending on where it is... */
104 ret = NT_STATUS_OBJECT_NAME_INVALID;
107 return NT_STATUS_INVALID_PARAMETER;
109 ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
113 if ((*s & 0x80) && IS_DIRECTORY_SEP(s[1])) {
115 * Potential mb char with second char a directory separator.
116 * All the encodings we care about are 2 byte only, so do a
117 * conversion to unicode. If the one byte char converts then
118 * it really is a directory separator following. Otherwise if
119 * the two byte character converts (and it should or our assumption
120 * about character sets is broken and we return an error) then copy both
121 * bytes as it's a MB character, not a directory separator.
126 if (convert_string(CH_UNIX, CH_UCS2, s, 1, &ucs2_val, 2, False) == 2) {
128 } else if (convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2, False) == 2) {
131 DEBUG(0,("check_path_syntax: directory separator assumptions invalid !\n"));
132 return NT_STATUS_INVALID_PARAMETER;
135 /* Just copy the char (or the second byte of the mb char). */
143 /****************************************************************************
144 Pull a string and check the path - provide for error return.
145 ****************************************************************************/
147 size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err)
150 char *tmppath_ptr = tmppath;
153 SMB_ASSERT(dest_len == sizeof(pstring));
157 ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags);
159 ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
161 *err = check_path_syntax(dest, tmppath);
165 /****************************************************************************
166 Reply to a special message.
167 ****************************************************************************/
169 int reply_special(char *inbuf,char *outbuf)
172 int msg_type = CVAL(inbuf,0);
173 int msg_flags = CVAL(inbuf,1);
177 static BOOL already_got_session = False;
181 memset(outbuf,'\0',smb_size);
183 smb_setlen(outbuf,0);
186 case 0x81: /* session request */
188 if (already_got_session) {
189 exit_server("multiple session request not permitted");
192 SCVAL(outbuf,0,0x82);
194 if (name_len(inbuf+4) > 50 ||
195 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
196 DEBUG(0,("Invalid name length in session request\n"));
199 name_extract(inbuf,4,name1);
200 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
201 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
204 set_local_machine_name(name1, True);
205 set_remote_machine_name(name2, True);
207 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
208 get_local_machine_name(), get_remote_machine_name(),
211 if (name_type == 'R') {
212 /* We are being asked for a pathworks session ---
214 SCVAL(outbuf, 0,0x83);
218 /* only add the client's machine name to the list
219 of possibly valid usernames if we are operating
220 in share mode security */
221 if (lp_security() == SEC_SHARE) {
222 add_session_user(get_remote_machine_name());
225 reload_services(True);
228 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
230 already_got_session = True;
233 case 0x89: /* session keepalive request
234 (some old clients produce this?) */
235 SCVAL(outbuf,0,SMBkeepalive);
239 case 0x82: /* positive session response */
240 case 0x83: /* negative session response */
241 case 0x84: /* retarget session response */
242 DEBUG(0,("Unexpected session response\n"));
245 case SMBkeepalive: /* session keepalive */
250 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
251 msg_type, msg_flags));
256 /****************************************************************************
258 ****************************************************************************/
260 int reply_tcon(connection_struct *conn,
261 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
268 uint16 vuid = SVAL(inbuf,smb_uid);
272 DATA_BLOB password_blob;
274 START_PROFILE(SMBtcon);
276 *service_buf = *password = *dev = 0;
278 p = smb_buf(inbuf)+1;
279 p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
280 pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
282 p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
284 p = strrchr_m(service_buf,'\\');
288 service = service_buf;
291 password_blob = data_blob(password, pwlen+1);
293 conn = make_connection(service,password_blob,dev,vuid,&nt_status);
295 data_blob_clear_free(&password_blob);
298 END_PROFILE(SMBtcon);
299 return ERROR_NT(nt_status);
302 outsize = set_message(outbuf,2,0,True);
303 SSVAL(outbuf,smb_vwv0,max_recv);
304 SSVAL(outbuf,smb_vwv1,conn->cnum);
305 SSVAL(outbuf,smb_tid,conn->cnum);
307 DEBUG(3,("tcon service=%s cnum=%d\n",
308 service, conn->cnum));
310 END_PROFILE(SMBtcon);
314 /****************************************************************************
315 Reply to a tcon and X.
316 ****************************************************************************/
318 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
323 /* what the cleint thinks the device is */
324 fstring client_devicetype;
325 /* what the server tells the client the share represents */
326 const char *server_devicetype;
328 uint16 vuid = SVAL(inbuf,smb_uid);
329 int passlen = SVAL(inbuf,smb_vwv3);
332 extern BOOL global_encrypted_passwords_negotiated;
334 START_PROFILE(SMBtconX);
336 *service = *client_devicetype = 0;
338 /* we might have to close an old one */
339 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
340 close_cnum(conn,vuid);
343 if (passlen > MAX_PASS_LEN) {
344 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
347 if (global_encrypted_passwords_negotiated) {
348 password = data_blob(smb_buf(inbuf),passlen);
350 password = data_blob(smb_buf(inbuf),passlen+1);
351 /* Ensure correct termination */
352 password.data[passlen]=0;
355 p = smb_buf(inbuf) + passlen;
356 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
359 * the service name can be either: \\server\share
360 * or share directly like on the DELL PowerVault 705
363 q = strchr_m(path+2,'\\');
365 END_PROFILE(SMBtconX);
366 return(ERROR_DOS(ERRDOS,ERRnosuchshare));
368 fstrcpy(service,q+1);
371 fstrcpy(service,path);
373 p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII);
375 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
377 conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
379 data_blob_clear_free(&password);
382 END_PROFILE(SMBtconX);
383 return ERROR_NT(nt_status);
387 server_devicetype = "IPC";
388 else if ( IS_PRINT(conn) )
389 server_devicetype = "LPT1:";
391 server_devicetype = "A:";
393 if (Protocol < PROTOCOL_NT1) {
394 set_message(outbuf,2,0,True);
396 p += srvstr_push(outbuf, p, server_devicetype, -1,
397 STR_TERMINATE|STR_ASCII);
398 set_message_end(outbuf,p);
400 /* NT sets the fstype of IPC$ to the null string */
401 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
403 set_message(outbuf,3,0,True);
406 p += srvstr_push(outbuf, p, server_devicetype, -1,
407 STR_TERMINATE|STR_ASCII);
408 p += srvstr_push(outbuf, p, fstype, -1,
411 set_message_end(outbuf,p);
413 /* what does setting this bit do? It is set by NT4 and
414 may affect the ability to autorun mounted cdroms */
415 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
416 (lp_csc_policy(SNUM(conn)) << 2));
418 init_dfsroot(conn, inbuf, outbuf);
422 DEBUG(3,("tconX service=%s \n",
425 /* set the incoming and outgoing tid to the just created one */
426 SSVAL(inbuf,smb_tid,conn->cnum);
427 SSVAL(outbuf,smb_tid,conn->cnum);
429 END_PROFILE(SMBtconX);
430 return chain_reply(inbuf,outbuf,length,bufsize);
433 /****************************************************************************
434 Reply to an unknown type.
435 ****************************************************************************/
437 int reply_unknown(char *inbuf,char *outbuf)
440 type = CVAL(inbuf,smb_com);
442 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
443 smb_fn_name(type), type, type));
445 return(ERROR_DOS(ERRSRV,ERRunknownsmb));
448 /****************************************************************************
450 ****************************************************************************/
452 int reply_ioctl(connection_struct *conn,
453 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
455 uint16 device = SVAL(inbuf,smb_vwv1);
456 uint16 function = SVAL(inbuf,smb_vwv2);
457 uint32 ioctl_code = (device << 16) + function;
458 int replysize, outsize;
460 START_PROFILE(SMBioctl);
462 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
464 switch (ioctl_code) {
465 case IOCTL_QUERY_JOB_INFO:
469 END_PROFILE(SMBioctl);
470 return(ERROR_DOS(ERRSRV,ERRnosupport));
473 outsize = set_message(outbuf,8,replysize+1,True);
474 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
475 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
476 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
477 p = smb_buf(outbuf) + 1; /* Allow for alignment */
479 switch (ioctl_code) {
480 case IOCTL_QUERY_JOB_INFO:
482 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
484 END_PROFILE(SMBioctl);
485 return(UNIXERROR(ERRDOS,ERRbadfid));
487 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
488 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
489 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
494 END_PROFILE(SMBioctl);
498 /****************************************************************************
500 ****************************************************************************/
502 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
508 BOOL bad_path = False;
509 SMB_STRUCT_STAT sbuf;
512 START_PROFILE(SMBchkpth);
514 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status);
515 if (!NT_STATUS_IS_OK(status)) {
516 END_PROFILE(SMBchkpth);
517 return ERROR_NT(status);
520 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
522 unix_convert(name,conn,0,&bad_path,&sbuf);
524 mode = SVAL(inbuf,smb_vwv0);
526 if (check_name(name,conn)) {
527 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
528 if (!(ok = S_ISDIR(sbuf.st_mode))) {
529 END_PROFILE(SMBchkpth);
530 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath);
535 /* We special case this - as when a Windows machine
536 is parsing a path is steps through the components
537 one at a time - if a component fails it expects
538 ERRbadpath, not ERRbadfile.
540 if(errno == ENOENT) {
542 * Windows returns different error codes if
543 * the parent directory is valid but not the
544 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
545 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
546 * if the path is invalid.
549 END_PROFILE(SMBchkpth);
550 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
552 END_PROFILE(SMBchkpth);
553 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
555 } else if (errno == ENOTDIR) {
556 END_PROFILE(SMBchkpth);
557 return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY);
560 END_PROFILE(SMBchkpth);
561 return(UNIXERROR(ERRDOS,ERRbadpath));
564 outsize = set_message(outbuf,0,0,True);
566 DEBUG(3,("chkpth %s mode=%d\n", name, mode));
568 END_PROFILE(SMBchkpth);
572 /****************************************************************************
574 ****************************************************************************/
576 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
580 SMB_STRUCT_STAT sbuf;
585 BOOL bad_path = False;
589 START_PROFILE(SMBgetatr);
591 p = smb_buf(inbuf) + 1;
592 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status);
593 if (!NT_STATUS_IS_OK(status)) {
594 END_PROFILE(SMBgetatr);
595 return ERROR_NT(status);
598 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
600 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
601 under WfWg - weird! */
603 mode = aHIDDEN | aDIR;
604 if (!CAN_WRITE(conn))
610 unix_convert(fname,conn,0,&bad_path,&sbuf);
611 if (check_name(fname,conn)) {
612 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
613 mode = dos_mode(conn,fname,&sbuf);
615 mtime = sbuf.st_mtime;
620 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
626 END_PROFILE(SMBgetatr);
627 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadfile);
630 outsize = set_message(outbuf,10,0,True);
632 SSVAL(outbuf,smb_vwv0,mode);
633 if(lp_dos_filetime_resolution(SNUM(conn)) )
634 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
636 put_dos_date3(outbuf,smb_vwv1,mtime);
637 SIVAL(outbuf,smb_vwv3,(uint32)size);
639 if (Protocol >= PROTOCOL_NT1)
640 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
642 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
644 END_PROFILE(SMBgetatr);
648 /****************************************************************************
650 ****************************************************************************/
652 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
659 SMB_STRUCT_STAT sbuf;
660 BOOL bad_path = False;
664 START_PROFILE(SMBsetatr);
666 p = smb_buf(inbuf) + 1;
667 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status);
668 if (!NT_STATUS_IS_OK(status)) {
669 END_PROFILE(SMBsetatr);
670 return ERROR_NT(status);
673 unix_convert(fname,conn,0,&bad_path,&sbuf);
675 mode = SVAL(inbuf,smb_vwv0);
676 mtime = make_unix_date3(inbuf+smb_vwv1);
678 if (mode != FILE_ATTRIBUTE_NORMAL) {
679 if (VALID_STAT_OF_DIR(sbuf))
684 if (check_name(fname,conn))
685 ok = (file_chmod(conn,fname,mode,NULL) == 0);
691 ok = set_filetime(conn,fname,mtime);
694 END_PROFILE(SMBsetatr);
695 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
698 outsize = set_message(outbuf,0,0,True);
700 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
702 END_PROFILE(SMBsetatr);
706 /****************************************************************************
708 ****************************************************************************/
710 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
713 SMB_BIG_UINT dfree,dsize,bsize;
714 START_PROFILE(SMBdskattr);
716 SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
718 outsize = set_message(outbuf,5,0,True);
720 if (Protocol <= PROTOCOL_LANMAN2) {
721 double total_space, free_space;
722 /* we need to scale this to a number that DOS6 can handle. We
723 use floating point so we can handle large drives on systems
724 that don't have 64 bit integers
726 we end up displaying a maximum of 2G to DOS systems
728 total_space = dsize * (double)bsize;
729 free_space = dfree * (double)bsize;
731 dsize = (total_space+63*512) / (64*512);
732 dfree = (free_space+63*512) / (64*512);
734 if (dsize > 0xFFFF) dsize = 0xFFFF;
735 if (dfree > 0xFFFF) dfree = 0xFFFF;
737 SSVAL(outbuf,smb_vwv0,dsize);
738 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
739 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
740 SSVAL(outbuf,smb_vwv3,dfree);
742 SSVAL(outbuf,smb_vwv0,dsize);
743 SSVAL(outbuf,smb_vwv1,bsize/512);
744 SSVAL(outbuf,smb_vwv2,512);
745 SSVAL(outbuf,smb_vwv3,dfree);
748 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
750 END_PROFILE(SMBdskattr);
754 /****************************************************************************
756 Can be called from SMBsearch, SMBffirst or SMBfunique.
757 ****************************************************************************/
759 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
769 unsigned int numentries = 0;
770 unsigned int maxentries = 0;
771 BOOL finished = False;
778 BOOL check_descend = False;
779 BOOL expect_close = False;
780 BOOL can_open = True;
781 BOOL bad_path = False;
783 START_PROFILE(SMBsearch);
785 *mask = *directory = *fname = 0;
787 /* If we were called as SMBffirst then we must expect close. */
788 if(CVAL(inbuf,smb_com) == SMBffirst)
791 outsize = set_message(outbuf,1,3,True);
792 maxentries = SVAL(inbuf,smb_vwv0);
793 dirtype = SVAL(inbuf,smb_vwv1);
794 p = smb_buf(inbuf) + 1;
795 p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status);
796 if (!NT_STATUS_IS_OK(nt_status)) {
797 END_PROFILE(SMBsearch);
798 return ERROR_NT(nt_status);
801 status_len = SVAL(p, 0);
804 /* dirtype &= ~aDIR; */
806 if (status_len == 0) {
807 SMB_STRUCT_STAT sbuf;
810 pstrcpy(directory,path);
812 unix_convert(directory,conn,0,&bad_path,&sbuf);
815 if (!check_name(directory,conn))
818 p = strrchr_m(dir2,'/');
827 p = strrchr_m(directory,'/');
833 if (strlen(directory) == 0)
834 pstrcpy(directory,".");
835 memset((char *)status,'\0',21);
836 SCVAL(status,0,(dirtype & 0x1F));
841 status_dirtype = CVAL(status,0) & 0x1F;
842 if (status_dirtype != (dirtype & 0x1F))
843 dirtype = status_dirtype;
845 conn->dirptr = dptr_fetch(status+12,&dptr_num);
848 string_set(&conn->dirpath,dptr_path(dptr_num));
849 pstrcpy(mask, dptr_wcard(dptr_num));
853 p = smb_buf(outbuf) + 3;
856 if (status_len == 0) {
857 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
860 END_PROFILE(SMBsearch);
861 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnofids);
863 END_PROFILE(SMBsearch);
864 return ERROR_DOS(ERRDOS,ERRnofids);
866 dptr_set_wcard(dptr_num, strdup(mask));
867 dptr_set_attr(dptr_num, dirtype);
869 dirtype = dptr_attr(dptr_num);
872 DEBUG(4,("dptr_num is %d\n",dptr_num));
875 if ((dirtype&0x1F) == aVOLID) {
877 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
878 dptr_fill(p+12,dptr_num);
879 if (dptr_zero(p+12) && (status_len==0))
883 p += DIR_STRUCT_SIZE;
886 maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
888 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
889 conn->dirpath,lp_dontdescend(SNUM(conn))));
890 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
891 check_descend = True;
893 for (i=numentries;(i<maxentries) && !finished;i++) {
894 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
897 make_dir_struct(p,mask,fname,size,mode,date);
898 dptr_fill(p+12,dptr_num);
901 p += DIR_STRUCT_SIZE;
910 /* If we were called as SMBffirst with smb_search_id == NULL
911 and no entries were found then return error and close dirptr
914 if(ok && expect_close && numentries == 0 && status_len == 0) {
915 if (Protocol < PROTOCOL_NT1) {
916 SCVAL(outbuf,smb_rcls,ERRDOS);
917 SSVAL(outbuf,smb_err,ERRnofiles);
919 /* Also close the dptr - we know it's gone */
920 dptr_close(&dptr_num);
921 } else if (numentries == 0 || !ok) {
922 if (Protocol < PROTOCOL_NT1) {
923 SCVAL(outbuf,smb_rcls,ERRDOS);
924 SSVAL(outbuf,smb_err,ERRnofiles);
926 dptr_close(&dptr_num);
929 /* If we were called as SMBfunique, then we can close the dirptr now ! */
930 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
931 dptr_close(&dptr_num);
933 SSVAL(outbuf,smb_vwv0,numentries);
934 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
935 SCVAL(smb_buf(outbuf),0,5);
936 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
938 if (Protocol >= PROTOCOL_NT1)
939 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
941 outsize += DIR_STRUCT_SIZE*numentries;
942 smb_setlen(outbuf,outsize - 4);
944 if ((! *directory) && dptr_path(dptr_num))
945 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
947 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
948 smb_fn_name(CVAL(inbuf,smb_com)),
949 mask, directory, dirtype, numentries, maxentries ) );
951 END_PROFILE(SMBsearch);
955 /****************************************************************************
956 Reply to a fclose (stop directory search).
957 ****************************************************************************/
959 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
969 START_PROFILE(SMBfclose);
971 outsize = set_message(outbuf,1,0,True);
972 p = smb_buf(inbuf) + 1;
973 p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err);
974 if (!NT_STATUS_IS_OK(err)) {
975 END_PROFILE(SMBfclose);
976 return ERROR_NT(err);
979 status_len = SVAL(p,0);
982 if (status_len == 0) {
983 END_PROFILE(SMBfclose);
984 return ERROR_DOS(ERRSRV,ERRsrverror);
989 if(dptr_fetch(status+12,&dptr_num)) {
990 /* Close the dptr - we know it's gone */
991 dptr_close(&dptr_num);
994 SSVAL(outbuf,smb_vwv0,0);
996 DEBUG(3,("search close\n"));
998 END_PROFILE(SMBfclose);
1002 /****************************************************************************
1004 ****************************************************************************/
1006 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1016 SMB_STRUCT_STAT sbuf;
1017 BOOL bad_path = False;
1019 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1021 START_PROFILE(SMBopen);
1023 share_mode = SVAL(inbuf,smb_vwv0);
1025 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
1026 if (!NT_STATUS_IS_OK(status)) {
1027 END_PROFILE(SMBopen);
1028 return ERROR_NT(status);
1031 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1033 unix_convert(fname,conn,0,&bad_path,&sbuf);
1035 unixmode = unix_mode(conn,aARCH,fname);
1037 fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1038 unixmode, oplock_request,&rmode,NULL);
1041 END_PROFILE(SMBopen);
1042 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1045 size = sbuf.st_size;
1046 fmode = dos_mode(conn,fname,&sbuf);
1047 mtime = sbuf.st_mtime;
1050 DEBUG(3,("attempt to open a directory %s\n",fname));
1051 close_file(fsp,False);
1052 END_PROFILE(SMBopen);
1053 return ERROR_DOS(ERRDOS,ERRnoaccess);
1056 outsize = set_message(outbuf,7,0,True);
1057 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1058 SSVAL(outbuf,smb_vwv1,fmode);
1059 if(lp_dos_filetime_resolution(SNUM(conn)) )
1060 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
1062 put_dos_date3(outbuf,smb_vwv2,mtime);
1063 SIVAL(outbuf,smb_vwv4,(uint32)size);
1064 SSVAL(outbuf,smb_vwv6,rmode);
1066 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1067 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1069 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1070 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1071 END_PROFILE(SMBopen);
1075 /****************************************************************************
1076 Reply to an open and X.
1077 ****************************************************************************/
1079 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1082 int smb_mode = SVAL(inbuf,smb_vwv3);
1083 int smb_attr = SVAL(inbuf,smb_vwv5);
1084 /* Breakout the oplock request bits so we can set the
1085 reply bits separately. */
1086 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
1087 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1088 BOOL oplock_request = ex_oplock_request | core_oplock_request;
1090 int open_flags = SVAL(inbuf,smb_vwv2);
1091 int smb_sattr = SVAL(inbuf,smb_vwv4);
1092 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
1094 int smb_ofun = SVAL(inbuf,smb_vwv8);
1097 int fmode=0,mtime=0,rmode=0;
1098 SMB_STRUCT_STAT sbuf;
1100 BOOL bad_path = False;
1103 START_PROFILE(SMBopenX);
1105 /* If it's an IPC, pass off the pipe handler. */
1107 if (lp_nt_pipe_support()) {
1108 END_PROFILE(SMBopenX);
1109 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
1111 END_PROFILE(SMBopenX);
1112 return ERROR_DOS(ERRSRV,ERRaccess);
1116 /* XXXX we need to handle passed times, sattr and flags */
1117 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 END_PROFILE(SMBopenX);
1120 return ERROR_NT(status);
1123 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1125 unix_convert(fname,conn,0,&bad_path,&sbuf);
1127 unixmode = unix_mode(conn,smb_attr | aARCH, fname);
1129 fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
1130 oplock_request, &rmode,&smb_action);
1133 END_PROFILE(SMBopenX);
1134 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1137 size = sbuf.st_size;
1138 fmode = dos_mode(conn,fname,&sbuf);
1139 mtime = sbuf.st_mtime;
1141 close_file(fsp,False);
1142 END_PROFILE(SMBopenX);
1143 return ERROR_DOS(ERRDOS,ERRnoaccess);
1146 /* If the caller set the extended oplock request bit
1147 and we granted one (by whatever means) - set the
1148 correct bit for extended oplock reply.
1151 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn)))
1152 smb_action |= EXTENDED_OPLOCK_GRANTED;
1154 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1155 smb_action |= EXTENDED_OPLOCK_GRANTED;
1157 /* If the caller set the core oplock request bit
1158 and we granted one (by whatever means) - set the
1159 correct bit for core oplock reply.
1162 if (core_oplock_request && lp_fake_oplocks(SNUM(conn)))
1163 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1165 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1166 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1168 set_message(outbuf,15,0,True);
1169 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1170 SSVAL(outbuf,smb_vwv3,fmode);
1171 if(lp_dos_filetime_resolution(SNUM(conn)) )
1172 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1174 put_dos_date3(outbuf,smb_vwv4,mtime);
1175 SIVAL(outbuf,smb_vwv6,(uint32)size);
1176 SSVAL(outbuf,smb_vwv8,rmode);
1177 SSVAL(outbuf,smb_vwv11,smb_action);
1179 END_PROFILE(SMBopenX);
1180 return chain_reply(inbuf,outbuf,length,bufsize);
1183 /****************************************************************************
1184 Reply to a SMBulogoffX.
1185 ****************************************************************************/
1187 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1189 uint16 vuid = SVAL(inbuf,smb_uid);
1190 user_struct *vuser = get_valid_user_struct(vuid);
1191 START_PROFILE(SMBulogoffX);
1194 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1196 /* in user level security we are supposed to close any files
1197 open by this user */
1198 if ((vuser != 0) && (lp_security() != SEC_SHARE))
1199 file_close_user(vuid);
1201 invalidate_vuid(vuid);
1203 set_message(outbuf,2,0,True);
1205 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1207 END_PROFILE(SMBulogoffX);
1208 return chain_reply(inbuf,outbuf,length,bufsize);
1211 /****************************************************************************
1212 Reply to a mknew or a create.
1213 ****************************************************************************/
1215 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1223 BOOL bad_path = False;
1225 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1226 SMB_STRUCT_STAT sbuf;
1228 START_PROFILE(SMBcreate);
1230 com = SVAL(inbuf,smb_com);
1232 createmode = SVAL(inbuf,smb_vwv0);
1233 srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status);
1234 if (!NT_STATUS_IS_OK(status)) {
1235 END_PROFILE(SMBcreate);
1236 return ERROR_NT(status);
1239 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1241 unix_convert(fname,conn,0,&bad_path,&sbuf);
1243 if (createmode & aVOLID)
1244 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1246 unixmode = unix_mode(conn,createmode,fname);
1248 if(com == SMBmknew) {
1249 /* We should fail if file exists. */
1250 ofun = FILE_CREATE_IF_NOT_EXIST;
1252 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1253 ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
1256 /* Open file in dos compatibility share mode. */
1257 fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1258 ofun, unixmode, oplock_request, NULL, NULL);
1261 END_PROFILE(SMBcreate);
1262 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1265 outsize = set_message(outbuf,1,0,True);
1266 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1268 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1269 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1271 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1272 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1274 DEBUG( 2, ( "new file %s\n", fname ) );
1275 DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n", fname, fsp->fd, createmode, (int)unixmode ) );
1277 END_PROFILE(SMBcreate);
1281 /****************************************************************************
1282 Reply to a create temporary file.
1283 ****************************************************************************/
1285 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1291 BOOL bad_path = False;
1293 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1295 SMB_STRUCT_STAT sbuf;
1299 START_PROFILE(SMBctemp);
1301 createmode = SVAL(inbuf,smb_vwv0);
1302 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
1303 if (!NT_STATUS_IS_OK(status)) {
1304 END_PROFILE(SMBctemp);
1305 return ERROR_NT(status);
1307 pstrcat(fname,"\\TMXXXXXX");
1309 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1311 unix_convert(fname,conn,0,&bad_path,&sbuf);
1313 unixmode = unix_mode(conn,createmode,fname);
1315 tmpfd = smb_mkstemp(fname);
1317 END_PROFILE(SMBctemp);
1318 return(UNIXERROR(ERRDOS,ERRnoaccess));
1321 SMB_VFS_STAT(conn,fname,&sbuf);
1323 /* Open file in dos compatibility share mode. */
1324 /* We should fail if file does not exist. */
1325 fsp = open_file_shared(conn,fname,&sbuf,
1326 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1327 FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
1328 unixmode, oplock_request, NULL, NULL);
1330 /* close fd from smb_mkstemp() */
1334 END_PROFILE(SMBctemp);
1335 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1338 outsize = set_message(outbuf,1,0,True);
1339 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1341 /* the returned filename is relative to the directory */
1342 s = strrchr_m(fname, '/');
1348 p = smb_buf(outbuf);
1349 SSVALS(p, 0, -1); /* what is this? not in spec */
1350 SSVAL(p, 2, strlen(s));
1352 p += srvstr_push(outbuf, p, s, -1, STR_ASCII);
1353 outsize = set_message_end(outbuf, p);
1355 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1356 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1358 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1359 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1361 DEBUG( 2, ( "created temp file %s\n", fname ) );
1362 DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
1363 fname, fsp->fd, createmode, (int)unixmode ) );
1365 END_PROFILE(SMBctemp);
1369 /*******************************************************************
1370 Check if a user is allowed to rename a file.
1371 ********************************************************************/
1373 static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT *pst)
1379 if (!CAN_WRITE(conn))
1380 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1382 if (S_ISDIR(pst->st_mode))
1383 return NT_STATUS_OK;
1385 /* We need a better way to return NT status codes from open... */
1389 fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1390 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1393 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1394 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1395 ret = NT_STATUS_SHARING_VIOLATION;
1398 unix_ERR_ntstatus = NT_STATUS_OK;
1401 close_file(fsp,False);
1402 return NT_STATUS_OK;
1405 /*******************************************************************
1406 Check if a user is allowed to delete a file.
1407 ********************************************************************/
1409 static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype, BOOL bad_path)
1411 SMB_STRUCT_STAT sbuf;
1417 DEBUG(10,("can_delete: %s, dirtype = %d\n",
1420 if (!CAN_WRITE(conn))
1421 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1423 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
1424 if(errno == ENOENT) {
1426 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1428 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1430 return map_nt_error_from_unix(errno);
1433 fmode = dos_mode(conn,fname,&sbuf);
1435 /* Can't delete a directory. */
1437 return NT_STATUS_FILE_IS_A_DIRECTORY;
1439 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
1440 return NT_STATUS_OBJECT_NAME_INVALID;
1441 #endif /* JRATEST */
1443 if (!lp_delete_readonly(SNUM(conn))) {
1445 return NT_STATUS_CANNOT_DELETE;
1447 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1448 return NT_STATUS_NO_SUCH_FILE;
1450 /* We need a better way to return NT status codes from open... */
1454 fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1455 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1458 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1459 if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
1460 ret = unix_ERR_ntstatus;
1461 else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1462 ret = NT_STATUS_SHARING_VIOLATION;
1465 unix_ERR_ntstatus = NT_STATUS_OK;
1468 close_file(fsp,False);
1469 return NT_STATUS_OK;
1472 /****************************************************************************
1473 The guts of the unlink command, split out so it may be called by the NT SMB
1475 ****************************************************************************/
1477 NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
1483 NTSTATUS error = NT_STATUS_OK;
1485 BOOL bad_path = False;
1487 SMB_STRUCT_STAT sbuf;
1489 *directory = *mask = 0;
1491 /* We must check for wildcards in the name given
1492 * directly by the client - before any unmangling.
1493 * This prevents an unmangling of a UNIX name containing
1494 * a DOS wildcard like '*' or '?' from unmangling into
1495 * a wildcard delete which was not intended.
1496 * FIX for #226. JRA.
1499 has_wild = ms_has_wild(name);
1501 rc = unix_convert(name,conn,0,&bad_path,&sbuf);
1503 p = strrchr_m(name,'/');
1505 pstrcpy(directory,".");
1509 pstrcpy(directory,name);
1514 * We should only check the mangled cache
1515 * here if unix_convert failed. This means
1516 * that the path in 'mask' doesn't exist
1517 * on the file system and so we need to look
1518 * for a possible mangle. This patch from
1519 * Tine Smukavec <valentin.smukavec@hermes.si>.
1522 if (!rc && mangle_is_mangled(mask))
1523 mangle_check_cache( mask );
1526 pstrcat(directory,"/");
1527 pstrcat(directory,mask);
1528 error = can_delete(directory,conn,dirtype,bad_path);
1529 if (!NT_STATUS_IS_OK(error))
1532 if (SMB_VFS_UNLINK(conn,directory) == 0) {
1536 void *dirptr = NULL;
1539 if (check_name(directory,conn))
1540 dirptr = OpenDir(conn, directory, True);
1542 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1543 the pattern matches against the long name, otherwise the short name
1544 We don't implement this yet XXXX
1548 error = NT_STATUS_NO_SUCH_FILE;
1550 if (strequal(mask,"????????.???"))
1553 while ((dname = ReadDirName(dirptr))) {
1555 BOOL sys_direntry = False;
1556 pstrcpy(fname,dname);
1558 /* Quick check for "." and ".." */
1559 if (fname[0] == '.') {
1560 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
1561 if ((dirtype & aDIR)) {
1562 sys_direntry = True;
1569 if(!mask_match(fname, mask, case_sensitive))
1573 error = NT_STATUS_OBJECT_NAME_INVALID;
1577 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
1578 error = can_delete(fname,conn,dirtype,bad_path);
1579 if (!NT_STATUS_IS_OK(error))
1581 if (SMB_VFS_UNLINK(conn,fname) == 0)
1583 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
1589 if (count == 0 && NT_STATUS_IS_OK(error)) {
1590 error = map_nt_error_from_unix(errno);
1596 /****************************************************************************
1598 ****************************************************************************/
1600 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
1607 START_PROFILE(SMBunlink);
1609 dirtype = SVAL(inbuf,smb_vwv0);
1611 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status);
1612 if (!NT_STATUS_IS_OK(status)) {
1613 END_PROFILE(SMBunlink);
1614 return ERROR_NT(status);
1617 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
1619 DEBUG(3,("reply_unlink : %s\n",name));
1621 status = unlink_internals(conn, dirtype, name);
1622 if (!NT_STATUS_IS_OK(status))
1623 return ERROR_NT(status);
1626 * Win2k needs a changenotify request response before it will
1627 * update after a rename..
1629 process_pending_change_notify_queue((time_t)0);
1631 outsize = set_message(outbuf,0,0,True);
1633 END_PROFILE(SMBunlink);
1637 /****************************************************************************
1639 ****************************************************************************/
1641 void fail_readraw(void)
1644 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
1646 exit_server(errstr);
1649 /****************************************************************************
1650 Use sendfile in readbraw.
1651 ****************************************************************************/
1653 void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
1654 ssize_t mincount, char *outbuf)
1658 #if defined(WITH_SENDFILE)
1660 * We can only use sendfile on a non-chained packet and on a file
1661 * that is exclusively oplocked. reply_readbraw has already checked the length.
1664 if ((nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) &&
1665 EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_use_sendfile(SNUM(conn)) ) {
1668 _smb_setlen(outbuf,nread);
1669 header.data = outbuf;
1673 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
1675 * Special hack for broken Linux with no 64 bit clean sendfile. If we
1676 * return ENOSYS then pretend we just got a normal read.
1678 if (errno == ENOSYS)
1681 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
1682 fsp->fsp_name, strerror(errno) ));
1683 exit_server("send_file_readbraw sendfile failed");
1692 ret = read_file(fsp,outbuf+4,startpos,nread);
1693 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
1702 _smb_setlen(outbuf,ret);
1703 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
1707 /****************************************************************************
1708 Reply to a readbraw (core+ protocol).
1709 ****************************************************************************/
1711 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
1713 extern struct current_user current_user;
1714 ssize_t maxcount,mincount;
1717 char *header = outbuf;
1719 START_PROFILE(SMBreadbraw);
1721 if (srv_is_signing_active()) {
1722 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
1726 * Special check if an oplock break has been issued
1727 * and the readraw request croses on the wire, we must
1728 * return a zero length response here.
1731 if(global_oplock_break) {
1732 _smb_setlen(header,0);
1733 if (write_data(smbd_server_fd(),header,4) != 4)
1735 DEBUG(5,("readbraw - oplock break finished\n"));
1736 END_PROFILE(SMBreadbraw);
1740 fsp = file_fsp(inbuf,smb_vwv0);
1742 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
1744 * fsp could be NULL here so use the value from the packet. JRA.
1746 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
1747 _smb_setlen(header,0);
1748 if (write_data(smbd_server_fd(),header,4) != 4)
1750 END_PROFILE(SMBreadbraw);
1754 CHECK_FSP(fsp,conn);
1756 flush_write_cache(fsp, READRAW_FLUSH);
1758 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
1759 if(CVAL(inbuf,smb_wct) == 10) {
1761 * This is a large offset (64 bit) read.
1763 #ifdef LARGE_SMB_OFF_T
1765 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
1767 #else /* !LARGE_SMB_OFF_T */
1770 * Ensure we haven't been sent a >32 bit offset.
1773 if(IVAL(inbuf,smb_vwv8) != 0) {
1774 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
1775 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
1776 _smb_setlen(header,0);
1777 if (write_data(smbd_server_fd(),header,4) != 4)
1779 END_PROFILE(SMBreadbraw);
1783 #endif /* LARGE_SMB_OFF_T */
1786 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
1787 _smb_setlen(header,0);
1788 if (write_data(smbd_server_fd(),header,4) != 4)
1790 END_PROFILE(SMBreadbraw);
1794 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
1795 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
1797 /* ensure we don't overrun the packet size */
1798 maxcount = MIN(65535,maxcount);
1800 if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1801 SMB_OFF_T size = fsp->size;
1802 SMB_OFF_T sizeneeded = startpos + maxcount;
1804 if (size < sizeneeded) {
1806 if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
1808 if (!fsp->can_write)
1812 if (startpos >= size)
1815 nread = MIN(maxcount,(size - startpos));
1818 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
1819 if (nread < mincount)
1823 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
1824 (int)maxcount, (int)mincount, (int)nread ) );
1826 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf);
1828 DEBUG(5,("readbraw finished\n"));
1829 END_PROFILE(SMBreadbraw);
1833 /****************************************************************************
1834 Reply to a lockread (core+ protocol).
1835 ****************************************************************************/
1837 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
1845 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1846 BOOL my_lock_ctx = False;
1847 START_PROFILE(SMBlockread);
1849 CHECK_FSP(fsp,conn);
1852 release_level_2_oplocks_on_change(fsp);
1854 numtoread = SVAL(inbuf,smb_vwv1);
1855 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1857 outsize = set_message(outbuf,5,3,True);
1858 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1859 data = smb_buf(outbuf) + 3;
1862 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
1863 * protocol request that predates the read/write lock concept.
1864 * Thus instead of asking for a read lock here we need to ask
1865 * for a write lock. JRA.
1866 * Note that the requested lock size is unaffected by max_recv.
1869 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
1870 (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &my_lock_ctx);
1872 if (NT_STATUS_V(status)) {
1875 * We used to make lockread a blocking lock. It turns out
1876 * that this isn't on W2k. Found by the Samba 4 RAW-READ torture
1880 if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
1882 * A blocking lock was requested. Package up
1883 * this smb into a queued request and push it
1884 * onto the blocking lock queue.
1886 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)startpos,
1887 (SMB_BIG_UINT)numtoread)) {
1888 END_PROFILE(SMBlockread);
1893 END_PROFILE(SMBlockread);
1894 return ERROR_NT(status);
1898 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
1901 if (numtoread > max_recv) {
1902 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
1903 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
1904 (unsigned int)numtoread, (unsigned int)max_recv ));
1905 numtoread = MIN(numtoread,max_recv);
1907 nread = read_file(fsp,data,startpos,numtoread);
1910 END_PROFILE(SMBlockread);
1911 return(UNIXERROR(ERRDOS,ERRnoaccess));
1915 SSVAL(outbuf,smb_vwv0,nread);
1916 SSVAL(outbuf,smb_vwv5,nread+3);
1917 SSVAL(smb_buf(outbuf),1,nread);
1919 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
1920 fsp->fnum, (int)numtoread, (int)nread));
1922 END_PROFILE(SMBlockread);
1926 /****************************************************************************
1928 ****************************************************************************/
1930 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
1937 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1938 START_PROFILE(SMBread);
1940 CHECK_FSP(fsp,conn);
1943 numtoread = SVAL(inbuf,smb_vwv1);
1944 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1946 outsize = set_message(outbuf,5,3,True);
1947 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1949 * The requested read size cannot be greater than max_recv. JRA.
1951 if (numtoread > max_recv) {
1952 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
1953 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
1954 (unsigned int)numtoread, (unsigned int)max_recv ));
1955 numtoread = MIN(numtoread,max_recv);
1958 data = smb_buf(outbuf) + 3;
1960 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1961 END_PROFILE(SMBread);
1962 return ERROR_DOS(ERRDOS,ERRlock);
1966 nread = read_file(fsp,data,startpos,numtoread);
1969 END_PROFILE(SMBread);
1970 return(UNIXERROR(ERRDOS,ERRnoaccess));
1974 SSVAL(outbuf,smb_vwv0,nread);
1975 SSVAL(outbuf,smb_vwv5,nread+3);
1976 SCVAL(smb_buf(outbuf),0,1);
1977 SSVAL(smb_buf(outbuf),1,nread);
1979 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
1980 fsp->fnum, (int)numtoread, (int)nread ) );
1982 END_PROFILE(SMBread);
1986 /****************************************************************************
1987 Reply to a read and X - possibly using sendfile.
1988 ****************************************************************************/
1990 int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length,
1991 files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
1994 char *data = smb_buf(outbuf);
1996 #if defined(WITH_SENDFILE)
1998 * We can only use sendfile on a non-chained packet and on a file
1999 * that is exclusively oplocked.
2002 if ((CVAL(inbuf,smb_vwv0) == 0xFF) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
2003 lp_use_sendfile(SNUM(conn)) && (lp_write_cache_size(SNUM(conn)) == 0) ) {
2004 SMB_STRUCT_STAT sbuf;
2007 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
2008 return(UNIXERROR(ERRDOS,ERRnoaccess));
2010 if (startpos > sbuf.st_size)
2013 if (smb_maxcnt > (sbuf.st_size - startpos))
2014 smb_maxcnt = (sbuf.st_size - startpos);
2016 if (smb_maxcnt == 0)
2020 * Set up the packet header before send. We
2021 * assume here the sendfile will work (get the
2022 * correct amount of data).
2025 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2026 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
2027 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2028 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
2029 SCVAL(outbuf,smb_vwv0,0xFF);
2030 set_message(outbuf,12,smb_maxcnt,False);
2031 header.data = outbuf;
2032 header.length = data - outbuf;
2035 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
2037 * Special hack for broken Linux with no 64 bit clean sendfile. If we
2038 * return ENOSYS then pretend we just got a normal read.
2040 if (errno == ENOSYS)
2043 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
2044 fsp->fsp_name, strerror(errno) ));
2045 exit_server("send_file_readX sendfile failed");
2048 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
2049 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2057 nread = read_file(fsp,data,startpos,smb_maxcnt);
2060 END_PROFILE(SMBreadX);
2061 return(UNIXERROR(ERRDOS,ERRnoaccess));
2064 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2065 SSVAL(outbuf,smb_vwv5,nread);
2066 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2067 SSVAL(smb_buf(outbuf),-2,nread);
2069 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
2070 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2075 /****************************************************************************
2076 Reply to a read and X.
2077 ****************************************************************************/
2079 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2081 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2082 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2084 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
2086 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
2089 START_PROFILE(SMBreadX);
2091 /* If it's an IPC, pass off the pipe handler. */
2093 END_PROFILE(SMBreadX);
2094 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
2097 CHECK_FSP(fsp,conn);
2100 set_message(outbuf,12,0,True);
2102 if(CVAL(inbuf,smb_wct) == 12) {
2103 #ifdef LARGE_SMB_OFF_T
2105 * This is a large offset (64 bit) read.
2107 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
2109 #else /* !LARGE_SMB_OFF_T */
2112 * Ensure we haven't been sent a >32 bit offset.
2115 if(IVAL(inbuf,smb_vwv10) != 0) {
2116 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2117 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
2118 END_PROFILE(SMBreadX);
2119 return ERROR_DOS(ERRDOS,ERRbadaccess);
2122 #endif /* LARGE_SMB_OFF_T */
2126 if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
2127 END_PROFILE(SMBreadX);
2128 return ERROR_DOS(ERRDOS,ERRlock);
2131 nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt);
2133 nread = chain_reply(inbuf,outbuf,length,bufsize);
2135 END_PROFILE(SMBreadX);
2139 /****************************************************************************
2140 Reply to a writebraw (core+ or LANMAN1.0 protocol).
2141 ****************************************************************************/
2143 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2146 ssize_t total_written=0;
2147 size_t numtowrite=0;
2152 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2154 START_PROFILE(SMBwritebraw);
2156 if (srv_is_signing_active()) {
2157 exit_server("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
2160 CHECK_FSP(fsp,conn);
2163 tcount = IVAL(inbuf,smb_vwv1);
2164 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2165 write_through = BITSETW(inbuf+smb_vwv7,0);
2167 /* We have to deal with slightly different formats depending
2168 on whether we are using the core+ or lanman1.0 protocol */
2170 if(Protocol <= PROTOCOL_COREPLUS) {
2171 numtowrite = SVAL(smb_buf(inbuf),-2);
2172 data = smb_buf(inbuf);
2174 numtowrite = SVAL(inbuf,smb_vwv10);
2175 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
2178 /* force the error type */
2179 SCVAL(inbuf,smb_com,SMBwritec);
2180 SCVAL(outbuf,smb_com,SMBwritec);
2182 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2183 END_PROFILE(SMBwritebraw);
2184 return(ERROR_DOS(ERRDOS,ERRlock));
2188 nwritten = write_file(fsp,data,startpos,numtowrite);
2190 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2191 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
2193 if (nwritten < (ssize_t)numtowrite) {
2194 END_PROFILE(SMBwritebraw);
2195 return(UNIXERROR(ERRHRD,ERRdiskfull));
2198 total_written = nwritten;
2200 /* Return a message to the redirector to tell it to send more bytes */
2201 SCVAL(outbuf,smb_com,SMBwritebraw);
2202 SSVALS(outbuf,smb_vwv0,-1);
2203 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
2204 if (!send_smb(smbd_server_fd(),outbuf))
2205 exit_server("reply_writebraw: send_smb failed.");
2207 /* Now read the raw data into the buffer and write it */
2208 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
2209 exit_server("secondary writebraw failed");
2212 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
2213 numtowrite = smb_len(inbuf);
2215 /* Set up outbuf to return the correct return */
2216 outsize = set_message(outbuf,1,0,True);
2217 SCVAL(outbuf,smb_com,SMBwritec);
2218 SSVAL(outbuf,smb_vwv0,total_written);
2220 if (numtowrite != 0) {
2222 if (numtowrite > BUFFER_SIZE) {
2223 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2224 (unsigned int)numtowrite ));
2225 exit_server("secondary writebraw failed");
2228 if (tcount > nwritten+numtowrite) {
2229 DEBUG(3,("Client overestimated the write %d %d %d\n",
2230 (int)tcount,(int)nwritten,(int)numtowrite));
2233 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
2234 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2236 exit_server("secondary writebraw failed");
2239 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
2241 if (nwritten < (ssize_t)numtowrite) {
2242 SCVAL(outbuf,smb_rcls,ERRHRD);
2243 SSVAL(outbuf,smb_err,ERRdiskfull);
2247 total_written += nwritten;
2250 if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
2251 sync_file(conn,fsp);
2253 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2254 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2256 /* we won't return a status if write through is not selected - this follows what WfWg does */
2257 END_PROFILE(SMBwritebraw);
2258 if (!write_through && total_written==tcount) {
2260 #if RABBIT_PELLET_FIX
2262 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2263 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2265 if (!send_keepalive(smbd_server_fd()))
2266 exit_server("reply_writebraw: send of keepalive failed");
2274 /****************************************************************************
2275 Reply to a writeunlock (core+).
2276 ****************************************************************************/
2278 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
2279 int size, int dum_buffsize)
2281 ssize_t nwritten = -1;
2285 NTSTATUS status = NT_STATUS_OK;
2286 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2288 START_PROFILE(SMBwriteunlock);
2290 CHECK_FSP(fsp,conn);
2293 numtowrite = SVAL(inbuf,smb_vwv1);
2294 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2295 data = smb_buf(inbuf) + 3;
2297 if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
2298 WRITE_LOCK,False)) {
2299 END_PROFILE(SMBwriteunlock);
2300 return ERROR_DOS(ERRDOS,ERRlock);
2303 /* The special X/Open SMB protocol handling of
2304 zero length writes is *NOT* done for
2309 nwritten = write_file(fsp,data,startpos,numtowrite);
2311 if (lp_syncalways(SNUM(conn)))
2312 sync_file(conn,fsp);
2314 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2315 END_PROFILE(SMBwriteunlock);
2316 return(UNIXERROR(ERRHRD,ERRdiskfull));
2320 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
2321 (SMB_BIG_UINT)startpos);
2322 if (NT_STATUS_V(status)) {
2323 END_PROFILE(SMBwriteunlock);
2324 return ERROR_NT(status);
2328 outsize = set_message(outbuf,1,0,True);
2330 SSVAL(outbuf,smb_vwv0,nwritten);
2332 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2333 fsp->fnum, (int)numtowrite, (int)nwritten));
2335 END_PROFILE(SMBwriteunlock);
2339 /****************************************************************************
2341 ****************************************************************************/
2343 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
2346 ssize_t nwritten = -1;
2349 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2351 START_PROFILE(SMBwrite);
2353 /* If it's an IPC, pass off the pipe handler. */
2355 END_PROFILE(SMBwrite);
2356 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
2359 CHECK_FSP(fsp,conn);
2362 numtowrite = SVAL(inbuf,smb_vwv1);
2363 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2364 data = smb_buf(inbuf) + 3;
2366 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2367 END_PROFILE(SMBwrite);
2368 return ERROR_DOS(ERRDOS,ERRlock);
2372 * X/Open SMB protocol says that if smb_vwv1 is
2373 * zero then the file size should be extended or
2374 * truncated to the size given in smb_vwv[2-3].
2377 if(numtowrite == 0) {
2379 * This is actually an allocate call, and set EOF. JRA.
2381 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
2383 END_PROFILE(SMBwrite);
2384 return ERROR_NT(NT_STATUS_DISK_FULL);
2386 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
2388 END_PROFILE(SMBwrite);
2389 return ERROR_NT(NT_STATUS_DISK_FULL);
2392 nwritten = write_file(fsp,data,startpos,numtowrite);
2394 if (lp_syncalways(SNUM(conn)))
2395 sync_file(conn,fsp);
2397 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2398 END_PROFILE(SMBwrite);
2399 return(UNIXERROR(ERRHRD,ERRdiskfull));
2402 outsize = set_message(outbuf,1,0,True);
2404 SSVAL(outbuf,smb_vwv0,nwritten);
2406 if (nwritten < (ssize_t)numtowrite) {
2407 SCVAL(outbuf,smb_rcls,ERRHRD);
2408 SSVAL(outbuf,smb_err,ERRdiskfull);
2411 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
2413 END_PROFILE(SMBwrite);
2417 /****************************************************************************
2418 Reply to a write and X.
2419 ****************************************************************************/
2421 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2423 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2424 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2425 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2426 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2427 ssize_t nwritten = -1;
2428 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
2429 unsigned int smblen = smb_len(inbuf);
2431 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
2432 START_PROFILE(SMBwriteX);
2434 /* If it's an IPC, pass off the pipe handler. */
2436 END_PROFILE(SMBwriteX);
2437 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2440 CHECK_FSP(fsp,conn);
2443 /* Deal with possible LARGE_WRITEX */
2445 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
2447 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
2448 END_PROFILE(SMBwriteX);
2449 return ERROR_DOS(ERRDOS,ERRbadmem);
2452 data = smb_base(inbuf) + smb_doff;
2454 if(CVAL(inbuf,smb_wct) == 14) {
2455 #ifdef LARGE_SMB_OFF_T
2457 * This is a large offset (64 bit) write.
2459 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2461 #else /* !LARGE_SMB_OFF_T */
2464 * Ensure we haven't been sent a >32 bit offset.
2467 if(IVAL(inbuf,smb_vwv12) != 0) {
2468 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
2469 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
2470 END_PROFILE(SMBwriteX);
2471 return ERROR_DOS(ERRDOS,ERRbadaccess);
2474 #endif /* LARGE_SMB_OFF_T */
2477 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2478 END_PROFILE(SMBwriteX);
2479 return ERROR_DOS(ERRDOS,ERRlock);
2482 /* X/Open SMB protocol says that, unlike SMBwrite
2483 if the length is zero then NO truncation is
2484 done, just a write of zero. To truncate a file,
2490 nwritten = write_file(fsp,data,startpos,numtowrite);
2492 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2493 END_PROFILE(SMBwriteX);
2494 return(UNIXERROR(ERRHRD,ERRdiskfull));
2497 set_message(outbuf,6,0,True);
2499 SSVAL(outbuf,smb_vwv2,nwritten);
2501 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
2503 if (nwritten < (ssize_t)numtowrite) {
2504 SCVAL(outbuf,smb_rcls,ERRHRD);
2505 SSVAL(outbuf,smb_err,ERRdiskfull);
2508 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2509 fsp->fnum, (int)numtowrite, (int)nwritten));
2511 if (lp_syncalways(SNUM(conn)) || write_through)
2512 sync_file(conn,fsp);
2514 END_PROFILE(SMBwriteX);
2515 return chain_reply(inbuf,outbuf,length,bufsize);
2518 /****************************************************************************
2520 ****************************************************************************/
2522 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2528 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2529 START_PROFILE(SMBlseek);
2531 CHECK_FSP(fsp,conn);
2533 flush_write_cache(fsp, SEEK_FLUSH);
2535 mode = SVAL(inbuf,smb_vwv1) & 3;
2536 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
2537 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
2546 res = fsp->pos + startpos;
2557 if (umode == SEEK_END) {
2558 if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
2559 if(errno == EINVAL) {
2560 SMB_OFF_T current_pos = startpos;
2561 SMB_STRUCT_STAT sbuf;
2563 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
2564 END_PROFILE(SMBlseek);
2565 return(UNIXERROR(ERRDOS,ERRnoaccess));
2568 current_pos += sbuf.st_size;
2570 res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
2575 END_PROFILE(SMBlseek);
2576 return(UNIXERROR(ERRDOS,ERRnoaccess));
2582 outsize = set_message(outbuf,2,0,True);
2583 SIVAL(outbuf,smb_vwv0,res);
2585 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2586 fsp->fnum, (double)startpos, (double)res, mode));
2588 END_PROFILE(SMBlseek);
2592 /****************************************************************************
2594 ****************************************************************************/
2596 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2598 int outsize = set_message(outbuf,0,0,True);
2599 uint16 fnum = SVAL(inbuf,smb_vwv0);
2600 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2601 START_PROFILE(SMBflush);
2604 CHECK_FSP(fsp,conn);
2607 file_sync_all(conn);
2609 sync_file(conn,fsp);
2612 DEBUG(3,("flush\n"));
2613 END_PROFILE(SMBflush);
2617 /****************************************************************************
2619 ****************************************************************************/
2621 int reply_exit(connection_struct *conn,
2622 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2625 START_PROFILE(SMBexit);
2627 file_close_pid(SVAL(inbuf,smb_pid));
2629 outsize = set_message(outbuf,0,0,True);
2631 DEBUG(3,("exit\n"));
2633 END_PROFILE(SMBexit);
2637 /****************************************************************************
2638 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2639 ****************************************************************************/
2641 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
2644 extern struct current_user current_user;
2647 int32 eclass = 0, err = 0;
2648 files_struct *fsp = NULL;
2649 START_PROFILE(SMBclose);
2651 outsize = set_message(outbuf,0,0,True);
2653 /* If it's an IPC, pass off to the pipe handler. */
2655 END_PROFILE(SMBclose);
2656 return reply_pipe_close(conn, inbuf,outbuf);
2659 fsp = file_fsp(inbuf,smb_vwv0);
2662 * We can only use CHECK_FSP if we know it's not a directory.
2665 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
2666 END_PROFILE(SMBclose);
2667 return ERROR_DOS(ERRDOS,ERRbadfid);
2670 if(fsp->is_directory) {
2672 * Special case - close NT SMB directory handle.
2674 DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
2675 close_file(fsp,True);
2678 * Close ordinary file.
2683 /* Save the name for time set in close. */
2684 pstrcpy( file_name, fsp->fsp_name);
2686 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2688 conn->num_files_open));
2691 * close_file() returns the unix errno if an error
2692 * was detected on close - normally this is due to
2693 * a disk full error. If not then it was probably an I/O error.
2696 if((close_err = close_file(fsp,True)) != 0) {
2698 END_PROFILE(SMBclose);
2699 return (UNIXERROR(ERRHRD,ERRgeneral));
2703 * Now take care of any time sent in the close.
2706 mtime = make_unix_date3(inbuf+smb_vwv1);
2708 /* try and set the date */
2709 set_filetime(conn, file_name, mtime);
2713 /* We have a cached error */
2715 END_PROFILE(SMBclose);
2716 return ERROR_DOS(eclass,err);
2719 END_PROFILE(SMBclose);
2723 /****************************************************************************
2724 Reply to a writeclose (Core+ protocol).
2725 ****************************************************************************/
2727 int reply_writeclose(connection_struct *conn,
2728 char *inbuf,char *outbuf, int size, int dum_buffsize)
2731 ssize_t nwritten = -1;
2737 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2738 START_PROFILE(SMBwriteclose);
2740 CHECK_FSP(fsp,conn);
2743 numtowrite = SVAL(inbuf,smb_vwv1);
2744 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2745 mtime = make_unix_date3(inbuf+smb_vwv4);
2746 data = smb_buf(inbuf) + 1;
2748 if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2749 END_PROFILE(SMBwriteclose);
2750 return ERROR_DOS(ERRDOS,ERRlock);
2753 nwritten = write_file(fsp,data,startpos,numtowrite);
2755 set_filetime(conn, fsp->fsp_name,mtime);
2758 * More insanity. W2K only closes the file if writelen > 0.
2763 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
2765 close_err = close_file(fsp,True);
2768 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2769 fsp->fnum, (int)numtowrite, (int)nwritten,
2770 conn->num_files_open));
2772 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2773 END_PROFILE(SMBwriteclose);
2774 return(UNIXERROR(ERRHRD,ERRdiskfull));
2777 if(close_err != 0) {
2779 END_PROFILE(SMBwriteclose);
2780 return(UNIXERROR(ERRHRD,ERRgeneral));
2783 outsize = set_message(outbuf,1,0,True);
2785 SSVAL(outbuf,smb_vwv0,nwritten);
2786 END_PROFILE(SMBwriteclose);
2790 /****************************************************************************
2792 ****************************************************************************/
2794 int reply_lock(connection_struct *conn,
2795 char *inbuf,char *outbuf, int length, int dum_buffsize)
2797 int outsize = set_message(outbuf,0,0,True);
2798 SMB_BIG_UINT count,offset;
2800 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2801 BOOL my_lock_ctx = False;
2803 START_PROFILE(SMBlock);
2805 CHECK_FSP(fsp,conn);
2807 release_level_2_oplocks_on_change(fsp);
2809 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2810 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2812 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2813 fsp->fd, fsp->fnum, (double)offset, (double)count));
2815 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx);
2816 if (NT_STATUS_V(status)) {
2818 /* Tests using Samba4 against W2K show this call never creates a blocking lock. */
2819 if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
2821 * A blocking lock was requested. Package up
2822 * this smb into a queued request and push it
2823 * onto the blocking lock queue.
2825 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), offset, count)) {
2826 END_PROFILE(SMBlock);
2831 END_PROFILE(SMBlock);
2832 return ERROR_NT(status);
2835 END_PROFILE(SMBlock);
2839 /****************************************************************************
2841 ****************************************************************************/
2843 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
2846 int outsize = set_message(outbuf,0,0,True);
2847 SMB_BIG_UINT count,offset;
2849 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2850 START_PROFILE(SMBunlock);
2852 CHECK_FSP(fsp,conn);
2854 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2855 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2857 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
2858 if (NT_STATUS_V(status)) {
2859 END_PROFILE(SMBunlock);
2860 return ERROR_NT(status);
2863 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2864 fsp->fd, fsp->fnum, (double)offset, (double)count ) );
2866 END_PROFILE(SMBunlock);
2870 /****************************************************************************
2872 ****************************************************************************/
2874 int reply_tdis(connection_struct *conn,
2875 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2877 int outsize = set_message(outbuf,0,0,True);
2879 START_PROFILE(SMBtdis);
2881 vuid = SVAL(inbuf,smb_uid);
2884 DEBUG(4,("Invalid connection in tdis\n"));
2885 END_PROFILE(SMBtdis);
2886 return ERROR_DOS(ERRSRV,ERRinvnid);
2891 close_cnum(conn,vuid);
2893 END_PROFILE(SMBtdis);
2897 /****************************************************************************
2899 ****************************************************************************/
2901 int reply_echo(connection_struct *conn,
2902 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2904 int smb_reverb = SVAL(inbuf,smb_vwv0);
2906 unsigned int data_len = smb_buflen(inbuf);
2907 int outsize = set_message(outbuf,1,data_len,True);
2908 START_PROFILE(SMBecho);
2910 if (data_len > BUFFER_SIZE) {
2911 DEBUG(0,("reply_echo: data_len too large.\n"));
2912 END_PROFILE(SMBecho);
2916 /* copy any incoming data back out */
2918 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
2920 if (smb_reverb > 100) {
2921 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
2925 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
2926 SSVAL(outbuf,smb_vwv0,seq_num);
2928 smb_setlen(outbuf,outsize - 4);
2930 if (!send_smb(smbd_server_fd(),outbuf))
2931 exit_server("reply_echo: send_smb failed.");
2934 DEBUG(3,("echo %d times\n", smb_reverb));
2938 END_PROFILE(SMBecho);
2942 /****************************************************************************
2943 Reply to a printopen.
2944 ****************************************************************************/
2946 int reply_printopen(connection_struct *conn,
2947 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2951 START_PROFILE(SMBsplopen);
2953 if (!CAN_PRINT(conn)) {
2954 END_PROFILE(SMBsplopen);
2955 return ERROR_DOS(ERRDOS,ERRnoaccess);
2958 /* Open for exclusive use, write only. */
2959 fsp = print_fsp_open(conn, NULL);
2962 END_PROFILE(SMBsplopen);
2963 return(UNIXERROR(ERRDOS,ERRnoaccess));
2966 outsize = set_message(outbuf,1,0,True);
2967 SSVAL(outbuf,smb_vwv0,fsp->fnum);
2969 DEBUG(3,("openprint fd=%d fnum=%d\n",
2970 fsp->fd, fsp->fnum));
2972 END_PROFILE(SMBsplopen);
2976 /****************************************************************************
2977 Reply to a printclose.
2978 ****************************************************************************/
2980 int reply_printclose(connection_struct *conn,
2981 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2983 int outsize = set_message(outbuf,0,0,True);
2984 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2986 START_PROFILE(SMBsplclose);
2988 CHECK_FSP(fsp,conn);
2990 if (!CAN_PRINT(conn)) {
2991 END_PROFILE(SMBsplclose);
2992 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
2995 DEBUG(3,("printclose fd=%d fnum=%d\n",
2996 fsp->fd,fsp->fnum));
2998 close_err = close_file(fsp,True);
3000 if(close_err != 0) {
3002 END_PROFILE(SMBsplclose);
3003 return(UNIXERROR(ERRHRD,ERRgeneral));
3006 END_PROFILE(SMBsplclose);
3010 /****************************************************************************
3011 Reply to a printqueue.
3012 ****************************************************************************/
3014 int reply_printqueue(connection_struct *conn,
3015 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3017 int outsize = set_message(outbuf,2,3,True);
3018 int max_count = SVAL(inbuf,smb_vwv0);
3019 int start_index = SVAL(inbuf,smb_vwv1);
3020 START_PROFILE(SMBsplretq);
3022 /* we used to allow the client to get the cnum wrong, but that
3023 is really quite gross and only worked when there was only
3024 one printer - I think we should now only accept it if they
3025 get it right (tridge) */
3026 if (!CAN_PRINT(conn)) {
3027 END_PROFILE(SMBsplretq);
3028 return ERROR_DOS(ERRDOS,ERRnoaccess);
3031 SSVAL(outbuf,smb_vwv0,0);
3032 SSVAL(outbuf,smb_vwv1,0);
3033 SCVAL(smb_buf(outbuf),0,1);
3034 SSVAL(smb_buf(outbuf),1,0);
3036 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
3037 start_index, max_count));
3040 print_queue_struct *queue = NULL;
3041 print_status_struct status;
3042 char *p = smb_buf(outbuf) + 3;
3043 int count = print_queue_status(SNUM(conn), &queue, &status);
3044 int num_to_get = ABS(max_count);
3045 int first = (max_count>0?start_index:start_index+max_count+1);
3051 num_to_get = MIN(num_to_get,count-first);
3054 for (i=first;i<first+num_to_get;i++) {
3055 put_dos_date2(p,0,queue[i].time);
3056 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
3057 SSVAL(p,5, queue[i].job);
3058 SIVAL(p,7,queue[i].size);
3060 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
3065 outsize = set_message(outbuf,2,28*count+3,False);
3066 SSVAL(outbuf,smb_vwv0,count);
3067 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
3068 SCVAL(smb_buf(outbuf),0,1);
3069 SSVAL(smb_buf(outbuf),1,28*count);
3074 DEBUG(3,("%d entries returned in queue\n",count));
3077 END_PROFILE(SMBsplretq);
3081 /****************************************************************************
3082 Reply to a printwrite.
3083 ****************************************************************************/
3085 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3088 int outsize = set_message(outbuf,0,0,True);
3090 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3092 START_PROFILE(SMBsplwr);
3094 if (!CAN_PRINT(conn)) {
3095 END_PROFILE(SMBsplwr);
3096 return ERROR_DOS(ERRDOS,ERRnoaccess);
3099 CHECK_FSP(fsp,conn);
3102 numtowrite = SVAL(smb_buf(inbuf),1);
3103 data = smb_buf(inbuf) + 3;
3105 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
3106 END_PROFILE(SMBsplwr);
3107 return(UNIXERROR(ERRHRD,ERRdiskfull));
3110 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
3112 END_PROFILE(SMBsplwr);
3116 /****************************************************************************
3117 The guts of the mkdir command, split out so it may be called by the NT SMB
3119 ****************************************************************************/
3121 NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
3123 BOOL bad_path = False;
3124 SMB_STRUCT_STAT sbuf;
3127 unix_convert(directory,conn,0,&bad_path,&sbuf);
3129 if( strchr_m(directory, ':')) {
3130 return NT_STATUS_NOT_A_DIRECTORY;
3133 if (ms_has_wild(directory)) {
3134 return NT_STATUS_OBJECT_NAME_INVALID;
3137 if (check_name(directory, conn))
3138 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3141 if(errno == ENOENT) {
3143 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3145 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3147 return map_nt_error_from_unix(errno);
3150 return NT_STATUS_OK;
3153 /****************************************************************************
3155 ****************************************************************************/
3157 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3162 START_PROFILE(SMBmkdir);
3164 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status);
3165 if (!NT_STATUS_IS_OK(status)) {
3166 END_PROFILE(SMBmkdir);
3167 return ERROR_NT(status);
3170 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
3172 status = mkdir_internal(conn, directory);
3173 if (!NT_STATUS_IS_OK(status)) {
3174 END_PROFILE(SMBmkdir);
3175 return ERROR_NT(status);
3178 outsize = set_message(outbuf,0,0,True);
3180 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
3182 END_PROFILE(SMBmkdir);
3186 /****************************************************************************
3187 Static function used by reply_rmdir to delete an entire directory
3188 tree recursively. Return False on ok, True on fail.
3189 ****************************************************************************/
3191 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
3193 const char *dname = NULL;
3195 void *dirptr = OpenDir(conn, directory, False);
3200 while((dname = ReadDirName(dirptr))) {
3204 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3207 /* Construct the full name. */
3208 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3214 pstrcpy(fullname, directory);
3215 pstrcat(fullname, "/");
3216 pstrcat(fullname, dname);
3218 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
3223 if(st.st_mode & S_IFDIR) {
3224 if(recursive_rmdir(conn, fullname)!=0) {
3228 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
3232 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
3241 /****************************************************************************
3242 The internals of the rmdir code - called elsewhere.
3243 ****************************************************************************/
3245 BOOL rmdir_internals(connection_struct *conn, char *directory)
3249 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3250 if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
3252 * Check to see if the only thing in this directory are
3253 * vetoed files/directories. If so then delete them and
3254 * retry. If we fail to delete any of them (and we *don't*
3255 * do a recursive delete) then fail the rmdir.
3257 BOOL all_veto_files = True;
3259 void *dirptr = OpenDir(conn, directory, False);
3261 if(dirptr != NULL) {
3262 int dirpos = TellDir(dirptr);
3263 while ((dname = ReadDirName(dirptr))) {
3264 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3266 if(!IS_VETO_PATH(conn, dname)) {
3267 all_veto_files = False;
3272 if(all_veto_files) {
3273 SeekDir(dirptr,dirpos);
3274 while ((dname = ReadDirName(dirptr))) {
3278 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3281 /* Construct the full name. */
3282 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3287 pstrcpy(fullname, directory);
3288 pstrcat(fullname, "/");
3289 pstrcat(fullname, dname);
3291 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
3293 if(st.st_mode & S_IFDIR) {
3294 if(lp_recursive_veto_delete(SNUM(conn))) {
3295 if(recursive_rmdir(conn, fullname) != 0)
3298 if(SMB_VFS_RMDIR(conn,fullname) != 0)
3300 } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
3304 /* Retry the rmdir */
3305 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3315 DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory,strerror(errno)));
3320 /****************************************************************************
3322 ****************************************************************************/
3324 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3329 BOOL bad_path = False;
3330 SMB_STRUCT_STAT sbuf;
3332 START_PROFILE(SMBrmdir);
3334 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status);
3335 if (!NT_STATUS_IS_OK(status)) {
3336 END_PROFILE(SMBrmdir);
3337 return ERROR_NT(status);
3340 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
3342 unix_convert(directory,conn, NULL,&bad_path,&sbuf);
3344 if (check_name(directory,conn)) {
3345 dptr_closepath(directory,SVAL(inbuf,smb_pid));
3346 ok = rmdir_internals(conn, directory);
3350 END_PROFILE(SMBrmdir);
3351 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRbadpath);
3354 outsize = set_message(outbuf,0,0,True);
3356 DEBUG( 3, ( "rmdir %s\n", directory ) );
3358 END_PROFILE(SMBrmdir);
3362 /*******************************************************************
3363 Resolve wildcards in a filename rename.
3364 ********************************************************************/
3366 static BOOL resolve_wildcards(const char *name1, char *name2)
3368 fstring root1,root2;
3370 char *p,*p2, *pname1, *pname2;
3371 int available_space;
3374 pname1 = strrchr_m(name1,'/');
3375 pname2 = strrchr_m(name2,'/');
3377 if (!pname1 || !pname2)
3380 fstrcpy(root1,pname1);
3381 fstrcpy(root2,pname2);
3382 p = strrchr_m(root1,'.');
3389 p = strrchr_m(root2,'.');
3423 available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
3426 snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
3428 pstrcpy_base(pname2, root2, name2);
3434 /****************************************************************************
3435 Ensure open files have their names updates.
3436 ****************************************************************************/
3438 static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, char *newname)
3441 BOOL did_rename = False;
3443 for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
3444 DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
3445 fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode,
3446 fsp->fsp_name, newname ));
3447 string_set(&fsp->fsp_name, newname);
3452 DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
3453 (unsigned int)dev, (double)inode, newname ));
3456 /****************************************************************************
3457 Rename an open file - given an fsp.
3458 ****************************************************************************/
3460 NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, BOOL replace_if_exists)
3462 SMB_STRUCT_STAT sbuf;
3463 BOOL bad_path = False;
3464 pstring newname_last_component;
3465 NTSTATUS error = NT_STATUS_OK;
3470 rcdest = unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf);
3472 /* Quick check for "." and ".." */
3473 if (!bad_path && newname_last_component[0] == '.') {
3474 if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) {
3475 return NT_STATUS_ACCESS_DENIED;
3478 if (!rcdest && bad_path) {
3479 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3482 /* Ensure newname contains a '/' */
3483 if(strrchr_m(newname,'/') == 0) {
3486 pstrcpy(tmpstr, "./");
3487 pstrcat(tmpstr, newname);
3488 pstrcpy(newname, tmpstr);
3492 * Check for special case with case preserving and not
3493 * case sensitive. If the old last component differs from the original
3494 * last component only by case, then we should allow
3495 * the rename (user is trying to change the case of the
3499 if((case_sensitive == False) && (case_preserve == True) &&
3500 strequal(newname, fsp->fsp_name)) {
3502 pstring newname_modified_last_component;
3505 * Get the last component of the modified name.
3506 * Note that we guarantee that newname contains a '/'
3509 p = strrchr_m(newname,'/');
3510 pstrcpy(newname_modified_last_component,p+1);
3512 if(strcsequal(newname_modified_last_component,
3513 newname_last_component) == False) {
3515 * Replace the modified last component with
3518 pstrcpy(p+1, newname_last_component);
3523 * If the src and dest names are identical - including case,
3524 * don't do the rename, just return success.
3527 if (strcsequal(fsp->fsp_name, newname)) {
3528 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
3530 return NT_STATUS_OK;
3533 dest_exists = vfs_object_exist(conn,newname,NULL);
3535 if(!replace_if_exists && dest_exists) {
3536 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
3537 fsp->fsp_name,newname));
3538 return NT_STATUS_OBJECT_NAME_COLLISION;
3541 error = can_rename(newname,conn,&sbuf);
3543 if (dest_exists && !NT_STATUS_IS_OK(error)) {
3544 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3545 nt_errstr(error), fsp->fsp_name,newname));
3546 if (NT_STATUS_EQUAL(error,NT_STATUS_SHARING_VIOLATION))
3547 error = NT_STATUS_ACCESS_DENIED;
3551 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
3552 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
3553 fsp->fsp_name,newname));
3554 rename_open_files(conn, fsp->dev, fsp->inode, newname);
3555 return NT_STATUS_OK;
3558 if (errno == ENOTDIR || errno == EISDIR)
3559 error = NT_STATUS_OBJECT_NAME_COLLISION;
3561 error = map_nt_error_from_unix(errno);
3563 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
3564 nt_errstr(error), fsp->fsp_name,newname));
3569 /****************************************************************************
3570 The guts of the rename command, split out so it may be called by the NT SMB
3572 ****************************************************************************/
3574 NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint16 attrs, BOOL replace_if_exists)
3578 pstring last_component_src;
3579 pstring last_component_dest;
3582 BOOL bad_path_src = False;
3583 BOOL bad_path_dest = False;
3585 NTSTATUS error = NT_STATUS_OK;
3588 SMB_STRUCT_STAT sbuf1, sbuf2;
3590 *directory = *mask = 0;
3595 rc = unix_convert(name,conn,last_component_src,&bad_path_src,&sbuf1);
3596 if (!rc && bad_path_src) {
3597 if (ms_has_wild(last_component_src))
3598 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3599 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3602 /* Quick check for "." and ".." */
3603 if (last_component_src[0] == '.') {
3604 if (!last_component_src[1] || (last_component_src[1] == '.' && !last_component_src[2])) {
3605 return NT_STATUS_OBJECT_NAME_INVALID;
3609 rcdest = unix_convert(newname,conn,last_component_dest,&bad_path_dest,&sbuf2);
3611 /* Quick check for "." and ".." */
3612 if (last_component_dest[0] == '.') {
3613 if (!last_component_dest[1] || (last_component_dest[1] == '.' && !last_component_dest[2])) {
3614 return NT_STATUS_OBJECT_NAME_INVALID;
3619 * Split the old name into directory and last component
3620 * strings. Note that unix_convert may have stripped off a
3621 * leading ./ from both name and newname if the rename is
3622 * at the root of the share. We need to make sure either both
3623 * name and newname contain a / character or neither of them do
3624 * as this is checked in resolve_wildcards().
3627 p = strrchr_m(name,'/');
3629 pstrcpy(directory,".");
3633 pstrcpy(directory,name);
3635 *p = '/'; /* Replace needed for exceptional test below. */
3639 * We should only check the mangled cache
3640 * here if unix_convert failed. This means
3641 * that the path in 'mask' doesn't exist
3642 * on the file system and so we need to look
3643 * for a possible mangle. This patch from
3644 * Tine Smukavec <valentin.smukavec@hermes.si>.
3647 if (!rc && mangle_is_mangled(mask))
3648 mangle_check_cache( mask );
3650 has_wild = ms_has_wild(mask);
3654 * No wildcards - just process the one file.
3656 BOOL is_short_name = mangle_is_8_3(name, True);
3658 /* Add a terminating '/' to the directory name. */
3659 pstrcat(directory,"/");
3660 pstrcat(directory,mask);
3662 /* Ensure newname contains a '/' also */
3663 if(strrchr_m(newname,'/') == 0) {
3666 pstrcpy(tmpstr, "./");
3667 pstrcat(tmpstr, newname);
3668 pstrcpy(newname, tmpstr);
3671 DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
3672 directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
3673 case_sensitive, case_preserve, short_case_preserve, directory,
3674 newname, last_component_dest, is_short_name));
3677 * Check for special case with case preserving and not
3678 * case sensitive, if directory and newname are identical,
3679 * and the old last component differs from the original
3680 * last component only by case, then we should allow
3681 * the rename (user is trying to change the case of the
3684 if((case_sensitive == False) &&
3685 (((case_preserve == True) &&
3686 (is_short_name == False)) ||
3687 ((short_case_preserve == True) &&
3688 (is_short_name == True))) &&
3689 strcsequal(directory, newname)) {
3690 pstring modified_last_component;
3693 * Get the last component of the modified name.
3694 * Note that we guarantee that newname contains a '/'
3697 p = strrchr_m(newname,'/');
3698 pstrcpy(modified_last_component,p+1);
3700 if(strcsequal(modified_last_component,
3701 last_component_dest) == False) {
3703 * Replace the modified last component with
3706 pstrcpy(p+1, last_component_dest);
3710 resolve_wildcards(directory,newname);
3713 * The source object must exist.
3716 if (!vfs_object_exist(conn, directory, &sbuf1)) {
3717 DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
3718 directory,newname));
3720 if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
3722 * Must return different errors depending on whether the parent
3723 * directory existed or not.
3726 p = strrchr_m(directory, '/');
3728 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3730 if (vfs_object_exist(conn, directory, NULL))
3731 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3732 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3734 error = map_nt_error_from_unix(errno);
3735 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3736 nt_errstr(error), directory,newname));
3741 if (!rcdest && bad_path_dest) {
3742 if (ms_has_wild(last_component_dest))
3743 return NT_STATUS_OBJECT_NAME_INVALID;
3744 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3747 error = can_rename(directory,conn,&sbuf1);
3749 if (!NT_STATUS_IS_OK(error)) {
3750 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3751 nt_errstr(error), directory,newname));
3756 * If the src and dest names are identical - including case,
3757 * don't do the rename, just return success.
3760 if (strcsequal(directory, newname)) {
3761 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3762 DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
3763 return NT_STATUS_OK;
3766 if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
3767 DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
3768 directory,newname));
3769 return NT_STATUS_OBJECT_NAME_COLLISION;
3772 if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
3773 DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
3774 directory,newname));
3775 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3776 return NT_STATUS_OK;
3779 if (errno == ENOTDIR || errno == EISDIR)
3780 error = NT_STATUS_OBJECT_NAME_COLLISION;
3782 error = map_nt_error_from_unix(errno);
3784 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3785 nt_errstr(error), directory,newname));
3790 * Wildcards - process each file that matches.
3792 void *dirptr = NULL;
3796 if (check_name(directory,conn))
3797 dirptr = OpenDir(conn, directory, True);
3800 error = NT_STATUS_NO_SUCH_FILE;
3801 /* Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */
3803 if (strequal(mask,"????????.???"))
3806 while ((dname = ReadDirName(dirptr))) {
3808 BOOL sysdir_entry = False;
3810 pstrcpy(fname,dname);
3812 /* Quick check for "." and ".." */
3813 if (fname[0] == '.') {
3814 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
3816 sysdir_entry = True;
3823 if(!mask_match(fname, mask, case_sensitive))
3827 error = NT_STATUS_OBJECT_NAME_INVALID;
3831 error = NT_STATUS_ACCESS_DENIED;
3832 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
3833 if (!vfs_object_exist(conn, fname, &sbuf1)) {
3834 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3835 DEBUG(6,("rename %s failed. Error %s\n", fname, nt_errstr(error)));
3838 error = can_rename(fname,conn,&sbuf1);
3839 if (!NT_STATUS_IS_OK(error)) {
3840 DEBUG(6,("rename %s refused\n", fname));
3843 pstrcpy(destname,newname);
3845 if (!resolve_wildcards(fname,destname)) {
3846 DEBUG(6,("resolve_wildcards %s %s failed\n",
3851 if (!replace_if_exists &&
3852 vfs_file_exist(conn,destname, NULL)) {
3853 DEBUG(6,("file_exist %s\n", destname));
3854 error = NT_STATUS_OBJECT_NAME_COLLISION;
3858 if (!SMB_VFS_RENAME(conn,fname,destname)) {
3859 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3861 error = NT_STATUS_OK;
3863 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
3868 if (!NT_STATUS_EQUAL(error,NT_STATUS_NO_SUCH_FILE)) {
3869 if (!rcdest && bad_path_dest) {
3870 if (ms_has_wild(last_component_dest))
3871 return NT_STATUS_OBJECT_NAME_INVALID;
3872 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3877 if (count == 0 && NT_STATUS_IS_OK(error)) {
3878 error = map_nt_error_from_unix(errno);
3884 /****************************************************************************
3886 ****************************************************************************/
3888 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
3895 uint16 attrs = SVAL(inbuf,smb_vwv0);
3898 START_PROFILE(SMBmv);
3900 p = smb_buf(inbuf) + 1;
3901 p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status);
3902 if (!NT_STATUS_IS_OK(status)) {
3904 return ERROR_NT(status);
3907 p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
3908 if (!NT_STATUS_IS_OK(status)) {
3910 return ERROR_NT(status);
3913 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3914 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3916 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
3918 status = rename_internals(conn, name, newname, attrs, False);
3919 if (!NT_STATUS_IS_OK(status)) {
3921 return ERROR_NT(status);
3925 * Win2k needs a changenotify request response before it will
3926 * update after a rename..
3928 process_pending_change_notify_queue((time_t)0);
3929 outsize = set_message(outbuf,0,0,True);
3935 /*******************************************************************
3936 Copy a file as part of a reply_copy.
3937 ******************************************************************/
3939 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
3940 int count,BOOL target_is_directory, int *err_ret)
3943 SMB_STRUCT_STAT src_sbuf, sbuf2;
3945 files_struct *fsp1,*fsp2;
3950 pstrcpy(dest,dest1);
3951 if (target_is_directory) {
3952 char *p = strrchr_m(src,'/');
3961 if (!vfs_file_exist(conn,src,&src_sbuf))
3964 fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
3965 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
3970 if (!target_is_directory && count)
3971 ofun = FILE_EXISTS_OPEN;
3973 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
3974 ZERO_STRUCTP(&sbuf2);
3976 fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
3977 ofun,src_sbuf.st_mode,0,&Access,&action);
3980 close_file(fsp1,False);
3984 if ((ofun&3) == 1) {
3985 if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
3986 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
3988 * Stop the copy from occurring.
3991 src_sbuf.st_size = 0;
3995 if (src_sbuf.st_size)
3996 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
3998 close_file(fsp1,False);
4000 /* Ensure the modtime is set correctly on the destination file. */
4001 fsp2->pending_modtime = src_sbuf.st_mtime;
4004 * As we are opening fsp1 read-only we only expect
4005 * an error on close on fsp2 if we are out of space.
4006 * Thus we don't look at the error return from the
4009 *err_ret = close_file(fsp2,False);
4011 return(ret == (SMB_OFF_T)src_sbuf.st_size);
4014 /****************************************************************************
4015 Reply to a file copy.
4016 ****************************************************************************/
4018 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4023 pstring mask,newname;
4026 int error = ERRnoaccess;
4030 int tid2 = SVAL(inbuf,smb_vwv0);
4031 int ofun = SVAL(inbuf,smb_vwv1);
4032 int flags = SVAL(inbuf,smb_vwv2);
4033 BOOL target_is_directory=False;
4034 BOOL bad_path1 = False;
4035 BOOL bad_path2 = False;
4037 SMB_STRUCT_STAT sbuf1, sbuf2;
4040 START_PROFILE(SMBcopy);
4042 *directory = *mask = 0;
4045 p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status);
4046 if (!NT_STATUS_IS_OK(status)) {
4047 END_PROFILE(SMBcopy);
4048 return ERROR_NT(status);
4050 p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
4051 if (!NT_STATUS_IS_OK(status)) {
4052 END_PROFILE(SMBcopy);
4053 return ERROR_NT(status);
4056 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
4058 if (tid2 != conn->cnum) {
4059 /* can't currently handle inter share copies XXXX */
4060 DEBUG(3,("Rejecting inter-share copy\n"));
4061 END_PROFILE(SMBcopy);
4062 return ERROR_DOS(ERRSRV,ERRinvdevice);
4065 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
4066 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4068 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
4069 unix_convert(newname,conn,0,&bad_path2,&sbuf2);
4071 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
4073 if ((flags&1) && target_is_directory) {
4074 END_PROFILE(SMBcopy);
4075 return ERROR_DOS(ERRDOS,ERRbadfile);
4078 if ((flags&2) && !target_is_directory) {
4079 END_PROFILE(SMBcopy);
4080 return ERROR_DOS(ERRDOS,ERRbadpath);
4083 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
4084 /* wants a tree copy! XXXX */
4085 DEBUG(3,("Rejecting tree copy\n"));
4086 END_PROFILE(SMBcopy);
4087 return ERROR_DOS(ERRSRV,ERRerror);
4090 p = strrchr_m(name,'/');
4092 pstrcpy(directory,"./");
4096 pstrcpy(directory,name);
4101 * We should only check the mangled cache
4102 * here if unix_convert failed. This means
4103 * that the path in 'mask' doesn't exist
4104 * on the file system and so we need to look
4105 * for a possible mangle. This patch from
4106 * Tine Smukavec <valentin.smukavec@hermes.si>.
4109 if (!rc && mangle_is_mangled(mask))
4110 mangle_check_cache( mask );
4112 has_wild = ms_has_wild(mask);
4115 pstrcat(directory,"/");
4116 pstrcat(directory,mask);
4117 if (resolve_wildcards(directory,newname) &&
4118 copy_file(directory,newname,conn,ofun, count,target_is_directory,&err))
4122 END_PROFILE(SMBcopy);
4123 return(UNIXERROR(ERRHRD,ERRgeneral));
4126 exists = vfs_file_exist(conn,directory,NULL);
4129 void *dirptr = NULL;
4133 if (check_name(directory,conn))
4134 dirptr = OpenDir(conn, directory, True);
4139 if (strequal(mask,"????????.???"))
4142 while ((dname = ReadDirName(dirptr))) {
4144 pstrcpy(fname,dname);
4146 if(!mask_match(fname, mask, case_sensitive))
4149 error = ERRnoaccess;
4150 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
4151 pstrcpy(destname,newname);
4152 if (resolve_wildcards(fname,destname) &&
4153 copy_file(fname,destname,conn,ofun,
4154 count,target_is_directory,&err))
4156 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
4164 /* Error on close... */
4166 END_PROFILE(SMBcopy);
4167 return(UNIXERROR(ERRHRD,ERRgeneral));
4171 END_PROFILE(SMBcopy);
4172 return ERROR_DOS(ERRDOS,error);
4174 if((errno == ENOENT) && (bad_path1 || bad_path2)) {
4175 unix_ERR_class = ERRDOS;
4176 unix_ERR_code = ERRbadpath;
4178 END_PROFILE(SMBcopy);
4179 return(UNIXERROR(ERRDOS,error));
4183 outsize = set_message(outbuf,1,0,True);
4184 SSVAL(outbuf,smb_vwv0,count);
4186 END_PROFILE(SMBcopy);
4190 /****************************************************************************
4192 ****************************************************************************/
4194 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4202 START_PROFILE(pathworks_setdir);
4205 if (!CAN_SETDIR(snum)) {
4206 END_PROFILE(pathworks_setdir);
4207 return ERROR_DOS(ERRDOS,ERRnoaccess);
4210 srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE, &status);
4211 if (!NT_STATUS_IS_OK(status)) {
4212 END_PROFILE(pathworks_setdir);
4213 return ERROR_NT(status);
4216 if (strlen(newdir) == 0) {
4219 ok = vfs_directory_exist(conn,newdir,NULL);
4221 string_set(&conn->connectpath,newdir);
4225 END_PROFILE(pathworks_setdir);
4226 return ERROR_DOS(ERRDOS,ERRbadpath);
4229 outsize = set_message(outbuf,0,0,True);
4230 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
4232 DEBUG(3,("setdir %s\n", newdir));
4234 END_PROFILE(pathworks_setdir);
4238 /****************************************************************************
4239 Get a lock pid, dealing with large count requests.
4240 ****************************************************************************/
4242 uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
4244 if(!large_file_format)
4245 return SVAL(data,SMB_LPID_OFFSET(data_offset));
4247 return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
4250 /****************************************************************************
4251 Get a lock count, dealing with large count requests.
4252 ****************************************************************************/
4254 SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
4256 SMB_BIG_UINT count = 0;
4258 if(!large_file_format) {
4259 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
4262 #if defined(HAVE_LONGLONG)
4263 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
4264 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
4265 #else /* HAVE_LONGLONG */
4268 * NT4.x seems to be broken in that it sends large file (64 bit)
4269 * lockingX calls even if the CAP_LARGE_FILES was *not*
4270 * negotiated. For boxes without large unsigned ints truncate the
4271 * lock count by dropping the top 32 bits.
4274 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
4275 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
4276 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
4277 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
4278 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
4281 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
4282 #endif /* HAVE_LONGLONG */
4288 #if !defined(HAVE_LONGLONG)
4289 /****************************************************************************
4290 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
4291 ****************************************************************************/
4293 static uint32 map_lock_offset(uint32 high, uint32 low)
4297 uint32 highcopy = high;
4300 * Try and find out how many significant bits there are in high.
4303 for(i = 0; highcopy; i++)
4307 * We use 31 bits not 32 here as POSIX
4308 * lock offsets may not be negative.
4311 mask = (~0) << (31 - i);
4314 return 0; /* Fail. */
4320 #endif /* !defined(HAVE_LONGLONG) */
4322 /****************************************************************************
4323 Get a lock offset, dealing with large offset requests.
4324 ****************************************************************************/
4326 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
4328 SMB_BIG_UINT offset = 0;
4332 if(!large_file_format) {
4333 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
4336 #if defined(HAVE_LONGLONG)
4337 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
4338 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
4339 #else /* HAVE_LONGLONG */
4342 * NT4.x seems to be broken in that it sends large file (64 bit)
4343 * lockingX calls even if the CAP_LARGE_FILES was *not*
4344 * negotiated. For boxes without large unsigned ints mangle the
4345 * lock offset by mapping the top 32 bits onto the lower 32.
4348 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
4349 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4350 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
4353 if((new_low = map_lock_offset(high, low)) == 0) {
4355 return (SMB_BIG_UINT)-1;
4358 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
4359 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
4360 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
4361 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
4364 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4365 #endif /* HAVE_LONGLONG */
4371 /****************************************************************************
4372 Reply to a lockingX request.
4373 ****************************************************************************/
4375 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4377 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
4378 unsigned char locktype = CVAL(inbuf,smb_vwv3);
4379 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
4380 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
4381 uint16 num_locks = SVAL(inbuf,smb_vwv7);
4382 SMB_BIG_UINT count = 0, offset = 0;
4384 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
4387 BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
4389 BOOL my_lock_ctx = False;
4392 START_PROFILE(SMBlockingX);
4394 CHECK_FSP(fsp,conn);
4396 data = smb_buf(inbuf);
4398 if (locktype & (LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_CHANGE_LOCKTYPE)) {
4399 /* we don't support these - and CANCEL_LOCK makes w2k
4400 and XP reboot so I don't really want to be
4401 compatible! (tridge) */
4402 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4405 /* Check if this is an oplock break on a file
4406 we have granted an oplock on.
4408 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
4409 /* Client can insist on breaking to none. */
4410 BOOL break_to_none = (oplocklevel == 0);
4412 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
4413 (unsigned int)oplocklevel, fsp->fnum ));
4416 * Make sure we have granted an exclusive or batch oplock on this file.
4419 if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
4420 DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
4421 no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
4423 /* if this is a pure oplock break request then don't send a reply */
4424 if (num_locks == 0 && num_ulocks == 0) {
4425 END_PROFILE(SMBlockingX);
4428 END_PROFILE(SMBlockingX);
4429 return ERROR_DOS(ERRDOS,ERRlock);
4433 if (remove_oplock(fsp, break_to_none) == False) {
4434 DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
4438 /* if this is a pure oplock break request then don't send a reply */
4439 if (num_locks == 0 && num_ulocks == 0) {
4440 /* Sanity check - ensure a pure oplock break is not a
4442 if(CVAL(inbuf,smb_vwv0) != 0xff)
4443 DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
4444 (unsigned int)CVAL(inbuf,smb_vwv0) ));
4445 END_PROFILE(SMBlockingX);
4451 * We do this check *after* we have checked this is not a oplock break
4452 * response message. JRA.
4455 release_level_2_oplocks_on_change(fsp);
4457 /* Data now points at the beginning of the list
4458 of smb_unlkrng structs */
4459 for(i = 0; i < (int)num_ulocks; i++) {
4460 lock_pid = get_lock_pid( data, i, large_file_format);
4461 count = get_lock_count( data, i, large_file_format);
4462 offset = get_lock_offset( data, i, large_file_format, &err);
4465 * There is no error code marked "stupid client bug".... :-).
4468 END_PROFILE(SMBlockingX);
4469 return ERROR_DOS(ERRDOS,ERRnoaccess);
4472 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
4473 (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
4475 status = do_unlock(fsp,conn,lock_pid,count,offset);
4476 if (NT_STATUS_V(status)) {
4477 END_PROFILE(SMBlockingX);
4478 return ERROR_NT(status);
4482 /* Setup the timeout in seconds. */
4484 lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000);
4486 /* Now do any requested locks */
4487 data += ((large_file_format ? 20 : 10)*num_ulocks);
4489 /* Data now points at the beginning of the list
4490 of smb_lkrng structs */
4492 for(i = 0; i < (int)num_locks; i++) {
4493 lock_pid = get_lock_pid( data, i, large_file_format);
4494 count = get_lock_count( data, i, large_file_format);
4495 offset = get_lock_offset( data, i, large_file_format, &err);
4498 * There is no error code marked "stupid client bug".... :-).
4501 END_PROFILE(SMBlockingX);
4502 return ERROR_DOS(ERRDOS,ERRnoaccess);
4505 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
4506 (double)offset, (double)count, (unsigned int)lock_pid,
4507 fsp->fsp_name, (int)lock_timeout ));
4509 status = do_lock_spin(fsp,conn,lock_pid, count,offset,
4510 ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx);
4511 if (NT_STATUS_V(status)) {
4513 * Interesting fact found by IFSTEST /t LockOverlappedTest...
4514 * Even if it's our own lock context, we need to wait here as
4515 * there may be an unlock on the way.
4516 * So I removed a "&& !my_lock_ctx" from the following
4517 * if statement. JRA.
4519 if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
4521 * A blocking lock was requested. Package up
4522 * this smb into a queued request and push it
4523 * onto the blocking lock queue.
4525 if(push_blocking_lock_request(inbuf, length, lock_timeout, i, lock_pid, offset, count)) {
4526 END_PROFILE(SMBlockingX);
4534 /* If any of the above locks failed, then we must unlock
4535 all of the previous locks (X/Open spec). */
4536 if (i != num_locks && num_locks != 0) {
4538 * Ensure we don't do a remove on the lock that just failed,
4539 * as under POSIX rules, if we have a lock already there, we
4540 * will delete it (and we shouldn't) .....
4542 for(i--; i >= 0; i--) {
4543 lock_pid = get_lock_pid( data, i, large_file_format);
4544 count = get_lock_count( data, i, large_file_format);
4545 offset = get_lock_offset( data, i, large_file_format, &err);
4548 * There is no error code marked "stupid client bug".... :-).
4551 END_PROFILE(SMBlockingX);
4552 return ERROR_DOS(ERRDOS,ERRnoaccess);
4555 do_unlock(fsp,conn,lock_pid,count,offset);
4557 END_PROFILE(SMBlockingX);
4558 return ERROR_NT(status);
4561 set_message(outbuf,2,0,True);
4563 DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
4564 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
4566 END_PROFILE(SMBlockingX);
4567 return chain_reply(inbuf,outbuf,length,bufsize);
4570 /****************************************************************************
4571 Reply to a SMBreadbmpx (read block multiplex) request.
4572 ****************************************************************************/
4574 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4585 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4586 START_PROFILE(SMBreadBmpx);
4588 /* this function doesn't seem to work - disable by default */
4589 if (!lp_readbmpx()) {
4590 END_PROFILE(SMBreadBmpx);
4591 return ERROR_DOS(ERRSRV,ERRuseSTD);
4594 outsize = set_message(outbuf,8,0,True);
4596 CHECK_FSP(fsp,conn);
4599 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
4600 maxcount = SVAL(inbuf,smb_vwv3);
4602 data = smb_buf(outbuf);
4603 pad = ((long)data)%4;
4608 max_per_packet = bufsize-(outsize+pad);
4612 if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
4613 END_PROFILE(SMBreadBmpx);
4614 return ERROR_DOS(ERRDOS,ERRlock);
4618 size_t N = MIN(max_per_packet,tcount-total_read);
4620 nread = read_file(fsp,data,startpos,N);
4625 if (nread < (ssize_t)N)
4626 tcount = total_read + nread;
4628 set_message(outbuf,8,nread,False);
4629 SIVAL(outbuf,smb_vwv0,startpos);
4630 SSVAL(outbuf,smb_vwv2,tcount);
4631 SSVAL(outbuf,smb_vwv6,nread);
4632 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
4634 if (!send_smb(smbd_server_fd(),outbuf))
4635 exit_server("reply_readbmpx: send_smb failed.");
4637 total_read += nread;
4639 } while (total_read < (ssize_t)tcount);
4641 END_PROFILE(SMBreadBmpx);
4645 /****************************************************************************
4646 Reply to a SMBsetattrE.
4647 ****************************************************************************/
4649 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4651 struct utimbuf unix_times;
4653 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4654 START_PROFILE(SMBsetattrE);
4656 outsize = set_message(outbuf,0,0,True);
4658 if(!fsp || (fsp->conn != conn)) {
4659 END_PROFILE(SMBgetattrE);
4660 return ERROR_DOS(ERRDOS,ERRbadfid);
4664 * Convert the DOS times into unix times. Ignore create
4665 * time as UNIX can't set this.
4668 unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
4669 unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
4672 * Patch from Ray Frush <frush@engr.colostate.edu>
4673 * Sometimes times are sent as zero - ignore them.
4676 if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
4677 /* Ignore request */
4678 if( DEBUGLVL( 3 ) ) {
4679 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
4680 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
4682 END_PROFILE(SMBsetattrE);
4684 } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
4685 /* set modify time = to access time if modify time was 0 */
4686 unix_times.modtime = unix_times.actime;
4689 /* Set the date on this file */
4690 if(file_utime(conn, fsp->fsp_name, &unix_times)) {
4691 END_PROFILE(SMBsetattrE);
4692 return ERROR_DOS(ERRDOS,ERRnoaccess);
4695 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
4696 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
4698 END_PROFILE(SMBsetattrE);
4703 /* Back from the dead for OS/2..... JRA. */
4705 /****************************************************************************
4706 Reply to a SMBwritebmpx (write block multiplex primary) request.
4707 ****************************************************************************/
4709 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4712 ssize_t nwritten = -1;
4719 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4720 START_PROFILE(SMBwriteBmpx);
4722 CHECK_FSP(fsp,conn);
4726 tcount = SVAL(inbuf,smb_vwv1);
4727 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
4728 write_through = BITSETW(inbuf+smb_vwv7,0);
4729 numtowrite = SVAL(inbuf,smb_vwv10);
4730 smb_doff = SVAL(inbuf,smb_vwv11);
4732 data = smb_base(inbuf) + smb_doff;
4734 /* If this fails we need to send an SMBwriteC response,
4735 not an SMBwritebmpx - set this up now so we don't forget */
4736 SCVAL(outbuf,smb_com,SMBwritec);
4738 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
4739 END_PROFILE(SMBwriteBmpx);
4740 return(ERROR_DOS(ERRDOS,ERRlock));
4743 nwritten = write_file(fsp,data,startpos,numtowrite);
4745 if(lp_syncalways(SNUM(conn)) || write_through)
4746 sync_file(conn,fsp);
4748 if(nwritten < (ssize_t)numtowrite) {
4749 END_PROFILE(SMBwriteBmpx);
4750 return(UNIXERROR(ERRHRD,ERRdiskfull));
4753 /* If the maximum to be written to this file
4754 is greater than what we just wrote then set
4755 up a secondary struct to be attached to this
4756 fd, we will use this to cache error messages etc. */
4758 if((ssize_t)tcount > nwritten) {
4759 write_bmpx_struct *wbms;
4760 if(fsp->wbmpx_ptr != NULL)
4761 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
4763 wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
4765 DEBUG(0,("Out of memory in reply_readmpx\n"));
4766 END_PROFILE(SMBwriteBmpx);
4767 return(ERROR_DOS(ERRSRV,ERRnoresource));
4769 wbms->wr_mode = write_through;
4770 wbms->wr_discard = False; /* No errors yet */
4771 wbms->wr_total_written = nwritten;
4772 wbms->wr_errclass = 0;
4774 fsp->wbmpx_ptr = wbms;
4777 /* We are returning successfully, set the message type back to
4779 SCVAL(outbuf,smb_com,SMBwriteBmpx);
4781 outsize = set_message(outbuf,1,0,True);
4783 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
4785 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
4786 fsp->fnum, (int)numtowrite, (int)nwritten ) );
4788 if (write_through && tcount==nwritten) {
4789 /* We need to send both a primary and a secondary response */
4790 smb_setlen(outbuf,outsize - 4);
4791 if (!send_smb(smbd_server_fd(),outbuf))
4792 exit_server("reply_writebmpx: send_smb failed.");
4794 /* Now the secondary */
4795 outsize = set_message(outbuf,1,0,True);
4796 SCVAL(outbuf,smb_com,SMBwritec);
4797 SSVAL(outbuf,smb_vwv0,nwritten);
4800 END_PROFILE(SMBwriteBmpx);
4804 /****************************************************************************
4805 Reply to a SMBwritebs (write block multiplex secondary) request.
4806 ****************************************************************************/
4808 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4811 ssize_t nwritten = -1;
4818 write_bmpx_struct *wbms;
4819 BOOL send_response = False;
4820 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4821 START_PROFILE(SMBwriteBs);
4823 CHECK_FSP(fsp,conn);
4826 tcount = SVAL(inbuf,smb_vwv1);
4827 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
4828 numtowrite = SVAL(inbuf,smb_vwv6);
4829 smb_doff = SVAL(inbuf,smb_vwv7);
4831 data = smb_base(inbuf) + smb_doff;
4833 /* We need to send an SMBwriteC response, not an SMBwritebs */
4834 SCVAL(outbuf,smb_com,SMBwritec);
4836 /* This fd should have an auxiliary struct attached,
4837 check that it does */
4838 wbms = fsp->wbmpx_ptr;
4840 END_PROFILE(SMBwriteBs);
4844 /* If write through is set we can return errors, else we must cache them */
4845 write_through = wbms->wr_mode;
4847 /* Check for an earlier error */
4848 if(wbms->wr_discard) {
4849 END_PROFILE(SMBwriteBs);
4850 return -1; /* Just discard the packet */
4853 nwritten = write_file(fsp,data,startpos,numtowrite);
4855 if(lp_syncalways(SNUM(conn)) || write_through)
4856 sync_file(conn,fsp);
4858 if (nwritten < (ssize_t)numtowrite) {
4860 /* We are returning an error - we can delete the aux struct */
4863 fsp->wbmpx_ptr = NULL;
4864 END_PROFILE(SMBwriteBs);
4865 return(ERROR_DOS(ERRHRD,ERRdiskfull));
4867 END_PROFILE(SMBwriteBs);
4868 return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
4871 /* Increment the total written, if this matches tcount
4872 we can discard the auxiliary struct (hurrah !) and return a writeC */
4873 wbms->wr_total_written += nwritten;
4874 if(wbms->wr_total_written >= tcount) {
4875 if (write_through) {
4876 outsize = set_message(outbuf,1,0,True);
4877 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
4878 send_response = True;
4882 fsp->wbmpx_ptr = NULL;
4886 END_PROFILE(SMBwriteBs);
4890 END_PROFILE(SMBwriteBs);
4894 /****************************************************************************
4895 Reply to a SMBgetattrE.
4896 ****************************************************************************/
4898 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4900 SMB_STRUCT_STAT sbuf;
4903 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4904 START_PROFILE(SMBgetattrE);
4906 outsize = set_message(outbuf,11,0,True);
4908 if(!fsp || (fsp->conn != conn)) {
4909 END_PROFILE(SMBgetattrE);
4910 return ERROR_DOS(ERRDOS,ERRbadfid);
4913 /* Do an fstat on this file */
4914 if(fsp_stat(fsp, &sbuf)) {
4915 END_PROFILE(SMBgetattrE);
4916 return(UNIXERROR(ERRDOS,ERRnoaccess));
4919 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
4922 * Convert the times into dos times. Set create
4923 * date to be last modify date as UNIX doesn't save
4927 put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
4928 put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
4929 put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
4932 SIVAL(outbuf,smb_vwv6,0);
4933 SIVAL(outbuf,smb_vwv8,0);
4935 uint32 allocation_size = get_allocation_size(fsp, &sbuf);
4936 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
4937 SIVAL(outbuf,smb_vwv8,allocation_size);
4939 SSVAL(outbuf,smb_vwv10, mode);
4941 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
4943 END_PROFILE(SMBgetattrE);