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 ****************************************************************************/
45 NTSTATUS check_path_syntax(const char *name)
47 while (*name == '\\' || *name == '/')
49 if (name[0] == '.' && name[1] == '\0')
50 return NT_STATUS_OBJECT_NAME_INVALID;
51 else if (name[0] == '.' && name[1] == '.' &&
52 (name[2] == '\\' || name [2] == '/' || name[2] == '\0'))
53 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
57 /****************************************************************************
58 Pull a string and check the path - provide for error return.
59 ****************************************************************************/
61 size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, int flags, NTSTATUS *err)
63 size_t ret = srvstr_pull_buf( inbuf, dest, src, dest_len, flags);
64 *err = check_path_syntax(dest);
68 /****************************************************************************
69 Reply to a special message.
70 ****************************************************************************/
72 int reply_special(char *inbuf,char *outbuf)
75 int msg_type = CVAL(inbuf,0);
76 int msg_flags = CVAL(inbuf,1);
80 static BOOL already_got_session = False;
84 memset(outbuf,'\0',smb_size);
89 case 0x81: /* session request */
91 if (already_got_session) {
92 exit_server("multiple session request not permitted");
97 if (name_len(inbuf+4) > 50 ||
98 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
99 DEBUG(0,("Invalid name length in session request\n"));
102 name_extract(inbuf,4,name1);
103 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
104 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
107 set_local_machine_name(name1, True);
108 set_remote_machine_name(name2, True);
110 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
111 get_local_machine_name(), get_remote_machine_name(),
114 if (name_type == 'R') {
115 /* We are being asked for a pathworks session ---
117 SCVAL(outbuf, 0,0x83);
121 /* only add the client's machine name to the list
122 of possibly valid usernames if we are operating
123 in share mode security */
124 if (lp_security() == SEC_SHARE) {
125 add_session_user(get_remote_machine_name());
128 reload_services(True);
131 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
133 already_got_session = True;
136 case 0x89: /* session keepalive request
137 (some old clients produce this?) */
138 SCVAL(outbuf,0,SMBkeepalive);
142 case 0x82: /* positive session response */
143 case 0x83: /* negative session response */
144 case 0x84: /* retarget session response */
145 DEBUG(0,("Unexpected session response\n"));
148 case SMBkeepalive: /* session keepalive */
153 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
154 msg_type, msg_flags));
159 /****************************************************************************
161 ****************************************************************************/
163 int reply_tcon(connection_struct *conn,
164 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
171 uint16 vuid = SVAL(inbuf,smb_uid);
175 DATA_BLOB password_blob;
177 START_PROFILE(SMBtcon);
179 *service_buf = *password = *dev = 0;
181 p = smb_buf(inbuf)+1;
182 p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
183 pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
185 p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
187 p = strrchr_m(service_buf,'\\');
191 service = service_buf;
194 password_blob = data_blob(password, pwlen+1);
196 conn = make_connection(service,password_blob,dev,vuid,&nt_status);
198 data_blob_clear_free(&password_blob);
201 END_PROFILE(SMBtcon);
202 return ERROR_NT(nt_status);
205 outsize = set_message(outbuf,2,0,True);
206 SSVAL(outbuf,smb_vwv0,max_recv);
207 SSVAL(outbuf,smb_vwv1,conn->cnum);
208 SSVAL(outbuf,smb_tid,conn->cnum);
210 DEBUG(3,("tcon service=%s cnum=%d\n",
211 service, conn->cnum));
213 END_PROFILE(SMBtcon);
217 /****************************************************************************
218 Reply to a tcon and X.
219 ****************************************************************************/
221 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
226 /* what the cleint thinks the device is */
227 fstring client_devicetype;
228 /* what the server tells the client the share represents */
229 const char *server_devicetype;
231 uint16 vuid = SVAL(inbuf,smb_uid);
232 int passlen = SVAL(inbuf,smb_vwv3);
235 extern BOOL global_encrypted_passwords_negotiated;
237 START_PROFILE(SMBtconX);
239 *service = *client_devicetype = 0;
241 /* we might have to close an old one */
242 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
243 close_cnum(conn,vuid);
246 if (passlen > MAX_PASS_LEN) {
247 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
250 if (global_encrypted_passwords_negotiated) {
251 password = data_blob(smb_buf(inbuf),passlen);
253 password = data_blob(smb_buf(inbuf),passlen+1);
254 /* Ensure correct termination */
255 password.data[passlen]=0;
258 p = smb_buf(inbuf) + passlen;
259 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
262 * the service name can be either: \\server\share
263 * or share directly like on the DELL PowerVault 705
266 q = strchr_m(path+2,'\\');
268 END_PROFILE(SMBtconX);
269 return(ERROR_DOS(ERRDOS,ERRnosuchshare));
271 fstrcpy(service,q+1);
274 fstrcpy(service,path);
276 p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII);
278 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
280 conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
282 data_blob_clear_free(&password);
285 END_PROFILE(SMBtconX);
286 return ERROR_NT(nt_status);
290 server_devicetype = "IPC";
291 else if ( IS_PRINT(conn) )
292 server_devicetype = "LPT1:";
294 server_devicetype = "A:";
296 if (Protocol < PROTOCOL_NT1) {
297 set_message(outbuf,2,0,True);
299 p += srvstr_push(outbuf, p, server_devicetype, -1,
300 STR_TERMINATE|STR_ASCII);
301 set_message_end(outbuf,p);
303 /* NT sets the fstype of IPC$ to the null string */
304 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
306 set_message(outbuf,3,0,True);
309 p += srvstr_push(outbuf, p, server_devicetype, -1,
310 STR_TERMINATE|STR_ASCII);
311 p += srvstr_push(outbuf, p, fstype, -1,
314 set_message_end(outbuf,p);
316 /* what does setting this bit do? It is set by NT4 and
317 may affect the ability to autorun mounted cdroms */
318 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
319 (lp_csc_policy(SNUM(conn)) << 2));
321 init_dfsroot(conn, inbuf, outbuf);
325 DEBUG(3,("tconX service=%s \n",
328 /* set the incoming and outgoing tid to the just created one */
329 SSVAL(inbuf,smb_tid,conn->cnum);
330 SSVAL(outbuf,smb_tid,conn->cnum);
332 END_PROFILE(SMBtconX);
333 return chain_reply(inbuf,outbuf,length,bufsize);
336 /****************************************************************************
337 Reply to an unknown type.
338 ****************************************************************************/
340 int reply_unknown(char *inbuf,char *outbuf)
343 type = CVAL(inbuf,smb_com);
345 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
346 smb_fn_name(type), type, type));
348 return(ERROR_DOS(ERRSRV,ERRunknownsmb));
351 /****************************************************************************
353 ****************************************************************************/
355 int reply_ioctl(connection_struct *conn,
356 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
358 uint16 device = SVAL(inbuf,smb_vwv1);
359 uint16 function = SVAL(inbuf,smb_vwv2);
360 uint32 ioctl_code = (device << 16) + function;
361 int replysize, outsize;
363 START_PROFILE(SMBioctl);
365 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
367 switch (ioctl_code) {
368 case IOCTL_QUERY_JOB_INFO:
372 END_PROFILE(SMBioctl);
373 return(ERROR_DOS(ERRSRV,ERRnosupport));
376 outsize = set_message(outbuf,8,replysize+1,True);
377 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
378 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
379 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
380 p = smb_buf(outbuf) + 1; /* Allow for alignment */
382 switch (ioctl_code) {
383 case IOCTL_QUERY_JOB_INFO:
385 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
387 END_PROFILE(SMBioctl);
388 return(UNIXERROR(ERRDOS,ERRbadfid));
390 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
391 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
392 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
397 END_PROFILE(SMBioctl);
401 /****************************************************************************
403 ****************************************************************************/
405 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
411 BOOL bad_path = False;
412 SMB_STRUCT_STAT sbuf;
415 START_PROFILE(SMBchkpth);
417 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE, &status);
418 if (!NT_STATUS_IS_OK(status)) {
419 END_PROFILE(SMBchkpth);
420 return ERROR_NT(status);
423 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
425 unix_convert(name,conn,0,&bad_path,&sbuf);
427 mode = SVAL(inbuf,smb_vwv0);
429 if (check_name(name,conn)) {
430 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
431 if (!(ok = S_ISDIR(sbuf.st_mode))) {
432 END_PROFILE(SMBchkpth);
433 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath);
438 /* We special case this - as when a Windows machine
439 is parsing a path is steps through the components
440 one at a time - if a component fails it expects
441 ERRbadpath, not ERRbadfile.
443 if(errno == ENOENT) {
445 * Windows returns different error codes if
446 * the parent directory is valid but not the
447 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
448 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
449 * if the path is invalid.
452 END_PROFILE(SMBchkpth);
453 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
455 END_PROFILE(SMBchkpth);
456 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
458 } else if (errno == ENOTDIR) {
459 END_PROFILE(SMBchkpth);
460 return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY);
463 END_PROFILE(SMBchkpth);
464 return(UNIXERROR(ERRDOS,ERRbadpath));
467 outsize = set_message(outbuf,0,0,True);
469 DEBUG(3,("chkpth %s mode=%d\n", name, mode));
471 END_PROFILE(SMBchkpth);
475 /****************************************************************************
477 ****************************************************************************/
479 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
483 SMB_STRUCT_STAT sbuf;
488 BOOL bad_path = False;
492 START_PROFILE(SMBgetatr);
494 p = smb_buf(inbuf) + 1;
495 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), STR_TERMINATE,&status);
496 if (!NT_STATUS_IS_OK(status)) {
497 END_PROFILE(SMBgetatr);
498 return ERROR_NT(status);
501 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
503 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
504 under WfWg - weird! */
506 mode = aHIDDEN | aDIR;
507 if (!CAN_WRITE(conn))
513 unix_convert(fname,conn,0,&bad_path,&sbuf);
514 if (check_name(fname,conn)) {
515 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
516 mode = dos_mode(conn,fname,&sbuf);
518 mtime = sbuf.st_mtime;
523 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
529 END_PROFILE(SMBgetatr);
530 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadfile);
533 outsize = set_message(outbuf,10,0,True);
535 SSVAL(outbuf,smb_vwv0,mode);
536 if(lp_dos_filetime_resolution(SNUM(conn)) )
537 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
539 put_dos_date3(outbuf,smb_vwv1,mtime);
540 SIVAL(outbuf,smb_vwv3,(uint32)size);
542 if (Protocol >= PROTOCOL_NT1)
543 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
545 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
547 END_PROFILE(SMBgetatr);
551 /****************************************************************************
553 ****************************************************************************/
555 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
562 SMB_STRUCT_STAT sbuf;
563 BOOL bad_path = False;
567 START_PROFILE(SMBsetatr);
569 p = smb_buf(inbuf) + 1;
570 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), STR_TERMINATE,&status);
571 if (!NT_STATUS_IS_OK(status)) {
572 END_PROFILE(SMBsetatr);
573 return ERROR_NT(status);
576 unix_convert(fname,conn,0,&bad_path,&sbuf);
578 mode = SVAL(inbuf,smb_vwv0);
579 mtime = make_unix_date3(inbuf+smb_vwv1);
581 if (mode != FILE_ATTRIBUTE_NORMAL) {
582 if (VALID_STAT_OF_DIR(sbuf))
587 if (check_name(fname,conn))
588 ok = (file_chmod(conn,fname,mode,NULL) == 0);
594 ok = set_filetime(conn,fname,mtime);
597 END_PROFILE(SMBsetatr);
598 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
601 outsize = set_message(outbuf,0,0,True);
603 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
605 END_PROFILE(SMBsetatr);
609 /****************************************************************************
611 ****************************************************************************/
613 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
616 SMB_BIG_UINT dfree,dsize,bsize;
617 START_PROFILE(SMBdskattr);
619 SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
621 outsize = set_message(outbuf,5,0,True);
623 if (Protocol <= PROTOCOL_LANMAN2) {
624 double total_space, free_space;
625 /* we need to scale this to a number that DOS6 can handle. We
626 use floating point so we can handle large drives on systems
627 that don't have 64 bit integers
629 we end up displaying a maximum of 2G to DOS systems
631 total_space = dsize * (double)bsize;
632 free_space = dfree * (double)bsize;
634 dsize = (total_space+63*512) / (64*512);
635 dfree = (free_space+63*512) / (64*512);
637 if (dsize > 0xFFFF) dsize = 0xFFFF;
638 if (dfree > 0xFFFF) dfree = 0xFFFF;
640 SSVAL(outbuf,smb_vwv0,dsize);
641 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
642 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
643 SSVAL(outbuf,smb_vwv3,dfree);
645 SSVAL(outbuf,smb_vwv0,dsize);
646 SSVAL(outbuf,smb_vwv1,bsize/512);
647 SSVAL(outbuf,smb_vwv2,512);
648 SSVAL(outbuf,smb_vwv3,dfree);
651 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
653 END_PROFILE(SMBdskattr);
657 /****************************************************************************
659 Can be called from SMBsearch, SMBffirst or SMBfunique.
660 ****************************************************************************/
662 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
672 unsigned int numentries = 0;
673 unsigned int maxentries = 0;
674 BOOL finished = False;
681 BOOL check_descend = False;
682 BOOL expect_close = False;
683 BOOL can_open = True;
684 BOOL bad_path = False;
686 START_PROFILE(SMBsearch);
688 *mask = *directory = *fname = 0;
690 /* If we were called as SMBffirst then we must expect close. */
691 if(CVAL(inbuf,smb_com) == SMBffirst)
694 outsize = set_message(outbuf,1,3,True);
695 maxentries = SVAL(inbuf,smb_vwv0);
696 dirtype = SVAL(inbuf,smb_vwv1);
697 p = smb_buf(inbuf) + 1;
698 p += srvstr_get_path(inbuf, path, p, sizeof(path), STR_TERMINATE,&nt_status);
699 if (!NT_STATUS_IS_OK(nt_status)) {
700 END_PROFILE(SMBsearch);
701 return ERROR_NT(nt_status);
704 status_len = SVAL(p, 0);
707 /* dirtype &= ~aDIR; */
709 if (status_len == 0) {
710 SMB_STRUCT_STAT sbuf;
713 pstrcpy(directory,path);
715 unix_convert(directory,conn,0,&bad_path,&sbuf);
718 if (!check_name(directory,conn))
721 p = strrchr_m(dir2,'/');
730 p = strrchr_m(directory,'/');
736 if (strlen(directory) == 0)
737 pstrcpy(directory,".");
738 memset((char *)status,'\0',21);
739 SCVAL(status,0,(dirtype & 0x1F));
744 status_dirtype = CVAL(status,0) & 0x1F;
745 if (status_dirtype != (dirtype & 0x1F))
746 dirtype = status_dirtype;
748 conn->dirptr = dptr_fetch(status+12,&dptr_num);
751 string_set(&conn->dirpath,dptr_path(dptr_num));
752 pstrcpy(mask, dptr_wcard(dptr_num));
756 p = smb_buf(outbuf) + 3;
759 if (status_len == 0) {
760 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
763 END_PROFILE(SMBsearch);
764 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnofids);
766 END_PROFILE(SMBsearch);
767 return ERROR_DOS(ERRDOS,ERRnofids);
769 dptr_set_wcard(dptr_num, strdup(mask));
770 dptr_set_attr(dptr_num, dirtype);
772 dirtype = dptr_attr(dptr_num);
775 DEBUG(4,("dptr_num is %d\n",dptr_num));
778 if ((dirtype&0x1F) == aVOLID) {
780 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
781 dptr_fill(p+12,dptr_num);
782 if (dptr_zero(p+12) && (status_len==0))
786 p += DIR_STRUCT_SIZE;
789 maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
791 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
792 conn->dirpath,lp_dontdescend(SNUM(conn))));
793 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
794 check_descend = True;
796 for (i=numentries;(i<maxentries) && !finished;i++) {
797 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
800 make_dir_struct(p,mask,fname,size,mode,date);
801 dptr_fill(p+12,dptr_num);
804 p += DIR_STRUCT_SIZE;
813 /* If we were called as SMBffirst with smb_search_id == NULL
814 and no entries were found then return error and close dirptr
817 if(ok && expect_close && numentries == 0 && status_len == 0) {
818 if (Protocol < PROTOCOL_NT1) {
819 SCVAL(outbuf,smb_rcls,ERRDOS);
820 SSVAL(outbuf,smb_err,ERRnofiles);
822 /* Also close the dptr - we know it's gone */
823 dptr_close(&dptr_num);
824 } else if (numentries == 0 || !ok) {
825 if (Protocol < PROTOCOL_NT1) {
826 SCVAL(outbuf,smb_rcls,ERRDOS);
827 SSVAL(outbuf,smb_err,ERRnofiles);
829 dptr_close(&dptr_num);
832 /* If we were called as SMBfunique, then we can close the dirptr now ! */
833 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
834 dptr_close(&dptr_num);
836 SSVAL(outbuf,smb_vwv0,numentries);
837 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
838 SCVAL(smb_buf(outbuf),0,5);
839 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
841 if (Protocol >= PROTOCOL_NT1)
842 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
844 outsize += DIR_STRUCT_SIZE*numentries;
845 smb_setlen(outbuf,outsize - 4);
847 if ((! *directory) && dptr_path(dptr_num))
848 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
850 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
851 smb_fn_name(CVAL(inbuf,smb_com)),
852 mask, directory, dirtype, numentries, maxentries ) );
854 END_PROFILE(SMBsearch);
858 /****************************************************************************
859 Reply to a fclose (stop directory search).
860 ****************************************************************************/
862 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
872 START_PROFILE(SMBfclose);
874 outsize = set_message(outbuf,1,0,True);
875 p = smb_buf(inbuf) + 1;
876 p += srvstr_get_path(inbuf, path, p, sizeof(path), STR_TERMINATE,&err);
877 if (!NT_STATUS_IS_OK(err)) {
878 END_PROFILE(SMBfclose);
879 return ERROR_NT(err);
882 status_len = SVAL(p,0);
885 if (status_len == 0) {
886 END_PROFILE(SMBfclose);
887 return ERROR_DOS(ERRSRV,ERRsrverror);
892 if(dptr_fetch(status+12,&dptr_num)) {
893 /* Close the dptr - we know it's gone */
894 dptr_close(&dptr_num);
897 SSVAL(outbuf,smb_vwv0,0);
899 DEBUG(3,("search close\n"));
901 END_PROFILE(SMBfclose);
905 /****************************************************************************
907 ****************************************************************************/
909 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
919 SMB_STRUCT_STAT sbuf;
920 BOOL bad_path = False;
922 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
924 START_PROFILE(SMBopen);
926 share_mode = SVAL(inbuf,smb_vwv0);
928 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE,&status);
929 if (!NT_STATUS_IS_OK(status)) {
930 END_PROFILE(SMBopen);
931 return ERROR_NT(status);
934 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
936 unix_convert(fname,conn,0,&bad_path,&sbuf);
938 unixmode = unix_mode(conn,aARCH,fname);
940 fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
941 unixmode, oplock_request,&rmode,NULL);
944 END_PROFILE(SMBopen);
945 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
949 fmode = dos_mode(conn,fname,&sbuf);
950 mtime = sbuf.st_mtime;
953 DEBUG(3,("attempt to open a directory %s\n",fname));
954 close_file(fsp,False);
955 END_PROFILE(SMBopen);
956 return ERROR_DOS(ERRDOS,ERRnoaccess);
959 outsize = set_message(outbuf,7,0,True);
960 SSVAL(outbuf,smb_vwv0,fsp->fnum);
961 SSVAL(outbuf,smb_vwv1,fmode);
962 if(lp_dos_filetime_resolution(SNUM(conn)) )
963 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
965 put_dos_date3(outbuf,smb_vwv2,mtime);
966 SIVAL(outbuf,smb_vwv4,(uint32)size);
967 SSVAL(outbuf,smb_vwv6,rmode);
969 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
970 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
972 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
973 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
974 END_PROFILE(SMBopen);
978 /****************************************************************************
979 Reply to an open and X.
980 ****************************************************************************/
982 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
985 int smb_mode = SVAL(inbuf,smb_vwv3);
986 int smb_attr = SVAL(inbuf,smb_vwv5);
987 /* Breakout the oplock request bits so we can set the
988 reply bits separately. */
989 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
990 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
991 BOOL oplock_request = ex_oplock_request | core_oplock_request;
993 int open_flags = SVAL(inbuf,smb_vwv2);
994 int smb_sattr = SVAL(inbuf,smb_vwv4);
995 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
997 int smb_ofun = SVAL(inbuf,smb_vwv8);
1000 int fmode=0,mtime=0,rmode=0;
1001 SMB_STRUCT_STAT sbuf;
1003 BOOL bad_path = False;
1006 START_PROFILE(SMBopenX);
1008 /* If it's an IPC, pass off the pipe handler. */
1010 if (lp_nt_pipe_support()) {
1011 END_PROFILE(SMBopenX);
1012 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
1014 END_PROFILE(SMBopenX);
1015 return ERROR_DOS(ERRSRV,ERRaccess);
1019 /* XXXX we need to handle passed times, sattr and flags */
1020 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE,&status);
1021 if (!NT_STATUS_IS_OK(status)) {
1022 END_PROFILE(SMBopenX);
1023 return ERROR_NT(status);
1026 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1028 unix_convert(fname,conn,0,&bad_path,&sbuf);
1030 unixmode = unix_mode(conn,smb_attr | aARCH, fname);
1032 fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
1033 oplock_request, &rmode,&smb_action);
1036 END_PROFILE(SMBopenX);
1037 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1040 size = sbuf.st_size;
1041 fmode = dos_mode(conn,fname,&sbuf);
1042 mtime = sbuf.st_mtime;
1044 close_file(fsp,False);
1045 END_PROFILE(SMBopenX);
1046 return ERROR_DOS(ERRDOS,ERRnoaccess);
1049 /* If the caller set the extended oplock request bit
1050 and we granted one (by whatever means) - set the
1051 correct bit for extended oplock reply.
1054 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn)))
1055 smb_action |= EXTENDED_OPLOCK_GRANTED;
1057 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1058 smb_action |= EXTENDED_OPLOCK_GRANTED;
1060 /* If the caller set the core oplock request bit
1061 and we granted one (by whatever means) - set the
1062 correct bit for core oplock reply.
1065 if (core_oplock_request && lp_fake_oplocks(SNUM(conn)))
1066 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1068 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1069 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1071 set_message(outbuf,15,0,True);
1072 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1073 SSVAL(outbuf,smb_vwv3,fmode);
1074 if(lp_dos_filetime_resolution(SNUM(conn)) )
1075 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1077 put_dos_date3(outbuf,smb_vwv4,mtime);
1078 SIVAL(outbuf,smb_vwv6,(uint32)size);
1079 SSVAL(outbuf,smb_vwv8,rmode);
1080 SSVAL(outbuf,smb_vwv11,smb_action);
1082 END_PROFILE(SMBopenX);
1083 return chain_reply(inbuf,outbuf,length,bufsize);
1086 /****************************************************************************
1087 Reply to a SMBulogoffX.
1088 ****************************************************************************/
1090 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1092 uint16 vuid = SVAL(inbuf,smb_uid);
1093 user_struct *vuser = get_valid_user_struct(vuid);
1094 START_PROFILE(SMBulogoffX);
1097 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1099 /* in user level security we are supposed to close any files
1100 open by this user */
1101 if ((vuser != 0) && (lp_security() != SEC_SHARE))
1102 file_close_user(vuid);
1104 invalidate_vuid(vuid);
1106 set_message(outbuf,2,0,True);
1108 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1110 END_PROFILE(SMBulogoffX);
1111 return chain_reply(inbuf,outbuf,length,bufsize);
1114 /****************************************************************************
1115 Reply to a mknew or a create.
1116 ****************************************************************************/
1118 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1126 BOOL bad_path = False;
1128 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1129 SMB_STRUCT_STAT sbuf;
1131 START_PROFILE(SMBcreate);
1133 com = SVAL(inbuf,smb_com);
1135 createmode = SVAL(inbuf,smb_vwv0);
1136 srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), STR_TERMINATE,&status);
1137 if (!NT_STATUS_IS_OK(status)) {
1138 END_PROFILE(SMBcreate);
1139 return ERROR_NT(status);
1142 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1144 unix_convert(fname,conn,0,&bad_path,&sbuf);
1146 if (createmode & aVOLID)
1147 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1149 unixmode = unix_mode(conn,createmode,fname);
1151 if(com == SMBmknew) {
1152 /* We should fail if file exists. */
1153 ofun = FILE_CREATE_IF_NOT_EXIST;
1155 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1156 ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
1159 /* Open file in dos compatibility share mode. */
1160 fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1161 ofun, unixmode, oplock_request, NULL, NULL);
1164 END_PROFILE(SMBcreate);
1165 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1168 outsize = set_message(outbuf,1,0,True);
1169 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1171 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1172 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1174 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1175 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1177 DEBUG( 2, ( "new file %s\n", fname ) );
1178 DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n", fname, fsp->fd, createmode, (int)unixmode ) );
1180 END_PROFILE(SMBcreate);
1184 /****************************************************************************
1185 Reply to a create temporary file.
1186 ****************************************************************************/
1188 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1194 BOOL bad_path = False;
1196 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1198 SMB_STRUCT_STAT sbuf;
1202 START_PROFILE(SMBctemp);
1204 createmode = SVAL(inbuf,smb_vwv0);
1205 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE,&status);
1206 if (!NT_STATUS_IS_OK(status)) {
1207 END_PROFILE(SMBctemp);
1208 return ERROR_NT(status);
1210 pstrcat(fname,"\\TMXXXXXX");
1212 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1214 unix_convert(fname,conn,0,&bad_path,&sbuf);
1216 unixmode = unix_mode(conn,createmode,fname);
1218 tmpfd = smb_mkstemp(fname);
1220 END_PROFILE(SMBctemp);
1221 return(UNIXERROR(ERRDOS,ERRnoaccess));
1224 SMB_VFS_STAT(conn,fname,&sbuf);
1226 /* Open file in dos compatibility share mode. */
1227 /* We should fail if file does not exist. */
1228 fsp = open_file_shared(conn,fname,&sbuf,
1229 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1230 FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
1231 unixmode, oplock_request, NULL, NULL);
1233 /* close fd from smb_mkstemp() */
1237 END_PROFILE(SMBctemp);
1238 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1241 outsize = set_message(outbuf,1,0,True);
1242 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1244 /* the returned filename is relative to the directory */
1245 s = strrchr_m(fname, '/');
1251 p = smb_buf(outbuf);
1252 SSVALS(p, 0, -1); /* what is this? not in spec */
1253 SSVAL(p, 2, strlen(s));
1255 p += srvstr_push(outbuf, p, s, -1, STR_ASCII);
1256 outsize = set_message_end(outbuf, p);
1258 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1259 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1261 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1262 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1264 DEBUG( 2, ( "created temp file %s\n", fname ) );
1265 DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
1266 fname, fsp->fd, createmode, (int)unixmode ) );
1268 END_PROFILE(SMBctemp);
1272 /*******************************************************************
1273 Check if a user is allowed to rename a file.
1274 ********************************************************************/
1276 static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT *pst)
1282 if (!CAN_WRITE(conn))
1283 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1285 if (S_ISDIR(pst->st_mode))
1286 return NT_STATUS_OK;
1288 /* We need a better way to return NT status codes from open... */
1292 fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1293 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1296 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1297 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1298 ret = NT_STATUS_SHARING_VIOLATION;
1301 unix_ERR_ntstatus = NT_STATUS_OK;
1304 close_file(fsp,False);
1305 return NT_STATUS_OK;
1308 /*******************************************************************
1309 Check if a user is allowed to delete a file.
1310 ********************************************************************/
1312 static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype, BOOL bad_path)
1314 SMB_STRUCT_STAT sbuf;
1320 DEBUG(10,("can_delete: %s, dirtype = %d\n",
1323 if (!CAN_WRITE(conn))
1324 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1326 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
1327 if(errno == ENOENT) {
1329 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1331 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1333 return map_nt_error_from_unix(errno);
1336 fmode = dos_mode(conn,fname,&sbuf);
1338 /* Can't delete a directory. */
1340 return NT_STATUS_FILE_IS_A_DIRECTORY;
1342 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
1343 return NT_STATUS_OBJECT_NAME_INVALID;
1344 #endif /* JRATEST */
1346 if (!lp_delete_readonly(SNUM(conn))) {
1348 return NT_STATUS_CANNOT_DELETE;
1350 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1351 return NT_STATUS_NO_SUCH_FILE;
1353 /* We need a better way to return NT status codes from open... */
1357 fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1358 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1361 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1362 if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
1363 ret = unix_ERR_ntstatus;
1364 else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1365 ret = NT_STATUS_SHARING_VIOLATION;
1368 unix_ERR_ntstatus = NT_STATUS_OK;
1371 close_file(fsp,False);
1372 return NT_STATUS_OK;
1375 /****************************************************************************
1376 The guts of the unlink command, split out so it may be called by the NT SMB
1378 ****************************************************************************/
1380 NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
1386 NTSTATUS error = NT_STATUS_OK;
1388 BOOL bad_path = False;
1390 SMB_STRUCT_STAT sbuf;
1392 *directory = *mask = 0;
1394 /* We must check for wildcards in the name given
1395 * directly by the client - before any unmangling.
1396 * This prevents an unmangling of a UNIX name containing
1397 * a DOS wildcard like '*' or '?' from unmangling into
1398 * a wildcard delete which was not intended.
1399 * FIX for #226. JRA.
1402 has_wild = ms_has_wild(name);
1404 rc = unix_convert(name,conn,0,&bad_path,&sbuf);
1406 p = strrchr_m(name,'/');
1408 pstrcpy(directory,".");
1412 pstrcpy(directory,name);
1417 * We should only check the mangled cache
1418 * here if unix_convert failed. This means
1419 * that the path in 'mask' doesn't exist
1420 * on the file system and so we need to look
1421 * for a possible mangle. This patch from
1422 * Tine Smukavec <valentin.smukavec@hermes.si>.
1425 if (!rc && mangle_is_mangled(mask))
1426 mangle_check_cache( mask );
1429 pstrcat(directory,"/");
1430 pstrcat(directory,mask);
1431 error = can_delete(directory,conn,dirtype,bad_path);
1432 if (!NT_STATUS_IS_OK(error))
1435 if (SMB_VFS_UNLINK(conn,directory) == 0) {
1439 void *dirptr = NULL;
1442 if (check_name(directory,conn))
1443 dirptr = OpenDir(conn, directory, True);
1445 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1446 the pattern matches against the long name, otherwise the short name
1447 We don't implement this yet XXXX
1451 error = NT_STATUS_NO_SUCH_FILE;
1453 if (strequal(mask,"????????.???"))
1456 while ((dname = ReadDirName(dirptr))) {
1458 pstrcpy(fname,dname);
1460 if((strcmp(fname, ".") == 0) || (strcmp(fname, "..")==0))
1463 if(!mask_match(fname, mask, case_sensitive))
1466 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
1467 error = can_delete(fname,conn,dirtype,bad_path);
1468 if (!NT_STATUS_IS_OK(error))
1470 if (SMB_VFS_UNLINK(conn,fname) == 0)
1472 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
1478 if (count == 0 && NT_STATUS_IS_OK(error)) {
1479 error = map_nt_error_from_unix(errno);
1485 /****************************************************************************
1487 ****************************************************************************/
1489 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
1496 START_PROFILE(SMBunlink);
1498 dirtype = SVAL(inbuf,smb_vwv0);
1500 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE,&status);
1501 if (!NT_STATUS_IS_OK(status)) {
1502 END_PROFILE(SMBunlink);
1503 return ERROR_NT(status);
1506 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
1508 DEBUG(3,("reply_unlink : %s\n",name));
1510 status = unlink_internals(conn, dirtype, name);
1511 if (!NT_STATUS_IS_OK(status))
1512 return ERROR_NT(status);
1515 * Win2k needs a changenotify request response before it will
1516 * update after a rename..
1518 process_pending_change_notify_queue((time_t)0);
1520 outsize = set_message(outbuf,0,0,True);
1522 END_PROFILE(SMBunlink);
1526 /****************************************************************************
1528 ****************************************************************************/
1530 void fail_readraw(void)
1533 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
1535 exit_server(errstr);
1538 /****************************************************************************
1539 Use sendfile in readbraw.
1540 ****************************************************************************/
1542 void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
1543 ssize_t mincount, char *outbuf)
1547 #if defined(WITH_SENDFILE)
1549 * We can only use sendfile on a non-chained packet and on a file
1550 * that is exclusively oplocked. reply_readbraw has already checked the length.
1553 if ((nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) &&
1554 EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_use_sendfile(SNUM(conn)) ) {
1557 _smb_setlen(outbuf,nread);
1558 header.data = outbuf;
1562 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
1564 * Special hack for broken Linux with no 64 bit clean sendfile. If we
1565 * return ENOSYS then pretend we just got a normal read.
1567 if (errno == ENOSYS)
1570 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
1571 fsp->fsp_name, strerror(errno) ));
1572 exit_server("send_file_readbraw sendfile failed");
1581 ret = read_file(fsp,outbuf+4,startpos,nread);
1582 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
1591 _smb_setlen(outbuf,ret);
1592 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
1596 /****************************************************************************
1597 Reply to a readbraw (core+ protocol).
1598 ****************************************************************************/
1600 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
1602 extern struct current_user current_user;
1603 ssize_t maxcount,mincount;
1606 char *header = outbuf;
1608 START_PROFILE(SMBreadbraw);
1610 if (srv_is_signing_active()) {
1611 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
1615 * Special check if an oplock break has been issued
1616 * and the readraw request croses on the wire, we must
1617 * return a zero length response here.
1620 if(global_oplock_break) {
1621 _smb_setlen(header,0);
1622 if (write_data(smbd_server_fd(),header,4) != 4)
1624 DEBUG(5,("readbraw - oplock break finished\n"));
1625 END_PROFILE(SMBreadbraw);
1629 fsp = file_fsp(inbuf,smb_vwv0);
1631 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
1633 * fsp could be NULL here so use the value from the packet. JRA.
1635 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
1636 _smb_setlen(header,0);
1637 if (write_data(smbd_server_fd(),header,4) != 4)
1639 END_PROFILE(SMBreadbraw);
1643 CHECK_FSP(fsp,conn);
1645 flush_write_cache(fsp, READRAW_FLUSH);
1647 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
1648 if(CVAL(inbuf,smb_wct) == 10) {
1650 * This is a large offset (64 bit) read.
1652 #ifdef LARGE_SMB_OFF_T
1654 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
1656 #else /* !LARGE_SMB_OFF_T */
1659 * Ensure we haven't been sent a >32 bit offset.
1662 if(IVAL(inbuf,smb_vwv8) != 0) {
1663 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
1664 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
1665 _smb_setlen(header,0);
1666 if (write_data(smbd_server_fd(),header,4) != 4)
1668 END_PROFILE(SMBreadbraw);
1672 #endif /* LARGE_SMB_OFF_T */
1675 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
1676 _smb_setlen(header,0);
1677 if (write_data(smbd_server_fd(),header,4) != 4)
1679 END_PROFILE(SMBreadbraw);
1683 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
1684 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
1686 /* ensure we don't overrun the packet size */
1687 maxcount = MIN(65535,maxcount);
1689 if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1690 SMB_OFF_T size = fsp->size;
1691 SMB_OFF_T sizeneeded = startpos + maxcount;
1693 if (size < sizeneeded) {
1695 if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
1697 if (!fsp->can_write)
1701 if (startpos >= size)
1704 nread = MIN(maxcount,(size - startpos));
1707 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
1708 if (nread < mincount)
1712 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
1713 (int)maxcount, (int)mincount, (int)nread ) );
1715 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf);
1717 DEBUG(5,("readbraw finished\n"));
1718 END_PROFILE(SMBreadbraw);
1722 /****************************************************************************
1723 Reply to a lockread (core+ protocol).
1724 ****************************************************************************/
1726 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
1734 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1735 BOOL my_lock_ctx = False;
1736 START_PROFILE(SMBlockread);
1738 CHECK_FSP(fsp,conn);
1741 release_level_2_oplocks_on_change(fsp);
1743 numtoread = SVAL(inbuf,smb_vwv1);
1744 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1746 outsize = set_message(outbuf,5,3,True);
1747 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1748 data = smb_buf(outbuf) + 3;
1751 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
1752 * protocol request that predates the read/write lock concept.
1753 * Thus instead of asking for a read lock here we need to ask
1754 * for a write lock. JRA.
1755 * Note that the requested lock size is unaffected by max_recv.
1758 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
1759 (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &my_lock_ctx);
1761 if (NT_STATUS_V(status)) {
1764 * We used to make lockread a blocking lock. It turns out
1765 * that this isn't on W2k. Found by the Samba 4 RAW-READ torture
1769 if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
1771 * A blocking lock was requested. Package up
1772 * this smb into a queued request and push it
1773 * onto the blocking lock queue.
1775 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)startpos,
1776 (SMB_BIG_UINT)numtoread)) {
1777 END_PROFILE(SMBlockread);
1782 END_PROFILE(SMBlockread);
1783 return ERROR_NT(status);
1787 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
1790 if (numtoread > max_recv) {
1791 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
1792 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
1793 (unsigned int)numtoread, (unsigned int)max_recv ));
1794 numtoread = MIN(numtoread,max_recv);
1796 nread = read_file(fsp,data,startpos,numtoread);
1799 END_PROFILE(SMBlockread);
1800 return(UNIXERROR(ERRDOS,ERRnoaccess));
1804 SSVAL(outbuf,smb_vwv0,nread);
1805 SSVAL(outbuf,smb_vwv5,nread+3);
1806 SSVAL(smb_buf(outbuf),1,nread);
1808 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
1809 fsp->fnum, (int)numtoread, (int)nread));
1811 END_PROFILE(SMBlockread);
1815 /****************************************************************************
1817 ****************************************************************************/
1819 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
1826 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1827 START_PROFILE(SMBread);
1829 CHECK_FSP(fsp,conn);
1832 numtoread = SVAL(inbuf,smb_vwv1);
1833 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1835 outsize = set_message(outbuf,5,3,True);
1836 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1838 * The requested read size cannot be greater than max_recv. JRA.
1840 if (numtoread > max_recv) {
1841 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
1842 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
1843 (unsigned int)numtoread, (unsigned int)max_recv ));
1844 numtoread = MIN(numtoread,max_recv);
1847 data = smb_buf(outbuf) + 3;
1849 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1850 END_PROFILE(SMBread);
1851 return ERROR_DOS(ERRDOS,ERRlock);
1855 nread = read_file(fsp,data,startpos,numtoread);
1858 END_PROFILE(SMBread);
1859 return(UNIXERROR(ERRDOS,ERRnoaccess));
1863 SSVAL(outbuf,smb_vwv0,nread);
1864 SSVAL(outbuf,smb_vwv5,nread+3);
1865 SCVAL(smb_buf(outbuf),0,1);
1866 SSVAL(smb_buf(outbuf),1,nread);
1868 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
1869 fsp->fnum, (int)numtoread, (int)nread ) );
1871 END_PROFILE(SMBread);
1875 /****************************************************************************
1876 Reply to a read and X - possibly using sendfile.
1877 ****************************************************************************/
1879 int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length,
1880 files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
1883 char *data = smb_buf(outbuf);
1885 #if defined(WITH_SENDFILE)
1887 * We can only use sendfile on a non-chained packet and on a file
1888 * that is exclusively oplocked.
1891 if ((CVAL(inbuf,smb_vwv0) == 0xFF) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
1892 lp_use_sendfile(SNUM(conn)) && (lp_write_cache_size(SNUM(conn)) == 0) ) {
1893 SMB_STRUCT_STAT sbuf;
1896 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
1897 return(UNIXERROR(ERRDOS,ERRnoaccess));
1899 if (startpos > sbuf.st_size)
1902 if (smb_maxcnt > (sbuf.st_size - startpos))
1903 smb_maxcnt = (sbuf.st_size - startpos);
1905 if (smb_maxcnt == 0)
1909 * Set up the packet header before send. We
1910 * assume here the sendfile will work (get the
1911 * correct amount of data).
1914 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
1915 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
1916 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
1917 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
1918 SCVAL(outbuf,smb_vwv0,0xFF);
1919 set_message(outbuf,12,smb_maxcnt,False);
1920 header.data = outbuf;
1921 header.length = data - outbuf;
1924 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
1926 * Special hack for broken Linux with no 64 bit clean sendfile. If we
1927 * return ENOSYS then pretend we just got a normal read.
1929 if (errno == ENOSYS)
1932 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
1933 fsp->fsp_name, strerror(errno) ));
1934 exit_server("send_file_readX sendfile failed");
1937 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
1938 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
1946 nread = read_file(fsp,data,startpos,smb_maxcnt);
1949 END_PROFILE(SMBreadX);
1950 return(UNIXERROR(ERRDOS,ERRnoaccess));
1953 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
1954 SSVAL(outbuf,smb_vwv5,nread);
1955 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
1956 SSVAL(smb_buf(outbuf),-2,nread);
1958 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
1959 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
1964 /****************************************************************************
1965 Reply to a read and X.
1966 ****************************************************************************/
1968 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1970 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
1971 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
1973 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
1975 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
1978 START_PROFILE(SMBreadX);
1980 /* If it's an IPC, pass off the pipe handler. */
1982 END_PROFILE(SMBreadX);
1983 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
1986 CHECK_FSP(fsp,conn);
1989 set_message(outbuf,12,0,True);
1991 if(CVAL(inbuf,smb_wct) == 12) {
1992 #ifdef LARGE_SMB_OFF_T
1994 * This is a large offset (64 bit) read.
1996 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
1998 #else /* !LARGE_SMB_OFF_T */
2001 * Ensure we haven't been sent a >32 bit offset.
2004 if(IVAL(inbuf,smb_vwv10) != 0) {
2005 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2006 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
2007 END_PROFILE(SMBreadX);
2008 return ERROR_DOS(ERRDOS,ERRbadaccess);
2011 #endif /* LARGE_SMB_OFF_T */
2015 if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
2016 END_PROFILE(SMBreadX);
2017 return ERROR_DOS(ERRDOS,ERRlock);
2020 nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt);
2022 nread = chain_reply(inbuf,outbuf,length,bufsize);
2024 END_PROFILE(SMBreadX);
2028 /****************************************************************************
2029 Reply to a writebraw (core+ or LANMAN1.0 protocol).
2030 ****************************************************************************/
2032 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2035 ssize_t total_written=0;
2036 size_t numtowrite=0;
2041 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2043 START_PROFILE(SMBwritebraw);
2045 if (srv_is_signing_active()) {
2046 exit_server("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
2049 CHECK_FSP(fsp,conn);
2052 tcount = IVAL(inbuf,smb_vwv1);
2053 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2054 write_through = BITSETW(inbuf+smb_vwv7,0);
2056 /* We have to deal with slightly different formats depending
2057 on whether we are using the core+ or lanman1.0 protocol */
2059 if(Protocol <= PROTOCOL_COREPLUS) {
2060 numtowrite = SVAL(smb_buf(inbuf),-2);
2061 data = smb_buf(inbuf);
2063 numtowrite = SVAL(inbuf,smb_vwv10);
2064 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
2067 /* force the error type */
2068 SCVAL(inbuf,smb_com,SMBwritec);
2069 SCVAL(outbuf,smb_com,SMBwritec);
2071 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2072 END_PROFILE(SMBwritebraw);
2073 return(ERROR_DOS(ERRDOS,ERRlock));
2077 nwritten = write_file(fsp,data,startpos,numtowrite);
2079 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2080 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
2082 if (nwritten < (ssize_t)numtowrite) {
2083 END_PROFILE(SMBwritebraw);
2084 return(UNIXERROR(ERRHRD,ERRdiskfull));
2087 total_written = nwritten;
2089 /* Return a message to the redirector to tell it to send more bytes */
2090 SCVAL(outbuf,smb_com,SMBwritebraw);
2091 SSVALS(outbuf,smb_vwv0,-1);
2092 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
2093 if (!send_smb(smbd_server_fd(),outbuf))
2094 exit_server("reply_writebraw: send_smb failed.");
2096 /* Now read the raw data into the buffer and write it */
2097 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
2098 exit_server("secondary writebraw failed");
2101 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
2102 numtowrite = smb_len(inbuf);
2104 /* Set up outbuf to return the correct return */
2105 outsize = set_message(outbuf,1,0,True);
2106 SCVAL(outbuf,smb_com,SMBwritec);
2107 SSVAL(outbuf,smb_vwv0,total_written);
2109 if (numtowrite != 0) {
2111 if (numtowrite > BUFFER_SIZE) {
2112 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2113 (unsigned int)numtowrite ));
2114 exit_server("secondary writebraw failed");
2117 if (tcount > nwritten+numtowrite) {
2118 DEBUG(3,("Client overestimated the write %d %d %d\n",
2119 (int)tcount,(int)nwritten,(int)numtowrite));
2122 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
2123 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2125 exit_server("secondary writebraw failed");
2128 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
2130 if (nwritten < (ssize_t)numtowrite) {
2131 SCVAL(outbuf,smb_rcls,ERRHRD);
2132 SSVAL(outbuf,smb_err,ERRdiskfull);
2136 total_written += nwritten;
2139 if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
2140 sync_file(conn,fsp);
2142 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2143 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2145 /* we won't return a status if write through is not selected - this follows what WfWg does */
2146 END_PROFILE(SMBwritebraw);
2147 if (!write_through && total_written==tcount) {
2149 #if RABBIT_PELLET_FIX
2151 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2152 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2154 if (!send_keepalive(smbd_server_fd()))
2155 exit_server("reply_writebraw: send of keepalive failed");
2163 /****************************************************************************
2164 Reply to a writeunlock (core+).
2165 ****************************************************************************/
2167 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
2168 int size, int dum_buffsize)
2170 ssize_t nwritten = -1;
2174 NTSTATUS status = NT_STATUS_OK;
2175 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2177 START_PROFILE(SMBwriteunlock);
2179 CHECK_FSP(fsp,conn);
2182 numtowrite = SVAL(inbuf,smb_vwv1);
2183 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2184 data = smb_buf(inbuf) + 3;
2186 if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
2187 WRITE_LOCK,False)) {
2188 END_PROFILE(SMBwriteunlock);
2189 return ERROR_DOS(ERRDOS,ERRlock);
2192 /* The special X/Open SMB protocol handling of
2193 zero length writes is *NOT* done for
2198 nwritten = write_file(fsp,data,startpos,numtowrite);
2200 if (lp_syncalways(SNUM(conn)))
2201 sync_file(conn,fsp);
2203 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2204 END_PROFILE(SMBwriteunlock);
2205 return(UNIXERROR(ERRHRD,ERRdiskfull));
2209 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
2210 (SMB_BIG_UINT)startpos);
2211 if (NT_STATUS_V(status)) {
2212 END_PROFILE(SMBwriteunlock);
2213 return ERROR_NT(status);
2217 outsize = set_message(outbuf,1,0,True);
2219 SSVAL(outbuf,smb_vwv0,nwritten);
2221 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2222 fsp->fnum, (int)numtowrite, (int)nwritten));
2224 END_PROFILE(SMBwriteunlock);
2228 /****************************************************************************
2230 ****************************************************************************/
2232 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
2235 ssize_t nwritten = -1;
2238 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2240 START_PROFILE(SMBwrite);
2242 /* If it's an IPC, pass off the pipe handler. */
2244 END_PROFILE(SMBwrite);
2245 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
2248 CHECK_FSP(fsp,conn);
2251 numtowrite = SVAL(inbuf,smb_vwv1);
2252 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2253 data = smb_buf(inbuf) + 3;
2255 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2256 END_PROFILE(SMBwrite);
2257 return ERROR_DOS(ERRDOS,ERRlock);
2261 * X/Open SMB protocol says that if smb_vwv1 is
2262 * zero then the file size should be extended or
2263 * truncated to the size given in smb_vwv[2-3].
2266 if(numtowrite == 0) {
2268 * This is actually an allocate call, and set EOF. JRA.
2270 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
2272 END_PROFILE(SMBwrite);
2273 return ERROR_NT(NT_STATUS_DISK_FULL);
2275 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
2277 END_PROFILE(SMBwrite);
2278 return ERROR_NT(NT_STATUS_DISK_FULL);
2281 nwritten = write_file(fsp,data,startpos,numtowrite);
2283 if (lp_syncalways(SNUM(conn)))
2284 sync_file(conn,fsp);
2286 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2287 END_PROFILE(SMBwrite);
2288 return(UNIXERROR(ERRHRD,ERRdiskfull));
2291 outsize = set_message(outbuf,1,0,True);
2293 SSVAL(outbuf,smb_vwv0,nwritten);
2295 if (nwritten < (ssize_t)numtowrite) {
2296 SCVAL(outbuf,smb_rcls,ERRHRD);
2297 SSVAL(outbuf,smb_err,ERRdiskfull);
2300 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
2302 END_PROFILE(SMBwrite);
2306 /****************************************************************************
2307 Reply to a write and X.
2308 ****************************************************************************/
2310 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2312 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2313 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2314 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2315 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2316 ssize_t nwritten = -1;
2317 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
2318 unsigned int smblen = smb_len(inbuf);
2320 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
2321 START_PROFILE(SMBwriteX);
2323 /* If it's an IPC, pass off the pipe handler. */
2325 END_PROFILE(SMBwriteX);
2326 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2329 CHECK_FSP(fsp,conn);
2332 /* Deal with possible LARGE_WRITEX */
2334 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
2336 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
2337 END_PROFILE(SMBwriteX);
2338 return ERROR_DOS(ERRDOS,ERRbadmem);
2341 data = smb_base(inbuf) + smb_doff;
2343 if(CVAL(inbuf,smb_wct) == 14) {
2344 #ifdef LARGE_SMB_OFF_T
2346 * This is a large offset (64 bit) write.
2348 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2350 #else /* !LARGE_SMB_OFF_T */
2353 * Ensure we haven't been sent a >32 bit offset.
2356 if(IVAL(inbuf,smb_vwv12) != 0) {
2357 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
2358 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
2359 END_PROFILE(SMBwriteX);
2360 return ERROR_DOS(ERRDOS,ERRbadaccess);
2363 #endif /* LARGE_SMB_OFF_T */
2366 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2367 END_PROFILE(SMBwriteX);
2368 return ERROR_DOS(ERRDOS,ERRlock);
2371 /* X/Open SMB protocol says that, unlike SMBwrite
2372 if the length is zero then NO truncation is
2373 done, just a write of zero. To truncate a file,
2379 nwritten = write_file(fsp,data,startpos,numtowrite);
2381 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2382 END_PROFILE(SMBwriteX);
2383 return(UNIXERROR(ERRHRD,ERRdiskfull));
2386 set_message(outbuf,6,0,True);
2388 SSVAL(outbuf,smb_vwv2,nwritten);
2390 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
2392 if (nwritten < (ssize_t)numtowrite) {
2393 SCVAL(outbuf,smb_rcls,ERRHRD);
2394 SSVAL(outbuf,smb_err,ERRdiskfull);
2397 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2398 fsp->fnum, (int)numtowrite, (int)nwritten));
2400 if (lp_syncalways(SNUM(conn)) || write_through)
2401 sync_file(conn,fsp);
2403 END_PROFILE(SMBwriteX);
2404 return chain_reply(inbuf,outbuf,length,bufsize);
2407 /****************************************************************************
2409 ****************************************************************************/
2411 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2417 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2418 START_PROFILE(SMBlseek);
2420 CHECK_FSP(fsp,conn);
2422 flush_write_cache(fsp, SEEK_FLUSH);
2424 mode = SVAL(inbuf,smb_vwv1) & 3;
2425 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
2426 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
2435 res = fsp->pos + startpos;
2446 if (umode == SEEK_END) {
2447 if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
2448 if(errno == EINVAL) {
2449 SMB_OFF_T current_pos = startpos;
2450 SMB_STRUCT_STAT sbuf;
2452 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
2453 END_PROFILE(SMBlseek);
2454 return(UNIXERROR(ERRDOS,ERRnoaccess));
2457 current_pos += sbuf.st_size;
2459 res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
2464 END_PROFILE(SMBlseek);
2465 return(UNIXERROR(ERRDOS,ERRnoaccess));
2471 outsize = set_message(outbuf,2,0,True);
2472 SIVAL(outbuf,smb_vwv0,res);
2474 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2475 fsp->fnum, (double)startpos, (double)res, mode));
2477 END_PROFILE(SMBlseek);
2481 /****************************************************************************
2483 ****************************************************************************/
2485 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2487 int outsize = set_message(outbuf,0,0,True);
2488 uint16 fnum = SVAL(inbuf,smb_vwv0);
2489 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2490 START_PROFILE(SMBflush);
2493 CHECK_FSP(fsp,conn);
2496 file_sync_all(conn);
2498 sync_file(conn,fsp);
2501 DEBUG(3,("flush\n"));
2502 END_PROFILE(SMBflush);
2506 /****************************************************************************
2508 ****************************************************************************/
2510 int reply_exit(connection_struct *conn,
2511 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2514 START_PROFILE(SMBexit);
2516 file_close_pid(SVAL(inbuf,smb_pid));
2518 outsize = set_message(outbuf,0,0,True);
2520 DEBUG(3,("exit\n"));
2522 END_PROFILE(SMBexit);
2526 /****************************************************************************
2527 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2528 ****************************************************************************/
2530 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
2533 extern struct current_user current_user;
2536 int32 eclass = 0, err = 0;
2537 files_struct *fsp = NULL;
2538 START_PROFILE(SMBclose);
2540 outsize = set_message(outbuf,0,0,True);
2542 /* If it's an IPC, pass off to the pipe handler. */
2544 END_PROFILE(SMBclose);
2545 return reply_pipe_close(conn, inbuf,outbuf);
2548 fsp = file_fsp(inbuf,smb_vwv0);
2551 * We can only use CHECK_FSP if we know it's not a directory.
2554 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
2555 END_PROFILE(SMBclose);
2556 return ERROR_DOS(ERRDOS,ERRbadfid);
2559 if(fsp->is_directory) {
2561 * Special case - close NT SMB directory handle.
2563 DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
2564 close_file(fsp,True);
2567 * Close ordinary file.
2572 /* Save the name for time set in close. */
2573 pstrcpy( file_name, fsp->fsp_name);
2575 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2577 conn->num_files_open));
2580 * close_file() returns the unix errno if an error
2581 * was detected on close - normally this is due to
2582 * a disk full error. If not then it was probably an I/O error.
2585 if((close_err = close_file(fsp,True)) != 0) {
2587 END_PROFILE(SMBclose);
2588 return (UNIXERROR(ERRHRD,ERRgeneral));
2592 * Now take care of any time sent in the close.
2595 mtime = make_unix_date3(inbuf+smb_vwv1);
2597 /* try and set the date */
2598 set_filetime(conn, file_name, mtime);
2602 /* We have a cached error */
2604 END_PROFILE(SMBclose);
2605 return ERROR_DOS(eclass,err);
2608 END_PROFILE(SMBclose);
2612 /****************************************************************************
2613 Reply to a writeclose (Core+ protocol).
2614 ****************************************************************************/
2616 int reply_writeclose(connection_struct *conn,
2617 char *inbuf,char *outbuf, int size, int dum_buffsize)
2620 ssize_t nwritten = -1;
2626 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2627 START_PROFILE(SMBwriteclose);
2629 CHECK_FSP(fsp,conn);
2632 numtowrite = SVAL(inbuf,smb_vwv1);
2633 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2634 mtime = make_unix_date3(inbuf+smb_vwv4);
2635 data = smb_buf(inbuf) + 1;
2637 if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2638 END_PROFILE(SMBwriteclose);
2639 return ERROR_DOS(ERRDOS,ERRlock);
2642 nwritten = write_file(fsp,data,startpos,numtowrite);
2644 set_filetime(conn, fsp->fsp_name,mtime);
2647 * More insanity. W2K only closes the file if writelen > 0.
2652 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
2654 close_err = close_file(fsp,True);
2657 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2658 fsp->fnum, (int)numtowrite, (int)nwritten,
2659 conn->num_files_open));
2661 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2662 END_PROFILE(SMBwriteclose);
2663 return(UNIXERROR(ERRHRD,ERRdiskfull));
2666 if(close_err != 0) {
2668 END_PROFILE(SMBwriteclose);
2669 return(UNIXERROR(ERRHRD,ERRgeneral));
2672 outsize = set_message(outbuf,1,0,True);
2674 SSVAL(outbuf,smb_vwv0,nwritten);
2675 END_PROFILE(SMBwriteclose);
2679 /****************************************************************************
2681 ****************************************************************************/
2683 int reply_lock(connection_struct *conn,
2684 char *inbuf,char *outbuf, int length, int dum_buffsize)
2686 int outsize = set_message(outbuf,0,0,True);
2687 SMB_BIG_UINT count,offset;
2689 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2690 BOOL my_lock_ctx = False;
2692 START_PROFILE(SMBlock);
2694 CHECK_FSP(fsp,conn);
2696 release_level_2_oplocks_on_change(fsp);
2698 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2699 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2701 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2702 fsp->fd, fsp->fnum, (double)offset, (double)count));
2704 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx);
2705 if (NT_STATUS_V(status)) {
2707 /* Tests using Samba4 against W2K show this call never creates a blocking lock. */
2708 if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
2710 * A blocking lock was requested. Package up
2711 * this smb into a queued request and push it
2712 * onto the blocking lock queue.
2714 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), offset, count)) {
2715 END_PROFILE(SMBlock);
2720 END_PROFILE(SMBlock);
2721 return ERROR_NT(status);
2724 END_PROFILE(SMBlock);
2728 /****************************************************************************
2730 ****************************************************************************/
2732 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
2735 int outsize = set_message(outbuf,0,0,True);
2736 SMB_BIG_UINT count,offset;
2738 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2739 START_PROFILE(SMBunlock);
2741 CHECK_FSP(fsp,conn);
2743 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2744 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2746 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
2747 if (NT_STATUS_V(status)) {
2748 END_PROFILE(SMBunlock);
2749 return ERROR_NT(status);
2752 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2753 fsp->fd, fsp->fnum, (double)offset, (double)count ) );
2755 END_PROFILE(SMBunlock);
2759 /****************************************************************************
2761 ****************************************************************************/
2763 int reply_tdis(connection_struct *conn,
2764 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2766 int outsize = set_message(outbuf,0,0,True);
2768 START_PROFILE(SMBtdis);
2770 vuid = SVAL(inbuf,smb_uid);
2773 DEBUG(4,("Invalid connection in tdis\n"));
2774 END_PROFILE(SMBtdis);
2775 return ERROR_DOS(ERRSRV,ERRinvnid);
2780 close_cnum(conn,vuid);
2782 END_PROFILE(SMBtdis);
2786 /****************************************************************************
2788 ****************************************************************************/
2790 int reply_echo(connection_struct *conn,
2791 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2793 int smb_reverb = SVAL(inbuf,smb_vwv0);
2795 unsigned int data_len = smb_buflen(inbuf);
2796 int outsize = set_message(outbuf,1,data_len,True);
2797 START_PROFILE(SMBecho);
2799 if (data_len > BUFFER_SIZE) {
2800 DEBUG(0,("reply_echo: data_len too large.\n"));
2801 END_PROFILE(SMBecho);
2805 /* copy any incoming data back out */
2807 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
2809 if (smb_reverb > 100) {
2810 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
2814 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
2815 SSVAL(outbuf,smb_vwv0,seq_num);
2817 smb_setlen(outbuf,outsize - 4);
2819 if (!send_smb(smbd_server_fd(),outbuf))
2820 exit_server("reply_echo: send_smb failed.");
2823 DEBUG(3,("echo %d times\n", smb_reverb));
2827 END_PROFILE(SMBecho);
2831 /****************************************************************************
2832 Reply to a printopen.
2833 ****************************************************************************/
2835 int reply_printopen(connection_struct *conn,
2836 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2840 START_PROFILE(SMBsplopen);
2842 if (!CAN_PRINT(conn)) {
2843 END_PROFILE(SMBsplopen);
2844 return ERROR_DOS(ERRDOS,ERRnoaccess);
2847 /* Open for exclusive use, write only. */
2848 fsp = print_fsp_open(conn, NULL);
2851 END_PROFILE(SMBsplopen);
2852 return(UNIXERROR(ERRDOS,ERRnoaccess));
2855 outsize = set_message(outbuf,1,0,True);
2856 SSVAL(outbuf,smb_vwv0,fsp->fnum);
2858 DEBUG(3,("openprint fd=%d fnum=%d\n",
2859 fsp->fd, fsp->fnum));
2861 END_PROFILE(SMBsplopen);
2865 /****************************************************************************
2866 Reply to a printclose.
2867 ****************************************************************************/
2869 int reply_printclose(connection_struct *conn,
2870 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2872 int outsize = set_message(outbuf,0,0,True);
2873 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2875 START_PROFILE(SMBsplclose);
2877 CHECK_FSP(fsp,conn);
2879 if (!CAN_PRINT(conn)) {
2880 END_PROFILE(SMBsplclose);
2881 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
2884 DEBUG(3,("printclose fd=%d fnum=%d\n",
2885 fsp->fd,fsp->fnum));
2887 close_err = close_file(fsp,True);
2889 if(close_err != 0) {
2891 END_PROFILE(SMBsplclose);
2892 return(UNIXERROR(ERRHRD,ERRgeneral));
2895 END_PROFILE(SMBsplclose);
2899 /****************************************************************************
2900 Reply to a printqueue.
2901 ****************************************************************************/
2903 int reply_printqueue(connection_struct *conn,
2904 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2906 int outsize = set_message(outbuf,2,3,True);
2907 int max_count = SVAL(inbuf,smb_vwv0);
2908 int start_index = SVAL(inbuf,smb_vwv1);
2909 START_PROFILE(SMBsplretq);
2911 /* we used to allow the client to get the cnum wrong, but that
2912 is really quite gross and only worked when there was only
2913 one printer - I think we should now only accept it if they
2914 get it right (tridge) */
2915 if (!CAN_PRINT(conn)) {
2916 END_PROFILE(SMBsplretq);
2917 return ERROR_DOS(ERRDOS,ERRnoaccess);
2920 SSVAL(outbuf,smb_vwv0,0);
2921 SSVAL(outbuf,smb_vwv1,0);
2922 SCVAL(smb_buf(outbuf),0,1);
2923 SSVAL(smb_buf(outbuf),1,0);
2925 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
2926 start_index, max_count));
2929 print_queue_struct *queue = NULL;
2930 print_status_struct status;
2931 char *p = smb_buf(outbuf) + 3;
2932 int count = print_queue_status(SNUM(conn), &queue, &status);
2933 int num_to_get = ABS(max_count);
2934 int first = (max_count>0?start_index:start_index+max_count+1);
2940 num_to_get = MIN(num_to_get,count-first);
2943 for (i=first;i<first+num_to_get;i++) {
2944 put_dos_date2(p,0,queue[i].time);
2945 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
2946 SSVAL(p,5, queue[i].job);
2947 SIVAL(p,7,queue[i].size);
2949 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
2954 outsize = set_message(outbuf,2,28*count+3,False);
2955 SSVAL(outbuf,smb_vwv0,count);
2956 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
2957 SCVAL(smb_buf(outbuf),0,1);
2958 SSVAL(smb_buf(outbuf),1,28*count);
2963 DEBUG(3,("%d entries returned in queue\n",count));
2966 END_PROFILE(SMBsplretq);
2970 /****************************************************************************
2971 Reply to a printwrite.
2972 ****************************************************************************/
2974 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2977 int outsize = set_message(outbuf,0,0,True);
2979 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2981 START_PROFILE(SMBsplwr);
2983 if (!CAN_PRINT(conn)) {
2984 END_PROFILE(SMBsplwr);
2985 return ERROR_DOS(ERRDOS,ERRnoaccess);
2988 CHECK_FSP(fsp,conn);
2991 numtowrite = SVAL(smb_buf(inbuf),1);
2992 data = smb_buf(inbuf) + 3;
2994 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
2995 END_PROFILE(SMBsplwr);
2996 return(UNIXERROR(ERRHRD,ERRdiskfull));
2999 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
3001 END_PROFILE(SMBsplwr);
3005 /****************************************************************************
3006 The guts of the mkdir command, split out so it may be called by the NT SMB
3008 ****************************************************************************/
3010 NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
3012 BOOL bad_path = False;
3013 SMB_STRUCT_STAT sbuf;
3016 unix_convert(directory,conn,0,&bad_path,&sbuf);
3018 if( strchr_m(directory, ':')) {
3019 return NT_STATUS_NOT_A_DIRECTORY;
3022 if (ms_has_wild(directory)) {
3023 return NT_STATUS_OBJECT_NAME_INVALID;
3026 if (check_name(directory, conn))
3027 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3030 if(errno == ENOENT) {
3032 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3034 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3036 return map_nt_error_from_unix(errno);
3039 return NT_STATUS_OK;
3042 /****************************************************************************
3044 ****************************************************************************/
3046 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3051 START_PROFILE(SMBmkdir);
3053 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE,&status);
3054 if (!NT_STATUS_IS_OK(status)) {
3055 END_PROFILE(SMBmkdir);
3056 return ERROR_NT(status);
3059 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
3061 status = mkdir_internal(conn, directory);
3062 if (!NT_STATUS_IS_OK(status)) {
3063 END_PROFILE(SMBmkdir);
3064 return ERROR_NT(status);
3067 outsize = set_message(outbuf,0,0,True);
3069 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
3071 END_PROFILE(SMBmkdir);
3075 /****************************************************************************
3076 Static function used by reply_rmdir to delete an entire directory
3077 tree recursively. Return False on ok, True on fail.
3078 ****************************************************************************/
3080 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
3082 const char *dname = NULL;
3084 void *dirptr = OpenDir(conn, directory, False);
3089 while((dname = ReadDirName(dirptr))) {
3093 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3096 /* Construct the full name. */
3097 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3103 pstrcpy(fullname, directory);
3104 pstrcat(fullname, "/");
3105 pstrcat(fullname, dname);
3107 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
3112 if(st.st_mode & S_IFDIR) {
3113 if(recursive_rmdir(conn, fullname)!=0) {
3117 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
3121 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
3130 /****************************************************************************
3131 The internals of the rmdir code - called elsewhere.
3132 ****************************************************************************/
3134 BOOL rmdir_internals(connection_struct *conn, char *directory)
3138 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3139 if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
3141 * Check to see if the only thing in this directory are
3142 * vetoed files/directories. If so then delete them and
3143 * retry. If we fail to delete any of them (and we *don't*
3144 * do a recursive delete) then fail the rmdir.
3146 BOOL all_veto_files = True;
3148 void *dirptr = OpenDir(conn, directory, False);
3150 if(dirptr != NULL) {
3151 int dirpos = TellDir(dirptr);
3152 while ((dname = ReadDirName(dirptr))) {
3153 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3155 if(!IS_VETO_PATH(conn, dname)) {
3156 all_veto_files = False;
3161 if(all_veto_files) {
3162 SeekDir(dirptr,dirpos);
3163 while ((dname = ReadDirName(dirptr))) {
3167 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3170 /* Construct the full name. */
3171 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3176 pstrcpy(fullname, directory);
3177 pstrcat(fullname, "/");
3178 pstrcat(fullname, dname);
3180 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
3182 if(st.st_mode & S_IFDIR) {
3183 if(lp_recursive_veto_delete(SNUM(conn))) {
3184 if(recursive_rmdir(conn, fullname) != 0)
3187 if(SMB_VFS_RMDIR(conn,fullname) != 0)
3189 } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
3193 /* Retry the rmdir */
3194 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3204 DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory,strerror(errno)));
3209 /****************************************************************************
3211 ****************************************************************************/
3213 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3218 BOOL bad_path = False;
3219 SMB_STRUCT_STAT sbuf;
3221 START_PROFILE(SMBrmdir);
3223 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE,&status);
3224 if (!NT_STATUS_IS_OK(status)) {
3225 END_PROFILE(SMBrmdir);
3226 return ERROR_NT(status);
3229 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
3231 unix_convert(directory,conn, NULL,&bad_path,&sbuf);
3233 if (check_name(directory,conn)) {
3234 dptr_closepath(directory,SVAL(inbuf,smb_pid));
3235 ok = rmdir_internals(conn, directory);
3239 END_PROFILE(SMBrmdir);
3240 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRbadpath);
3243 outsize = set_message(outbuf,0,0,True);
3245 DEBUG( 3, ( "rmdir %s\n", directory ) );
3247 END_PROFILE(SMBrmdir);
3251 /*******************************************************************
3252 Resolve wildcards in a filename rename.
3253 ********************************************************************/
3255 static BOOL resolve_wildcards(const char *name1, char *name2)
3257 fstring root1,root2;
3259 char *p,*p2, *pname1, *pname2;
3260 int available_space;
3263 pname1 = strrchr_m(name1,'/');
3264 pname2 = strrchr_m(name2,'/');
3266 if (!pname1 || !pname2)
3269 fstrcpy(root1,pname1);
3270 fstrcpy(root2,pname2);
3271 p = strrchr_m(root1,'.');
3278 p = strrchr_m(root2,'.');
3312 available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
3315 snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
3317 pstrcpy_base(pname2, root2, name2);
3323 /****************************************************************************
3324 Ensure open files have their names updates.
3325 ****************************************************************************/
3327 static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, char *newname)
3330 BOOL did_rename = False;
3332 for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
3333 DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
3334 fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode,
3335 fsp->fsp_name, newname ));
3336 string_set(&fsp->fsp_name, newname);
3341 DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
3342 (unsigned int)dev, (double)inode, newname ));
3345 /****************************************************************************
3346 Rename an open file - given an fsp.
3347 ****************************************************************************/
3349 NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, BOOL replace_if_exists)
3351 SMB_STRUCT_STAT sbuf;
3352 BOOL bad_path = False;
3353 pstring newname_last_component;
3354 NTSTATUS error = NT_STATUS_OK;
3358 unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf);
3360 /* Ensure newname contains a '/' */
3361 if(strrchr_m(newname,'/') == 0) {
3364 pstrcpy(tmpstr, "./");
3365 pstrcat(tmpstr, newname);
3366 pstrcpy(newname, tmpstr);
3370 * Check for special case with case preserving and not
3371 * case sensitive. If the old last component differs from the original
3372 * last component only by case, then we should allow
3373 * the rename (user is trying to change the case of the
3377 if((case_sensitive == False) && (case_preserve == True) &&
3378 strequal(newname, fsp->fsp_name)) {
3380 pstring newname_modified_last_component;
3383 * Get the last component of the modified name.
3384 * Note that we guarantee that newname contains a '/'
3387 p = strrchr_m(newname,'/');
3388 pstrcpy(newname_modified_last_component,p+1);
3390 if(strcsequal(newname_modified_last_component,
3391 newname_last_component) == False) {
3393 * Replace the modified last component with
3396 pstrcpy(p+1, newname_last_component);
3401 * If the src and dest names are identical - including case,
3402 * don't do the rename, just return success.
3405 if (strcsequal(fsp->fsp_name, newname)) {
3406 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
3408 return NT_STATUS_OK;
3411 dest_exists = vfs_object_exist(conn,newname,NULL);
3413 if(!replace_if_exists && dest_exists) {
3414 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
3415 fsp->fsp_name,newname));
3416 return NT_STATUS_OBJECT_NAME_COLLISION;
3419 error = can_rename(newname,conn,&sbuf);
3421 if (dest_exists && !NT_STATUS_IS_OK(error)) {
3422 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3423 nt_errstr(error), fsp->fsp_name,newname));
3424 if (NT_STATUS_EQUAL(error,NT_STATUS_SHARING_VIOLATION))
3425 error = NT_STATUS_ACCESS_DENIED;
3429 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
3430 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
3431 fsp->fsp_name,newname));
3432 rename_open_files(conn, fsp->dev, fsp->inode, newname);
3433 return NT_STATUS_OK;
3436 if (errno == ENOTDIR || errno == EISDIR)
3437 error = NT_STATUS_OBJECT_NAME_COLLISION;
3439 error = map_nt_error_from_unix(errno);
3441 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
3442 nt_errstr(error), fsp->fsp_name,newname));
3447 /****************************************************************************
3448 The guts of the rename command, split out so it may be called by the NT SMB
3450 ****************************************************************************/
3452 NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists)
3456 pstring newname_last_component;
3459 BOOL bad_path1 = False;
3460 BOOL bad_path2 = False;
3462 NTSTATUS error = NT_STATUS_OK;
3464 SMB_STRUCT_STAT sbuf1, sbuf2;
3466 *directory = *mask = 0;
3470 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
3471 unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2);
3474 * Split the old name into directory and last component
3475 * strings. Note that unix_convert may have stripped off a
3476 * leading ./ from both name and newname if the rename is
3477 * at the root of the share. We need to make sure either both
3478 * name and newname contain a / character or neither of them do
3479 * as this is checked in resolve_wildcards().
3482 p = strrchr_m(name,'/');
3484 pstrcpy(directory,".");
3488 pstrcpy(directory,name);
3490 *p = '/'; /* Replace needed for exceptional test below. */
3494 * We should only check the mangled cache
3495 * here if unix_convert failed. This means
3496 * that the path in 'mask' doesn't exist
3497 * on the file system and so we need to look
3498 * for a possible mangle. This patch from
3499 * Tine Smukavec <valentin.smukavec@hermes.si>.
3502 if (!rc && mangle_is_mangled(mask))
3503 mangle_check_cache( mask );
3505 has_wild = ms_has_wild(mask);
3509 * No wildcards - just process the one file.
3511 BOOL is_short_name = mangle_is_8_3(name, True);
3513 /* Add a terminating '/' to the directory name. */
3514 pstrcat(directory,"/");
3515 pstrcat(directory,mask);
3517 /* Ensure newname contains a '/' also */
3518 if(strrchr_m(newname,'/') == 0) {
3521 pstrcpy(tmpstr, "./");
3522 pstrcat(tmpstr, newname);
3523 pstrcpy(newname, tmpstr);
3526 DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
3527 directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
3528 case_sensitive, case_preserve, short_case_preserve, directory,
3529 newname, newname_last_component, is_short_name));
3532 * Check for special case with case preserving and not
3533 * case sensitive, if directory and newname are identical,
3534 * and the old last component differs from the original
3535 * last component only by case, then we should allow
3536 * the rename (user is trying to change the case of the
3539 if((case_sensitive == False) &&
3540 (((case_preserve == True) &&
3541 (is_short_name == False)) ||
3542 ((short_case_preserve == True) &&
3543 (is_short_name == True))) &&
3544 strcsequal(directory, newname)) {
3545 pstring newname_modified_last_component;
3548 * Get the last component of the modified name.
3549 * Note that we guarantee that newname contains a '/'
3552 p = strrchr_m(newname,'/');
3553 pstrcpy(newname_modified_last_component,p+1);
3555 if(strcsequal(newname_modified_last_component,
3556 newname_last_component) == False) {
3558 * Replace the modified last component with
3561 pstrcpy(p+1, newname_last_component);
3565 resolve_wildcards(directory,newname);
3568 * The source object must exist.
3571 if (!vfs_object_exist(conn, directory, &sbuf1)) {
3572 DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
3573 directory,newname));
3575 if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
3577 * Must return different errors depending on whether the parent
3578 * directory existed or not.
3581 p = strrchr_m(directory, '/');
3583 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3585 if (vfs_object_exist(conn, directory, NULL))
3586 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3587 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3589 error = map_nt_error_from_unix(errno);
3590 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3591 nt_errstr(error), directory,newname));
3596 error = can_rename(directory,conn,&sbuf1);
3598 if (!NT_STATUS_IS_OK(error)) {
3599 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3600 nt_errstr(error), directory,newname));
3605 * If the src and dest names are identical - including case,
3606 * don't do the rename, just return success.
3609 if (strcsequal(directory, newname)) {
3610 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3611 DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
3612 return NT_STATUS_OK;
3615 if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
3616 DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
3617 directory,newname));
3618 return NT_STATUS_OBJECT_NAME_COLLISION;
3621 if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
3622 DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
3623 directory,newname));
3624 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3625 return NT_STATUS_OK;
3628 if (errno == ENOTDIR || errno == EISDIR)
3629 error = NT_STATUS_OBJECT_NAME_COLLISION;
3631 error = map_nt_error_from_unix(errno);
3633 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3634 nt_errstr(error), directory,newname));
3639 * Wildcards - process each file that matches.
3641 void *dirptr = NULL;
3645 if (check_name(directory,conn))
3646 dirptr = OpenDir(conn, directory, True);
3649 error = NT_STATUS_NO_SUCH_FILE;
3650 /* Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */
3652 if (strequal(mask,"????????.???"))
3655 while ((dname = ReadDirName(dirptr))) {
3658 pstrcpy(fname,dname);
3660 if((strcmp(fname, ".") == 0) || (strcmp(fname, "..")==0))
3663 if(!mask_match(fname, mask, case_sensitive))
3666 error = NT_STATUS_ACCESS_DENIED;
3667 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
3668 if (!vfs_object_exist(conn, fname, &sbuf1)) {
3669 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3670 DEBUG(6,("rename %s failed. Error %s\n", fname, nt_errstr(error)));
3673 error = can_rename(fname,conn,&sbuf1);
3674 if (!NT_STATUS_IS_OK(error)) {
3675 DEBUG(6,("rename %s refused\n", fname));
3678 pstrcpy(destname,newname);
3680 if (!resolve_wildcards(fname,destname)) {
3681 DEBUG(6,("resolve_wildcards %s %s failed\n",
3686 if (!replace_if_exists &&
3687 vfs_file_exist(conn,destname, NULL)) {
3688 DEBUG(6,("file_exist %s\n", destname));
3689 error = NT_STATUS_OBJECT_NAME_COLLISION;
3693 if (!SMB_VFS_RENAME(conn,fname,destname)) {
3694 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3697 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
3703 if (count == 0 && NT_STATUS_IS_OK(error)) {
3704 error = map_nt_error_from_unix(errno);
3710 /****************************************************************************
3712 ****************************************************************************/
3714 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
3723 START_PROFILE(SMBmv);
3725 p = smb_buf(inbuf) + 1;
3726 p += srvstr_get_path(inbuf, name, p, sizeof(name), STR_TERMINATE,&status);
3727 if (!NT_STATUS_IS_OK(status)) {
3729 return ERROR_NT(status);
3732 p += srvstr_get_path(inbuf, newname, p, sizeof(newname), STR_TERMINATE,&status);
3733 if (!NT_STATUS_IS_OK(status)) {
3735 return ERROR_NT(status);
3738 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3739 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3741 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
3743 status = rename_internals(conn, name, newname, False);
3744 if (!NT_STATUS_IS_OK(status)) {
3746 return ERROR_NT(status);
3750 * Win2k needs a changenotify request response before it will
3751 * update after a rename..
3753 process_pending_change_notify_queue((time_t)0);
3754 outsize = set_message(outbuf,0,0,True);
3760 /*******************************************************************
3761 Copy a file as part of a reply_copy.
3762 ******************************************************************/
3764 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
3765 int count,BOOL target_is_directory, int *err_ret)
3768 SMB_STRUCT_STAT src_sbuf, sbuf2;
3770 files_struct *fsp1,*fsp2;
3775 pstrcpy(dest,dest1);
3776 if (target_is_directory) {
3777 char *p = strrchr_m(src,'/');
3786 if (!vfs_file_exist(conn,src,&src_sbuf))
3789 fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
3790 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
3795 if (!target_is_directory && count)
3796 ofun = FILE_EXISTS_OPEN;
3798 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
3799 ZERO_STRUCTP(&sbuf2);
3801 fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
3802 ofun,src_sbuf.st_mode,0,&Access,&action);
3805 close_file(fsp1,False);
3809 if ((ofun&3) == 1) {
3810 if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
3811 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
3813 * Stop the copy from occurring.
3816 src_sbuf.st_size = 0;
3820 if (src_sbuf.st_size)
3821 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
3823 close_file(fsp1,False);
3825 /* Ensure the modtime is set correctly on the destination file. */
3826 fsp2->pending_modtime = src_sbuf.st_mtime;
3829 * As we are opening fsp1 read-only we only expect
3830 * an error on close on fsp2 if we are out of space.
3831 * Thus we don't look at the error return from the
3834 *err_ret = close_file(fsp2,False);
3836 return(ret == (SMB_OFF_T)src_sbuf.st_size);
3839 /****************************************************************************
3840 Reply to a file copy.
3841 ****************************************************************************/
3843 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3848 pstring mask,newname;
3851 int error = ERRnoaccess;
3855 int tid2 = SVAL(inbuf,smb_vwv0);
3856 int ofun = SVAL(inbuf,smb_vwv1);
3857 int flags = SVAL(inbuf,smb_vwv2);
3858 BOOL target_is_directory=False;
3859 BOOL bad_path1 = False;
3860 BOOL bad_path2 = False;
3862 SMB_STRUCT_STAT sbuf1, sbuf2;
3865 START_PROFILE(SMBcopy);
3867 *directory = *mask = 0;
3870 p += srvstr_get_path(inbuf, name, p, sizeof(name), STR_TERMINATE,&status);
3871 if (!NT_STATUS_IS_OK(status)) {
3872 END_PROFILE(SMBcopy);
3873 return ERROR_NT(status);
3875 p += srvstr_get_path(inbuf, newname, p, sizeof(newname), STR_TERMINATE,&status);
3876 if (!NT_STATUS_IS_OK(status)) {
3877 END_PROFILE(SMBcopy);
3878 return ERROR_NT(status);
3881 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
3883 if (tid2 != conn->cnum) {
3884 /* can't currently handle inter share copies XXXX */
3885 DEBUG(3,("Rejecting inter-share copy\n"));
3886 END_PROFILE(SMBcopy);
3887 return ERROR_DOS(ERRSRV,ERRinvdevice);
3890 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3891 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3893 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
3894 unix_convert(newname,conn,0,&bad_path2,&sbuf2);
3896 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
3898 if ((flags&1) && target_is_directory) {
3899 END_PROFILE(SMBcopy);
3900 return ERROR_DOS(ERRDOS,ERRbadfile);
3903 if ((flags&2) && !target_is_directory) {
3904 END_PROFILE(SMBcopy);
3905 return ERROR_DOS(ERRDOS,ERRbadpath);
3908 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
3909 /* wants a tree copy! XXXX */
3910 DEBUG(3,("Rejecting tree copy\n"));
3911 END_PROFILE(SMBcopy);
3912 return ERROR_DOS(ERRSRV,ERRerror);
3915 p = strrchr_m(name,'/');
3917 pstrcpy(directory,"./");
3921 pstrcpy(directory,name);
3926 * We should only check the mangled cache
3927 * here if unix_convert failed. This means
3928 * that the path in 'mask' doesn't exist
3929 * on the file system and so we need to look
3930 * for a possible mangle. This patch from
3931 * Tine Smukavec <valentin.smukavec@hermes.si>.
3934 if (!rc && mangle_is_mangled(mask))
3935 mangle_check_cache( mask );
3937 has_wild = ms_has_wild(mask);
3940 pstrcat(directory,"/");
3941 pstrcat(directory,mask);
3942 if (resolve_wildcards(directory,newname) &&
3943 copy_file(directory,newname,conn,ofun, count,target_is_directory,&err))
3947 END_PROFILE(SMBcopy);
3948 return(UNIXERROR(ERRHRD,ERRgeneral));
3951 exists = vfs_file_exist(conn,directory,NULL);
3954 void *dirptr = NULL;
3958 if (check_name(directory,conn))
3959 dirptr = OpenDir(conn, directory, True);
3964 if (strequal(mask,"????????.???"))
3967 while ((dname = ReadDirName(dirptr))) {
3969 pstrcpy(fname,dname);
3971 if(!mask_match(fname, mask, case_sensitive))
3974 error = ERRnoaccess;
3975 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
3976 pstrcpy(destname,newname);
3977 if (resolve_wildcards(fname,destname) &&
3978 copy_file(fname,destname,conn,ofun,
3979 count,target_is_directory,&err))
3981 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
3989 /* Error on close... */
3991 END_PROFILE(SMBcopy);
3992 return(UNIXERROR(ERRHRD,ERRgeneral));
3996 END_PROFILE(SMBcopy);
3997 return ERROR_DOS(ERRDOS,error);
3999 if((errno == ENOENT) && (bad_path1 || bad_path2)) {
4000 unix_ERR_class = ERRDOS;
4001 unix_ERR_code = ERRbadpath;
4003 END_PROFILE(SMBcopy);
4004 return(UNIXERROR(ERRDOS,error));
4008 outsize = set_message(outbuf,1,0,True);
4009 SSVAL(outbuf,smb_vwv0,count);
4011 END_PROFILE(SMBcopy);
4015 /****************************************************************************
4017 ****************************************************************************/
4019 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4027 START_PROFILE(pathworks_setdir);
4030 if (!CAN_SETDIR(snum)) {
4031 END_PROFILE(pathworks_setdir);
4032 return ERROR_DOS(ERRDOS,ERRnoaccess);
4035 srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), STR_TERMINATE,&status);
4036 if (!NT_STATUS_IS_OK(status)) {
4037 END_PROFILE(pathworks_setdir);
4038 return ERROR_NT(status);
4041 if (strlen(newdir) == 0) {
4044 ok = vfs_directory_exist(conn,newdir,NULL);
4046 string_set(&conn->connectpath,newdir);
4050 END_PROFILE(pathworks_setdir);
4051 return ERROR_DOS(ERRDOS,ERRbadpath);
4054 outsize = set_message(outbuf,0,0,True);
4055 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
4057 DEBUG(3,("setdir %s\n", newdir));
4059 END_PROFILE(pathworks_setdir);
4063 /****************************************************************************
4064 Get a lock pid, dealing with large count requests.
4065 ****************************************************************************/
4067 uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
4069 if(!large_file_format)
4070 return SVAL(data,SMB_LPID_OFFSET(data_offset));
4072 return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
4075 /****************************************************************************
4076 Get a lock count, dealing with large count requests.
4077 ****************************************************************************/
4079 SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
4081 SMB_BIG_UINT count = 0;
4083 if(!large_file_format) {
4084 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
4087 #if defined(HAVE_LONGLONG)
4088 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
4089 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
4090 #else /* HAVE_LONGLONG */
4093 * NT4.x seems to be broken in that it sends large file (64 bit)
4094 * lockingX calls even if the CAP_LARGE_FILES was *not*
4095 * negotiated. For boxes without large unsigned ints truncate the
4096 * lock count by dropping the top 32 bits.
4099 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
4100 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
4101 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
4102 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
4103 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
4106 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
4107 #endif /* HAVE_LONGLONG */
4113 #if !defined(HAVE_LONGLONG)
4114 /****************************************************************************
4115 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
4116 ****************************************************************************/
4118 static uint32 map_lock_offset(uint32 high, uint32 low)
4122 uint32 highcopy = high;
4125 * Try and find out how many significant bits there are in high.
4128 for(i = 0; highcopy; i++)
4132 * We use 31 bits not 32 here as POSIX
4133 * lock offsets may not be negative.
4136 mask = (~0) << (31 - i);
4139 return 0; /* Fail. */
4145 #endif /* !defined(HAVE_LONGLONG) */
4147 /****************************************************************************
4148 Get a lock offset, dealing with large offset requests.
4149 ****************************************************************************/
4151 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
4153 SMB_BIG_UINT offset = 0;
4157 if(!large_file_format) {
4158 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
4161 #if defined(HAVE_LONGLONG)
4162 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
4163 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
4164 #else /* HAVE_LONGLONG */
4167 * NT4.x seems to be broken in that it sends large file (64 bit)
4168 * lockingX calls even if the CAP_LARGE_FILES was *not*
4169 * negotiated. For boxes without large unsigned ints mangle the
4170 * lock offset by mapping the top 32 bits onto the lower 32.
4173 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
4174 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4175 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
4178 if((new_low = map_lock_offset(high, low)) == 0) {
4180 return (SMB_BIG_UINT)-1;
4183 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
4184 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
4185 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
4186 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
4189 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4190 #endif /* HAVE_LONGLONG */
4196 /****************************************************************************
4197 Reply to a lockingX request.
4198 ****************************************************************************/
4200 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4202 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
4203 unsigned char locktype = CVAL(inbuf,smb_vwv3);
4204 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
4205 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
4206 uint16 num_locks = SVAL(inbuf,smb_vwv7);
4207 SMB_BIG_UINT count = 0, offset = 0;
4209 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
4212 BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
4214 BOOL my_lock_ctx = False;
4217 START_PROFILE(SMBlockingX);
4219 CHECK_FSP(fsp,conn);
4221 data = smb_buf(inbuf);
4223 if (locktype & (LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_CHANGE_LOCKTYPE)) {
4224 /* we don't support these - and CANCEL_LOCK makes w2k
4225 and XP reboot so I don't really want to be
4226 compatible! (tridge) */
4227 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4230 /* Check if this is an oplock break on a file
4231 we have granted an oplock on.
4233 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
4234 /* Client can insist on breaking to none. */
4235 BOOL break_to_none = (oplocklevel == 0);
4237 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
4238 (unsigned int)oplocklevel, fsp->fnum ));
4241 * Make sure we have granted an exclusive or batch oplock on this file.
4244 if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
4245 DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
4246 no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
4248 /* if this is a pure oplock break request then don't send a reply */
4249 if (num_locks == 0 && num_ulocks == 0) {
4250 END_PROFILE(SMBlockingX);
4253 END_PROFILE(SMBlockingX);
4254 return ERROR_DOS(ERRDOS,ERRlock);
4258 if (remove_oplock(fsp, break_to_none) == False) {
4259 DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
4263 /* if this is a pure oplock break request then don't send a reply */
4264 if (num_locks == 0 && num_ulocks == 0) {
4265 /* Sanity check - ensure a pure oplock break is not a
4267 if(CVAL(inbuf,smb_vwv0) != 0xff)
4268 DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
4269 (unsigned int)CVAL(inbuf,smb_vwv0) ));
4270 END_PROFILE(SMBlockingX);
4276 * We do this check *after* we have checked this is not a oplock break
4277 * response message. JRA.
4280 release_level_2_oplocks_on_change(fsp);
4282 /* Data now points at the beginning of the list
4283 of smb_unlkrng structs */
4284 for(i = 0; i < (int)num_ulocks; i++) {
4285 lock_pid = get_lock_pid( data, i, large_file_format);
4286 count = get_lock_count( data, i, large_file_format);
4287 offset = get_lock_offset( data, i, large_file_format, &err);
4290 * There is no error code marked "stupid client bug".... :-).
4293 END_PROFILE(SMBlockingX);
4294 return ERROR_DOS(ERRDOS,ERRnoaccess);
4297 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
4298 (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
4300 status = do_unlock(fsp,conn,lock_pid,count,offset);
4301 if (NT_STATUS_V(status)) {
4302 END_PROFILE(SMBlockingX);
4303 return ERROR_NT(status);
4307 /* Setup the timeout in seconds. */
4309 lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000);
4311 /* Now do any requested locks */
4312 data += ((large_file_format ? 20 : 10)*num_ulocks);
4314 /* Data now points at the beginning of the list
4315 of smb_lkrng structs */
4317 for(i = 0; i < (int)num_locks; i++) {
4318 lock_pid = get_lock_pid( data, i, large_file_format);
4319 count = get_lock_count( data, i, large_file_format);
4320 offset = get_lock_offset( data, i, large_file_format, &err);
4323 * There is no error code marked "stupid client bug".... :-).
4326 END_PROFILE(SMBlockingX);
4327 return ERROR_DOS(ERRDOS,ERRnoaccess);
4330 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
4331 (double)offset, (double)count, (unsigned int)lock_pid,
4332 fsp->fsp_name, (int)lock_timeout ));
4334 status = do_lock_spin(fsp,conn,lock_pid, count,offset,
4335 ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx);
4336 if (NT_STATUS_V(status)) {
4337 if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
4339 * A blocking lock was requested. Package up
4340 * this smb into a queued request and push it
4341 * onto the blocking lock queue.
4343 if(push_blocking_lock_request(inbuf, length, lock_timeout, i, lock_pid, offset, count)) {
4344 END_PROFILE(SMBlockingX);
4352 /* If any of the above locks failed, then we must unlock
4353 all of the previous locks (X/Open spec). */
4354 if (i != num_locks && num_locks != 0) {
4356 * Ensure we don't do a remove on the lock that just failed,
4357 * as under POSIX rules, if we have a lock already there, we
4358 * will delete it (and we shouldn't) .....
4360 for(i--; i >= 0; i--) {
4361 lock_pid = get_lock_pid( data, i, large_file_format);
4362 count = get_lock_count( data, i, large_file_format);
4363 offset = get_lock_offset( data, i, large_file_format, &err);
4366 * There is no error code marked "stupid client bug".... :-).
4369 END_PROFILE(SMBlockingX);
4370 return ERROR_DOS(ERRDOS,ERRnoaccess);
4373 do_unlock(fsp,conn,lock_pid,count,offset);
4375 END_PROFILE(SMBlockingX);
4376 return ERROR_NT(status);
4379 set_message(outbuf,2,0,True);
4381 DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
4382 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
4384 END_PROFILE(SMBlockingX);
4385 return chain_reply(inbuf,outbuf,length,bufsize);
4388 /****************************************************************************
4389 Reply to a SMBreadbmpx (read block multiplex) request.
4390 ****************************************************************************/
4392 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4403 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4404 START_PROFILE(SMBreadBmpx);
4406 /* this function doesn't seem to work - disable by default */
4407 if (!lp_readbmpx()) {
4408 END_PROFILE(SMBreadBmpx);
4409 return ERROR_DOS(ERRSRV,ERRuseSTD);
4412 outsize = set_message(outbuf,8,0,True);
4414 CHECK_FSP(fsp,conn);
4417 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
4418 maxcount = SVAL(inbuf,smb_vwv3);
4420 data = smb_buf(outbuf);
4421 pad = ((long)data)%4;
4426 max_per_packet = bufsize-(outsize+pad);
4430 if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
4431 END_PROFILE(SMBreadBmpx);
4432 return ERROR_DOS(ERRDOS,ERRlock);
4436 size_t N = MIN(max_per_packet,tcount-total_read);
4438 nread = read_file(fsp,data,startpos,N);
4443 if (nread < (ssize_t)N)
4444 tcount = total_read + nread;
4446 set_message(outbuf,8,nread,False);
4447 SIVAL(outbuf,smb_vwv0,startpos);
4448 SSVAL(outbuf,smb_vwv2,tcount);
4449 SSVAL(outbuf,smb_vwv6,nread);
4450 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
4452 if (!send_smb(smbd_server_fd(),outbuf))
4453 exit_server("reply_readbmpx: send_smb failed.");
4455 total_read += nread;
4457 } while (total_read < (ssize_t)tcount);
4459 END_PROFILE(SMBreadBmpx);
4463 /****************************************************************************
4464 Reply to a SMBsetattrE.
4465 ****************************************************************************/
4467 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4469 struct utimbuf unix_times;
4471 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4472 START_PROFILE(SMBsetattrE);
4474 outsize = set_message(outbuf,0,0,True);
4476 if(!fsp || (fsp->conn != conn)) {
4477 END_PROFILE(SMBgetattrE);
4478 return ERROR_DOS(ERRDOS,ERRbadfid);
4482 * Convert the DOS times into unix times. Ignore create
4483 * time as UNIX can't set this.
4486 unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
4487 unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
4490 * Patch from Ray Frush <frush@engr.colostate.edu>
4491 * Sometimes times are sent as zero - ignore them.
4494 if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
4495 /* Ignore request */
4496 if( DEBUGLVL( 3 ) ) {
4497 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
4498 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
4500 END_PROFILE(SMBsetattrE);
4502 } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
4503 /* set modify time = to access time if modify time was 0 */
4504 unix_times.modtime = unix_times.actime;
4507 /* Set the date on this file */
4508 if(file_utime(conn, fsp->fsp_name, &unix_times)) {
4509 END_PROFILE(SMBsetattrE);
4510 return ERROR_DOS(ERRDOS,ERRnoaccess);
4513 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
4514 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
4516 END_PROFILE(SMBsetattrE);
4521 /* Back from the dead for OS/2..... JRA. */
4523 /****************************************************************************
4524 Reply to a SMBwritebmpx (write block multiplex primary) request.
4525 ****************************************************************************/
4527 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4530 ssize_t nwritten = -1;
4537 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4538 START_PROFILE(SMBwriteBmpx);
4540 CHECK_FSP(fsp,conn);
4544 tcount = SVAL(inbuf,smb_vwv1);
4545 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
4546 write_through = BITSETW(inbuf+smb_vwv7,0);
4547 numtowrite = SVAL(inbuf,smb_vwv10);
4548 smb_doff = SVAL(inbuf,smb_vwv11);
4550 data = smb_base(inbuf) + smb_doff;
4552 /* If this fails we need to send an SMBwriteC response,
4553 not an SMBwritebmpx - set this up now so we don't forget */
4554 SCVAL(outbuf,smb_com,SMBwritec);
4556 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
4557 END_PROFILE(SMBwriteBmpx);
4558 return(ERROR_DOS(ERRDOS,ERRlock));
4561 nwritten = write_file(fsp,data,startpos,numtowrite);
4563 if(lp_syncalways(SNUM(conn)) || write_through)
4564 sync_file(conn,fsp);
4566 if(nwritten < (ssize_t)numtowrite) {
4567 END_PROFILE(SMBwriteBmpx);
4568 return(UNIXERROR(ERRHRD,ERRdiskfull));
4571 /* If the maximum to be written to this file
4572 is greater than what we just wrote then set
4573 up a secondary struct to be attached to this
4574 fd, we will use this to cache error messages etc. */
4576 if((ssize_t)tcount > nwritten) {
4577 write_bmpx_struct *wbms;
4578 if(fsp->wbmpx_ptr != NULL)
4579 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
4581 wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
4583 DEBUG(0,("Out of memory in reply_readmpx\n"));
4584 END_PROFILE(SMBwriteBmpx);
4585 return(ERROR_DOS(ERRSRV,ERRnoresource));
4587 wbms->wr_mode = write_through;
4588 wbms->wr_discard = False; /* No errors yet */
4589 wbms->wr_total_written = nwritten;
4590 wbms->wr_errclass = 0;
4592 fsp->wbmpx_ptr = wbms;
4595 /* We are returning successfully, set the message type back to
4597 SCVAL(outbuf,smb_com,SMBwriteBmpx);
4599 outsize = set_message(outbuf,1,0,True);
4601 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
4603 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
4604 fsp->fnum, (int)numtowrite, (int)nwritten ) );
4606 if (write_through && tcount==nwritten) {
4607 /* We need to send both a primary and a secondary response */
4608 smb_setlen(outbuf,outsize - 4);
4609 if (!send_smb(smbd_server_fd(),outbuf))
4610 exit_server("reply_writebmpx: send_smb failed.");
4612 /* Now the secondary */
4613 outsize = set_message(outbuf,1,0,True);
4614 SCVAL(outbuf,smb_com,SMBwritec);
4615 SSVAL(outbuf,smb_vwv0,nwritten);
4618 END_PROFILE(SMBwriteBmpx);
4622 /****************************************************************************
4623 Reply to a SMBwritebs (write block multiplex secondary) request.
4624 ****************************************************************************/
4626 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4629 ssize_t nwritten = -1;
4636 write_bmpx_struct *wbms;
4637 BOOL send_response = False;
4638 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4639 START_PROFILE(SMBwriteBs);
4641 CHECK_FSP(fsp,conn);
4644 tcount = SVAL(inbuf,smb_vwv1);
4645 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
4646 numtowrite = SVAL(inbuf,smb_vwv6);
4647 smb_doff = SVAL(inbuf,smb_vwv7);
4649 data = smb_base(inbuf) + smb_doff;
4651 /* We need to send an SMBwriteC response, not an SMBwritebs */
4652 SCVAL(outbuf,smb_com,SMBwritec);
4654 /* This fd should have an auxiliary struct attached,
4655 check that it does */
4656 wbms = fsp->wbmpx_ptr;
4658 END_PROFILE(SMBwriteBs);
4662 /* If write through is set we can return errors, else we must cache them */
4663 write_through = wbms->wr_mode;
4665 /* Check for an earlier error */
4666 if(wbms->wr_discard) {
4667 END_PROFILE(SMBwriteBs);
4668 return -1; /* Just discard the packet */
4671 nwritten = write_file(fsp,data,startpos,numtowrite);
4673 if(lp_syncalways(SNUM(conn)) || write_through)
4674 sync_file(conn,fsp);
4676 if (nwritten < (ssize_t)numtowrite) {
4678 /* We are returning an error - we can delete the aux struct */
4681 fsp->wbmpx_ptr = NULL;
4682 END_PROFILE(SMBwriteBs);
4683 return(ERROR_DOS(ERRHRD,ERRdiskfull));
4685 END_PROFILE(SMBwriteBs);
4686 return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
4689 /* Increment the total written, if this matches tcount
4690 we can discard the auxiliary struct (hurrah !) and return a writeC */
4691 wbms->wr_total_written += nwritten;
4692 if(wbms->wr_total_written >= tcount) {
4693 if (write_through) {
4694 outsize = set_message(outbuf,1,0,True);
4695 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
4696 send_response = True;
4700 fsp->wbmpx_ptr = NULL;
4704 END_PROFILE(SMBwriteBs);
4708 END_PROFILE(SMBwriteBs);
4712 /****************************************************************************
4713 Reply to a SMBgetattrE.
4714 ****************************************************************************/
4716 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4718 SMB_STRUCT_STAT sbuf;
4721 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4722 START_PROFILE(SMBgetattrE);
4724 outsize = set_message(outbuf,11,0,True);
4726 if(!fsp || (fsp->conn != conn)) {
4727 END_PROFILE(SMBgetattrE);
4728 return ERROR_DOS(ERRDOS,ERRbadfid);
4731 /* Do an fstat on this file */
4732 if(fsp_stat(fsp, &sbuf)) {
4733 END_PROFILE(SMBgetattrE);
4734 return(UNIXERROR(ERRDOS,ERRnoaccess));
4737 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
4740 * Convert the times into dos times. Set create
4741 * date to be last modify date as UNIX doesn't save
4745 put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
4746 put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
4747 put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
4750 SIVAL(outbuf,smb_vwv6,0);
4751 SIVAL(outbuf,smb_vwv8,0);
4753 uint32 allocation_size = get_allocation_size(fsp, &sbuf);
4754 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
4755 SIVAL(outbuf,smb_vwv8,allocation_size);
4757 SSVAL(outbuf,smb_vwv10, mode);
4759 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
4761 END_PROFILE(SMBgetattrE);