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
29 /* look in server.c for some explanation of these variables */
33 extern char magic_char;
34 extern BOOL case_sensitive;
35 extern BOOL case_preserve;
36 extern BOOL short_case_preserve;
37 extern pstring global_myname;
38 extern int global_oplock_break;
39 unsigned int smb_echo_count = 0;
41 extern fstring remote_machine;
42 extern BOOL global_encrypted_passwords_negotiated;
45 /****************************************************************************
46 reply to an special message
47 ****************************************************************************/
49 int reply_special(char *inbuf,char *outbuf)
52 int msg_type = CVAL(inbuf,0);
53 int msg_flags = CVAL(inbuf,1);
59 static BOOL already_got_session = False;
63 memset(outbuf,'\0',smb_size);
68 case 0x81: /* session request */
70 if (already_got_session) {
71 exit_server("multiple session request not permitted");
76 if (name_len(inbuf+4) > 50 ||
77 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
78 DEBUG(0,("Invalid name length in session request\n"));
81 name_extract(inbuf,4,name1);
82 name_extract(inbuf,4 + name_len(inbuf + 4),name2);
83 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
90 name_type = name2[15];
94 set_local_machine_name(name1);
95 set_remote_machine_name(name2);
97 DEBUG(2,("netbios connect: local=%s remote=%s\n",
98 get_local_machine_name(), get_remote_machine_name() ));
100 if (name_type == 'R') {
101 /* We are being asked for a pathworks session ---
103 SCVAL(outbuf, 0,0x83);
107 /* only add the client's machine name to the list
108 of possibly valid usernames if we are operating
109 in share mode security */
110 if (lp_security() == SEC_SHARE) {
111 add_session_user(remote_machine);
114 reload_services(True);
117 claim_connection(NULL,"",MAXSTATUS,True);
119 already_got_session = True;
122 case 0x89: /* session keepalive request
123 (some old clients produce this?) */
124 SCVAL(outbuf,0,SMBkeepalive);
128 case 0x82: /* positive session response */
129 case 0x83: /* negative session response */
130 case 0x84: /* retarget session response */
131 DEBUG(0,("Unexpected session response\n"));
134 case SMBkeepalive: /* session keepalive */
139 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
140 msg_type, msg_flags));
146 /****************************************************************************
148 ****************************************************************************/
150 int reply_tcon(connection_struct *conn,
151 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
158 uint16 vuid = SVAL(inbuf,smb_uid);
162 DATA_BLOB password_blob;
164 START_PROFILE(SMBtcon);
166 *service_buf = *password = *dev = 0;
168 p = smb_buf(inbuf)+1;
169 p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service), STR_TERMINATE) + 1;
170 pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
172 p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
174 p = strrchr_m(service_buf,'\\');
178 service = service_buf;
181 password_blob = data_blob(password, pwlen+1);
183 conn = make_connection(service,password_blob,dev,vuid,&nt_status);
185 data_blob_clear_free(&password_blob);
188 END_PROFILE(SMBtcon);
189 return ERROR_NT(nt_status);
192 outsize = set_message(outbuf,2,0,True);
193 SSVAL(outbuf,smb_vwv0,max_recv);
194 SSVAL(outbuf,smb_vwv1,conn->cnum);
195 SSVAL(outbuf,smb_tid,conn->cnum);
197 DEBUG(3,("tcon service=%s cnum=%d\n",
198 service, conn->cnum));
200 END_PROFILE(SMBtcon);
204 /****************************************************************************
205 Reply to a tcon and X.
206 ****************************************************************************/
208 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
214 uint16 vuid = SVAL(inbuf,smb_uid);
215 int passlen = SVAL(inbuf,smb_vwv3);
218 extern BOOL global_encrypted_passwords_negotiated;
219 START_PROFILE(SMBtconX);
221 *service = *devicename = 0;
223 /* we might have to close an old one */
224 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
225 close_cnum(conn,vuid);
228 if (passlen > MAX_PASS_LEN) {
229 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
232 if (global_encrypted_passwords_negotiated) {
233 password = data_blob(smb_buf(inbuf),passlen);
235 password = data_blob(smb_buf(inbuf),passlen+1);
236 /* Ensure correct termination */
237 password.data[passlen]=0;
240 p = smb_buf(inbuf) + passlen;
241 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
244 * the service name can be either: \\server\share
245 * or share directly like on the DELL PowerVault 705
248 q = strchr_m(path+2,'\\');
250 END_PROFILE(SMBtconX);
251 return(ERROR_DOS(ERRDOS,ERRnosuchshare));
253 fstrcpy(service,q+1);
256 fstrcpy(service,path);
258 p += srvstr_pull(inbuf, devicename, p, sizeof(devicename), 6, STR_ASCII);
260 DEBUG(4,("Got device type %s\n",devicename));
262 conn = make_connection(service,password,devicename,vuid,&nt_status);
264 data_blob_clear_free(&password);
267 END_PROFILE(SMBtconX);
268 return ERROR_NT(nt_status);
271 if (Protocol < PROTOCOL_NT1) {
272 set_message(outbuf,2,0,True);
274 p += srvstr_push(outbuf, p, devicename, -1,
275 STR_TERMINATE|STR_ASCII);
276 set_message_end(outbuf,p);
278 /* NT sets the fstype of IPC$ to the null string */
279 char *fsname = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
281 set_message(outbuf,3,0,True);
284 p += srvstr_push(outbuf, p, devicename, -1,
285 STR_TERMINATE|STR_ASCII);
286 p += srvstr_push(outbuf, p, fsname, -1,
289 set_message_end(outbuf,p);
291 /* what does setting this bit do? It is set by NT4 and
292 may affect the ability to autorun mounted cdroms */
293 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
294 (lp_csc_policy(SNUM(conn)) << 2));
296 init_dfsroot(conn, inbuf, outbuf);
300 DEBUG(3,("tconX service=%s \n",
303 /* set the incoming and outgoing tid to the just created one */
304 SSVAL(inbuf,smb_tid,conn->cnum);
305 SSVAL(outbuf,smb_tid,conn->cnum);
307 END_PROFILE(SMBtconX);
308 return chain_reply(inbuf,outbuf,length,bufsize);
312 /****************************************************************************
313 reply to an unknown type
314 ****************************************************************************/
315 int reply_unknown(char *inbuf,char *outbuf)
318 type = CVAL(inbuf,smb_com);
320 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
321 smb_fn_name(type), type, type));
323 return(ERROR_DOS(ERRSRV,ERRunknownsmb));
327 /****************************************************************************
329 ****************************************************************************/
330 int reply_ioctl(connection_struct *conn,
331 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
333 uint16 device = SVAL(inbuf,smb_vwv1);
334 uint16 function = SVAL(inbuf,smb_vwv2);
335 uint32 ioctl_code = (device << 16) + function;
336 int replysize, outsize;
338 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
339 START_PROFILE(SMBioctl);
341 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
345 case IOCTL_QUERY_JOB_INFO:
349 END_PROFILE(SMBioctl);
350 return(ERROR_DOS(ERRSRV,ERRnosupport));
353 outsize = set_message(outbuf,8,replysize+1,True);
354 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
355 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
356 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
357 p = smb_buf(outbuf) + 1; /* Allow for alignment */
361 case IOCTL_QUERY_JOB_INFO:
363 uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid);
364 SSVAL(p,0,rap_jobid); /* Job number */
365 srvstr_push(outbuf, p+2, global_myname, 15, STR_TERMINATE|STR_ASCII);
366 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
371 END_PROFILE(SMBioctl);
375 /****************************************************************************
377 ****************************************************************************/
378 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
384 BOOL bad_path = False;
385 SMB_STRUCT_STAT sbuf;
386 START_PROFILE(SMBchkpth);
388 srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE);
390 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
392 unix_convert(name,conn,0,&bad_path,&sbuf);
394 mode = SVAL(inbuf,smb_vwv0);
396 if (check_name(name,conn)) {
397 if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0)
398 ok = S_ISDIR(sbuf.st_mode);
402 /* We special case this - as when a Windows machine
403 is parsing a path is steps through the components
404 one at a time - if a component fails it expects
405 ERRbadpath, not ERRbadfile.
407 if(errno == ENOENT) {
408 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
411 return(UNIXERROR(ERRDOS,ERRbadpath));
414 outsize = set_message(outbuf,0,0,True);
416 DEBUG(3,("chkpth %s mode=%d\n", name, mode));
418 END_PROFILE(SMBchkpth);
423 /****************************************************************************
425 ****************************************************************************/
426 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
430 SMB_STRUCT_STAT sbuf;
435 BOOL bad_path = False;
437 START_PROFILE(SMBgetatr);
439 p = smb_buf(inbuf) + 1;
440 p += srvstr_pull_buf(inbuf, fname, p, sizeof(fname), STR_TERMINATE);
442 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
444 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
445 under WfWg - weird! */
448 mode = aHIDDEN | aDIR;
449 if (!CAN_WRITE(conn)) mode |= aRONLY;
456 unix_convert(fname,conn,0,&bad_path,&sbuf);
457 if (check_name(fname,conn))
459 if (VALID_STAT(sbuf) || vfs_stat(conn,fname,&sbuf) == 0)
461 mode = dos_mode(conn,fname,&sbuf);
463 mtime = sbuf.st_mtime;
469 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
475 set_bad_path_error(errno, bad_path);
476 END_PROFILE(SMBgetatr);
477 return(UNIXERROR(ERRDOS,ERRbadfile));
480 outsize = set_message(outbuf,10,0,True);
482 SSVAL(outbuf,smb_vwv0,mode);
483 if(lp_dos_filetime_resolution(SNUM(conn)) )
484 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
486 put_dos_date3(outbuf,smb_vwv1,mtime);
487 SIVAL(outbuf,smb_vwv3,(uint32)size);
489 if (Protocol >= PROTOCOL_NT1)
490 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
492 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
494 END_PROFILE(SMBgetatr);
499 /****************************************************************************
501 ****************************************************************************/
502 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
509 SMB_STRUCT_STAT sbuf;
510 BOOL bad_path = False;
513 START_PROFILE(SMBsetatr);
515 p = smb_buf(inbuf) + 1;
516 p += srvstr_pull_buf(inbuf, fname, p, sizeof(fname), STR_TERMINATE);
517 unix_convert(fname,conn,0,&bad_path,&sbuf);
519 mode = SVAL(inbuf,smb_vwv0);
520 mtime = make_unix_date3(inbuf+smb_vwv1);
522 if (VALID_STAT_OF_DIR(sbuf))
527 if (check_name(fname,conn))
528 ok = (file_chmod(conn,fname,mode,NULL) == 0);
530 ok = set_filetime(conn,fname,mtime);
534 set_bad_path_error(errno, bad_path);
535 END_PROFILE(SMBsetatr);
536 return(UNIXERROR(ERRDOS,ERRnoaccess));
539 outsize = set_message(outbuf,0,0,True);
541 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
543 END_PROFILE(SMBsetatr);
548 /****************************************************************************
550 ****************************************************************************/
551 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
554 SMB_BIG_UINT dfree,dsize,bsize;
555 START_PROFILE(SMBdskattr);
557 conn->vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize);
559 outsize = set_message(outbuf,5,0,True);
561 if (Protocol <= PROTOCOL_LANMAN2) {
562 double total_space, free_space;
563 /* we need to scale this to a number that DOS6 can handle. We
564 use floating point so we can handle large drives on systems
565 that don't have 64 bit integers
567 we end up displaying a maximum of 2G to DOS systems
569 total_space = dsize * (double)bsize;
570 free_space = dfree * (double)bsize;
572 dsize = (total_space+63*512) / (64*512);
573 dfree = (free_space+63*512) / (64*512);
575 if (dsize > 0xFFFF) dsize = 0xFFFF;
576 if (dfree > 0xFFFF) dfree = 0xFFFF;
578 SSVAL(outbuf,smb_vwv0,dsize);
579 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
580 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
581 SSVAL(outbuf,smb_vwv3,dfree);
583 SSVAL(outbuf,smb_vwv0,dsize);
584 SSVAL(outbuf,smb_vwv1,bsize/512);
585 SSVAL(outbuf,smb_vwv2,512);
586 SSVAL(outbuf,smb_vwv3,dfree);
589 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
591 END_PROFILE(SMBdskattr);
596 /****************************************************************************
598 Can be called from SMBsearch, SMBffirst or SMBfunique.
599 ****************************************************************************/
600 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
611 BOOL finished = False;
620 BOOL check_descend = False;
621 BOOL expect_close = False;
622 BOOL can_open = True;
623 BOOL bad_path = False;
624 START_PROFILE(SMBsearch);
626 *mask = *directory = *fname = 0;
628 /* If we were called as SMBffirst then we must expect close. */
629 if(CVAL(inbuf,smb_com) == SMBffirst)
632 outsize = set_message(outbuf,1,3,True);
633 maxentries = SVAL(inbuf,smb_vwv0);
634 dirtype = SVAL(inbuf,smb_vwv1);
635 p = smb_buf(inbuf) + 1;
636 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
638 status_len = SVAL(p, 0);
641 /* dirtype &= ~aDIR; */
645 SMB_STRUCT_STAT sbuf;
648 pstrcpy(directory,path);
650 unix_convert(directory,conn,0,&bad_path,&sbuf);
653 if (!check_name(directory,conn))
656 p = strrchr_m(dir2,'/');
668 p = strrchr_m(directory,'/');
674 if (strlen(directory) == 0)
675 pstrcpy(directory,"./");
676 memset((char *)status,'\0',21);
677 SCVAL(status,0,dirtype);
682 dirtype = CVAL(status,0) & 0x1F;
683 conn->dirptr = dptr_fetch(status+12,&dptr_num);
686 string_set(&conn->dirpath,dptr_path(dptr_num));
687 fstrcpy(mask, dptr_wcard(dptr_num));
692 p = smb_buf(outbuf) + 3;
698 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
703 set_bad_path_error(errno, bad_path);
704 END_PROFILE(SMBsearch);
705 return (UNIXERROR(ERRDOS,ERRnofids));
707 END_PROFILE(SMBsearch);
708 return ERROR_DOS(ERRDOS,ERRnofids);
710 dptr_set_wcard(dptr_num, strdup(mask));
713 DEBUG(4,("dptr_num is %d\n",dptr_num));
717 if ((dirtype&0x1F) == aVOLID)
720 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
721 dptr_fill(p+12,dptr_num);
722 if (dptr_zero(p+12) && (status_len==0))
726 p += DIR_STRUCT_SIZE;
730 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
731 conn->dirpath,lp_dontdescend(SNUM(conn))));
732 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
733 check_descend = True;
735 for (i=numentries;(i<maxentries) && !finished;i++)
738 !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
742 make_dir_struct(p,mask,fname,size,mode,date);
743 dptr_fill(p+12,dptr_num);
746 p += DIR_STRUCT_SIZE;
755 if (numentries == 0 || !ok)
757 SCVAL(outbuf,smb_rcls,ERRDOS);
758 SSVAL(outbuf,smb_err,ERRnofiles);
759 dptr_close(&dptr_num);
762 /* If we were called as SMBffirst with smb_search_id == NULL
763 and no entries were found then return error and close dirptr
766 if(ok && expect_close && numentries == 0 && status_len == 0)
768 SCVAL(outbuf,smb_rcls,ERRDOS);
769 SSVAL(outbuf,smb_err,ERRnofiles);
770 /* Also close the dptr - we know it's gone */
771 dptr_close(&dptr_num);
774 /* If we were called as SMBfunique, then we can close the dirptr now ! */
775 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
776 dptr_close(&dptr_num);
778 SSVAL(outbuf,smb_vwv0,numentries);
779 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
780 SCVAL(smb_buf(outbuf),0,5);
781 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
783 if (Protocol >= PROTOCOL_NT1)
784 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
786 outsize += DIR_STRUCT_SIZE*numentries;
787 smb_setlen(outbuf,outsize - 4);
789 if ((! *directory) && dptr_path(dptr_num))
790 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
792 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
793 smb_fn_name(CVAL(inbuf,smb_com)),
794 mask, directory, dirtype, numentries, maxentries ) );
796 END_PROFILE(SMBsearch);
801 /****************************************************************************
802 reply to a fclose (stop directory search)
803 ****************************************************************************/
804 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
813 START_PROFILE(SMBfclose);
815 outsize = set_message(outbuf,1,0,True);
816 p = smb_buf(inbuf) + 1;
817 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
819 status_len = SVAL(p,0);
822 if (status_len == 0) {
823 END_PROFILE(SMBfclose);
824 return ERROR_DOS(ERRSRV,ERRsrverror);
829 if(dptr_fetch(status+12,&dptr_num)) {
830 /* Close the dptr - we know it's gone */
831 dptr_close(&dptr_num);
834 SSVAL(outbuf,smb_vwv0,0);
836 DEBUG(3,("search close\n"));
838 END_PROFILE(SMBfclose);
843 /****************************************************************************
845 ****************************************************************************/
847 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
857 SMB_STRUCT_STAT sbuf;
858 BOOL bad_path = False;
860 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
861 START_PROFILE(SMBopen);
863 share_mode = SVAL(inbuf,smb_vwv0);
865 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE);
867 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
869 unix_convert(fname,conn,0,&bad_path,&sbuf);
871 unixmode = unix_mode(conn,aARCH,fname);
873 fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
874 unixmode, oplock_request,&rmode,NULL);
878 set_bad_path_error(errno, bad_path);
879 END_PROFILE(SMBopen);
880 return(UNIXERROR(ERRDOS,ERRnoaccess));
884 fmode = dos_mode(conn,fname,&sbuf);
885 mtime = sbuf.st_mtime;
888 DEBUG(3,("attempt to open a directory %s\n",fname));
889 close_file(fsp,False);
890 END_PROFILE(SMBopen);
891 return ERROR_DOS(ERRDOS,ERRnoaccess);
894 outsize = set_message(outbuf,7,0,True);
895 SSVAL(outbuf,smb_vwv0,fsp->fnum);
896 SSVAL(outbuf,smb_vwv1,fmode);
897 if(lp_dos_filetime_resolution(SNUM(conn)) )
898 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
900 put_dos_date3(outbuf,smb_vwv2,mtime);
901 SIVAL(outbuf,smb_vwv4,(uint32)size);
902 SSVAL(outbuf,smb_vwv6,rmode);
904 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
905 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
908 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
909 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
910 END_PROFILE(SMBopen);
915 /****************************************************************************
916 reply to an open and X
917 ****************************************************************************/
918 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
921 int smb_mode = SVAL(inbuf,smb_vwv3);
922 int smb_attr = SVAL(inbuf,smb_vwv5);
923 /* Breakout the oplock request bits so we can set the
924 reply bits separately. */
925 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
926 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
927 BOOL oplock_request = ex_oplock_request | core_oplock_request;
929 int open_flags = SVAL(inbuf,smb_vwv2);
930 int smb_sattr = SVAL(inbuf,smb_vwv4);
931 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
933 int smb_ofun = SVAL(inbuf,smb_vwv8);
936 int fmode=0,mtime=0,rmode=0;
937 SMB_STRUCT_STAT sbuf;
939 BOOL bad_path = False;
941 START_PROFILE(SMBopenX);
943 /* If it's an IPC, pass off the pipe handler. */
945 if (lp_nt_pipe_support()) {
946 END_PROFILE(SMBopenX);
947 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
949 END_PROFILE(SMBopenX);
950 return ERROR_DOS(ERRSRV,ERRaccess);
954 /* XXXX we need to handle passed times, sattr and flags */
955 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
957 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
959 unix_convert(fname,conn,0,&bad_path,&sbuf);
961 unixmode = unix_mode(conn,smb_attr | aARCH, fname);
963 fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
964 oplock_request, &rmode,&smb_action);
968 set_bad_path_error(errno, bad_path);
969 END_PROFILE(SMBopenX);
970 return(UNIXERROR(ERRDOS,ERRnoaccess));
974 fmode = dos_mode(conn,fname,&sbuf);
975 mtime = sbuf.st_mtime;
977 close_file(fsp,False);
978 END_PROFILE(SMBopenX);
979 return ERROR_DOS(ERRDOS,ERRnoaccess);
982 /* If the caller set the extended oplock request bit
983 and we granted one (by whatever means) - set the
984 correct bit for extended oplock reply.
987 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
988 smb_action |= EXTENDED_OPLOCK_GRANTED;
991 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
992 smb_action |= EXTENDED_OPLOCK_GRANTED;
995 /* If the caller set the core oplock request bit
996 and we granted one (by whatever means) - set the
997 correct bit for core oplock reply.
1000 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1001 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1004 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1005 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1008 set_message(outbuf,15,0,True);
1009 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1010 SSVAL(outbuf,smb_vwv3,fmode);
1011 if(lp_dos_filetime_resolution(SNUM(conn)) )
1012 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1014 put_dos_date3(outbuf,smb_vwv4,mtime);
1015 SIVAL(outbuf,smb_vwv6,(uint32)size);
1016 SSVAL(outbuf,smb_vwv8,rmode);
1017 SSVAL(outbuf,smb_vwv11,smb_action);
1019 END_PROFILE(SMBopenX);
1020 return chain_reply(inbuf,outbuf,length,bufsize);
1024 /****************************************************************************
1025 reply to a SMBulogoffX
1026 ****************************************************************************/
1027 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1029 uint16 vuid = SVAL(inbuf,smb_uid);
1030 user_struct *vuser = get_valid_user_struct(vuid);
1031 START_PROFILE(SMBulogoffX);
1034 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1037 /* in user level security we are supposed to close any files
1038 open by this user */
1039 if ((vuser != 0) && (lp_security() != SEC_SHARE)) {
1040 file_close_user(vuid);
1043 invalidate_vuid(vuid);
1045 set_message(outbuf,2,0,True);
1047 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1049 END_PROFILE(SMBulogoffX);
1050 return chain_reply(inbuf,outbuf,length,bufsize);
1054 /****************************************************************************
1055 reply to a mknew or a create
1056 ****************************************************************************/
1057 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1065 BOOL bad_path = False;
1067 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1068 SMB_STRUCT_STAT sbuf;
1069 START_PROFILE(SMBcreate);
1071 com = SVAL(inbuf,smb_com);
1073 createmode = SVAL(inbuf,smb_vwv0);
1074 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), STR_TERMINATE);
1076 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1078 unix_convert(fname,conn,0,&bad_path,&sbuf);
1080 if (createmode & aVOLID) {
1081 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1084 unixmode = unix_mode(conn,createmode,fname);
1088 /* We should fail if file exists. */
1089 ofun = FILE_CREATE_IF_NOT_EXIST;
1093 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1094 ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
1097 /* Open file in dos compatibility share mode. */
1098 fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1099 ofun, unixmode, oplock_request, NULL, NULL);
1103 set_bad_path_error(errno, bad_path);
1104 END_PROFILE(SMBcreate);
1105 return(UNIXERROR(ERRDOS,ERRnoaccess));
1108 outsize = set_message(outbuf,1,0,True);
1109 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1111 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1112 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1115 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1116 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1118 DEBUG( 2, ( "new file %s\n", fname ) );
1119 DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n",
1120 fname, fsp->fd, createmode, (int)unixmode ) );
1122 END_PROFILE(SMBcreate);
1127 /****************************************************************************
1128 reply to a create temporary file
1129 ****************************************************************************/
1130 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1136 BOOL bad_path = False;
1138 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1140 SMB_STRUCT_STAT sbuf;
1143 START_PROFILE(SMBctemp);
1145 createmode = SVAL(inbuf,smb_vwv0);
1146 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE);
1147 pstrcat(fname,"\\TMXXXXXX");
1149 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1151 unix_convert(fname,conn,0,&bad_path,&sbuf);
1153 unixmode = unix_mode(conn,createmode,fname);
1155 tmpfd = smb_mkstemp(fname);
1157 END_PROFILE(SMBctemp);
1158 return(UNIXERROR(ERRDOS,ERRnoaccess));
1161 vfs_stat(conn,fname,&sbuf);
1163 /* Open file in dos compatibility share mode. */
1164 /* We should fail if file does not exist. */
1165 fsp = open_file_shared(conn,fname,&sbuf,
1166 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1167 FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
1168 unixmode, oplock_request, NULL, NULL);
1170 /* close fd from smb_mkstemp() */
1174 set_bad_path_error(errno, bad_path);
1175 END_PROFILE(SMBctemp);
1176 return(UNIXERROR(ERRDOS,ERRnoaccess));
1179 outsize = set_message(outbuf,1,0,True);
1180 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1182 /* the returned filename is relative to the directory */
1183 s = strrchr_m(fname, '/');
1190 p = smb_buf(outbuf);
1191 SSVALS(p, 0, -1); /* what is this? not in spec */
1192 SSVAL(p, 2, strlen(s));
1194 p += srvstr_push(outbuf, p, s, -1, STR_ASCII);
1195 outsize = set_message_end(outbuf, p);
1197 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1198 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1201 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1202 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1204 DEBUG( 2, ( "created temp file %s\n", fname ) );
1205 DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
1206 fname, fsp->fd, createmode, (int)unixmode ) );
1208 END_PROFILE(SMBctemp);
1212 /*******************************************************************
1213 Check if a user is allowed to rename a file.
1214 ********************************************************************/
1216 static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT *pst)
1222 if (!CAN_WRITE(conn))
1223 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1225 if (S_ISDIR(pst->st_mode))
1226 return NT_STATUS_OK;
1228 /* We need a better way to return NT status codes from open... */
1232 fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1233 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1236 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1237 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1238 ret = NT_STATUS_SHARING_VIOLATION;
1243 close_file(fsp,False);
1244 return NT_STATUS_OK;
1247 /*******************************************************************
1248 Check if a user is allowed to delete a file.
1249 ********************************************************************/
1251 static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
1253 SMB_STRUCT_STAT sbuf;
1259 if (!CAN_WRITE(conn))
1260 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1262 if (conn->vfs_ops.lstat(conn,fname,&sbuf) != 0)
1263 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1265 fmode = dos_mode(conn,fname,&sbuf);
1267 return NT_STATUS_FILE_IS_A_DIRECTORY;
1268 if (!lp_delete_readonly(SNUM(conn))) {
1270 return NT_STATUS_CANNOT_DELETE;
1272 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1273 return NT_STATUS_CANNOT_DELETE;
1275 /* We need a better way to return NT status codes from open... */
1279 fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1280 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1283 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1284 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1285 ret = NT_STATUS_SHARING_VIOLATION;
1290 close_file(fsp,False);
1291 return NT_STATUS_OK;
1294 /****************************************************************************
1295 The guts of the unlink command, split out so it may be called by the NT SMB
1297 ****************************************************************************/
1299 NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
1305 NTSTATUS error = NT_STATUS_OK;
1307 BOOL bad_path = False;
1309 SMB_STRUCT_STAT sbuf;
1311 *directory = *mask = 0;
1313 rc = unix_convert(name,conn,0,&bad_path,&sbuf);
1315 p = strrchr_m(name,'/');
1317 pstrcpy(directory,".");
1321 pstrcpy(directory,name);
1326 * We should only check the mangled cache
1327 * here if unix_convert failed. This means
1328 * that the path in 'mask' doesn't exist
1329 * on the file system and so we need to look
1330 * for a possible mangle. This patch from
1331 * Tine Smukavec <valentin.smukavec@hermes.si>.
1334 if (!rc && mangle_is_mangled(mask))
1335 mangle_check_cache( mask );
1337 has_wild = ms_has_wild(mask);
1340 pstrcat(directory,"/");
1341 pstrcat(directory,mask);
1342 error = can_delete(directory,conn,dirtype);
1343 if (!NT_STATUS_IS_OK(error)) return error;
1345 if (vfs_unlink(conn,directory) == 0) {
1349 void *dirptr = NULL;
1352 if (check_name(directory,conn))
1353 dirptr = OpenDir(conn, directory, True);
1355 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1356 the pattern matches against the long name, otherwise the short name
1357 We don't implement this yet XXXX
1361 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1363 if (strequal(mask,"????????.???"))
1366 while ((dname = ReadDirName(dirptr))) {
1368 pstrcpy(fname,dname);
1370 if(!mask_match(fname, mask, case_sensitive)) continue;
1372 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
1373 error = can_delete(fname,conn,dirtype);
1374 if (!NT_STATUS_IS_OK(error)) continue;
1375 if (vfs_unlink(conn,fname) == 0) count++;
1376 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
1382 if (count == 0 && NT_STATUS_IS_OK(error)) {
1383 error = map_nt_error_from_unix(errno);
1389 /****************************************************************************
1391 ****************************************************************************/
1393 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
1400 START_PROFILE(SMBunlink);
1402 dirtype = SVAL(inbuf,smb_vwv0);
1404 srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE);
1406 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
1408 DEBUG(3,("reply_unlink : %s\n",name));
1410 status = unlink_internals(conn, dirtype, name);
1411 if (!NT_STATUS_IS_OK(status)) return ERROR_NT(status);
1414 * Win2k needs a changenotify request response before it will
1415 * update after a rename..
1417 process_pending_change_notify_queue((time_t)0);
1419 outsize = set_message(outbuf,0,0,True);
1421 END_PROFILE(SMBunlink);
1425 /****************************************************************************
1427 ****************************************************************************/
1429 void fail_readraw(void)
1432 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
1434 exit_server(errstr);
1437 /****************************************************************************
1438 Reply to a readbraw (core+ protocol).
1439 ****************************************************************************/
1441 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
1443 ssize_t maxcount,mincount;
1446 char *header = outbuf;
1449 START_PROFILE(SMBreadbraw);
1452 * Special check if an oplock break has been issued
1453 * and the readraw request croses on the wire, we must
1454 * return a zero length response here.
1457 if(global_oplock_break) {
1458 _smb_setlen(header,0);
1459 if (write_data(smbd_server_fd(),header,4) != 4)
1461 DEBUG(5,("readbraw - oplock break finished\n"));
1462 END_PROFILE(SMBreadbraw);
1466 fsp = file_fsp(inbuf,smb_vwv0);
1468 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
1470 * fsp could be NULL here so use the value from the packet. JRA.
1472 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
1473 _smb_setlen(header,0);
1474 if (write_data(smbd_server_fd(),header,4) != 4)
1476 END_PROFILE(SMBreadbraw);
1480 CHECK_FSP(fsp,conn);
1482 flush_write_cache(fsp, READRAW_FLUSH);
1484 startpos = IVAL(inbuf,smb_vwv1);
1485 if(CVAL(inbuf,smb_wct) == 10) {
1487 * This is a large offset (64 bit) read.
1489 #ifdef LARGE_SMB_OFF_T
1491 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
1493 #else /* !LARGE_SMB_OFF_T */
1496 * Ensure we haven't been sent a >32 bit offset.
1499 if(IVAL(inbuf,smb_vwv8) != 0) {
1500 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
1501 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
1502 _smb_setlen(header,0);
1503 if (write_data(smbd_server_fd(),header,4) != 4)
1505 END_PROFILE(SMBreadbraw);
1509 #endif /* LARGE_SMB_OFF_T */
1512 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
1513 _smb_setlen(header,0);
1514 if (write_data(smbd_server_fd(),header,4) != 4)
1516 END_PROFILE(SMBreadbraw);
1520 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
1521 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
1523 /* ensure we don't overrun the packet size */
1524 maxcount = MIN(65535,maxcount);
1525 maxcount = MAX(mincount,maxcount);
1527 if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1528 SMB_OFF_T size = fsp->size;
1529 SMB_OFF_T sizeneeded = startpos + maxcount;
1531 if (size < sizeneeded) {
1533 if (vfs_fstat(fsp,fsp->fd,&st) == 0)
1535 if (!fsp->can_write)
1539 if (startpos >= size)
1542 nread = MIN(maxcount,(size - startpos));
1545 if (nread < mincount)
1548 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
1549 (int)maxcount, (int)mincount, (int)nread ) );
1552 ret = read_file(fsp,header+4,startpos,nread);
1557 _smb_setlen(header,ret);
1558 if (write_data(smbd_server_fd(),header,4+ret) != 4+ret)
1561 DEBUG(5,("readbraw finished\n"));
1562 END_PROFILE(SMBreadbraw);
1566 /****************************************************************************
1567 reply to a lockread (core+ protocol)
1568 ****************************************************************************/
1569 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
1577 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1578 START_PROFILE(SMBlockread);
1580 CHECK_FSP(fsp,conn);
1583 release_level_2_oplocks_on_change(fsp);
1585 numtoread = SVAL(inbuf,smb_vwv1);
1586 startpos = IVAL(inbuf,smb_vwv2);
1588 outsize = set_message(outbuf,5,3,True);
1589 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1590 data = smb_buf(outbuf) + 3;
1593 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
1594 * protocol request that predates the read/write lock concept.
1595 * Thus instead of asking for a read lock here we need to ask
1596 * for a write lock. JRA.
1599 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
1600 (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK);
1602 if (NT_STATUS_V(status)) {
1603 if (lp_blocking_locks(SNUM(conn))) {
1605 * A blocking lock was requested. Package up
1606 * this smb into a queued request and push it
1607 * onto the blocking lock queue.
1609 if(push_blocking_lock_request(inbuf, length, -1, 0))
1610 END_PROFILE(SMBlockread);
1613 END_PROFILE(SMBlockread);
1614 return ERROR_NT(status);
1617 nread = read_file(fsp,data,startpos,numtoread);
1620 END_PROFILE(SMBlockread);
1621 return(UNIXERROR(ERRDOS,ERRnoaccess));
1625 SSVAL(outbuf,smb_vwv0,nread);
1626 SSVAL(outbuf,smb_vwv5,nread+3);
1627 SSVAL(smb_buf(outbuf),1,nread);
1629 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
1630 fsp->fnum, (int)numtoread, (int)nread));
1632 END_PROFILE(SMBlockread);
1637 /****************************************************************************
1639 ****************************************************************************/
1641 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
1648 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1649 START_PROFILE(SMBread);
1651 CHECK_FSP(fsp,conn);
1654 numtoread = SVAL(inbuf,smb_vwv1);
1655 startpos = IVAL(inbuf,smb_vwv2);
1658 outsize = set_message(outbuf,5,3,True);
1659 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1660 data = smb_buf(outbuf) + 3;
1662 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1663 END_PROFILE(SMBread);
1664 return ERROR_DOS(ERRDOS,ERRlock);
1668 nread = read_file(fsp,data,startpos,numtoread);
1671 END_PROFILE(SMBread);
1672 return(UNIXERROR(ERRDOS,ERRnoaccess));
1676 SSVAL(outbuf,smb_vwv0,nread);
1677 SSVAL(outbuf,smb_vwv5,nread+3);
1678 SCVAL(smb_buf(outbuf),0,1);
1679 SSVAL(smb_buf(outbuf),1,nread);
1681 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
1682 fsp->fnum, (int)numtoread, (int)nread ) );
1684 END_PROFILE(SMBread);
1689 /****************************************************************************
1690 reply to a read and X
1691 ****************************************************************************/
1692 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1694 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
1695 SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
1696 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
1697 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
1700 START_PROFILE(SMBreadX);
1702 /* If it's an IPC, pass off the pipe handler. */
1704 END_PROFILE(SMBreadX);
1705 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
1708 CHECK_FSP(fsp,conn);
1711 set_message(outbuf,12,0,True);
1712 data = smb_buf(outbuf);
1714 if(CVAL(inbuf,smb_wct) == 12) {
1715 #ifdef LARGE_SMB_OFF_T
1717 * This is a large offset (64 bit) read.
1719 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
1721 #else /* !LARGE_SMB_OFF_T */
1724 * Ensure we haven't been sent a >32 bit offset.
1727 if(IVAL(inbuf,smb_vwv10) != 0) {
1728 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
1729 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
1730 END_PROFILE(SMBreadX);
1731 return ERROR_DOS(ERRDOS,ERRbadaccess);
1734 #endif /* LARGE_SMB_OFF_T */
1738 if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1739 END_PROFILE(SMBreadX);
1740 return ERROR_DOS(ERRDOS,ERRlock);
1742 nread = read_file(fsp,data,startpos,smb_maxcnt);
1745 END_PROFILE(SMBreadX);
1746 return(UNIXERROR(ERRDOS,ERRnoaccess));
1749 SSVAL(outbuf,smb_vwv5,nread);
1750 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
1751 SSVAL(smb_buf(outbuf),-2,nread);
1753 DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n",
1754 fsp->fnum, (int)smb_mincnt, (int)smb_maxcnt, (int)nread ) );
1756 END_PROFILE(SMBreadX);
1757 return chain_reply(inbuf,outbuf,length,bufsize);
1760 /****************************************************************************
1761 reply to a writebraw (core+ or LANMAN1.0 protocol)
1762 ****************************************************************************/
1764 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
1767 ssize_t total_written=0;
1768 size_t numtowrite=0;
1773 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1775 START_PROFILE(SMBwritebraw);
1777 CHECK_FSP(fsp,conn);
1780 tcount = IVAL(inbuf,smb_vwv1);
1781 startpos = IVAL(inbuf,smb_vwv3);
1782 write_through = BITSETW(inbuf+smb_vwv7,0);
1784 /* We have to deal with slightly different formats depending
1785 on whether we are using the core+ or lanman1.0 protocol */
1787 if(Protocol <= PROTOCOL_COREPLUS) {
1788 numtowrite = SVAL(smb_buf(inbuf),-2);
1789 data = smb_buf(inbuf);
1791 numtowrite = SVAL(inbuf,smb_vwv10);
1792 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
1795 /* force the error type */
1796 SCVAL(inbuf,smb_com,SMBwritec);
1797 SCVAL(outbuf,smb_com,SMBwritec);
1799 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
1800 END_PROFILE(SMBwritebraw);
1801 return(ERROR_DOS(ERRDOS,ERRlock));
1805 nwritten = write_file(fsp,data,startpos,numtowrite);
1807 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
1808 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
1810 if (nwritten < numtowrite) {
1811 END_PROFILE(SMBwritebraw);
1812 return(UNIXERROR(ERRHRD,ERRdiskfull));
1815 total_written = nwritten;
1817 /* Return a message to the redirector to tell it to send more bytes */
1818 SCVAL(outbuf,smb_com,SMBwritebraw);
1819 SSVALS(outbuf,smb_vwv0,-1);
1820 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
1821 if (!send_smb(smbd_server_fd(),outbuf))
1822 exit_server("reply_writebraw: send_smb failed.");
1824 /* Now read the raw data into the buffer and write it */
1825 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
1826 exit_server("secondary writebraw failed");
1829 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
1830 numtowrite = smb_len(inbuf);
1832 /* Set up outbuf to return the correct return */
1833 outsize = set_message(outbuf,1,0,True);
1834 SCVAL(outbuf,smb_com,SMBwritec);
1835 SSVAL(outbuf,smb_vwv0,total_written);
1837 if (numtowrite != 0) {
1839 if (numtowrite > BUFFER_SIZE) {
1840 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
1841 (unsigned int)numtowrite ));
1842 exit_server("secondary writebraw failed");
1845 if (tcount > nwritten+numtowrite) {
1846 DEBUG(3,("Client overestimated the write %d %d %d\n",
1847 (int)tcount,(int)nwritten,(int)numtowrite));
1850 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
1851 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
1853 exit_server("secondary writebraw failed");
1856 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
1858 if (nwritten < (ssize_t)numtowrite) {
1859 SCVAL(outbuf,smb_rcls,ERRHRD);
1860 SSVAL(outbuf,smb_err,ERRdiskfull);
1864 total_written += nwritten;
1867 if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
1868 sync_file(conn,fsp);
1870 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
1871 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
1873 /* we won't return a status if write through is not selected - this follows what WfWg does */
1874 END_PROFILE(SMBwritebraw);
1875 if (!write_through && total_written==tcount) {
1877 #if RABBIT_PELLET_FIX
1879 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
1880 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
1882 if (!send_keepalive(smbd_server_fd()))
1883 exit_server("reply_writebraw: send of keepalive failed");
1891 /****************************************************************************
1892 reply to a writeunlock (core+)
1893 ****************************************************************************/
1895 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
1896 int size, int dum_buffsize)
1898 ssize_t nwritten = -1;
1903 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1905 START_PROFILE(SMBwriteunlock);
1907 CHECK_FSP(fsp,conn);
1910 numtowrite = SVAL(inbuf,smb_vwv1);
1911 startpos = IVAL(inbuf,smb_vwv2);
1912 data = smb_buf(inbuf) + 3;
1914 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
1915 WRITE_LOCK,False)) {
1916 END_PROFILE(SMBwriteunlock);
1917 return ERROR_DOS(ERRDOS,ERRlock);
1920 /* The special X/Open SMB protocol handling of
1921 zero length writes is *NOT* done for
1926 nwritten = write_file(fsp,data,startpos,numtowrite);
1928 if (lp_syncalways(SNUM(conn)))
1929 sync_file(conn,fsp);
1931 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
1932 END_PROFILE(SMBwriteunlock);
1933 return(UNIXERROR(ERRDOS,ERRnoaccess));
1936 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
1937 (SMB_BIG_UINT)startpos);
1938 if (NT_STATUS_V(status)) {
1939 END_PROFILE(SMBwriteunlock);
1940 return ERROR_NT(status);
1943 outsize = set_message(outbuf,1,0,True);
1945 SSVAL(outbuf,smb_vwv0,nwritten);
1947 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
1948 fsp->fnum, (int)numtowrite, (int)nwritten));
1950 END_PROFILE(SMBwriteunlock);
1955 /****************************************************************************
1957 ****************************************************************************/
1959 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
1962 ssize_t nwritten = -1;
1965 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1967 START_PROFILE(SMBwrite);
1969 /* If it's an IPC, pass off the pipe handler. */
1971 END_PROFILE(SMBwrite);
1972 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
1975 CHECK_FSP(fsp,conn);
1978 numtowrite = SVAL(inbuf,smb_vwv1);
1979 startpos = IVAL(inbuf,smb_vwv2);
1980 data = smb_buf(inbuf) + 3;
1982 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
1983 END_PROFILE(SMBwrite);
1984 return ERROR_DOS(ERRDOS,ERRlock);
1988 * X/Open SMB protocol says that if smb_vwv1 is
1989 * zero then the file size should be extended or
1990 * truncated to the size given in smb_vwv[2-3].
1993 if(numtowrite == 0) {
1995 * This is actually an allocate call, and set EOF. JRA.
1997 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
1999 END_PROFILE(SMBwrite);
2000 return ERROR_NT(NT_STATUS_DISK_FULL);
2002 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
2004 END_PROFILE(SMBwrite);
2005 return ERROR_NT(NT_STATUS_DISK_FULL);
2008 nwritten = write_file(fsp,data,startpos,numtowrite);
2010 if (lp_syncalways(SNUM(conn)))
2011 sync_file(conn,fsp);
2013 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2014 END_PROFILE(SMBwrite);
2015 return(UNIXERROR(ERRDOS,ERRnoaccess));
2018 outsize = set_message(outbuf,1,0,True);
2020 SSVAL(outbuf,smb_vwv0,nwritten);
2022 if (nwritten < (ssize_t)numtowrite) {
2023 SCVAL(outbuf,smb_rcls,ERRHRD);
2024 SSVAL(outbuf,smb_err,ERRdiskfull);
2027 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
2029 END_PROFILE(SMBwrite);
2034 /****************************************************************************
2035 reply to a write and X
2036 ****************************************************************************/
2037 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2039 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2040 SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
2041 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2042 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2043 ssize_t nwritten = -1;
2044 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
2045 unsigned int smblen = smb_len(inbuf);
2047 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
2048 START_PROFILE(SMBwriteX);
2050 /* If it's an IPC, pass off the pipe handler. */
2052 END_PROFILE(SMBwriteX);
2053 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2056 CHECK_FSP(fsp,conn);
2059 /* Deal with possible LARGE_WRITEX */
2061 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
2063 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
2064 END_PROFILE(SMBwriteX);
2065 return ERROR_DOS(ERRDOS,ERRbadmem);
2068 data = smb_base(inbuf) + smb_doff;
2070 if(CVAL(inbuf,smb_wct) == 14) {
2071 #ifdef LARGE_SMB_OFF_T
2073 * This is a large offset (64 bit) write.
2075 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2077 #else /* !LARGE_SMB_OFF_T */
2080 * Ensure we haven't been sent a >32 bit offset.
2083 if(IVAL(inbuf,smb_vwv12) != 0) {
2084 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
2085 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
2086 END_PROFILE(SMBwriteX);
2087 return ERROR_DOS(ERRDOS,ERRbadaccess);
2090 #endif /* LARGE_SMB_OFF_T */
2093 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2094 END_PROFILE(SMBwriteX);
2095 return ERROR_DOS(ERRDOS,ERRlock);
2098 /* X/Open SMB protocol says that, unlike SMBwrite
2099 if the length is zero then NO truncation is
2100 done, just a write of zero. To truncate a file,
2105 nwritten = write_file(fsp,data,startpos,numtowrite);
2107 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2108 END_PROFILE(SMBwriteX);
2109 return(UNIXERROR(ERRDOS,ERRnoaccess));
2112 set_message(outbuf,6,0,True);
2114 SSVAL(outbuf,smb_vwv2,nwritten);
2116 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
2118 if (nwritten < (ssize_t)numtowrite) {
2119 SCVAL(outbuf,smb_rcls,ERRHRD);
2120 SSVAL(outbuf,smb_err,ERRdiskfull);
2123 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2124 fsp->fnum, (int)numtowrite, (int)nwritten));
2126 if (lp_syncalways(SNUM(conn)) || write_through)
2127 sync_file(conn,fsp);
2129 END_PROFILE(SMBwriteX);
2130 return chain_reply(inbuf,outbuf,length,bufsize);
2134 /****************************************************************************
2136 ****************************************************************************/
2138 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2144 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2145 START_PROFILE(SMBlseek);
2147 CHECK_FSP(fsp,conn);
2149 flush_write_cache(fsp, SEEK_FLUSH);
2151 mode = SVAL(inbuf,smb_vwv1) & 3;
2152 startpos = IVALS(inbuf,smb_vwv2);
2155 case 0: umode = SEEK_SET; break;
2156 case 1: umode = SEEK_CUR; break;
2157 case 2: umode = SEEK_END; break;
2159 umode = SEEK_SET; break;
2162 if((res = conn->vfs_ops.lseek(fsp,fsp->fd,startpos,umode)) == -1) {
2164 * Check for the special case where a seek before the start
2165 * of the file sets the offset to zero. Added in the CIFS spec,
2169 if(errno == EINVAL) {
2170 SMB_OFF_T current_pos = startpos;
2172 if(umode == SEEK_CUR) {
2174 if((current_pos = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
2175 END_PROFILE(SMBlseek);
2176 return(UNIXERROR(ERRDOS,ERRnoaccess));
2179 current_pos += startpos;
2181 } else if (umode == SEEK_END) {
2183 SMB_STRUCT_STAT sbuf;
2185 if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) {
2186 END_PROFILE(SMBlseek);
2187 return(UNIXERROR(ERRDOS,ERRnoaccess));
2190 current_pos += sbuf.st_size;
2194 res = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_SET);
2198 END_PROFILE(SMBlseek);
2199 return(UNIXERROR(ERRDOS,ERRnoaccess));
2205 outsize = set_message(outbuf,2,0,True);
2206 SIVAL(outbuf,smb_vwv0,res);
2208 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2209 fsp->fnum, (double)startpos, (double)res, mode));
2211 END_PROFILE(SMBlseek);
2215 /****************************************************************************
2217 ****************************************************************************/
2219 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2221 int outsize = set_message(outbuf,0,0,True);
2222 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2223 START_PROFILE(SMBflush);
2225 CHECK_FSP(fsp,conn);
2228 file_sync_all(conn);
2230 sync_file(conn,fsp);
2233 DEBUG(3,("flush\n"));
2234 END_PROFILE(SMBflush);
2239 /****************************************************************************
2241 ****************************************************************************/
2242 int reply_exit(connection_struct *conn,
2243 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2246 START_PROFILE(SMBexit);
2247 outsize = set_message(outbuf,0,0,True);
2249 DEBUG(3,("exit\n"));
2251 END_PROFILE(SMBexit);
2256 /****************************************************************************
2257 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2258 ****************************************************************************/
2259 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
2264 int32 eclass = 0, err = 0;
2265 files_struct *fsp = NULL;
2266 START_PROFILE(SMBclose);
2268 outsize = set_message(outbuf,0,0,True);
2270 /* If it's an IPC, pass off to the pipe handler. */
2272 END_PROFILE(SMBclose);
2273 return reply_pipe_close(conn, inbuf,outbuf);
2276 fsp = file_fsp(inbuf,smb_vwv0);
2279 * We can only use CHECK_FSP if we know it's not a directory.
2282 if(!fsp || (fsp->conn != conn)) {
2283 END_PROFILE(SMBclose);
2284 return ERROR_DOS(ERRDOS,ERRbadfid);
2287 if(fsp->is_directory) {
2289 * Special case - close NT SMB directory handle.
2291 DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
2292 close_file(fsp,True);
2295 * Close ordinary file.
2300 /* Save the name for time set in close. */
2301 pstrcpy( file_name, fsp->fsp_name);
2303 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2305 conn->num_files_open));
2308 * close_file() returns the unix errno if an error
2309 * was detected on close - normally this is due to
2310 * a disk full error. If not then it was probably an I/O error.
2313 if((close_err = close_file(fsp,True)) != 0) {
2315 END_PROFILE(SMBclose);
2316 return (UNIXERROR(ERRHRD,ERRgeneral));
2320 * Now take care of any time sent in the close.
2323 mtime = make_unix_date3(inbuf+smb_vwv1);
2325 /* try and set the date */
2326 set_filetime(conn, file_name, mtime);
2330 /* We have a cached error */
2332 END_PROFILE(SMBclose);
2333 return ERROR_DOS(eclass,err);
2336 END_PROFILE(SMBclose);
2341 /****************************************************************************
2342 reply to a writeclose (Core+ protocol)
2343 ****************************************************************************/
2345 int reply_writeclose(connection_struct *conn,
2346 char *inbuf,char *outbuf, int size, int dum_buffsize)
2349 ssize_t nwritten = -1;
2355 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2356 START_PROFILE(SMBwriteclose);
2358 CHECK_FSP(fsp,conn);
2361 numtowrite = SVAL(inbuf,smb_vwv1);
2362 startpos = IVAL(inbuf,smb_vwv2);
2363 mtime = make_unix_date3(inbuf+smb_vwv4);
2364 data = smb_buf(inbuf) + 1;
2366 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2367 END_PROFILE(SMBwriteclose);
2368 return ERROR_DOS(ERRDOS,ERRlock);
2371 nwritten = write_file(fsp,data,startpos,numtowrite);
2373 set_filetime(conn, fsp->fsp_name,mtime);
2375 close_err = close_file(fsp,True);
2377 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2378 fsp->fnum, (int)numtowrite, (int)nwritten,
2379 conn->num_files_open));
2381 if (nwritten <= 0) {
2382 END_PROFILE(SMBwriteclose);
2383 return(UNIXERROR(ERRDOS,ERRnoaccess));
2386 if(close_err != 0) {
2388 END_PROFILE(SMBwriteclose);
2389 return(UNIXERROR(ERRHRD,ERRgeneral));
2392 outsize = set_message(outbuf,1,0,True);
2394 SSVAL(outbuf,smb_vwv0,nwritten);
2395 END_PROFILE(SMBwriteclose);
2400 /****************************************************************************
2402 ****************************************************************************/
2403 int reply_lock(connection_struct *conn,
2404 char *inbuf,char *outbuf, int length, int dum_buffsize)
2406 int outsize = set_message(outbuf,0,0,True);
2407 SMB_BIG_UINT count,offset;
2409 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2410 START_PROFILE(SMBlock);
2412 CHECK_FSP(fsp,conn);
2414 release_level_2_oplocks_on_change(fsp);
2416 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2417 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2419 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2420 fsp->fd, fsp->fnum, (double)offset, (double)count));
2422 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK);
2423 if (NT_STATUS_V(status)) {
2424 if (lp_blocking_locks(SNUM(conn))) {
2426 * A blocking lock was requested. Package up
2427 * this smb into a queued request and push it
2428 * onto the blocking lock queue.
2430 if(push_blocking_lock_request(inbuf, length, -1, 0)) {
2431 END_PROFILE(SMBlock);
2435 END_PROFILE(SMBlock);
2436 return ERROR_NT(status);
2439 END_PROFILE(SMBlock);
2444 /****************************************************************************
2446 ****************************************************************************/
2447 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
2450 int outsize = set_message(outbuf,0,0,True);
2451 SMB_BIG_UINT count,offset;
2453 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2454 START_PROFILE(SMBunlock);
2456 CHECK_FSP(fsp,conn);
2458 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2459 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2461 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
2462 if (NT_STATUS_V(status)) {
2463 END_PROFILE(SMBunlock);
2464 return ERROR_NT(status);
2467 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2468 fsp->fd, fsp->fnum, (double)offset, (double)count ) );
2470 END_PROFILE(SMBunlock);
2475 /****************************************************************************
2477 ****************************************************************************/
2478 int reply_tdis(connection_struct *conn,
2479 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2481 int outsize = set_message(outbuf,0,0,True);
2483 START_PROFILE(SMBtdis);
2485 vuid = SVAL(inbuf,smb_uid);
2488 DEBUG(4,("Invalid connection in tdis\n"));
2489 END_PROFILE(SMBtdis);
2490 return ERROR_DOS(ERRSRV,ERRinvnid);
2495 close_cnum(conn,vuid);
2497 END_PROFILE(SMBtdis);
2503 /****************************************************************************
2505 ****************************************************************************/
2506 int reply_echo(connection_struct *conn,
2507 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2509 int smb_reverb = SVAL(inbuf,smb_vwv0);
2511 unsigned int data_len = smb_buflen(inbuf);
2512 int outsize = set_message(outbuf,1,data_len,True);
2513 START_PROFILE(SMBecho);
2515 data_len = MIN(data_len, (sizeof(inbuf)-(smb_buf(inbuf)-inbuf)));
2517 /* copy any incoming data back out */
2519 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
2521 if (smb_reverb > 100) {
2522 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
2526 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
2527 SSVAL(outbuf,smb_vwv0,seq_num);
2529 smb_setlen(outbuf,outsize - 4);
2531 if (!send_smb(smbd_server_fd(),outbuf))
2532 exit_server("reply_echo: send_smb failed.");
2535 DEBUG(3,("echo %d times\n", smb_reverb));
2539 END_PROFILE(SMBecho);
2544 /****************************************************************************
2545 reply to a printopen
2546 ****************************************************************************/
2547 int reply_printopen(connection_struct *conn,
2548 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2552 START_PROFILE(SMBsplopen);
2554 if (!CAN_PRINT(conn)) {
2555 END_PROFILE(SMBsplopen);
2556 return ERROR_DOS(ERRDOS,ERRnoaccess);
2559 /* Open for exclusive use, write only. */
2560 fsp = print_fsp_open(conn, NULL);
2563 END_PROFILE(SMBsplopen);
2564 return(UNIXERROR(ERRDOS,ERRnoaccess));
2567 outsize = set_message(outbuf,1,0,True);
2568 SSVAL(outbuf,smb_vwv0,fsp->fnum);
2570 DEBUG(3,("openprint fd=%d fnum=%d\n",
2571 fsp->fd, fsp->fnum));
2573 END_PROFILE(SMBsplopen);
2578 /****************************************************************************
2579 reply to a printclose
2580 ****************************************************************************/
2581 int reply_printclose(connection_struct *conn,
2582 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2584 int outsize = set_message(outbuf,0,0,True);
2585 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2587 START_PROFILE(SMBsplclose);
2589 CHECK_FSP(fsp,conn);
2591 if (!CAN_PRINT(conn)) {
2592 END_PROFILE(SMBsplclose);
2593 return ERROR_DOS(ERRDOS,ERRnoaccess);
2596 DEBUG(3,("printclose fd=%d fnum=%d\n",
2597 fsp->fd,fsp->fnum));
2599 close_err = close_file(fsp,True);
2601 if(close_err != 0) {
2603 END_PROFILE(SMBsplclose);
2604 return(UNIXERROR(ERRHRD,ERRgeneral));
2607 END_PROFILE(SMBsplclose);
2612 /****************************************************************************
2613 reply to a printqueue
2614 ****************************************************************************/
2615 int reply_printqueue(connection_struct *conn,
2616 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2618 int outsize = set_message(outbuf,2,3,True);
2619 int max_count = SVAL(inbuf,smb_vwv0);
2620 int start_index = SVAL(inbuf,smb_vwv1);
2621 START_PROFILE(SMBsplretq);
2623 /* we used to allow the client to get the cnum wrong, but that
2624 is really quite gross and only worked when there was only
2625 one printer - I think we should now only accept it if they
2626 get it right (tridge) */
2627 if (!CAN_PRINT(conn)) {
2628 END_PROFILE(SMBsplretq);
2629 return ERROR_DOS(ERRDOS,ERRnoaccess);
2632 SSVAL(outbuf,smb_vwv0,0);
2633 SSVAL(outbuf,smb_vwv1,0);
2634 SCVAL(smb_buf(outbuf),0,1);
2635 SSVAL(smb_buf(outbuf),1,0);
2637 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
2638 start_index, max_count));
2641 print_queue_struct *queue = NULL;
2642 print_status_struct status;
2643 char *p = smb_buf(outbuf) + 3;
2644 int count = print_queue_status(SNUM(conn), &queue, &status);
2645 int num_to_get = ABS(max_count);
2646 int first = (max_count>0?start_index:start_index+max_count+1);
2652 num_to_get = MIN(num_to_get,count-first);
2655 for (i=first;i<first+num_to_get;i++) {
2656 put_dos_date2(p,0,queue[i].time);
2657 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
2658 SSVAL(p,5, queue[i].job);
2659 SIVAL(p,7,queue[i].size);
2661 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
2666 outsize = set_message(outbuf,2,28*count+3,False);
2667 SSVAL(outbuf,smb_vwv0,count);
2668 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
2669 SCVAL(smb_buf(outbuf),0,1);
2670 SSVAL(smb_buf(outbuf),1,28*count);
2675 DEBUG(3,("%d entries returned in queue\n",count));
2678 END_PROFILE(SMBsplretq);
2683 /****************************************************************************
2684 reply to a printwrite
2685 ****************************************************************************/
2686 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2689 int outsize = set_message(outbuf,0,0,True);
2691 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2692 START_PROFILE(SMBsplwr);
2694 if (!CAN_PRINT(conn)) {
2695 END_PROFILE(SMBsplwr);
2696 return ERROR_DOS(ERRDOS,ERRnoaccess);
2699 CHECK_FSP(fsp,conn);
2702 numtowrite = SVAL(smb_buf(inbuf),1);
2703 data = smb_buf(inbuf) + 3;
2705 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
2706 END_PROFILE(SMBsplwr);
2707 return(UNIXERROR(ERRDOS,ERRnoaccess));
2710 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
2712 END_PROFILE(SMBsplwr);
2717 /****************************************************************************
2718 The guts of the mkdir command, split out so it may be called by the NT SMB
2720 ****************************************************************************/
2721 NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
2723 BOOL bad_path = False;
2724 SMB_STRUCT_STAT sbuf;
2727 unix_convert(directory,conn,0,&bad_path,&sbuf);
2729 if (check_name(directory, conn))
2730 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2733 NTSTATUS nterr = set_bad_path_error(errno, bad_path);
2734 if (!NT_STATUS_IS_OK(nterr))
2736 return map_nt_error_from_unix(errno);
2739 return NT_STATUS_OK;
2742 /****************************************************************************
2744 ****************************************************************************/
2746 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2751 START_PROFILE(SMBmkdir);
2753 srvstr_pull_buf(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE);
2755 status = mkdir_internal(conn, directory);
2756 if (!NT_STATUS_IS_OK(status))
2757 return ERROR_NT(status);
2759 outsize = set_message(outbuf,0,0,True);
2761 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
2763 END_PROFILE(SMBmkdir);
2767 /****************************************************************************
2768 Static function used by reply_rmdir to delete an entire directory
2769 tree recursively. Return False on ok, True on fail.
2770 ****************************************************************************/
2772 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
2776 void *dirptr = OpenDir(conn, directory, False);
2781 while((dname = ReadDirName(dirptr))) {
2785 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
2788 /* Construct the full name. */
2789 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
2795 pstrcpy(fullname, directory);
2796 pstrcat(fullname, "/");
2797 pstrcat(fullname, dname);
2799 if(conn->vfs_ops.lstat(conn,fullname, &st) != 0) {
2804 if(st.st_mode & S_IFDIR) {
2805 if(recursive_rmdir(conn, fullname)!=0) {
2809 if(vfs_rmdir(conn,fullname) != 0) {
2813 } else if(vfs_unlink(conn,fullname) != 0) {
2822 /****************************************************************************
2823 The internals of the rmdir code - called elsewhere.
2824 ****************************************************************************/
2826 BOOL rmdir_internals(connection_struct *conn, char *directory)
2830 ok = (vfs_rmdir(conn,directory) == 0);
2831 if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
2833 * Check to see if the only thing in this directory are
2834 * vetoed files/directories. If so then delete them and
2835 * retry. If we fail to delete any of them (and we *don't*
2836 * do a recursive delete) then fail the rmdir.
2838 BOOL all_veto_files = True;
2840 void *dirptr = OpenDir(conn, directory, False);
2842 if(dirptr != NULL) {
2843 int dirpos = TellDir(dirptr);
2844 while ((dname = ReadDirName(dirptr))) {
2845 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
2847 if(!IS_VETO_PATH(conn, dname)) {
2848 all_veto_files = False;
2853 if(all_veto_files) {
2854 SeekDir(dirptr,dirpos);
2855 while ((dname = ReadDirName(dirptr))) {
2859 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
2862 /* Construct the full name. */
2863 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
2868 pstrcpy(fullname, directory);
2869 pstrcat(fullname, "/");
2870 pstrcat(fullname, dname);
2872 if(conn->vfs_ops.lstat(conn,fullname, &st) != 0)
2874 if(st.st_mode & S_IFDIR) {
2875 if(lp_recursive_veto_delete(SNUM(conn))) {
2876 if(recursive_rmdir(conn, fullname) != 0)
2879 if(vfs_rmdir(conn,fullname) != 0)
2881 } else if(vfs_unlink(conn,fullname) != 0)
2885 /* Retry the rmdir */
2886 ok = (vfs_rmdir(conn,directory) == 0);
2896 DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory,strerror(errno)));
2901 /****************************************************************************
2903 ****************************************************************************/
2905 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2910 BOOL bad_path = False;
2911 SMB_STRUCT_STAT sbuf;
2912 START_PROFILE(SMBrmdir);
2914 srvstr_pull_buf(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE);
2916 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
2918 unix_convert(directory,conn, NULL,&bad_path,&sbuf);
2920 if (check_name(directory,conn))
2922 dptr_closepath(directory,SVAL(inbuf,smb_pid));
2923 ok = rmdir_internals(conn, directory);
2928 set_bad_path_error(errno, bad_path);
2929 END_PROFILE(SMBrmdir);
2930 return(UNIXERROR(ERRDOS,ERRbadpath));
2933 outsize = set_message(outbuf,0,0,True);
2935 DEBUG( 3, ( "rmdir %s\n", directory ) );
2937 END_PROFILE(SMBrmdir);
2942 /*******************************************************************
2943 resolve wildcards in a filename rename
2944 ********************************************************************/
2945 static BOOL resolve_wildcards(char *name1,char *name2)
2947 fstring root1,root2;
2951 name1 = strrchr_m(name1,'/');
2952 name2 = strrchr_m(name2,'/');
2954 if (!name1 || !name2) return(False);
2956 fstrcpy(root1,name1);
2957 fstrcpy(root2,name2);
2958 p = strrchr_m(root1,'.');
2965 p = strrchr_m(root2,'.');
2997 pstrcpy(name2,root2);
3000 pstrcat(name2,ext2);
3006 /****************************************************************************
3007 The guts of the rename command, split out so it may be called by the NT SMB
3009 ****************************************************************************/
3011 NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists)
3015 pstring newname_last_component;
3018 BOOL bad_path1 = False;
3019 BOOL bad_path2 = False;
3021 NTSTATUS error = NT_STATUS_OK;
3023 SMB_STRUCT_STAT sbuf1, sbuf2;
3025 *directory = *mask = 0;
3027 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
3028 unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2);
3031 * Split the old name into directory and last component
3032 * strings. Note that unix_convert may have stripped off a
3033 * leading ./ from both name and newname if the rename is
3034 * at the root of the share. We need to make sure either both
3035 * name and newname contain a / character or neither of them do
3036 * as this is checked in resolve_wildcards().
3039 p = strrchr_m(name,'/');
3041 pstrcpy(directory,".");
3045 pstrcpy(directory,name);
3047 *p = '/'; /* Replace needed for exceptional test below. */
3051 * We should only check the mangled cache
3052 * here if unix_convert failed. This means
3053 * that the path in 'mask' doesn't exist
3054 * on the file system and so we need to look
3055 * for a possible mangle. This patch from
3056 * Tine Smukavec <valentin.smukavec@hermes.si>.
3059 if (!rc && mangle_is_mangled(mask))
3060 mangle_check_cache( mask );
3062 has_wild = ms_has_wild(mask);
3066 * No wildcards - just process the one file.
3068 BOOL is_short_name = mangle_is_8_3(name, True);
3070 /* Add a terminating '/' to the directory name. */
3071 pstrcat(directory,"/");
3072 pstrcat(directory,mask);
3074 /* Ensure newname contains a '/' also */
3075 if(strrchr_m(newname,'/') == 0) {
3078 pstrcpy(tmpstr, "./");
3079 pstrcat(tmpstr, newname);
3080 pstrcpy(newname, tmpstr);
3083 DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
3084 directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
3085 case_sensitive, case_preserve, short_case_preserve, directory,
3086 newname, newname_last_component, is_short_name));
3089 * Check for special case with case preserving and not
3090 * case sensitive, if directory and newname are identical,
3091 * and the old last component differs from the original
3092 * last component only by case, then we should allow
3093 * the rename (user is trying to change the case of the
3096 if((case_sensitive == False) &&
3097 (((case_preserve == True) &&
3098 (is_short_name == False)) ||
3099 ((short_case_preserve == True) &&
3100 (is_short_name == True))) &&
3101 strcsequal(directory, newname)) {
3102 pstring newname_modified_last_component;
3105 * Get the last component of the modified name.
3106 * Note that we guarantee that newname contains a '/'
3109 p = strrchr_m(newname,'/');
3110 pstrcpy(newname_modified_last_component,p+1);
3112 if(strcsequal(newname_modified_last_component,
3113 newname_last_component) == False) {
3115 * Replace the modified last component with
3118 pstrcpy(p+1, newname_last_component);
3122 resolve_wildcards(directory,newname);
3125 * The source object must exist.
3128 if (!vfs_object_exist(conn, directory, &sbuf1)) {
3129 DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
3130 directory,newname));
3132 if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
3134 * Must return different errors depending on whether the parent
3135 * directory existed or not.
3138 p = strrchr_m(directory, '/');
3140 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3142 if (vfs_object_exist(conn, directory, NULL))
3143 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3144 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3146 error = map_nt_error_from_unix(errno);
3147 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3148 nt_errstr(error), directory,newname));
3153 error = can_rename(directory,conn,&sbuf1);
3155 if (!NT_STATUS_IS_OK(error)) {
3156 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3157 nt_errstr(error), directory,newname));
3162 * If the src and dest names are identical - including case,
3163 * don't do the rename, just return success.
3166 if (strcsequal(directory, newname)) {
3167 DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
3168 return NT_STATUS_OK;
3171 if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
3172 DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
3173 directory,newname));
3174 return NT_STATUS_OBJECT_NAME_COLLISION;
3177 if(conn->vfs_ops.rename(conn,directory, newname) == 0) {
3178 DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
3179 directory,newname));
3180 return NT_STATUS_OK;
3183 if (errno == ENOTDIR || errno == EISDIR)
3184 error = NT_STATUS_OBJECT_NAME_COLLISION;
3186 error = map_nt_error_from_unix(errno);
3188 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3189 nt_errstr(error), directory,newname));
3194 * Wildcards - process each file that matches.
3196 void *dirptr = NULL;
3200 if (check_name(directory,conn))
3201 dirptr = OpenDir(conn, directory, True);
3204 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3206 if (strequal(mask,"????????.???"))
3209 while ((dname = ReadDirName(dirptr))) {
3212 pstrcpy(fname,dname);
3214 if(!mask_match(fname, mask, case_sensitive))
3217 error = NT_STATUS_ACCESS_DENIED;
3218 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
3219 if (!vfs_object_exist(conn, fname, &sbuf1)) {
3220 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3221 DEBUG(6,("rename %s failed. Error %s\n", fname, nt_errstr(error)));
3224 error = can_rename(fname,conn,&sbuf1);
3225 if (!NT_STATUS_IS_OK(error)) {
3226 DEBUG(6,("rename %s refused\n", fname));
3229 pstrcpy(destname,newname);
3231 if (!resolve_wildcards(fname,destname)) {
3232 DEBUG(6,("resolve_wildcards %s %s failed\n",
3237 if (!replace_if_exists &&
3238 vfs_file_exist(conn,destname, NULL)) {
3239 DEBUG(6,("file_exist %s\n", destname));
3240 error = NT_STATUS_OBJECT_NAME_COLLISION;
3244 if (!conn->vfs_ops.rename(conn,fname,destname))
3246 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
3252 if (count == 0 && NT_STATUS_IS_OK(error)) {
3253 error = map_nt_error_from_unix(errno);
3259 /****************************************************************************
3261 ****************************************************************************/
3263 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
3272 START_PROFILE(SMBmv);
3274 p = smb_buf(inbuf) + 1;
3275 p += srvstr_pull_buf(inbuf, name, p, sizeof(name), STR_TERMINATE);
3277 p += srvstr_pull_buf(inbuf, newname, p, sizeof(newname), STR_TERMINATE);
3279 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3280 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3282 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
3284 status = rename_internals(conn, name, newname, False);
3285 if (!NT_STATUS_IS_OK(status)) {
3286 return ERROR_NT(status);
3290 * Win2k needs a changenotify request response before it will
3291 * update after a rename..
3293 process_pending_change_notify_queue((time_t)0);
3294 outsize = set_message(outbuf,0,0,True);
3300 /*******************************************************************
3301 Copy a file as part of a reply_copy.
3302 ******************************************************************/
3304 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
3305 int count,BOOL target_is_directory, int *err_ret)
3308 SMB_STRUCT_STAT src_sbuf, sbuf2;
3310 files_struct *fsp1,*fsp2;
3315 pstrcpy(dest,dest1);
3316 if (target_is_directory) {
3317 char *p = strrchr_m(src,'/');
3326 if (!vfs_file_exist(conn,src,&src_sbuf))
3329 fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
3330 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
3335 if (!target_is_directory && count)
3336 ofun = FILE_EXISTS_OPEN;
3338 if (vfs_stat(conn,dest,&sbuf2) == -1)
3339 ZERO_STRUCTP(&sbuf2);
3341 fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
3342 ofun,src_sbuf.st_mode,0,&Access,&action);
3345 close_file(fsp1,False);
3349 if ((ofun&3) == 1) {
3350 if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) {
3351 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
3353 * Stop the copy from occurring.
3356 src_sbuf.st_size = 0;
3360 if (src_sbuf.st_size)
3361 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
3363 close_file(fsp1,False);
3365 /* Ensure the modtime is set correctly on the destination file. */
3366 fsp2->pending_modtime = src_sbuf.st_mtime;
3369 * As we are opening fsp1 read-only we only expect
3370 * an error on close on fsp2 if we are out of space.
3371 * Thus we don't look at the error return from the
3374 *err_ret = close_file(fsp2,False);
3376 return(ret == (SMB_OFF_T)src_sbuf.st_size);
3379 /****************************************************************************
3380 reply to a file copy.
3381 ****************************************************************************/
3382 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3387 pstring mask,newname;
3390 int error = ERRnoaccess;
3394 int tid2 = SVAL(inbuf,smb_vwv0);
3395 int ofun = SVAL(inbuf,smb_vwv1);
3396 int flags = SVAL(inbuf,smb_vwv2);
3397 BOOL target_is_directory=False;
3398 BOOL bad_path1 = False;
3399 BOOL bad_path2 = False;
3401 SMB_STRUCT_STAT sbuf1, sbuf2;
3402 START_PROFILE(SMBcopy);
3404 *directory = *mask = 0;
3407 p += srvstr_pull_buf(inbuf, name, p, sizeof(name), STR_TERMINATE);
3408 p += srvstr_pull_buf(inbuf, newname, p, sizeof(newname), STR_TERMINATE);
3410 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
3412 if (tid2 != conn->cnum) {
3413 /* can't currently handle inter share copies XXXX */
3414 DEBUG(3,("Rejecting inter-share copy\n"));
3415 END_PROFILE(SMBcopy);
3416 return ERROR_DOS(ERRSRV,ERRinvdevice);
3419 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3420 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3422 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
3423 unix_convert(newname,conn,0,&bad_path2,&sbuf2);
3425 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
3427 if ((flags&1) && target_is_directory) {
3428 END_PROFILE(SMBcopy);
3429 return ERROR_DOS(ERRDOS,ERRbadfile);
3432 if ((flags&2) && !target_is_directory) {
3433 END_PROFILE(SMBcopy);
3434 return ERROR_DOS(ERRDOS,ERRbadpath);
3437 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
3438 /* wants a tree copy! XXXX */
3439 DEBUG(3,("Rejecting tree copy\n"));
3440 END_PROFILE(SMBcopy);
3441 return ERROR_DOS(ERRSRV,ERRerror);
3444 p = strrchr_m(name,'/');
3446 pstrcpy(directory,"./");
3450 pstrcpy(directory,name);
3455 * We should only check the mangled cache
3456 * here if unix_convert failed. This means
3457 * that the path in 'mask' doesn't exist
3458 * on the file system and so we need to look
3459 * for a possible mangle. This patch from
3460 * Tine Smukavec <valentin.smukavec@hermes.si>.
3463 if (!rc && mangle_is_mangled(mask))
3464 mangle_check_cache( mask );
3466 has_wild = ms_has_wild(mask);
3469 pstrcat(directory,"/");
3470 pstrcat(directory,mask);
3471 if (resolve_wildcards(directory,newname) &&
3472 copy_file(directory,newname,conn,ofun,
3473 count,target_is_directory,&err)) count++;
3476 END_PROFILE(SMBcopy);
3477 return(UNIXERROR(ERRHRD,ERRgeneral));
3479 if (!count) exists = vfs_file_exist(conn,directory,NULL);
3481 void *dirptr = NULL;
3485 if (check_name(directory,conn))
3486 dirptr = OpenDir(conn, directory, True);
3491 if (strequal(mask,"????????.???"))
3494 while ((dname = ReadDirName(dirptr))) {
3496 pstrcpy(fname,dname);
3498 if(!mask_match(fname, mask, case_sensitive))
3501 error = ERRnoaccess;
3502 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
3503 pstrcpy(destname,newname);
3504 if (resolve_wildcards(fname,destname) &&
3505 copy_file(fname,destname,conn,ofun,
3506 count,target_is_directory,&err)) count++;
3507 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
3515 /* Error on close... */
3517 END_PROFILE(SMBcopy);
3518 return(UNIXERROR(ERRHRD,ERRgeneral));
3522 END_PROFILE(SMBcopy);
3523 return ERROR_DOS(ERRDOS,error);
3526 if((errno == ENOENT) && (bad_path1 || bad_path2))
3528 unix_ERR_class = ERRDOS;
3529 unix_ERR_code = ERRbadpath;
3531 END_PROFILE(SMBcopy);
3532 return(UNIXERROR(ERRDOS,error));
3536 outsize = set_message(outbuf,1,0,True);
3537 SSVAL(outbuf,smb_vwv0,count);
3539 END_PROFILE(SMBcopy);
3543 /****************************************************************************
3545 ****************************************************************************/
3546 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3552 START_PROFILE(pathworks_setdir);
3555 if (!CAN_SETDIR(snum)) {
3556 END_PROFILE(pathworks_setdir);
3557 return ERROR_DOS(ERRDOS,ERRnoaccess);
3560 srvstr_pull_buf(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), STR_TERMINATE);
3562 if (strlen(newdir) == 0) {
3565 ok = vfs_directory_exist(conn,newdir,NULL);
3567 string_set(&conn->connectpath,newdir);
3572 END_PROFILE(pathworks_setdir);
3573 return ERROR_DOS(ERRDOS,ERRbadpath);
3576 outsize = set_message(outbuf,0,0,True);
3577 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
3579 DEBUG(3,("setdir %s\n", newdir));
3581 END_PROFILE(pathworks_setdir);
3585 /****************************************************************************
3586 Get a lock pid, dealing with large count requests.
3587 ****************************************************************************/
3589 uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
3591 if(!large_file_format)
3592 return SVAL(data,SMB_LPID_OFFSET(data_offset));
3594 return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
3597 /****************************************************************************
3598 Get a lock count, dealing with large count requests.
3599 ****************************************************************************/
3601 SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
3603 SMB_BIG_UINT count = 0;
3605 if(!large_file_format) {
3606 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
3609 #if defined(HAVE_LONGLONG)
3610 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
3611 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
3612 #else /* HAVE_LONGLONG */
3615 * NT4.x seems to be broken in that it sends large file (64 bit)
3616 * lockingX calls even if the CAP_LARGE_FILES was *not*
3617 * negotiated. For boxes without large unsigned ints truncate the
3618 * lock count by dropping the top 32 bits.
3621 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
3622 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
3623 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
3624 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
3625 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
3628 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
3629 #endif /* HAVE_LONGLONG */
3635 #if !defined(HAVE_LONGLONG)
3636 /****************************************************************************
3637 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
3638 ****************************************************************************/
3639 static uint32 map_lock_offset(uint32 high, uint32 low)
3643 uint32 highcopy = high;
3646 * Try and find out how many significant bits there are in high.
3649 for(i = 0; highcopy; i++)
3653 * We use 31 bits not 32 here as POSIX
3654 * lock offsets may not be negative.
3657 mask = (~0) << (31 - i);
3660 return 0; /* Fail. */
3666 #endif /* !defined(HAVE_LONGLONG) */
3668 /****************************************************************************
3669 Get a lock offset, dealing with large offset requests.
3670 ****************************************************************************/
3672 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
3674 SMB_BIG_UINT offset = 0;
3678 if(!large_file_format) {
3679 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
3682 #if defined(HAVE_LONGLONG)
3683 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
3684 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
3685 #else /* HAVE_LONGLONG */
3688 * NT4.x seems to be broken in that it sends large file (64 bit)
3689 * lockingX calls even if the CAP_LARGE_FILES was *not*
3690 * negotiated. For boxes without large unsigned ints mangle the
3691 * lock offset by mapping the top 32 bits onto the lower 32.
3694 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
3695 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
3696 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
3699 if((new_low = map_lock_offset(high, low)) == 0) {
3701 return (SMB_BIG_UINT)-1;
3704 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
3705 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
3706 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
3707 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
3710 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
3711 #endif /* HAVE_LONGLONG */
3717 /****************************************************************************
3718 reply to a lockingX request
3719 ****************************************************************************/
3721 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
3723 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
3724 unsigned char locktype = CVAL(inbuf,smb_vwv3);
3725 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
3726 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
3727 uint16 num_locks = SVAL(inbuf,smb_vwv7);
3728 SMB_BIG_UINT count = 0, offset = 0;
3730 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
3733 BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
3737 START_PROFILE(SMBlockingX);
3739 CHECK_FSP(fsp,conn);
3741 data = smb_buf(inbuf);
3743 if (locktype & (LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_CHANGE_LOCKTYPE)) {
3744 /* we don't support these - and CANCEL_LOCK makes w2k
3745 and XP reboot so I don't really want to be
3746 compatible! (tridge) */
3747 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3750 /* Check if this is an oplock break on a file
3751 we have granted an oplock on.
3753 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
3754 /* Client can insist on breaking to none. */
3755 BOOL break_to_none = (oplocklevel == 0);
3757 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
3758 (unsigned int)oplocklevel, fsp->fnum ));
3761 * Make sure we have granted an exclusive or batch oplock on this file.
3764 if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
3765 DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
3766 no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
3768 /* if this is a pure oplock break request then don't send a reply */
3769 if (num_locks == 0 && num_ulocks == 0) {
3770 END_PROFILE(SMBlockingX);
3773 END_PROFILE(SMBlockingX);
3774 return ERROR_DOS(ERRDOS,ERRlock);
3778 if (remove_oplock(fsp, break_to_none) == False) {
3779 DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
3783 /* if this is a pure oplock break request then don't send a reply */
3784 if (num_locks == 0 && num_ulocks == 0) {
3785 /* Sanity check - ensure a pure oplock break is not a
3787 if(CVAL(inbuf,smb_vwv0) != 0xff)
3788 DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
3789 (unsigned int)CVAL(inbuf,smb_vwv0) ));
3790 END_PROFILE(SMBlockingX);
3796 * We do this check *after* we have checked this is not a oplock break
3797 * response message. JRA.
3800 release_level_2_oplocks_on_change(fsp);
3802 /* Data now points at the beginning of the list
3803 of smb_unlkrng structs */
3804 for(i = 0; i < (int)num_ulocks; i++) {
3805 lock_pid = get_lock_pid( data, i, large_file_format);
3806 count = get_lock_count( data, i, large_file_format);
3807 offset = get_lock_offset( data, i, large_file_format, &err);
3810 * There is no error code marked "stupid client bug".... :-).
3813 END_PROFILE(SMBlockingX);
3814 return ERROR_DOS(ERRDOS,ERRnoaccess);
3817 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
3818 (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
3820 status = do_unlock(fsp,conn,lock_pid,count,offset);
3821 if (NT_STATUS_V(status)) {
3822 END_PROFILE(SMBlockingX);
3823 return ERROR_NT(status);
3827 /* Setup the timeout in seconds. */
3829 lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000);
3831 /* Now do any requested locks */
3832 data += ((large_file_format ? 20 : 10)*num_ulocks);
3834 /* Data now points at the beginning of the list
3835 of smb_lkrng structs */
3837 for(i = 0; i < (int)num_locks; i++) {
3838 lock_pid = get_lock_pid( data, i, large_file_format);
3839 count = get_lock_count( data, i, large_file_format);
3840 offset = get_lock_offset( data, i, large_file_format, &err);
3843 * There is no error code marked "stupid client bug".... :-).
3846 END_PROFILE(SMBlockingX);
3847 return ERROR_DOS(ERRDOS,ERRnoaccess);
3850 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
3851 (double)offset, (double)count, (unsigned int)lock_pid,
3852 fsp->fsp_name, (int)lock_timeout ));
3854 status = do_lock_spin(fsp,conn,lock_pid, count,offset,
3855 ((locktype & 1) ? READ_LOCK : WRITE_LOCK));
3856 if (NT_STATUS_V(status)) {
3857 if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) {
3859 * A blocking lock was requested. Package up
3860 * this smb into a queued request and push it
3861 * onto the blocking lock queue.
3863 if(push_blocking_lock_request(inbuf, length, lock_timeout, i)) {
3864 END_PROFILE(SMBlockingX);
3872 /* If any of the above locks failed, then we must unlock
3873 all of the previous locks (X/Open spec). */
3874 if (i != num_locks && num_locks != 0) {
3876 * Ensure we don't do a remove on the lock that just failed,
3877 * as under POSIX rules, if we have a lock already there, we
3878 * will delete it (and we shouldn't) .....
3880 for(i--; i >= 0; i--) {
3881 lock_pid = get_lock_pid( data, i, large_file_format);
3882 count = get_lock_count( data, i, large_file_format);
3883 offset = get_lock_offset( data, i, large_file_format, &err);
3886 * There is no error code marked "stupid client bug".... :-).
3889 END_PROFILE(SMBlockingX);
3890 return ERROR_DOS(ERRDOS,ERRnoaccess);
3893 do_unlock(fsp,conn,lock_pid,count,offset);
3895 END_PROFILE(SMBlockingX);
3896 return ERROR_NT(status);
3899 set_message(outbuf,2,0,True);
3901 DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
3902 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
3904 END_PROFILE(SMBlockingX);
3905 return chain_reply(inbuf,outbuf,length,bufsize);
3908 /****************************************************************************
3909 Reply to a SMBreadbmpx (read block multiplex) request.
3910 ****************************************************************************/
3912 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
3923 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3924 START_PROFILE(SMBreadBmpx);
3926 /* this function doesn't seem to work - disable by default */
3927 if (!lp_readbmpx()) {
3928 END_PROFILE(SMBreadBmpx);
3929 return ERROR_DOS(ERRSRV,ERRuseSTD);
3932 outsize = set_message(outbuf,8,0,True);
3934 CHECK_FSP(fsp,conn);
3937 startpos = IVAL(inbuf,smb_vwv1);
3938 maxcount = SVAL(inbuf,smb_vwv3);
3940 data = smb_buf(outbuf);
3941 pad = ((long)data)%4;
3946 max_per_packet = bufsize-(outsize+pad);
3950 if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
3951 END_PROFILE(SMBreadBmpx);
3952 return ERROR_DOS(ERRDOS,ERRlock);
3956 size_t N = MIN(max_per_packet,tcount-total_read);
3958 nread = read_file(fsp,data,startpos,N);
3963 if (nread < (ssize_t)N)
3964 tcount = total_read + nread;
3966 set_message(outbuf,8,nread,False);
3967 SIVAL(outbuf,smb_vwv0,startpos);
3968 SSVAL(outbuf,smb_vwv2,tcount);
3969 SSVAL(outbuf,smb_vwv6,nread);
3970 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
3972 if (!send_smb(smbd_server_fd(),outbuf))
3973 exit_server("reply_readbmpx: send_smb failed.");
3975 total_read += nread;
3977 } while (total_read < (ssize_t)tcount);
3979 END_PROFILE(SMBreadBmpx);
3983 /****************************************************************************
3984 Reply to a SMBsetattrE.
3985 ****************************************************************************/
3987 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
3989 struct utimbuf unix_times;
3991 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3992 START_PROFILE(SMBsetattrE);
3994 outsize = set_message(outbuf,0,0,True);
3996 if(!fsp || (fsp->conn != conn)) {
3997 END_PROFILE(SMBgetattrE);
3998 return ERROR_DOS(ERRDOS,ERRbadfid);
4002 * Convert the DOS times into unix times. Ignore create
4003 * time as UNIX can't set this.
4006 unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
4007 unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
4010 * Patch from Ray Frush <frush@engr.colostate.edu>
4011 * Sometimes times are sent as zero - ignore them.
4014 if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
4015 /* Ignore request */
4016 if( DEBUGLVL( 3 ) ) {
4017 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
4018 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
4020 END_PROFILE(SMBsetattrE);
4022 } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
4023 /* set modify time = to access time if modify time was 0 */
4024 unix_times.modtime = unix_times.actime;
4027 /* Set the date on this file */
4028 if(file_utime(conn, fsp->fsp_name, &unix_times)) {
4029 END_PROFILE(SMBsetattrE);
4030 return ERROR_DOS(ERRDOS,ERRnoaccess);
4033 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
4034 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
4036 END_PROFILE(SMBsetattrE);
4041 /* Back from the dead for OS/2..... JRA. */
4043 /****************************************************************************
4044 Reply to a SMBwritebmpx (write block multiplex primary) request.
4045 ****************************************************************************/
4047 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4050 ssize_t nwritten = -1;
4057 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4058 START_PROFILE(SMBwriteBmpx);
4060 CHECK_FSP(fsp,conn);
4064 tcount = SVAL(inbuf,smb_vwv1);
4065 startpos = IVAL(inbuf,smb_vwv3);
4066 write_through = BITSETW(inbuf+smb_vwv7,0);
4067 numtowrite = SVAL(inbuf,smb_vwv10);
4068 smb_doff = SVAL(inbuf,smb_vwv11);
4070 data = smb_base(inbuf) + smb_doff;
4072 /* If this fails we need to send an SMBwriteC response,
4073 not an SMBwritebmpx - set this up now so we don't forget */
4074 SCVAL(outbuf,smb_com,SMBwritec);
4076 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
4077 END_PROFILE(SMBwriteBmpx);
4078 return(ERROR_DOS(ERRDOS,ERRlock));
4081 nwritten = write_file(fsp,data,startpos,numtowrite);
4083 if(lp_syncalways(SNUM(conn)) || write_through)
4084 sync_file(conn,fsp);
4086 if(nwritten < (ssize_t)numtowrite) {
4087 END_PROFILE(SMBwriteBmpx);
4088 return(UNIXERROR(ERRHRD,ERRdiskfull));
4091 /* If the maximum to be written to this file
4092 is greater than what we just wrote then set
4093 up a secondary struct to be attached to this
4094 fd, we will use this to cache error messages etc. */
4096 if((ssize_t)tcount > nwritten) {
4097 write_bmpx_struct *wbms;
4098 if(fsp->wbmpx_ptr != NULL)
4099 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
4101 wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
4103 DEBUG(0,("Out of memory in reply_readmpx\n"));
4104 END_PROFILE(SMBwriteBmpx);
4105 return(ERROR_DOS(ERRSRV,ERRnoresource));
4107 wbms->wr_mode = write_through;
4108 wbms->wr_discard = False; /* No errors yet */
4109 wbms->wr_total_written = nwritten;
4110 wbms->wr_errclass = 0;
4112 fsp->wbmpx_ptr = wbms;
4115 /* We are returning successfully, set the message type back to
4117 SCVAL(outbuf,smb_com,SMBwriteBmpx);
4119 outsize = set_message(outbuf,1,0,True);
4121 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
4123 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
4124 fsp->fnum, (int)numtowrite, (int)nwritten ) );
4126 if (write_through && tcount==nwritten) {
4127 /* We need to send both a primary and a secondary response */
4128 smb_setlen(outbuf,outsize - 4);
4129 if (!send_smb(smbd_server_fd(),outbuf))
4130 exit_server("reply_writebmpx: send_smb failed.");
4132 /* Now the secondary */
4133 outsize = set_message(outbuf,1,0,True);
4134 SCVAL(outbuf,smb_com,SMBwritec);
4135 SSVAL(outbuf,smb_vwv0,nwritten);
4138 END_PROFILE(SMBwriteBmpx);
4142 /****************************************************************************
4143 Reply to a SMBwritebs (write block multiplex secondary) request.
4144 ****************************************************************************/
4146 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4149 ssize_t nwritten = -1;
4156 write_bmpx_struct *wbms;
4157 BOOL send_response = False;
4158 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4159 START_PROFILE(SMBwriteBs);
4161 CHECK_FSP(fsp,conn);
4164 tcount = SVAL(inbuf,smb_vwv1);
4165 startpos = IVAL(inbuf,smb_vwv2);
4166 numtowrite = SVAL(inbuf,smb_vwv6);
4167 smb_doff = SVAL(inbuf,smb_vwv7);
4169 data = smb_base(inbuf) + smb_doff;
4171 /* We need to send an SMBwriteC response, not an SMBwritebs */
4172 SCVAL(outbuf,smb_com,SMBwritec);
4174 /* This fd should have an auxiliary struct attached,
4175 check that it does */
4176 wbms = fsp->wbmpx_ptr;
4178 END_PROFILE(SMBwriteBs);
4182 /* If write through is set we can return errors, else we must cache them */
4183 write_through = wbms->wr_mode;
4185 /* Check for an earlier error */
4186 if(wbms->wr_discard) {
4187 END_PROFILE(SMBwriteBs);
4188 return -1; /* Just discard the packet */
4191 nwritten = write_file(fsp,data,startpos,numtowrite);
4193 if(lp_syncalways(SNUM(conn)) || write_through)
4194 sync_file(conn,fsp);
4196 if (nwritten < (ssize_t)numtowrite) {
4198 /* We are returning an error - we can delete the aux struct */
4201 fsp->wbmpx_ptr = NULL;
4202 END_PROFILE(SMBwriteBs);
4203 return(ERROR_DOS(ERRHRD,ERRdiskfull));
4205 END_PROFILE(SMBwriteBs);
4206 return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
4209 /* Increment the total written, if this matches tcount
4210 we can discard the auxiliary struct (hurrah !) and return a writeC */
4211 wbms->wr_total_written += nwritten;
4212 if(wbms->wr_total_written >= tcount) {
4213 if (write_through) {
4214 outsize = set_message(outbuf,1,0,True);
4215 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
4216 send_response = True;
4220 fsp->wbmpx_ptr = NULL;
4224 END_PROFILE(SMBwriteBs);
4228 END_PROFILE(SMBwriteBs);
4232 /****************************************************************************
4233 Reply to a SMBgetattrE.
4234 ****************************************************************************/
4236 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4238 SMB_STRUCT_STAT sbuf;
4241 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4242 START_PROFILE(SMBgetattrE);
4244 outsize = set_message(outbuf,11,0,True);
4246 if(!fsp || (fsp->conn != conn)) {
4247 END_PROFILE(SMBgetattrE);
4248 return ERROR_DOS(ERRDOS,ERRbadfid);
4251 /* Do an fstat on this file */
4252 if(fsp_stat(fsp, &sbuf)) {
4253 END_PROFILE(SMBgetattrE);
4254 return(UNIXERROR(ERRDOS,ERRnoaccess));
4257 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
4260 * Convert the times into dos times. Set create
4261 * date to be last modify date as UNIX doesn't save
4265 put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
4266 put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
4267 put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
4270 SIVAL(outbuf,smb_vwv6,0);
4271 SIVAL(outbuf,smb_vwv8,0);
4273 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
4274 SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
4276 SSVAL(outbuf,smb_vwv10, mode);
4278 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
4280 END_PROFILE(SMBgetattrE);