2 Unix SMB/CIFS implementation.
3 Main SMB reply routines
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 This file handles most of the reply_ calls that the server
23 makes to handle specific protocols
28 /* look in server.c for some explanation of these variables */
32 extern char magic_char;
33 extern BOOL case_sensitive;
34 extern BOOL case_preserve;
35 extern BOOL short_case_preserve;
36 extern int global_oplock_break;
37 unsigned int smb_echo_count = 0;
39 extern BOOL global_encrypted_passwords_negotiated;
41 /****************************************************************************
42 Ensure we check the path in the same way as W2K.
43 ****************************************************************************/
45 static NTSTATUS check_path_syntax(const char *name)
49 if (strequal(name, "."))
50 return NT_STATUS_OBJECT_NAME_INVALID;
51 else if (strequal(name, ".."))
52 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
56 /****************************************************************************
57 Reply to a special message.
58 ****************************************************************************/
60 int reply_special(char *inbuf,char *outbuf)
63 int msg_type = CVAL(inbuf,0);
64 int msg_flags = CVAL(inbuf,1);
68 static BOOL already_got_session = False;
72 memset(outbuf,'\0',smb_size);
77 case 0x81: /* session request */
79 if (already_got_session) {
80 exit_server("multiple session request not permitted");
85 if (name_len(inbuf+4) > 50 ||
86 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
87 DEBUG(0,("Invalid name length in session request\n"));
90 name_extract(inbuf,4,name1);
91 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
92 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
95 set_local_machine_name(name1, True);
96 set_remote_machine_name(name2, True);
98 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
99 get_local_machine_name(), get_remote_machine_name(),
102 if (name_type == 'R') {
103 /* We are being asked for a pathworks session ---
105 SCVAL(outbuf, 0,0x83);
109 /* only add the client's machine name to the list
110 of possibly valid usernames if we are operating
111 in share mode security */
112 if (lp_security() == SEC_SHARE) {
113 add_session_user(get_remote_machine_name());
116 reload_services(True);
119 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
121 already_got_session = True;
124 case 0x89: /* session keepalive request
125 (some old clients produce this?) */
126 SCVAL(outbuf,0,SMBkeepalive);
130 case 0x82: /* positive session response */
131 case 0x83: /* negative session response */
132 case 0x84: /* retarget session response */
133 DEBUG(0,("Unexpected session response\n"));
136 case SMBkeepalive: /* session keepalive */
141 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
142 msg_type, msg_flags));
147 /****************************************************************************
149 ****************************************************************************/
151 int reply_tcon(connection_struct *conn,
152 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
159 uint16 vuid = SVAL(inbuf,smb_uid);
163 DATA_BLOB password_blob;
165 START_PROFILE(SMBtcon);
167 *service_buf = *password = *dev = 0;
169 p = smb_buf(inbuf)+1;
170 p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
171 pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
173 p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
175 p = strrchr_m(service_buf,'\\');
179 service = service_buf;
182 password_blob = data_blob(password, pwlen+1);
184 conn = make_connection(service,password_blob,dev,vuid,&nt_status);
186 data_blob_clear_free(&password_blob);
189 END_PROFILE(SMBtcon);
190 return ERROR_NT(nt_status);
193 outsize = set_message(outbuf,2,0,True);
194 SSVAL(outbuf,smb_vwv0,max_recv);
195 SSVAL(outbuf,smb_vwv1,conn->cnum);
196 SSVAL(outbuf,smb_tid,conn->cnum);
198 DEBUG(3,("tcon service=%s cnum=%d\n",
199 service, conn->cnum));
201 END_PROFILE(SMBtcon);
205 /****************************************************************************
206 Reply to a tcon and X.
207 ****************************************************************************/
209 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
214 /* what the cleint thinks the device is */
215 fstring client_devicetype;
216 /* what the server tells the client the share represents */
217 const char *server_devicetype;
219 uint16 vuid = SVAL(inbuf,smb_uid);
220 int passlen = SVAL(inbuf,smb_vwv3);
223 extern BOOL global_encrypted_passwords_negotiated;
225 START_PROFILE(SMBtconX);
227 *service = *client_devicetype = 0;
229 /* we might have to close an old one */
230 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
231 close_cnum(conn,vuid);
234 if (passlen > MAX_PASS_LEN) {
235 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
238 if (global_encrypted_passwords_negotiated) {
239 password = data_blob(smb_buf(inbuf),passlen);
241 password = data_blob(smb_buf(inbuf),passlen+1);
242 /* Ensure correct termination */
243 password.data[passlen]=0;
246 p = smb_buf(inbuf) + passlen;
247 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
250 * the service name can be either: \\server\share
251 * or share directly like on the DELL PowerVault 705
254 q = strchr_m(path+2,'\\');
256 END_PROFILE(SMBtconX);
257 return(ERROR_DOS(ERRDOS,ERRnosuchshare));
259 fstrcpy(service,q+1);
262 fstrcpy(service,path);
264 p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII);
266 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
268 conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
270 data_blob_clear_free(&password);
273 END_PROFILE(SMBtconX);
274 return ERROR_NT(nt_status);
278 server_devicetype = "IPC";
279 else if ( IS_PRINT(conn) )
280 server_devicetype = "LPT1:";
282 server_devicetype = "A:";
284 if (Protocol < PROTOCOL_NT1) {
285 set_message(outbuf,2,0,True);
287 p += srvstr_push(outbuf, p, server_devicetype, -1,
288 STR_TERMINATE|STR_ASCII);
289 set_message_end(outbuf,p);
291 /* NT sets the fstype of IPC$ to the null string */
292 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
294 set_message(outbuf,3,0,True);
297 p += srvstr_push(outbuf, p, server_devicetype, -1,
298 STR_TERMINATE|STR_ASCII);
299 p += srvstr_push(outbuf, p, fstype, -1,
302 set_message_end(outbuf,p);
304 /* what does setting this bit do? It is set by NT4 and
305 may affect the ability to autorun mounted cdroms */
306 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
307 (lp_csc_policy(SNUM(conn)) << 2));
309 init_dfsroot(conn, inbuf, outbuf);
313 DEBUG(3,("tconX service=%s \n",
316 /* set the incoming and outgoing tid to the just created one */
317 SSVAL(inbuf,smb_tid,conn->cnum);
318 SSVAL(outbuf,smb_tid,conn->cnum);
320 END_PROFILE(SMBtconX);
321 return chain_reply(inbuf,outbuf,length,bufsize);
324 /****************************************************************************
325 Reply to an unknown type.
326 ****************************************************************************/
328 int reply_unknown(char *inbuf,char *outbuf)
331 type = CVAL(inbuf,smb_com);
333 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
334 smb_fn_name(type), type, type));
336 return(ERROR_DOS(ERRSRV,ERRunknownsmb));
339 /****************************************************************************
341 ****************************************************************************/
343 int reply_ioctl(connection_struct *conn,
344 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
346 uint16 device = SVAL(inbuf,smb_vwv1);
347 uint16 function = SVAL(inbuf,smb_vwv2);
348 uint32 ioctl_code = (device << 16) + function;
349 int replysize, outsize;
351 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
352 START_PROFILE(SMBioctl);
354 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
356 switch (ioctl_code) {
357 case IOCTL_QUERY_JOB_INFO:
361 END_PROFILE(SMBioctl);
362 return(ERROR_DOS(ERRSRV,ERRnosupport));
365 outsize = set_message(outbuf,8,replysize+1,True);
366 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
367 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
368 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
369 p = smb_buf(outbuf) + 1; /* Allow for alignment */
371 switch (ioctl_code) {
372 case IOCTL_QUERY_JOB_INFO:
374 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
375 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
376 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
381 END_PROFILE(SMBioctl);
385 /****************************************************************************
387 ****************************************************************************/
389 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
395 BOOL bad_path = False;
396 SMB_STRUCT_STAT sbuf;
399 START_PROFILE(SMBchkpth);
401 srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE);
403 status = check_path_syntax(name);
404 if (!NT_STATUS_IS_OK(status))
405 return ERROR_NT(status);
407 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
409 unix_convert(name,conn,0,&bad_path,&sbuf);
411 mode = SVAL(inbuf,smb_vwv0);
413 if (check_name(name,conn)) {
414 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
415 if (!(ok = S_ISDIR(sbuf.st_mode)))
420 /* We special case this - as when a Windows machine
421 is parsing a path is steps through the components
422 one at a time - if a component fails it expects
423 ERRbadpath, not ERRbadfile.
425 if(errno == ENOENT) {
427 * Windows returns different error codes if
428 * the parent directory is valid but not the
429 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
430 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
431 * if the path is invalid.
434 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
436 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
438 } else if (errno == ENOTDIR)
439 return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY);
441 return(UNIXERROR(ERRDOS,ERRbadpath));
444 outsize = set_message(outbuf,0,0,True);
446 DEBUG(3,("chkpth %s mode=%d\n", name, mode));
448 END_PROFILE(SMBchkpth);
452 /****************************************************************************
454 ****************************************************************************/
456 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
460 SMB_STRUCT_STAT sbuf;
465 BOOL bad_path = False;
467 START_PROFILE(SMBgetatr);
469 p = smb_buf(inbuf) + 1;
470 p += srvstr_pull_buf(inbuf, fname, p, sizeof(fname), STR_TERMINATE);
472 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
474 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
475 under WfWg - weird! */
477 mode = aHIDDEN | aDIR;
478 if (!CAN_WRITE(conn))
484 unix_convert(fname,conn,0,&bad_path,&sbuf);
485 if (check_name(fname,conn)) {
486 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
487 mode = dos_mode(conn,fname,&sbuf);
489 mtime = sbuf.st_mtime;
494 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
500 set_bad_path_error(errno, bad_path);
501 END_PROFILE(SMBgetatr);
502 return(UNIXERROR(ERRDOS,ERRbadfile));
505 outsize = set_message(outbuf,10,0,True);
507 SSVAL(outbuf,smb_vwv0,mode);
508 if(lp_dos_filetime_resolution(SNUM(conn)) )
509 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
511 put_dos_date3(outbuf,smb_vwv1,mtime);
512 SIVAL(outbuf,smb_vwv3,(uint32)size);
514 if (Protocol >= PROTOCOL_NT1)
515 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
517 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
519 END_PROFILE(SMBgetatr);
523 /****************************************************************************
525 ****************************************************************************/
527 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
534 SMB_STRUCT_STAT sbuf;
535 BOOL bad_path = False;
538 START_PROFILE(SMBsetatr);
540 p = smb_buf(inbuf) + 1;
541 p += srvstr_pull_buf(inbuf, fname, p, sizeof(fname), STR_TERMINATE);
542 unix_convert(fname,conn,0,&bad_path,&sbuf);
544 mode = SVAL(inbuf,smb_vwv0);
545 mtime = make_unix_date3(inbuf+smb_vwv1);
547 if (VALID_STAT_OF_DIR(sbuf))
552 if (check_name(fname,conn))
553 ok = (file_chmod(conn,fname,mode,NULL) == 0);
555 ok = set_filetime(conn,fname,mtime);
558 set_bad_path_error(errno, bad_path);
559 END_PROFILE(SMBsetatr);
560 return(UNIXERROR(ERRDOS,ERRnoaccess));
563 outsize = set_message(outbuf,0,0,True);
565 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
567 END_PROFILE(SMBsetatr);
571 /****************************************************************************
573 ****************************************************************************/
575 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
578 SMB_BIG_UINT dfree,dsize,bsize;
579 START_PROFILE(SMBdskattr);
581 SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
583 outsize = set_message(outbuf,5,0,True);
585 if (Protocol <= PROTOCOL_LANMAN2) {
586 double total_space, free_space;
587 /* we need to scale this to a number that DOS6 can handle. We
588 use floating point so we can handle large drives on systems
589 that don't have 64 bit integers
591 we end up displaying a maximum of 2G to DOS systems
593 total_space = dsize * (double)bsize;
594 free_space = dfree * (double)bsize;
596 dsize = (total_space+63*512) / (64*512);
597 dfree = (free_space+63*512) / (64*512);
599 if (dsize > 0xFFFF) dsize = 0xFFFF;
600 if (dfree > 0xFFFF) dfree = 0xFFFF;
602 SSVAL(outbuf,smb_vwv0,dsize);
603 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
604 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
605 SSVAL(outbuf,smb_vwv3,dfree);
607 SSVAL(outbuf,smb_vwv0,dsize);
608 SSVAL(outbuf,smb_vwv1,bsize/512);
609 SSVAL(outbuf,smb_vwv2,512);
610 SSVAL(outbuf,smb_vwv3,dfree);
613 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
615 END_PROFILE(SMBdskattr);
619 /****************************************************************************
621 Can be called from SMBsearch, SMBffirst or SMBfunique.
622 ****************************************************************************/
624 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
635 BOOL finished = False;
644 BOOL check_descend = False;
645 BOOL expect_close = False;
646 BOOL can_open = True;
647 BOOL bad_path = False;
648 START_PROFILE(SMBsearch);
650 *mask = *directory = *fname = 0;
652 /* If we were called as SMBffirst then we must expect close. */
653 if(CVAL(inbuf,smb_com) == SMBffirst)
656 outsize = set_message(outbuf,1,3,True);
657 maxentries = SVAL(inbuf,smb_vwv0);
658 dirtype = SVAL(inbuf,smb_vwv1);
659 p = smb_buf(inbuf) + 1;
660 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
662 status_len = SVAL(p, 0);
665 /* dirtype &= ~aDIR; */
667 if (status_len == 0) {
668 SMB_STRUCT_STAT sbuf;
671 pstrcpy(directory,path);
673 unix_convert(directory,conn,0,&bad_path,&sbuf);
676 if (!check_name(directory,conn))
679 p = strrchr_m(dir2,'/');
688 p = strrchr_m(directory,'/');
694 if (strlen(directory) == 0)
695 pstrcpy(directory,".");
696 memset((char *)status,'\0',21);
697 SCVAL(status,0,(dirtype & 0x1F));
702 status_dirtype = CVAL(status,0) & 0x1F;
703 if (status_dirtype != (dirtype & 0x1F))
704 dirtype = status_dirtype;
706 conn->dirptr = dptr_fetch(status+12,&dptr_num);
709 string_set(&conn->dirpath,dptr_path(dptr_num));
710 pstrcpy(mask, dptr_wcard(dptr_num));
714 p = smb_buf(outbuf) + 3;
717 if (status_len == 0) {
718 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
721 set_bad_path_error(errno, bad_path);
722 END_PROFILE(SMBsearch);
723 return (UNIXERROR(ERRDOS,ERRnofids));
725 END_PROFILE(SMBsearch);
726 return ERROR_DOS(ERRDOS,ERRnofids);
728 dptr_set_wcard(dptr_num, strdup(mask));
729 dptr_set_attr(dptr_num, dirtype);
731 dirtype = dptr_attr(dptr_num);
734 DEBUG(4,("dptr_num is %d\n",dptr_num));
737 if ((dirtype&0x1F) == aVOLID) {
739 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
740 dptr_fill(p+12,dptr_num);
741 if (dptr_zero(p+12) && (status_len==0))
745 p += DIR_STRUCT_SIZE;
747 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
748 conn->dirpath,lp_dontdescend(SNUM(conn))));
749 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
750 check_descend = True;
752 for (i=numentries;(i<maxentries) && !finished;i++) {
753 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
756 make_dir_struct(p,mask,fname,size,mode,date);
757 dptr_fill(p+12,dptr_num);
760 p += DIR_STRUCT_SIZE;
769 if (numentries == 0 || !ok) {
770 SCVAL(outbuf,smb_rcls,ERRDOS);
771 SSVAL(outbuf,smb_err,ERRnofiles);
772 dptr_close(&dptr_num);
775 /* If we were called as SMBffirst with smb_search_id == NULL
776 and no entries were found then return error and close dirptr
779 if(ok && expect_close && numentries == 0 && status_len == 0) {
780 SCVAL(outbuf,smb_rcls,ERRDOS);
781 SSVAL(outbuf,smb_err,ERRnofiles);
782 /* Also close the dptr - we know it's gone */
783 dptr_close(&dptr_num);
786 /* If we were called as SMBfunique, then we can close the dirptr now ! */
787 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
788 dptr_close(&dptr_num);
790 SSVAL(outbuf,smb_vwv0,numentries);
791 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
792 SCVAL(smb_buf(outbuf),0,5);
793 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
795 if (Protocol >= PROTOCOL_NT1)
796 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
798 outsize += DIR_STRUCT_SIZE*numentries;
799 smb_setlen(outbuf,outsize - 4);
801 if ((! *directory) && dptr_path(dptr_num))
802 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
804 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
805 smb_fn_name(CVAL(inbuf,smb_com)),
806 mask, directory, dirtype, numentries, maxentries ) );
808 END_PROFILE(SMBsearch);
812 /****************************************************************************
813 Reply to a fclose (stop directory search).
814 ****************************************************************************/
816 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
825 START_PROFILE(SMBfclose);
827 outsize = set_message(outbuf,1,0,True);
828 p = smb_buf(inbuf) + 1;
829 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
831 status_len = SVAL(p,0);
834 if (status_len == 0) {
835 END_PROFILE(SMBfclose);
836 return ERROR_DOS(ERRSRV,ERRsrverror);
841 if(dptr_fetch(status+12,&dptr_num)) {
842 /* Close the dptr - we know it's gone */
843 dptr_close(&dptr_num);
846 SSVAL(outbuf,smb_vwv0,0);
848 DEBUG(3,("search close\n"));
850 END_PROFILE(SMBfclose);
854 /****************************************************************************
856 ****************************************************************************/
858 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
868 SMB_STRUCT_STAT sbuf;
869 BOOL bad_path = False;
871 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
872 START_PROFILE(SMBopen);
874 share_mode = SVAL(inbuf,smb_vwv0);
876 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE);
878 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
880 unix_convert(fname,conn,0,&bad_path,&sbuf);
882 unixmode = unix_mode(conn,aARCH,fname);
884 fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
885 unixmode, oplock_request,&rmode,NULL);
888 set_bad_path_error(errno, bad_path);
889 END_PROFILE(SMBopen);
890 return(UNIXERROR(ERRDOS,ERRnoaccess));
894 fmode = dos_mode(conn,fname,&sbuf);
895 mtime = sbuf.st_mtime;
898 DEBUG(3,("attempt to open a directory %s\n",fname));
899 close_file(fsp,False);
900 END_PROFILE(SMBopen);
901 return ERROR_DOS(ERRDOS,ERRnoaccess);
904 outsize = set_message(outbuf,7,0,True);
905 SSVAL(outbuf,smb_vwv0,fsp->fnum);
906 SSVAL(outbuf,smb_vwv1,fmode);
907 if(lp_dos_filetime_resolution(SNUM(conn)) )
908 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
910 put_dos_date3(outbuf,smb_vwv2,mtime);
911 SIVAL(outbuf,smb_vwv4,(uint32)size);
912 SSVAL(outbuf,smb_vwv6,rmode);
914 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
915 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
917 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
918 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
919 END_PROFILE(SMBopen);
923 /****************************************************************************
924 Reply to an open and X.
925 ****************************************************************************/
927 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
930 int smb_mode = SVAL(inbuf,smb_vwv3);
931 int smb_attr = SVAL(inbuf,smb_vwv5);
932 /* Breakout the oplock request bits so we can set the
933 reply bits separately. */
934 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
935 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
936 BOOL oplock_request = ex_oplock_request | core_oplock_request;
938 int open_flags = SVAL(inbuf,smb_vwv2);
939 int smb_sattr = SVAL(inbuf,smb_vwv4);
940 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
942 int smb_ofun = SVAL(inbuf,smb_vwv8);
945 int fmode=0,mtime=0,rmode=0;
946 SMB_STRUCT_STAT sbuf;
948 BOOL bad_path = False;
950 START_PROFILE(SMBopenX);
952 /* If it's an IPC, pass off the pipe handler. */
954 if (lp_nt_pipe_support()) {
955 END_PROFILE(SMBopenX);
956 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
958 END_PROFILE(SMBopenX);
959 return ERROR_DOS(ERRSRV,ERRaccess);
963 /* XXXX we need to handle passed times, sattr and flags */
964 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
966 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
968 unix_convert(fname,conn,0,&bad_path,&sbuf);
970 unixmode = unix_mode(conn,smb_attr | aARCH, fname);
972 fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
973 oplock_request, &rmode,&smb_action);
976 set_bad_path_error(errno, bad_path);
977 END_PROFILE(SMBopenX);
978 return(UNIXERROR(ERRDOS,ERRnoaccess));
982 fmode = dos_mode(conn,fname,&sbuf);
983 mtime = sbuf.st_mtime;
985 close_file(fsp,False);
986 END_PROFILE(SMBopenX);
987 return ERROR_DOS(ERRDOS,ERRnoaccess);
990 /* If the caller set the extended oplock request bit
991 and we granted one (by whatever means) - set the
992 correct bit for extended oplock reply.
995 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn)))
996 smb_action |= EXTENDED_OPLOCK_GRANTED;
998 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
999 smb_action |= EXTENDED_OPLOCK_GRANTED;
1001 /* If the caller set the core oplock request bit
1002 and we granted one (by whatever means) - set the
1003 correct bit for core oplock reply.
1006 if (core_oplock_request && lp_fake_oplocks(SNUM(conn)))
1007 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1009 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1010 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1012 set_message(outbuf,15,0,True);
1013 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1014 SSVAL(outbuf,smb_vwv3,fmode);
1015 if(lp_dos_filetime_resolution(SNUM(conn)) )
1016 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1018 put_dos_date3(outbuf,smb_vwv4,mtime);
1019 SIVAL(outbuf,smb_vwv6,(uint32)size);
1020 SSVAL(outbuf,smb_vwv8,rmode);
1021 SSVAL(outbuf,smb_vwv11,smb_action);
1023 END_PROFILE(SMBopenX);
1024 return chain_reply(inbuf,outbuf,length,bufsize);
1027 /****************************************************************************
1028 Reply to a SMBulogoffX.
1029 ****************************************************************************/
1031 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1033 uint16 vuid = SVAL(inbuf,smb_uid);
1034 user_struct *vuser = get_valid_user_struct(vuid);
1035 START_PROFILE(SMBulogoffX);
1038 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1040 /* in user level security we are supposed to close any files
1041 open by this user */
1042 if ((vuser != 0) && (lp_security() != SEC_SHARE))
1043 file_close_user(vuid);
1045 invalidate_vuid(vuid);
1047 set_message(outbuf,2,0,True);
1049 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1051 END_PROFILE(SMBulogoffX);
1052 return chain_reply(inbuf,outbuf,length,bufsize);
1055 /****************************************************************************
1056 Reply to a mknew or a create.
1057 ****************************************************************************/
1059 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1067 BOOL bad_path = False;
1069 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1070 SMB_STRUCT_STAT sbuf;
1071 START_PROFILE(SMBcreate);
1073 com = SVAL(inbuf,smb_com);
1075 createmode = SVAL(inbuf,smb_vwv0);
1076 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), STR_TERMINATE);
1078 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1080 unix_convert(fname,conn,0,&bad_path,&sbuf);
1082 if (createmode & aVOLID)
1083 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1085 unixmode = unix_mode(conn,createmode,fname);
1087 if(com == SMBmknew) {
1088 /* We should fail if file exists. */
1089 ofun = FILE_CREATE_IF_NOT_EXIST;
1091 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1092 ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
1095 /* Open file in dos compatibility share mode. */
1096 fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1097 ofun, unixmode, oplock_request, NULL, NULL);
1100 set_bad_path_error(errno, bad_path);
1101 END_PROFILE(SMBcreate);
1102 return(UNIXERROR(ERRDOS,ERRnoaccess));
1105 outsize = set_message(outbuf,1,0,True);
1106 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1108 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1109 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1111 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1112 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1114 DEBUG( 2, ( "new file %s\n", fname ) );
1115 DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n", fname, fsp->fd, createmode, (int)unixmode ) );
1117 END_PROFILE(SMBcreate);
1121 /****************************************************************************
1122 Reply to a create temporary file.
1123 ****************************************************************************/
1125 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1131 BOOL bad_path = False;
1133 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1135 SMB_STRUCT_STAT sbuf;
1138 START_PROFILE(SMBctemp);
1140 createmode = SVAL(inbuf,smb_vwv0);
1141 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE);
1142 pstrcat(fname,"\\TMXXXXXX");
1144 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1146 unix_convert(fname,conn,0,&bad_path,&sbuf);
1148 unixmode = unix_mode(conn,createmode,fname);
1150 tmpfd = smb_mkstemp(fname);
1152 END_PROFILE(SMBctemp);
1153 return(UNIXERROR(ERRDOS,ERRnoaccess));
1156 SMB_VFS_STAT(conn,fname,&sbuf);
1158 /* Open file in dos compatibility share mode. */
1159 /* We should fail if file does not exist. */
1160 fsp = open_file_shared(conn,fname,&sbuf,
1161 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1162 FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
1163 unixmode, oplock_request, NULL, NULL);
1165 /* close fd from smb_mkstemp() */
1169 set_bad_path_error(errno, bad_path);
1170 END_PROFILE(SMBctemp);
1171 return(UNIXERROR(ERRDOS,ERRnoaccess));
1174 outsize = set_message(outbuf,1,0,True);
1175 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1177 /* the returned filename is relative to the directory */
1178 s = strrchr_m(fname, '/');
1184 p = smb_buf(outbuf);
1185 SSVALS(p, 0, -1); /* what is this? not in spec */
1186 SSVAL(p, 2, strlen(s));
1188 p += srvstr_push(outbuf, p, s, -1, STR_ASCII);
1189 outsize = set_message_end(outbuf, p);
1191 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1192 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1194 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1195 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1197 DEBUG( 2, ( "created temp file %s\n", fname ) );
1198 DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
1199 fname, fsp->fd, createmode, (int)unixmode ) );
1201 END_PROFILE(SMBctemp);
1205 /*******************************************************************
1206 Check if a user is allowed to rename a file.
1207 ********************************************************************/
1209 static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT *pst)
1215 if (!CAN_WRITE(conn))
1216 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1218 if (S_ISDIR(pst->st_mode))
1219 return NT_STATUS_OK;
1221 /* We need a better way to return NT status codes from open... */
1225 fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1226 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1229 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1230 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1231 ret = NT_STATUS_SHARING_VIOLATION;
1236 close_file(fsp,False);
1237 return NT_STATUS_OK;
1240 /*******************************************************************
1241 Check if a user is allowed to delete a file.
1242 ********************************************************************/
1244 static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
1246 SMB_STRUCT_STAT sbuf;
1252 DEBUG(10,("can_delete: %s, dirtype = %d\n",
1255 if (!CAN_WRITE(conn))
1256 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1258 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0)
1259 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1261 fmode = dos_mode(conn,fname,&sbuf);
1263 /* Can't delete a directory. */
1265 return NT_STATUS_FILE_IS_A_DIRECTORY;
1266 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
1267 return NT_STATUS_OBJECT_NAME_INVALID;
1269 if (!lp_delete_readonly(SNUM(conn))) {
1271 return NT_STATUS_CANNOT_DELETE;
1273 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1274 return NT_STATUS_NO_SUCH_FILE;
1276 /* We need a better way to return NT status codes from open... */
1280 fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1281 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1284 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1285 if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
1286 ret = unix_ERR_ntstatus;
1287 else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1288 ret = NT_STATUS_SHARING_VIOLATION;
1291 unix_ERR_ntstatus = NT_STATUS_OK;
1294 close_file(fsp,False);
1295 return NT_STATUS_OK;
1298 /****************************************************************************
1299 The guts of the unlink command, split out so it may be called by the NT SMB
1301 ****************************************************************************/
1303 NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
1309 NTSTATUS error = NT_STATUS_OK;
1311 BOOL bad_path = False;
1313 SMB_STRUCT_STAT sbuf;
1315 *directory = *mask = 0;
1317 /* We must check for wildcards in the name given
1318 * directly by the client - before any unmangling.
1319 * This prevents an unmangling of a UNIX name containing
1320 * a DOS wildcard like '*' or '?' from unmangling into
1321 * a wildcard delete which was not intended.
1322 * FIX for #226. JRA.
1325 has_wild = ms_has_wild(name);
1327 rc = unix_convert(name,conn,0,&bad_path,&sbuf);
1329 p = strrchr_m(name,'/');
1331 pstrcpy(directory,".");
1335 pstrcpy(directory,name);
1340 * We should only check the mangled cache
1341 * here if unix_convert failed. This means
1342 * that the path in 'mask' doesn't exist
1343 * on the file system and so we need to look
1344 * for a possible mangle. This patch from
1345 * Tine Smukavec <valentin.smukavec@hermes.si>.
1348 if (!rc && mangle_is_mangled(mask))
1349 mangle_check_cache( mask );
1352 pstrcat(directory,"/");
1353 pstrcat(directory,mask);
1354 error = can_delete(directory,conn,dirtype);
1355 if (!NT_STATUS_IS_OK(error))
1358 if (SMB_VFS_UNLINK(conn,directory) == 0) {
1362 void *dirptr = NULL;
1365 if (check_name(directory,conn))
1366 dirptr = OpenDir(conn, directory, True);
1368 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1369 the pattern matches against the long name, otherwise the short name
1370 We don't implement this yet XXXX
1374 error = NT_STATUS_NO_SUCH_FILE;
1376 if (strequal(mask,"????????.???"))
1379 while ((dname = ReadDirName(dirptr))) {
1381 pstrcpy(fname,dname);
1383 if(!mask_match(fname, mask, case_sensitive))
1386 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
1387 error = can_delete(fname,conn,dirtype);
1388 if (!NT_STATUS_IS_OK(error))
1390 if (SMB_VFS_UNLINK(conn,fname) == 0)
1392 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
1398 if (count == 0 && NT_STATUS_IS_OK(error)) {
1399 error = map_nt_error_from_unix(errno);
1405 /****************************************************************************
1407 ****************************************************************************/
1409 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
1416 START_PROFILE(SMBunlink);
1418 dirtype = SVAL(inbuf,smb_vwv0);
1420 srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE);
1422 status = check_path_syntax(name);
1423 if (!NT_STATUS_IS_OK(status))
1424 return ERROR_NT(status);
1426 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
1428 DEBUG(3,("reply_unlink : %s\n",name));
1430 status = unlink_internals(conn, dirtype, name);
1431 if (!NT_STATUS_IS_OK(status))
1432 return ERROR_NT(status);
1435 * Win2k needs a changenotify request response before it will
1436 * update after a rename..
1438 process_pending_change_notify_queue((time_t)0);
1440 outsize = set_message(outbuf,0,0,True);
1442 END_PROFILE(SMBunlink);
1446 /****************************************************************************
1448 ****************************************************************************/
1450 void fail_readraw(void)
1453 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
1455 exit_server(errstr);
1458 /****************************************************************************
1459 Use sendfile in readbraw.
1460 ****************************************************************************/
1462 void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
1463 ssize_t mincount, char *outbuf)
1467 #if defined(WITH_SENDFILE)
1469 * We can only use sendfile on a non-chained packet and on a file
1470 * that is exclusively oplocked. reply_readbraw has already checked the length.
1473 if ((nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) &&
1474 EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_use_sendfile(SNUM(conn)) ) {
1477 _smb_setlen(outbuf,nread);
1478 header.data = outbuf;
1482 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
1484 * Special hack for broken Linux with no 64 bit clean sendfile. If we
1485 * return ENOSYS then pretend we just got a normal read.
1487 if (errno == ENOSYS)
1490 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
1491 fsp->fsp_name, strerror(errno) ));
1492 exit_server("send_file_readbraw sendfile failed");
1501 ret = read_file(fsp,outbuf+4,startpos,nread);
1506 _smb_setlen(outbuf,ret);
1507 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
1511 /****************************************************************************
1512 Reply to a readbraw (core+ protocol).
1513 ****************************************************************************/
1515 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
1517 extern struct current_user current_user;
1518 ssize_t maxcount,mincount;
1521 char *header = outbuf;
1523 START_PROFILE(SMBreadbraw);
1525 if (srv_is_signing_active()) {
1526 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
1530 * Special check if an oplock break has been issued
1531 * and the readraw request croses on the wire, we must
1532 * return a zero length response here.
1535 if(global_oplock_break) {
1536 _smb_setlen(header,0);
1537 if (write_data(smbd_server_fd(),header,4) != 4)
1539 DEBUG(5,("readbraw - oplock break finished\n"));
1540 END_PROFILE(SMBreadbraw);
1544 fsp = file_fsp(inbuf,smb_vwv0);
1546 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
1548 * fsp could be NULL here so use the value from the packet. JRA.
1550 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
1551 _smb_setlen(header,0);
1552 if (write_data(smbd_server_fd(),header,4) != 4)
1554 END_PROFILE(SMBreadbraw);
1558 CHECK_FSP(fsp,conn);
1560 flush_write_cache(fsp, READRAW_FLUSH);
1562 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
1563 if(CVAL(inbuf,smb_wct) == 10) {
1565 * This is a large offset (64 bit) read.
1567 #ifdef LARGE_SMB_OFF_T
1569 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
1571 #else /* !LARGE_SMB_OFF_T */
1574 * Ensure we haven't been sent a >32 bit offset.
1577 if(IVAL(inbuf,smb_vwv8) != 0) {
1578 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
1579 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
1580 _smb_setlen(header,0);
1581 if (write_data(smbd_server_fd(),header,4) != 4)
1583 END_PROFILE(SMBreadbraw);
1587 #endif /* LARGE_SMB_OFF_T */
1590 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
1591 _smb_setlen(header,0);
1592 if (write_data(smbd_server_fd(),header,4) != 4)
1594 END_PROFILE(SMBreadbraw);
1598 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
1599 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
1601 /* ensure we don't overrun the packet size */
1602 maxcount = MIN(65535,maxcount);
1603 maxcount = MAX(mincount,maxcount);
1605 if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1606 SMB_OFF_T size = fsp->size;
1607 SMB_OFF_T sizeneeded = startpos + maxcount;
1609 if (size < sizeneeded) {
1611 if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
1613 if (!fsp->can_write)
1617 if (startpos >= size)
1620 nread = MIN(maxcount,(size - startpos));
1623 if (nread < mincount)
1626 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
1627 (int)maxcount, (int)mincount, (int)nread ) );
1629 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf);
1631 DEBUG(5,("readbraw finished\n"));
1632 END_PROFILE(SMBreadbraw);
1636 /****************************************************************************
1637 Reply to a lockread (core+ protocol).
1638 ****************************************************************************/
1640 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
1648 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1649 START_PROFILE(SMBlockread);
1651 CHECK_FSP(fsp,conn);
1654 release_level_2_oplocks_on_change(fsp);
1656 numtoread = SVAL(inbuf,smb_vwv1);
1657 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1659 outsize = set_message(outbuf,5,3,True);
1660 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1661 data = smb_buf(outbuf) + 3;
1664 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
1665 * protocol request that predates the read/write lock concept.
1666 * Thus instead of asking for a read lock here we need to ask
1667 * for a write lock. JRA.
1670 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
1671 (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK);
1673 if (NT_STATUS_V(status)) {
1674 if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
1676 * A blocking lock was requested. Package up
1677 * this smb into a queued request and push it
1678 * onto the blocking lock queue.
1680 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)startpos,
1681 (SMB_BIG_UINT)numtoread)) {
1682 END_PROFILE(SMBlockread);
1686 END_PROFILE(SMBlockread);
1687 return ERROR_NT(status);
1690 nread = read_file(fsp,data,startpos,numtoread);
1693 END_PROFILE(SMBlockread);
1694 return(UNIXERROR(ERRDOS,ERRnoaccess));
1698 SSVAL(outbuf,smb_vwv0,nread);
1699 SSVAL(outbuf,smb_vwv5,nread+3);
1700 SSVAL(smb_buf(outbuf),1,nread);
1702 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
1703 fsp->fnum, (int)numtoread, (int)nread));
1705 END_PROFILE(SMBlockread);
1709 /****************************************************************************
1711 ****************************************************************************/
1713 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
1720 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1721 START_PROFILE(SMBread);
1723 CHECK_FSP(fsp,conn);
1726 numtoread = SVAL(inbuf,smb_vwv1);
1727 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1729 outsize = set_message(outbuf,5,3,True);
1730 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1731 data = smb_buf(outbuf) + 3;
1733 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1734 END_PROFILE(SMBread);
1735 return ERROR_DOS(ERRDOS,ERRlock);
1739 nread = read_file(fsp,data,startpos,numtoread);
1742 END_PROFILE(SMBread);
1743 return(UNIXERROR(ERRDOS,ERRnoaccess));
1747 SSVAL(outbuf,smb_vwv0,nread);
1748 SSVAL(outbuf,smb_vwv5,nread+3);
1749 SCVAL(smb_buf(outbuf),0,1);
1750 SSVAL(smb_buf(outbuf),1,nread);
1752 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
1753 fsp->fnum, (int)numtoread, (int)nread ) );
1755 END_PROFILE(SMBread);
1759 /****************************************************************************
1760 Reply to a read and X - possibly using sendfile.
1761 ****************************************************************************/
1763 int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length,
1764 files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
1767 char *data = smb_buf(outbuf);
1769 #if defined(WITH_SENDFILE)
1771 * We can only use sendfile on a non-chained packet and on a file
1772 * that is exclusively oplocked.
1775 if ((CVAL(inbuf,smb_vwv0) == 0xFF) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
1776 lp_use_sendfile(SNUM(conn)) && (lp_write_cache_size(SNUM(conn)) == 0) ) {
1777 SMB_STRUCT_STAT sbuf;
1780 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
1781 return(UNIXERROR(ERRDOS,ERRnoaccess));
1783 if (startpos > sbuf.st_size)
1786 if (smb_maxcnt > (sbuf.st_size - startpos))
1787 smb_maxcnt = (sbuf.st_size - startpos);
1789 if (smb_maxcnt == 0)
1793 * Set up the packet header before send. We
1794 * assume here the sendfile will work (get the
1795 * correct amount of data).
1798 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
1799 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
1800 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
1801 SCVAL(outbuf,smb_vwv0,0xFF);
1802 set_message(outbuf,12,smb_maxcnt,False);
1803 header.data = outbuf;
1804 header.length = data - outbuf;
1807 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
1809 * Special hack for broken Linux with no 64 bit clean sendfile. If we
1810 * return ENOSYS then pretend we just got a normal read.
1812 if (errno == ENOSYS)
1815 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
1816 fsp->fsp_name, strerror(errno) ));
1817 exit_server("send_file_readX sendfile failed");
1820 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
1821 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
1829 nread = read_file(fsp,data,startpos,smb_maxcnt);
1832 END_PROFILE(SMBreadX);
1833 return(UNIXERROR(ERRDOS,ERRnoaccess));
1836 SSVAL(outbuf,smb_vwv5,nread);
1837 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
1838 SSVAL(smb_buf(outbuf),-2,nread);
1840 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
1841 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
1846 /****************************************************************************
1847 Reply to a read and X.
1848 ****************************************************************************/
1850 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1852 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
1853 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
1855 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
1857 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
1860 START_PROFILE(SMBreadX);
1862 /* If it's an IPC, pass off the pipe handler. */
1864 END_PROFILE(SMBreadX);
1865 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
1868 CHECK_FSP(fsp,conn);
1871 set_message(outbuf,12,0,True);
1873 if(CVAL(inbuf,smb_wct) == 12) {
1874 #ifdef LARGE_SMB_OFF_T
1876 * This is a large offset (64 bit) read.
1878 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
1880 #else /* !LARGE_SMB_OFF_T */
1883 * Ensure we haven't been sent a >32 bit offset.
1886 if(IVAL(inbuf,smb_vwv10) != 0) {
1887 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
1888 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
1889 END_PROFILE(SMBreadX);
1890 return ERROR_DOS(ERRDOS,ERRbadaccess);
1893 #endif /* LARGE_SMB_OFF_T */
1897 if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1898 END_PROFILE(SMBreadX);
1899 return ERROR_DOS(ERRDOS,ERRlock);
1902 nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt);
1904 nread = chain_reply(inbuf,outbuf,length,bufsize);
1906 END_PROFILE(SMBreadX);
1910 /****************************************************************************
1911 Reply to a writebraw (core+ or LANMAN1.0 protocol).
1912 ****************************************************************************/
1914 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
1917 ssize_t total_written=0;
1918 size_t numtowrite=0;
1923 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1925 START_PROFILE(SMBwritebraw);
1927 if (srv_is_signing_active()) {
1928 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
1931 CHECK_FSP(fsp,conn);
1934 tcount = IVAL(inbuf,smb_vwv1);
1935 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
1936 write_through = BITSETW(inbuf+smb_vwv7,0);
1938 /* We have to deal with slightly different formats depending
1939 on whether we are using the core+ or lanman1.0 protocol */
1941 if(Protocol <= PROTOCOL_COREPLUS) {
1942 numtowrite = SVAL(smb_buf(inbuf),-2);
1943 data = smb_buf(inbuf);
1945 numtowrite = SVAL(inbuf,smb_vwv10);
1946 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
1949 /* force the error type */
1950 SCVAL(inbuf,smb_com,SMBwritec);
1951 SCVAL(outbuf,smb_com,SMBwritec);
1953 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
1954 END_PROFILE(SMBwritebraw);
1955 return(ERROR_DOS(ERRDOS,ERRlock));
1959 nwritten = write_file(fsp,data,startpos,numtowrite);
1961 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
1962 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
1964 if (nwritten < (ssize_t)numtowrite) {
1965 END_PROFILE(SMBwritebraw);
1966 return(UNIXERROR(ERRHRD,ERRdiskfull));
1969 total_written = nwritten;
1971 /* Return a message to the redirector to tell it to send more bytes */
1972 SCVAL(outbuf,smb_com,SMBwritebraw);
1973 SSVALS(outbuf,smb_vwv0,-1);
1974 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
1975 if (!send_smb(smbd_server_fd(),outbuf))
1976 exit_server("reply_writebraw: send_smb failed.");
1978 /* Now read the raw data into the buffer and write it */
1979 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
1980 exit_server("secondary writebraw failed");
1983 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
1984 numtowrite = smb_len(inbuf);
1986 /* Set up outbuf to return the correct return */
1987 outsize = set_message(outbuf,1,0,True);
1988 SCVAL(outbuf,smb_com,SMBwritec);
1989 SSVAL(outbuf,smb_vwv0,total_written);
1991 if (numtowrite != 0) {
1993 if (numtowrite > BUFFER_SIZE) {
1994 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
1995 (unsigned int)numtowrite ));
1996 exit_server("secondary writebraw failed");
1999 if (tcount > nwritten+numtowrite) {
2000 DEBUG(3,("Client overestimated the write %d %d %d\n",
2001 (int)tcount,(int)nwritten,(int)numtowrite));
2004 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
2005 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2007 exit_server("secondary writebraw failed");
2010 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
2012 if (nwritten < (ssize_t)numtowrite) {
2013 SCVAL(outbuf,smb_rcls,ERRHRD);
2014 SSVAL(outbuf,smb_err,ERRdiskfull);
2018 total_written += nwritten;
2021 if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
2022 sync_file(conn,fsp);
2024 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2025 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2027 /* we won't return a status if write through is not selected - this follows what WfWg does */
2028 END_PROFILE(SMBwritebraw);
2029 if (!write_through && total_written==tcount) {
2031 #if RABBIT_PELLET_FIX
2033 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2034 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2036 if (!send_keepalive(smbd_server_fd()))
2037 exit_server("reply_writebraw: send of keepalive failed");
2045 /****************************************************************************
2046 Reply to a writeunlock (core+).
2047 ****************************************************************************/
2049 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
2050 int size, int dum_buffsize)
2052 ssize_t nwritten = -1;
2057 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2059 START_PROFILE(SMBwriteunlock);
2061 CHECK_FSP(fsp,conn);
2064 numtowrite = SVAL(inbuf,smb_vwv1);
2065 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2066 data = smb_buf(inbuf) + 3;
2068 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
2069 WRITE_LOCK,False)) {
2070 END_PROFILE(SMBwriteunlock);
2071 return ERROR_DOS(ERRDOS,ERRlock);
2074 /* The special X/Open SMB protocol handling of
2075 zero length writes is *NOT* done for
2080 nwritten = write_file(fsp,data,startpos,numtowrite);
2082 if (lp_syncalways(SNUM(conn)))
2083 sync_file(conn,fsp);
2085 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2086 END_PROFILE(SMBwriteunlock);
2087 return(UNIXERROR(ERRHRD,ERRdiskfull));
2090 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
2091 (SMB_BIG_UINT)startpos);
2092 if (NT_STATUS_V(status)) {
2093 END_PROFILE(SMBwriteunlock);
2094 return ERROR_NT(status);
2097 outsize = set_message(outbuf,1,0,True);
2099 SSVAL(outbuf,smb_vwv0,nwritten);
2101 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2102 fsp->fnum, (int)numtowrite, (int)nwritten));
2104 END_PROFILE(SMBwriteunlock);
2108 /****************************************************************************
2110 ****************************************************************************/
2112 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
2115 ssize_t nwritten = -1;
2118 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2120 START_PROFILE(SMBwrite);
2122 /* If it's an IPC, pass off the pipe handler. */
2124 END_PROFILE(SMBwrite);
2125 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
2128 CHECK_FSP(fsp,conn);
2131 numtowrite = SVAL(inbuf,smb_vwv1);
2132 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2133 data = smb_buf(inbuf) + 3;
2135 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2136 END_PROFILE(SMBwrite);
2137 return ERROR_DOS(ERRDOS,ERRlock);
2141 * X/Open SMB protocol says that if smb_vwv1 is
2142 * zero then the file size should be extended or
2143 * truncated to the size given in smb_vwv[2-3].
2146 if(numtowrite == 0) {
2148 * This is actually an allocate call, and set EOF. JRA.
2150 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
2152 END_PROFILE(SMBwrite);
2153 return ERROR_NT(NT_STATUS_DISK_FULL);
2155 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
2157 END_PROFILE(SMBwrite);
2158 return ERROR_NT(NT_STATUS_DISK_FULL);
2161 nwritten = write_file(fsp,data,startpos,numtowrite);
2163 if (lp_syncalways(SNUM(conn)))
2164 sync_file(conn,fsp);
2166 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2167 END_PROFILE(SMBwrite);
2168 return(UNIXERROR(ERRHRD,ERRdiskfull));
2171 outsize = set_message(outbuf,1,0,True);
2173 SSVAL(outbuf,smb_vwv0,nwritten);
2175 if (nwritten < (ssize_t)numtowrite) {
2176 SCVAL(outbuf,smb_rcls,ERRHRD);
2177 SSVAL(outbuf,smb_err,ERRdiskfull);
2180 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
2182 END_PROFILE(SMBwrite);
2186 /****************************************************************************
2187 Reply to a write and X.
2188 ****************************************************************************/
2190 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2192 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2193 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2194 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2195 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2196 ssize_t nwritten = -1;
2197 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
2198 unsigned int smblen = smb_len(inbuf);
2200 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
2201 START_PROFILE(SMBwriteX);
2203 /* If it's an IPC, pass off the pipe handler. */
2205 END_PROFILE(SMBwriteX);
2206 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2209 CHECK_FSP(fsp,conn);
2212 /* Deal with possible LARGE_WRITEX */
2214 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
2216 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
2217 END_PROFILE(SMBwriteX);
2218 return ERROR_DOS(ERRDOS,ERRbadmem);
2221 data = smb_base(inbuf) + smb_doff;
2223 if(CVAL(inbuf,smb_wct) == 14) {
2224 #ifdef LARGE_SMB_OFF_T
2226 * This is a large offset (64 bit) write.
2228 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2230 #else /* !LARGE_SMB_OFF_T */
2233 * Ensure we haven't been sent a >32 bit offset.
2236 if(IVAL(inbuf,smb_vwv12) != 0) {
2237 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
2238 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
2239 END_PROFILE(SMBwriteX);
2240 return ERROR_DOS(ERRDOS,ERRbadaccess);
2243 #endif /* LARGE_SMB_OFF_T */
2246 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2247 END_PROFILE(SMBwriteX);
2248 return ERROR_DOS(ERRDOS,ERRlock);
2251 /* X/Open SMB protocol says that, unlike SMBwrite
2252 if the length is zero then NO truncation is
2253 done, just a write of zero. To truncate a file,
2259 nwritten = write_file(fsp,data,startpos,numtowrite);
2261 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2262 END_PROFILE(SMBwriteX);
2263 return(UNIXERROR(ERRHRD,ERRdiskfull));
2266 set_message(outbuf,6,0,True);
2268 SSVAL(outbuf,smb_vwv2,nwritten);
2270 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
2272 if (nwritten < (ssize_t)numtowrite) {
2273 SCVAL(outbuf,smb_rcls,ERRHRD);
2274 SSVAL(outbuf,smb_err,ERRdiskfull);
2277 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2278 fsp->fnum, (int)numtowrite, (int)nwritten));
2280 if (lp_syncalways(SNUM(conn)) || write_through)
2281 sync_file(conn,fsp);
2283 END_PROFILE(SMBwriteX);
2284 return chain_reply(inbuf,outbuf,length,bufsize);
2287 /****************************************************************************
2289 ****************************************************************************/
2291 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2297 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2298 START_PROFILE(SMBlseek);
2300 CHECK_FSP(fsp,conn);
2302 flush_write_cache(fsp, SEEK_FLUSH);
2304 mode = SVAL(inbuf,smb_vwv1) & 3;
2305 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
2306 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
2315 res = fsp->pos + startpos;
2326 if (umode == SEEK_END) {
2327 if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
2328 if(errno == EINVAL) {
2329 SMB_OFF_T current_pos = startpos;
2330 SMB_STRUCT_STAT sbuf;
2332 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
2333 END_PROFILE(SMBlseek);
2334 return(UNIXERROR(ERRDOS,ERRnoaccess));
2337 current_pos += sbuf.st_size;
2339 res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
2344 END_PROFILE(SMBlseek);
2345 return(UNIXERROR(ERRDOS,ERRnoaccess));
2351 outsize = set_message(outbuf,2,0,True);
2352 SIVAL(outbuf,smb_vwv0,res);
2354 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2355 fsp->fnum, (double)startpos, (double)res, mode));
2357 END_PROFILE(SMBlseek);
2361 /****************************************************************************
2363 ****************************************************************************/
2365 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2367 int outsize = set_message(outbuf,0,0,True);
2368 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2369 START_PROFILE(SMBflush);
2371 CHECK_FSP(fsp,conn);
2374 file_sync_all(conn);
2376 sync_file(conn,fsp);
2379 DEBUG(3,("flush\n"));
2380 END_PROFILE(SMBflush);
2384 /****************************************************************************
2386 ****************************************************************************/
2388 int reply_exit(connection_struct *conn,
2389 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2392 START_PROFILE(SMBexit);
2393 outsize = set_message(outbuf,0,0,True);
2395 DEBUG(3,("exit\n"));
2397 END_PROFILE(SMBexit);
2401 /****************************************************************************
2402 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2403 ****************************************************************************/
2405 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
2408 extern struct current_user current_user;
2411 int32 eclass = 0, err = 0;
2412 files_struct *fsp = NULL;
2413 START_PROFILE(SMBclose);
2415 outsize = set_message(outbuf,0,0,True);
2417 /* If it's an IPC, pass off to the pipe handler. */
2419 END_PROFILE(SMBclose);
2420 return reply_pipe_close(conn, inbuf,outbuf);
2423 fsp = file_fsp(inbuf,smb_vwv0);
2426 * We can only use CHECK_FSP if we know it's not a directory.
2429 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
2430 END_PROFILE(SMBclose);
2431 return ERROR_DOS(ERRDOS,ERRbadfid);
2434 if(fsp->is_directory) {
2436 * Special case - close NT SMB directory handle.
2438 DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
2439 close_file(fsp,True);
2442 * Close ordinary file.
2447 /* Save the name for time set in close. */
2448 pstrcpy( file_name, fsp->fsp_name);
2450 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2452 conn->num_files_open));
2455 * close_file() returns the unix errno if an error
2456 * was detected on close - normally this is due to
2457 * a disk full error. If not then it was probably an I/O error.
2460 if((close_err = close_file(fsp,True)) != 0) {
2462 END_PROFILE(SMBclose);
2463 return (UNIXERROR(ERRHRD,ERRgeneral));
2467 * Now take care of any time sent in the close.
2470 mtime = make_unix_date3(inbuf+smb_vwv1);
2472 /* try and set the date */
2473 set_filetime(conn, file_name, mtime);
2477 /* We have a cached error */
2479 END_PROFILE(SMBclose);
2480 return ERROR_DOS(eclass,err);
2483 END_PROFILE(SMBclose);
2487 /****************************************************************************
2488 Reply to a writeclose (Core+ protocol).
2489 ****************************************************************************/
2491 int reply_writeclose(connection_struct *conn,
2492 char *inbuf,char *outbuf, int size, int dum_buffsize)
2495 ssize_t nwritten = -1;
2501 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2502 START_PROFILE(SMBwriteclose);
2504 CHECK_FSP(fsp,conn);
2507 numtowrite = SVAL(inbuf,smb_vwv1);
2508 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2509 mtime = make_unix_date3(inbuf+smb_vwv4);
2510 data = smb_buf(inbuf) + 1;
2512 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2513 END_PROFILE(SMBwriteclose);
2514 return ERROR_DOS(ERRDOS,ERRlock);
2517 nwritten = write_file(fsp,data,startpos,numtowrite);
2519 set_filetime(conn, fsp->fsp_name,mtime);
2521 close_err = close_file(fsp,True);
2523 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2524 fsp->fnum, (int)numtowrite, (int)nwritten,
2525 conn->num_files_open));
2527 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2528 END_PROFILE(SMBwriteclose);
2529 return(UNIXERROR(ERRHRD,ERRdiskfull));
2532 if(close_err != 0) {
2534 END_PROFILE(SMBwriteclose);
2535 return(UNIXERROR(ERRHRD,ERRgeneral));
2538 outsize = set_message(outbuf,1,0,True);
2540 SSVAL(outbuf,smb_vwv0,nwritten);
2541 END_PROFILE(SMBwriteclose);
2545 /****************************************************************************
2547 ****************************************************************************/
2549 int reply_lock(connection_struct *conn,
2550 char *inbuf,char *outbuf, int length, int dum_buffsize)
2552 int outsize = set_message(outbuf,0,0,True);
2553 SMB_BIG_UINT count,offset;
2555 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2556 START_PROFILE(SMBlock);
2558 CHECK_FSP(fsp,conn);
2560 release_level_2_oplocks_on_change(fsp);
2562 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2563 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2565 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2566 fsp->fd, fsp->fnum, (double)offset, (double)count));
2568 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK);
2569 if (NT_STATUS_V(status)) {
2570 if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
2572 * A blocking lock was requested. Package up
2573 * this smb into a queued request and push it
2574 * onto the blocking lock queue.
2576 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), offset, count)) {
2577 END_PROFILE(SMBlock);
2581 END_PROFILE(SMBlock);
2582 return ERROR_NT(status);
2585 END_PROFILE(SMBlock);
2589 /****************************************************************************
2591 ****************************************************************************/
2593 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
2596 int outsize = set_message(outbuf,0,0,True);
2597 SMB_BIG_UINT count,offset;
2599 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2600 START_PROFILE(SMBunlock);
2602 CHECK_FSP(fsp,conn);
2604 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2605 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2607 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
2608 if (NT_STATUS_V(status)) {
2609 END_PROFILE(SMBunlock);
2610 return ERROR_NT(status);
2613 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2614 fsp->fd, fsp->fnum, (double)offset, (double)count ) );
2616 END_PROFILE(SMBunlock);
2620 /****************************************************************************
2622 ****************************************************************************/
2624 int reply_tdis(connection_struct *conn,
2625 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2627 int outsize = set_message(outbuf,0,0,True);
2629 START_PROFILE(SMBtdis);
2631 vuid = SVAL(inbuf,smb_uid);
2634 DEBUG(4,("Invalid connection in tdis\n"));
2635 END_PROFILE(SMBtdis);
2636 return ERROR_DOS(ERRSRV,ERRinvnid);
2641 close_cnum(conn,vuid);
2643 END_PROFILE(SMBtdis);
2647 /****************************************************************************
2649 ****************************************************************************/
2651 int reply_echo(connection_struct *conn,
2652 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2654 int smb_reverb = SVAL(inbuf,smb_vwv0);
2656 unsigned int data_len = smb_buflen(inbuf);
2657 int outsize = set_message(outbuf,1,data_len,True);
2658 START_PROFILE(SMBecho);
2660 data_len = MIN(data_len, (sizeof(inbuf)-(smb_buf(inbuf)-inbuf)));
2662 /* copy any incoming data back out */
2664 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
2666 if (smb_reverb > 100) {
2667 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
2671 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
2672 SSVAL(outbuf,smb_vwv0,seq_num);
2674 smb_setlen(outbuf,outsize - 4);
2676 if (!send_smb(smbd_server_fd(),outbuf))
2677 exit_server("reply_echo: send_smb failed.");
2680 DEBUG(3,("echo %d times\n", smb_reverb));
2684 END_PROFILE(SMBecho);
2688 /****************************************************************************
2689 Reply to a printopen.
2690 ****************************************************************************/
2692 int reply_printopen(connection_struct *conn,
2693 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2697 START_PROFILE(SMBsplopen);
2699 if (!CAN_PRINT(conn)) {
2700 END_PROFILE(SMBsplopen);
2701 return ERROR_DOS(ERRDOS,ERRnoaccess);
2704 /* Open for exclusive use, write only. */
2705 fsp = print_fsp_open(conn, NULL);
2708 END_PROFILE(SMBsplopen);
2709 return(UNIXERROR(ERRDOS,ERRnoaccess));
2712 outsize = set_message(outbuf,1,0,True);
2713 SSVAL(outbuf,smb_vwv0,fsp->fnum);
2715 DEBUG(3,("openprint fd=%d fnum=%d\n",
2716 fsp->fd, fsp->fnum));
2718 END_PROFILE(SMBsplopen);
2722 /****************************************************************************
2723 Reply to a printclose.
2724 ****************************************************************************/
2726 int reply_printclose(connection_struct *conn,
2727 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2729 int outsize = set_message(outbuf,0,0,True);
2730 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2732 START_PROFILE(SMBsplclose);
2734 CHECK_FSP(fsp,conn);
2736 if (!CAN_PRINT(conn)) {
2737 END_PROFILE(SMBsplclose);
2738 return ERROR_DOS(ERRDOS,ERRnoaccess);
2741 DEBUG(3,("printclose fd=%d fnum=%d\n",
2742 fsp->fd,fsp->fnum));
2744 close_err = close_file(fsp,True);
2746 if(close_err != 0) {
2748 END_PROFILE(SMBsplclose);
2749 return(UNIXERROR(ERRHRD,ERRgeneral));
2752 END_PROFILE(SMBsplclose);
2756 /****************************************************************************
2757 Reply to a printqueue.
2758 ****************************************************************************/
2760 int reply_printqueue(connection_struct *conn,
2761 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2763 int outsize = set_message(outbuf,2,3,True);
2764 int max_count = SVAL(inbuf,smb_vwv0);
2765 int start_index = SVAL(inbuf,smb_vwv1);
2766 START_PROFILE(SMBsplretq);
2768 /* we used to allow the client to get the cnum wrong, but that
2769 is really quite gross and only worked when there was only
2770 one printer - I think we should now only accept it if they
2771 get it right (tridge) */
2772 if (!CAN_PRINT(conn)) {
2773 END_PROFILE(SMBsplretq);
2774 return ERROR_DOS(ERRDOS,ERRnoaccess);
2777 SSVAL(outbuf,smb_vwv0,0);
2778 SSVAL(outbuf,smb_vwv1,0);
2779 SCVAL(smb_buf(outbuf),0,1);
2780 SSVAL(smb_buf(outbuf),1,0);
2782 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
2783 start_index, max_count));
2786 print_queue_struct *queue = NULL;
2787 print_status_struct status;
2788 char *p = smb_buf(outbuf) + 3;
2789 int count = print_queue_status(SNUM(conn), &queue, &status);
2790 int num_to_get = ABS(max_count);
2791 int first = (max_count>0?start_index:start_index+max_count+1);
2797 num_to_get = MIN(num_to_get,count-first);
2800 for (i=first;i<first+num_to_get;i++) {
2801 put_dos_date2(p,0,queue[i].time);
2802 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
2803 SSVAL(p,5, queue[i].job);
2804 SIVAL(p,7,queue[i].size);
2806 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
2811 outsize = set_message(outbuf,2,28*count+3,False);
2812 SSVAL(outbuf,smb_vwv0,count);
2813 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
2814 SCVAL(smb_buf(outbuf),0,1);
2815 SSVAL(smb_buf(outbuf),1,28*count);
2820 DEBUG(3,("%d entries returned in queue\n",count));
2823 END_PROFILE(SMBsplretq);
2827 /****************************************************************************
2828 Reply to a printwrite.
2829 ****************************************************************************/
2831 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2834 int outsize = set_message(outbuf,0,0,True);
2836 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2838 START_PROFILE(SMBsplwr);
2840 if (!CAN_PRINT(conn)) {
2841 END_PROFILE(SMBsplwr);
2842 return ERROR_DOS(ERRDOS,ERRnoaccess);
2845 CHECK_FSP(fsp,conn);
2848 numtowrite = SVAL(smb_buf(inbuf),1);
2849 data = smb_buf(inbuf) + 3;
2851 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
2852 END_PROFILE(SMBsplwr);
2853 return(UNIXERROR(ERRHRD,ERRdiskfull));
2856 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
2858 END_PROFILE(SMBsplwr);
2862 /****************************************************************************
2863 The guts of the mkdir command, split out so it may be called by the NT SMB
2865 ****************************************************************************/
2867 NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
2869 BOOL bad_path = False;
2870 SMB_STRUCT_STAT sbuf;
2873 unix_convert(directory,conn,0,&bad_path,&sbuf);
2875 if (ms_has_wild(directory)) {
2876 return NT_STATUS_OBJECT_NAME_INVALID;
2879 if (check_name(directory, conn))
2880 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
2883 NTSTATUS nterr = set_bad_path_error(errno, bad_path);
2884 if (!NT_STATUS_IS_OK(nterr))
2886 return map_nt_error_from_unix(errno);
2889 return NT_STATUS_OK;
2892 /****************************************************************************
2894 ****************************************************************************/
2896 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2901 START_PROFILE(SMBmkdir);
2903 srvstr_pull_buf(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE);
2905 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
2907 status = mkdir_internal(conn, directory);
2908 if (!NT_STATUS_IS_OK(status))
2909 return ERROR_NT(status);
2911 outsize = set_message(outbuf,0,0,True);
2913 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
2915 END_PROFILE(SMBmkdir);
2919 /****************************************************************************
2920 Static function used by reply_rmdir to delete an entire directory
2921 tree recursively. Return False on ok, True on fail.
2922 ****************************************************************************/
2924 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
2926 const char *dname = NULL;
2928 void *dirptr = OpenDir(conn, directory, False);
2933 while((dname = ReadDirName(dirptr))) {
2937 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
2940 /* Construct the full name. */
2941 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
2947 pstrcpy(fullname, directory);
2948 pstrcat(fullname, "/");
2949 pstrcat(fullname, dname);
2951 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
2956 if(st.st_mode & S_IFDIR) {
2957 if(recursive_rmdir(conn, fullname)!=0) {
2961 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
2965 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
2974 /****************************************************************************
2975 The internals of the rmdir code - called elsewhere.
2976 ****************************************************************************/
2978 BOOL rmdir_internals(connection_struct *conn, char *directory)
2982 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
2983 if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
2985 * Check to see if the only thing in this directory are
2986 * vetoed files/directories. If so then delete them and
2987 * retry. If we fail to delete any of them (and we *don't*
2988 * do a recursive delete) then fail the rmdir.
2990 BOOL all_veto_files = True;
2992 void *dirptr = OpenDir(conn, directory, False);
2994 if(dirptr != NULL) {
2995 int dirpos = TellDir(dirptr);
2996 while ((dname = ReadDirName(dirptr))) {
2997 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
2999 if(!IS_VETO_PATH(conn, dname)) {
3000 all_veto_files = False;
3005 if(all_veto_files) {
3006 SeekDir(dirptr,dirpos);
3007 while ((dname = ReadDirName(dirptr))) {
3011 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3014 /* Construct the full name. */
3015 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3020 pstrcpy(fullname, directory);
3021 pstrcat(fullname, "/");
3022 pstrcat(fullname, dname);
3024 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
3026 if(st.st_mode & S_IFDIR) {
3027 if(lp_recursive_veto_delete(SNUM(conn))) {
3028 if(recursive_rmdir(conn, fullname) != 0)
3031 if(SMB_VFS_RMDIR(conn,fullname) != 0)
3033 } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
3037 /* Retry the rmdir */
3038 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3048 DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory,strerror(errno)));
3053 /****************************************************************************
3055 ****************************************************************************/
3057 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3062 BOOL bad_path = False;
3063 SMB_STRUCT_STAT sbuf;
3064 START_PROFILE(SMBrmdir);
3066 srvstr_pull_buf(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE);
3068 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
3070 unix_convert(directory,conn, NULL,&bad_path,&sbuf);
3072 if (check_name(directory,conn)) {
3073 dptr_closepath(directory,SVAL(inbuf,smb_pid));
3074 ok = rmdir_internals(conn, directory);
3078 set_bad_path_error(errno, bad_path);
3079 END_PROFILE(SMBrmdir);
3080 return(UNIXERROR(ERRDOS,ERRbadpath));
3083 outsize = set_message(outbuf,0,0,True);
3085 DEBUG( 3, ( "rmdir %s\n", directory ) );
3087 END_PROFILE(SMBrmdir);
3091 /*******************************************************************
3092 Resolve wildcards in a filename rename.
3093 ********************************************************************/
3095 static BOOL resolve_wildcards(const char *name1, char *name2)
3097 fstring root1,root2;
3099 char *p,*p2, *pname1, *pname2;
3100 int available_space;
3103 pname1 = strrchr_m(name1,'/');
3104 pname2 = strrchr_m(name2,'/');
3106 if (!pname1 || !pname2)
3109 fstrcpy(root1,pname1);
3110 fstrcpy(root2,pname2);
3111 p = strrchr_m(root1,'.');
3118 p = strrchr_m(root2,'.');
3152 available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
3155 snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
3157 pstrcpy_base(pname2, root2, name2);
3163 /****************************************************************************
3164 The guts of the rename command, split out so it may be called by the NT SMB
3166 ****************************************************************************/
3168 NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists)
3172 pstring newname_last_component;
3175 BOOL bad_path1 = False;
3176 BOOL bad_path2 = False;
3178 NTSTATUS error = NT_STATUS_OK;
3180 SMB_STRUCT_STAT sbuf1, sbuf2;
3182 *directory = *mask = 0;
3184 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
3185 unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2);
3188 * Split the old name into directory and last component
3189 * strings. Note that unix_convert may have stripped off a
3190 * leading ./ from both name and newname if the rename is
3191 * at the root of the share. We need to make sure either both
3192 * name and newname contain a / character or neither of them do
3193 * as this is checked in resolve_wildcards().
3196 p = strrchr_m(name,'/');
3198 pstrcpy(directory,".");
3202 pstrcpy(directory,name);
3204 *p = '/'; /* Replace needed for exceptional test below. */
3208 * We should only check the mangled cache
3209 * here if unix_convert failed. This means
3210 * that the path in 'mask' doesn't exist
3211 * on the file system and so we need to look
3212 * for a possible mangle. This patch from
3213 * Tine Smukavec <valentin.smukavec@hermes.si>.
3216 if (!rc && mangle_is_mangled(mask))
3217 mangle_check_cache( mask );
3219 has_wild = ms_has_wild(mask);
3223 * No wildcards - just process the one file.
3225 BOOL is_short_name = mangle_is_8_3(name, True);
3227 /* Add a terminating '/' to the directory name. */
3228 pstrcat(directory,"/");
3229 pstrcat(directory,mask);
3231 /* Ensure newname contains a '/' also */
3232 if(strrchr_m(newname,'/') == 0) {
3235 pstrcpy(tmpstr, "./");
3236 pstrcat(tmpstr, newname);
3237 pstrcpy(newname, tmpstr);
3240 DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
3241 directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
3242 case_sensitive, case_preserve, short_case_preserve, directory,
3243 newname, newname_last_component, is_short_name));
3246 * Check for special case with case preserving and not
3247 * case sensitive, if directory and newname are identical,
3248 * and the old last component differs from the original
3249 * last component only by case, then we should allow
3250 * the rename (user is trying to change the case of the
3253 if((case_sensitive == False) &&
3254 (((case_preserve == True) &&
3255 (is_short_name == False)) ||
3256 ((short_case_preserve == True) &&
3257 (is_short_name == True))) &&
3258 strcsequal(directory, newname)) {
3259 pstring newname_modified_last_component;
3262 * Get the last component of the modified name.
3263 * Note that we guarantee that newname contains a '/'
3266 p = strrchr_m(newname,'/');
3267 pstrcpy(newname_modified_last_component,p+1);
3269 if(strcsequal(newname_modified_last_component,
3270 newname_last_component) == False) {
3272 * Replace the modified last component with
3275 pstrcpy(p+1, newname_last_component);
3279 resolve_wildcards(directory,newname);
3282 * The source object must exist.
3285 if (!vfs_object_exist(conn, directory, &sbuf1)) {
3286 DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
3287 directory,newname));
3289 if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
3291 * Must return different errors depending on whether the parent
3292 * directory existed or not.
3295 p = strrchr_m(directory, '/');
3297 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3299 if (vfs_object_exist(conn, directory, NULL))
3300 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3301 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3303 error = map_nt_error_from_unix(errno);
3304 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3305 nt_errstr(error), directory,newname));
3310 error = can_rename(directory,conn,&sbuf1);
3312 if (!NT_STATUS_IS_OK(error)) {
3313 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3314 nt_errstr(error), directory,newname));
3319 * If the src and dest names are identical - including case,
3320 * don't do the rename, just return success.
3323 if (strcsequal(directory, newname)) {
3324 DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
3325 return NT_STATUS_OK;
3328 if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
3329 DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
3330 directory,newname));
3331 return NT_STATUS_OBJECT_NAME_COLLISION;
3334 if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
3335 DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
3336 directory,newname));
3337 return NT_STATUS_OK;
3340 if (errno == ENOTDIR || errno == EISDIR)
3341 error = NT_STATUS_OBJECT_NAME_COLLISION;
3343 error = map_nt_error_from_unix(errno);
3345 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3346 nt_errstr(error), directory,newname));
3351 * Wildcards - process each file that matches.
3353 void *dirptr = NULL;
3357 if (check_name(directory,conn))
3358 dirptr = OpenDir(conn, directory, True);
3361 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3363 if (strequal(mask,"????????.???"))
3366 while ((dname = ReadDirName(dirptr))) {
3369 pstrcpy(fname,dname);
3371 if(!mask_match(fname, mask, case_sensitive))
3374 error = NT_STATUS_ACCESS_DENIED;
3375 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
3376 if (!vfs_object_exist(conn, fname, &sbuf1)) {
3377 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3378 DEBUG(6,("rename %s failed. Error %s\n", fname, nt_errstr(error)));
3381 error = can_rename(fname,conn,&sbuf1);
3382 if (!NT_STATUS_IS_OK(error)) {
3383 DEBUG(6,("rename %s refused\n", fname));
3386 pstrcpy(destname,newname);
3388 if (!resolve_wildcards(fname,destname)) {
3389 DEBUG(6,("resolve_wildcards %s %s failed\n",
3394 if (!replace_if_exists &&
3395 vfs_file_exist(conn,destname, NULL)) {
3396 DEBUG(6,("file_exist %s\n", destname));
3397 error = NT_STATUS_OBJECT_NAME_COLLISION;
3401 if (!SMB_VFS_RENAME(conn,fname,destname))
3403 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
3409 if (count == 0 && NT_STATUS_IS_OK(error)) {
3410 error = map_nt_error_from_unix(errno);
3416 /****************************************************************************
3418 ****************************************************************************/
3420 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
3429 START_PROFILE(SMBmv);
3431 p = smb_buf(inbuf) + 1;
3432 p += srvstr_pull_buf(inbuf, name, p, sizeof(name), STR_TERMINATE);
3434 p += srvstr_pull_buf(inbuf, newname, p, sizeof(newname), STR_TERMINATE);
3436 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3437 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3439 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
3441 status = rename_internals(conn, name, newname, False);
3442 if (!NT_STATUS_IS_OK(status)) {
3443 return ERROR_NT(status);
3447 * Win2k needs a changenotify request response before it will
3448 * update after a rename..
3450 process_pending_change_notify_queue((time_t)0);
3451 outsize = set_message(outbuf,0,0,True);
3457 /*******************************************************************
3458 Copy a file as part of a reply_copy.
3459 ******************************************************************/
3461 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
3462 int count,BOOL target_is_directory, int *err_ret)
3465 SMB_STRUCT_STAT src_sbuf, sbuf2;
3467 files_struct *fsp1,*fsp2;
3472 pstrcpy(dest,dest1);
3473 if (target_is_directory) {
3474 char *p = strrchr_m(src,'/');
3483 if (!vfs_file_exist(conn,src,&src_sbuf))
3486 fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
3487 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
3492 if (!target_is_directory && count)
3493 ofun = FILE_EXISTS_OPEN;
3495 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
3496 ZERO_STRUCTP(&sbuf2);
3498 fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
3499 ofun,src_sbuf.st_mode,0,&Access,&action);
3502 close_file(fsp1,False);
3506 if ((ofun&3) == 1) {
3507 if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
3508 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
3510 * Stop the copy from occurring.
3513 src_sbuf.st_size = 0;
3517 if (src_sbuf.st_size)
3518 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
3520 close_file(fsp1,False);
3522 /* Ensure the modtime is set correctly on the destination file. */
3523 fsp2->pending_modtime = src_sbuf.st_mtime;
3526 * As we are opening fsp1 read-only we only expect
3527 * an error on close on fsp2 if we are out of space.
3528 * Thus we don't look at the error return from the
3531 *err_ret = close_file(fsp2,False);
3533 return(ret == (SMB_OFF_T)src_sbuf.st_size);
3536 /****************************************************************************
3537 Reply to a file copy.
3538 ****************************************************************************/
3540 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3545 pstring mask,newname;
3548 int error = ERRnoaccess;
3552 int tid2 = SVAL(inbuf,smb_vwv0);
3553 int ofun = SVAL(inbuf,smb_vwv1);
3554 int flags = SVAL(inbuf,smb_vwv2);
3555 BOOL target_is_directory=False;
3556 BOOL bad_path1 = False;
3557 BOOL bad_path2 = False;
3559 SMB_STRUCT_STAT sbuf1, sbuf2;
3561 START_PROFILE(SMBcopy);
3563 *directory = *mask = 0;
3566 p += srvstr_pull_buf(inbuf, name, p, sizeof(name), STR_TERMINATE);
3567 p += srvstr_pull_buf(inbuf, newname, p, sizeof(newname), STR_TERMINATE);
3569 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
3571 if (tid2 != conn->cnum) {
3572 /* can't currently handle inter share copies XXXX */
3573 DEBUG(3,("Rejecting inter-share copy\n"));
3574 END_PROFILE(SMBcopy);
3575 return ERROR_DOS(ERRSRV,ERRinvdevice);
3578 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3579 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3581 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
3582 unix_convert(newname,conn,0,&bad_path2,&sbuf2);
3584 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
3586 if ((flags&1) && target_is_directory) {
3587 END_PROFILE(SMBcopy);
3588 return ERROR_DOS(ERRDOS,ERRbadfile);
3591 if ((flags&2) && !target_is_directory) {
3592 END_PROFILE(SMBcopy);
3593 return ERROR_DOS(ERRDOS,ERRbadpath);
3596 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
3597 /* wants a tree copy! XXXX */
3598 DEBUG(3,("Rejecting tree copy\n"));
3599 END_PROFILE(SMBcopy);
3600 return ERROR_DOS(ERRSRV,ERRerror);
3603 p = strrchr_m(name,'/');
3605 pstrcpy(directory,"./");
3609 pstrcpy(directory,name);
3614 * We should only check the mangled cache
3615 * here if unix_convert failed. This means
3616 * that the path in 'mask' doesn't exist
3617 * on the file system and so we need to look
3618 * for a possible mangle. This patch from
3619 * Tine Smukavec <valentin.smukavec@hermes.si>.
3622 if (!rc && mangle_is_mangled(mask))
3623 mangle_check_cache( mask );
3625 has_wild = ms_has_wild(mask);
3628 pstrcat(directory,"/");
3629 pstrcat(directory,mask);
3630 if (resolve_wildcards(directory,newname) &&
3631 copy_file(directory,newname,conn,ofun, count,target_is_directory,&err))
3635 END_PROFILE(SMBcopy);
3636 return(UNIXERROR(ERRHRD,ERRgeneral));
3639 exists = vfs_file_exist(conn,directory,NULL);
3642 void *dirptr = NULL;
3646 if (check_name(directory,conn))
3647 dirptr = OpenDir(conn, directory, True);
3652 if (strequal(mask,"????????.???"))
3655 while ((dname = ReadDirName(dirptr))) {
3657 pstrcpy(fname,dname);
3659 if(!mask_match(fname, mask, case_sensitive))
3662 error = ERRnoaccess;
3663 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
3664 pstrcpy(destname,newname);
3665 if (resolve_wildcards(fname,destname) &&
3666 copy_file(fname,destname,conn,ofun,
3667 count,target_is_directory,&err))
3669 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
3677 /* Error on close... */
3679 END_PROFILE(SMBcopy);
3680 return(UNIXERROR(ERRHRD,ERRgeneral));
3684 END_PROFILE(SMBcopy);
3685 return ERROR_DOS(ERRDOS,error);
3687 if((errno == ENOENT) && (bad_path1 || bad_path2)) {
3688 unix_ERR_class = ERRDOS;
3689 unix_ERR_code = ERRbadpath;
3691 END_PROFILE(SMBcopy);
3692 return(UNIXERROR(ERRDOS,error));
3696 outsize = set_message(outbuf,1,0,True);
3697 SSVAL(outbuf,smb_vwv0,count);
3699 END_PROFILE(SMBcopy);
3703 /****************************************************************************
3705 ****************************************************************************/
3707 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3714 START_PROFILE(pathworks_setdir);
3717 if (!CAN_SETDIR(snum)) {
3718 END_PROFILE(pathworks_setdir);
3719 return ERROR_DOS(ERRDOS,ERRnoaccess);
3722 srvstr_pull_buf(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), STR_TERMINATE);
3724 if (strlen(newdir) == 0) {
3727 ok = vfs_directory_exist(conn,newdir,NULL);
3729 string_set(&conn->connectpath,newdir);
3733 END_PROFILE(pathworks_setdir);
3734 return ERROR_DOS(ERRDOS,ERRbadpath);
3737 outsize = set_message(outbuf,0,0,True);
3738 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
3740 DEBUG(3,("setdir %s\n", newdir));
3742 END_PROFILE(pathworks_setdir);
3746 /****************************************************************************
3747 Get a lock pid, dealing with large count requests.
3748 ****************************************************************************/
3750 uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
3752 if(!large_file_format)
3753 return SVAL(data,SMB_LPID_OFFSET(data_offset));
3755 return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
3758 /****************************************************************************
3759 Get a lock count, dealing with large count requests.
3760 ****************************************************************************/
3762 SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
3764 SMB_BIG_UINT count = 0;
3766 if(!large_file_format) {
3767 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
3770 #if defined(HAVE_LONGLONG)
3771 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
3772 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
3773 #else /* HAVE_LONGLONG */
3776 * NT4.x seems to be broken in that it sends large file (64 bit)
3777 * lockingX calls even if the CAP_LARGE_FILES was *not*
3778 * negotiated. For boxes without large unsigned ints truncate the
3779 * lock count by dropping the top 32 bits.
3782 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
3783 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
3784 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
3785 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
3786 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
3789 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
3790 #endif /* HAVE_LONGLONG */
3796 #if !defined(HAVE_LONGLONG)
3797 /****************************************************************************
3798 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
3799 ****************************************************************************/
3801 static uint32 map_lock_offset(uint32 high, uint32 low)
3805 uint32 highcopy = high;
3808 * Try and find out how many significant bits there are in high.
3811 for(i = 0; highcopy; i++)
3815 * We use 31 bits not 32 here as POSIX
3816 * lock offsets may not be negative.
3819 mask = (~0) << (31 - i);
3822 return 0; /* Fail. */
3828 #endif /* !defined(HAVE_LONGLONG) */
3830 /****************************************************************************
3831 Get a lock offset, dealing with large offset requests.
3832 ****************************************************************************/
3834 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
3836 SMB_BIG_UINT offset = 0;
3840 if(!large_file_format) {
3841 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
3844 #if defined(HAVE_LONGLONG)
3845 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
3846 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
3847 #else /* HAVE_LONGLONG */
3850 * NT4.x seems to be broken in that it sends large file (64 bit)
3851 * lockingX calls even if the CAP_LARGE_FILES was *not*
3852 * negotiated. For boxes without large unsigned ints mangle the
3853 * lock offset by mapping the top 32 bits onto the lower 32.
3856 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
3857 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
3858 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
3861 if((new_low = map_lock_offset(high, low)) == 0) {
3863 return (SMB_BIG_UINT)-1;
3866 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
3867 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
3868 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
3869 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
3872 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
3873 #endif /* HAVE_LONGLONG */
3879 /****************************************************************************
3880 Reply to a lockingX request.
3881 ****************************************************************************/
3883 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
3885 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
3886 unsigned char locktype = CVAL(inbuf,smb_vwv3);
3887 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
3888 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
3889 uint16 num_locks = SVAL(inbuf,smb_vwv7);
3890 SMB_BIG_UINT count = 0, offset = 0;
3892 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
3895 BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
3899 START_PROFILE(SMBlockingX);
3901 CHECK_FSP(fsp,conn);
3903 data = smb_buf(inbuf);
3905 if (locktype & (LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_CHANGE_LOCKTYPE)) {
3906 /* we don't support these - and CANCEL_LOCK makes w2k
3907 and XP reboot so I don't really want to be
3908 compatible! (tridge) */
3909 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3912 /* Check if this is an oplock break on a file
3913 we have granted an oplock on.
3915 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
3916 /* Client can insist on breaking to none. */
3917 BOOL break_to_none = (oplocklevel == 0);
3919 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
3920 (unsigned int)oplocklevel, fsp->fnum ));
3923 * Make sure we have granted an exclusive or batch oplock on this file.
3926 if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
3927 DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
3928 no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
3930 /* if this is a pure oplock break request then don't send a reply */
3931 if (num_locks == 0 && num_ulocks == 0) {
3932 END_PROFILE(SMBlockingX);
3935 END_PROFILE(SMBlockingX);
3936 return ERROR_DOS(ERRDOS,ERRlock);
3940 if (remove_oplock(fsp, break_to_none) == False) {
3941 DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
3945 /* if this is a pure oplock break request then don't send a reply */
3946 if (num_locks == 0 && num_ulocks == 0) {
3947 /* Sanity check - ensure a pure oplock break is not a
3949 if(CVAL(inbuf,smb_vwv0) != 0xff)
3950 DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
3951 (unsigned int)CVAL(inbuf,smb_vwv0) ));
3952 END_PROFILE(SMBlockingX);
3958 * We do this check *after* we have checked this is not a oplock break
3959 * response message. JRA.
3962 release_level_2_oplocks_on_change(fsp);
3964 /* Data now points at the beginning of the list
3965 of smb_unlkrng structs */
3966 for(i = 0; i < (int)num_ulocks; i++) {
3967 lock_pid = get_lock_pid( data, i, large_file_format);
3968 count = get_lock_count( data, i, large_file_format);
3969 offset = get_lock_offset( data, i, large_file_format, &err);
3972 * There is no error code marked "stupid client bug".... :-).
3975 END_PROFILE(SMBlockingX);
3976 return ERROR_DOS(ERRDOS,ERRnoaccess);
3979 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
3980 (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
3982 status = do_unlock(fsp,conn,lock_pid,count,offset);
3983 if (NT_STATUS_V(status)) {
3984 END_PROFILE(SMBlockingX);
3985 return ERROR_NT(status);
3989 /* Setup the timeout in seconds. */
3991 lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+499)/500);
3993 /* Now do any requested locks */
3994 data += ((large_file_format ? 20 : 10)*num_ulocks);
3996 /* Data now points at the beginning of the list
3997 of smb_lkrng structs */
3999 for(i = 0; i < (int)num_locks; i++) {
4000 lock_pid = get_lock_pid( data, i, large_file_format);
4001 count = get_lock_count( data, i, large_file_format);
4002 offset = get_lock_offset( data, i, large_file_format, &err);
4005 * There is no error code marked "stupid client bug".... :-).
4008 END_PROFILE(SMBlockingX);
4009 return ERROR_DOS(ERRDOS,ERRnoaccess);
4012 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
4013 (double)offset, (double)count, (unsigned int)lock_pid,
4014 fsp->fsp_name, (int)lock_timeout ));
4016 status = do_lock_spin(fsp,conn,lock_pid, count,offset,
4017 ((locktype & 1) ? READ_LOCK : WRITE_LOCK));
4018 if (NT_STATUS_V(status)) {
4019 if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
4021 * A blocking lock was requested. Package up
4022 * this smb into a queued request and push it
4023 * onto the blocking lock queue.
4025 if(push_blocking_lock_request(inbuf, length, lock_timeout, i, lock_pid, offset, count)) {
4026 END_PROFILE(SMBlockingX);
4034 /* If any of the above locks failed, then we must unlock
4035 all of the previous locks (X/Open spec). */
4036 if (i != num_locks && num_locks != 0) {
4038 * Ensure we don't do a remove on the lock that just failed,
4039 * as under POSIX rules, if we have a lock already there, we
4040 * will delete it (and we shouldn't) .....
4042 for(i--; i >= 0; i--) {
4043 lock_pid = get_lock_pid( data, i, large_file_format);
4044 count = get_lock_count( data, i, large_file_format);
4045 offset = get_lock_offset( data, i, large_file_format, &err);
4048 * There is no error code marked "stupid client bug".... :-).
4051 END_PROFILE(SMBlockingX);
4052 return ERROR_DOS(ERRDOS,ERRnoaccess);
4055 do_unlock(fsp,conn,lock_pid,count,offset);
4057 END_PROFILE(SMBlockingX);
4058 return ERROR_NT(status);
4061 set_message(outbuf,2,0,True);
4063 DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
4064 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
4066 END_PROFILE(SMBlockingX);
4067 return chain_reply(inbuf,outbuf,length,bufsize);
4070 /****************************************************************************
4071 Reply to a SMBreadbmpx (read block multiplex) request.
4072 ****************************************************************************/
4074 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4085 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4086 START_PROFILE(SMBreadBmpx);
4088 /* this function doesn't seem to work - disable by default */
4089 if (!lp_readbmpx()) {
4090 END_PROFILE(SMBreadBmpx);
4091 return ERROR_DOS(ERRSRV,ERRuseSTD);
4094 outsize = set_message(outbuf,8,0,True);
4096 CHECK_FSP(fsp,conn);
4099 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
4100 maxcount = SVAL(inbuf,smb_vwv3);
4102 data = smb_buf(outbuf);
4103 pad = ((long)data)%4;
4108 max_per_packet = bufsize-(outsize+pad);
4112 if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
4113 END_PROFILE(SMBreadBmpx);
4114 return ERROR_DOS(ERRDOS,ERRlock);
4118 size_t N = MIN(max_per_packet,tcount-total_read);
4120 nread = read_file(fsp,data,startpos,N);
4125 if (nread < (ssize_t)N)
4126 tcount = total_read + nread;
4128 set_message(outbuf,8,nread,False);
4129 SIVAL(outbuf,smb_vwv0,startpos);
4130 SSVAL(outbuf,smb_vwv2,tcount);
4131 SSVAL(outbuf,smb_vwv6,nread);
4132 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
4134 if (!send_smb(smbd_server_fd(),outbuf))
4135 exit_server("reply_readbmpx: send_smb failed.");
4137 total_read += nread;
4139 } while (total_read < (ssize_t)tcount);
4141 END_PROFILE(SMBreadBmpx);
4145 /****************************************************************************
4146 Reply to a SMBsetattrE.
4147 ****************************************************************************/
4149 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4151 struct utimbuf unix_times;
4153 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4154 START_PROFILE(SMBsetattrE);
4156 outsize = set_message(outbuf,0,0,True);
4158 if(!fsp || (fsp->conn != conn)) {
4159 END_PROFILE(SMBgetattrE);
4160 return ERROR_DOS(ERRDOS,ERRbadfid);
4164 * Convert the DOS times into unix times. Ignore create
4165 * time as UNIX can't set this.
4168 unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
4169 unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
4172 * Patch from Ray Frush <frush@engr.colostate.edu>
4173 * Sometimes times are sent as zero - ignore them.
4176 if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
4177 /* Ignore request */
4178 if( DEBUGLVL( 3 ) ) {
4179 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
4180 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
4182 END_PROFILE(SMBsetattrE);
4184 } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
4185 /* set modify time = to access time if modify time was 0 */
4186 unix_times.modtime = unix_times.actime;
4189 /* Set the date on this file */
4190 if(file_utime(conn, fsp->fsp_name, &unix_times)) {
4191 END_PROFILE(SMBsetattrE);
4192 return ERROR_DOS(ERRDOS,ERRnoaccess);
4195 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
4196 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
4198 END_PROFILE(SMBsetattrE);
4203 /* Back from the dead for OS/2..... JRA. */
4205 /****************************************************************************
4206 Reply to a SMBwritebmpx (write block multiplex primary) request.
4207 ****************************************************************************/
4209 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4212 ssize_t nwritten = -1;
4219 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4220 START_PROFILE(SMBwriteBmpx);
4222 CHECK_FSP(fsp,conn);
4226 tcount = SVAL(inbuf,smb_vwv1);
4227 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
4228 write_through = BITSETW(inbuf+smb_vwv7,0);
4229 numtowrite = SVAL(inbuf,smb_vwv10);
4230 smb_doff = SVAL(inbuf,smb_vwv11);
4232 data = smb_base(inbuf) + smb_doff;
4234 /* If this fails we need to send an SMBwriteC response,
4235 not an SMBwritebmpx - set this up now so we don't forget */
4236 SCVAL(outbuf,smb_com,SMBwritec);
4238 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
4239 END_PROFILE(SMBwriteBmpx);
4240 return(ERROR_DOS(ERRDOS,ERRlock));
4243 nwritten = write_file(fsp,data,startpos,numtowrite);
4245 if(lp_syncalways(SNUM(conn)) || write_through)
4246 sync_file(conn,fsp);
4248 if(nwritten < (ssize_t)numtowrite) {
4249 END_PROFILE(SMBwriteBmpx);
4250 return(UNIXERROR(ERRHRD,ERRdiskfull));
4253 /* If the maximum to be written to this file
4254 is greater than what we just wrote then set
4255 up a secondary struct to be attached to this
4256 fd, we will use this to cache error messages etc. */
4258 if((ssize_t)tcount > nwritten) {
4259 write_bmpx_struct *wbms;
4260 if(fsp->wbmpx_ptr != NULL)
4261 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
4263 wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
4265 DEBUG(0,("Out of memory in reply_readmpx\n"));
4266 END_PROFILE(SMBwriteBmpx);
4267 return(ERROR_DOS(ERRSRV,ERRnoresource));
4269 wbms->wr_mode = write_through;
4270 wbms->wr_discard = False; /* No errors yet */
4271 wbms->wr_total_written = nwritten;
4272 wbms->wr_errclass = 0;
4274 fsp->wbmpx_ptr = wbms;
4277 /* We are returning successfully, set the message type back to
4279 SCVAL(outbuf,smb_com,SMBwriteBmpx);
4281 outsize = set_message(outbuf,1,0,True);
4283 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
4285 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
4286 fsp->fnum, (int)numtowrite, (int)nwritten ) );
4288 if (write_through && tcount==nwritten) {
4289 /* We need to send both a primary and a secondary response */
4290 smb_setlen(outbuf,outsize - 4);
4291 if (!send_smb(smbd_server_fd(),outbuf))
4292 exit_server("reply_writebmpx: send_smb failed.");
4294 /* Now the secondary */
4295 outsize = set_message(outbuf,1,0,True);
4296 SCVAL(outbuf,smb_com,SMBwritec);
4297 SSVAL(outbuf,smb_vwv0,nwritten);
4300 END_PROFILE(SMBwriteBmpx);
4304 /****************************************************************************
4305 Reply to a SMBwritebs (write block multiplex secondary) request.
4306 ****************************************************************************/
4308 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4311 ssize_t nwritten = -1;
4318 write_bmpx_struct *wbms;
4319 BOOL send_response = False;
4320 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4321 START_PROFILE(SMBwriteBs);
4323 CHECK_FSP(fsp,conn);
4326 tcount = SVAL(inbuf,smb_vwv1);
4327 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
4328 numtowrite = SVAL(inbuf,smb_vwv6);
4329 smb_doff = SVAL(inbuf,smb_vwv7);
4331 data = smb_base(inbuf) + smb_doff;
4333 /* We need to send an SMBwriteC response, not an SMBwritebs */
4334 SCVAL(outbuf,smb_com,SMBwritec);
4336 /* This fd should have an auxiliary struct attached,
4337 check that it does */
4338 wbms = fsp->wbmpx_ptr;
4340 END_PROFILE(SMBwriteBs);
4344 /* If write through is set we can return errors, else we must cache them */
4345 write_through = wbms->wr_mode;
4347 /* Check for an earlier error */
4348 if(wbms->wr_discard) {
4349 END_PROFILE(SMBwriteBs);
4350 return -1; /* Just discard the packet */
4353 nwritten = write_file(fsp,data,startpos,numtowrite);
4355 if(lp_syncalways(SNUM(conn)) || write_through)
4356 sync_file(conn,fsp);
4358 if (nwritten < (ssize_t)numtowrite) {
4360 /* We are returning an error - we can delete the aux struct */
4363 fsp->wbmpx_ptr = NULL;
4364 END_PROFILE(SMBwriteBs);
4365 return(ERROR_DOS(ERRHRD,ERRdiskfull));
4367 END_PROFILE(SMBwriteBs);
4368 return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
4371 /* Increment the total written, if this matches tcount
4372 we can discard the auxiliary struct (hurrah !) and return a writeC */
4373 wbms->wr_total_written += nwritten;
4374 if(wbms->wr_total_written >= tcount) {
4375 if (write_through) {
4376 outsize = set_message(outbuf,1,0,True);
4377 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
4378 send_response = True;
4382 fsp->wbmpx_ptr = NULL;
4386 END_PROFILE(SMBwriteBs);
4390 END_PROFILE(SMBwriteBs);
4394 /****************************************************************************
4395 Reply to a SMBgetattrE.
4396 ****************************************************************************/
4398 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4400 SMB_STRUCT_STAT sbuf;
4403 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4404 START_PROFILE(SMBgetattrE);
4406 outsize = set_message(outbuf,11,0,True);
4408 if(!fsp || (fsp->conn != conn)) {
4409 END_PROFILE(SMBgetattrE);
4410 return ERROR_DOS(ERRDOS,ERRbadfid);
4413 /* Do an fstat on this file */
4414 if(fsp_stat(fsp, &sbuf)) {
4415 END_PROFILE(SMBgetattrE);
4416 return(UNIXERROR(ERRDOS,ERRnoaccess));
4419 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
4422 * Convert the times into dos times. Set create
4423 * date to be last modify date as UNIX doesn't save
4427 put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
4428 put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
4429 put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
4432 SIVAL(outbuf,smb_vwv6,0);
4433 SIVAL(outbuf,smb_vwv8,0);
4435 uint32 allocation_size = get_allocation_size(fsp, &sbuf);
4436 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
4437 SIVAL(outbuf,smb_vwv8,allocation_size);
4439 SSVAL(outbuf,smb_vwv10, mode);
4441 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
4443 END_PROFILE(SMBgetattrE);