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 START_PROFILE(SMBioctl);
353 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
355 switch (ioctl_code) {
356 case IOCTL_QUERY_JOB_INFO:
360 END_PROFILE(SMBioctl);
361 return(ERROR_DOS(ERRSRV,ERRnosupport));
364 outsize = set_message(outbuf,8,replysize+1,True);
365 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
366 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
367 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
368 p = smb_buf(outbuf) + 1; /* Allow for alignment */
370 switch (ioctl_code) {
371 case IOCTL_QUERY_JOB_INFO:
373 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
375 END_PROFILE(SMBioctl);
376 return(UNIXERROR(ERRDOS,ERRbadfid));
378 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
379 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
380 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
385 END_PROFILE(SMBioctl);
389 /****************************************************************************
391 ****************************************************************************/
393 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
399 BOOL bad_path = False;
400 SMB_STRUCT_STAT sbuf;
403 START_PROFILE(SMBchkpth);
405 srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE);
407 status = check_path_syntax(name);
408 if (!NT_STATUS_IS_OK(status))
409 return ERROR_NT(status);
411 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
413 unix_convert(name,conn,0,&bad_path,&sbuf);
415 mode = SVAL(inbuf,smb_vwv0);
417 if (check_name(name,conn)) {
418 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
419 if (!(ok = S_ISDIR(sbuf.st_mode)))
420 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath);
424 /* We special case this - as when a Windows machine
425 is parsing a path is steps through the components
426 one at a time - if a component fails it expects
427 ERRbadpath, not ERRbadfile.
429 if(errno == ENOENT) {
431 * Windows returns different error codes if
432 * the parent directory is valid but not the
433 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
434 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
435 * if the path is invalid.
438 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
440 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
442 } else if (errno == ENOTDIR)
443 return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY);
445 return(UNIXERROR(ERRDOS,ERRbadpath));
448 outsize = set_message(outbuf,0,0,True);
450 DEBUG(3,("chkpth %s mode=%d\n", name, mode));
452 END_PROFILE(SMBchkpth);
456 /****************************************************************************
458 ****************************************************************************/
460 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
464 SMB_STRUCT_STAT sbuf;
469 BOOL bad_path = False;
471 START_PROFILE(SMBgetatr);
473 p = smb_buf(inbuf) + 1;
474 p += srvstr_pull_buf(inbuf, fname, p, sizeof(fname), STR_TERMINATE);
476 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
478 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
479 under WfWg - weird! */
481 mode = aHIDDEN | aDIR;
482 if (!CAN_WRITE(conn))
488 unix_convert(fname,conn,0,&bad_path,&sbuf);
489 if (check_name(fname,conn)) {
490 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
491 mode = dos_mode(conn,fname,&sbuf);
493 mtime = sbuf.st_mtime;
498 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
504 END_PROFILE(SMBgetatr);
505 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadfile);
508 outsize = set_message(outbuf,10,0,True);
510 SSVAL(outbuf,smb_vwv0,mode);
511 if(lp_dos_filetime_resolution(SNUM(conn)) )
512 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
514 put_dos_date3(outbuf,smb_vwv1,mtime);
515 SIVAL(outbuf,smb_vwv3,(uint32)size);
517 if (Protocol >= PROTOCOL_NT1)
518 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
520 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
522 END_PROFILE(SMBgetatr);
526 /****************************************************************************
528 ****************************************************************************/
530 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
537 SMB_STRUCT_STAT sbuf;
538 BOOL bad_path = False;
541 START_PROFILE(SMBsetatr);
543 p = smb_buf(inbuf) + 1;
544 p += srvstr_pull_buf(inbuf, fname, p, sizeof(fname), STR_TERMINATE);
545 unix_convert(fname,conn,0,&bad_path,&sbuf);
547 mode = SVAL(inbuf,smb_vwv0);
548 mtime = make_unix_date3(inbuf+smb_vwv1);
550 if (mode != FILE_ATTRIBUTE_NORMAL) {
551 if (VALID_STAT_OF_DIR(sbuf))
556 if (check_name(fname,conn))
557 ok = (file_chmod(conn,fname,mode,NULL) == 0);
563 ok = set_filetime(conn,fname,mtime);
566 END_PROFILE(SMBsetatr);
567 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
570 outsize = set_message(outbuf,0,0,True);
572 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
574 END_PROFILE(SMBsetatr);
578 /****************************************************************************
580 ****************************************************************************/
582 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
585 SMB_BIG_UINT dfree,dsize,bsize;
586 START_PROFILE(SMBdskattr);
588 SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
590 outsize = set_message(outbuf,5,0,True);
592 if (Protocol <= PROTOCOL_LANMAN2) {
593 double total_space, free_space;
594 /* we need to scale this to a number that DOS6 can handle. We
595 use floating point so we can handle large drives on systems
596 that don't have 64 bit integers
598 we end up displaying a maximum of 2G to DOS systems
600 total_space = dsize * (double)bsize;
601 free_space = dfree * (double)bsize;
603 dsize = (total_space+63*512) / (64*512);
604 dfree = (free_space+63*512) / (64*512);
606 if (dsize > 0xFFFF) dsize = 0xFFFF;
607 if (dfree > 0xFFFF) dfree = 0xFFFF;
609 SSVAL(outbuf,smb_vwv0,dsize);
610 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
611 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
612 SSVAL(outbuf,smb_vwv3,dfree);
614 SSVAL(outbuf,smb_vwv0,dsize);
615 SSVAL(outbuf,smb_vwv1,bsize/512);
616 SSVAL(outbuf,smb_vwv2,512);
617 SSVAL(outbuf,smb_vwv3,dfree);
620 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
622 END_PROFILE(SMBdskattr);
626 /****************************************************************************
628 Can be called from SMBsearch, SMBffirst or SMBfunique.
629 ****************************************************************************/
631 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
642 BOOL finished = False;
651 BOOL check_descend = False;
652 BOOL expect_close = False;
653 BOOL can_open = True;
654 BOOL bad_path = False;
655 START_PROFILE(SMBsearch);
657 *mask = *directory = *fname = 0;
659 /* If we were called as SMBffirst then we must expect close. */
660 if(CVAL(inbuf,smb_com) == SMBffirst)
663 outsize = set_message(outbuf,1,3,True);
664 maxentries = SVAL(inbuf,smb_vwv0);
665 dirtype = SVAL(inbuf,smb_vwv1);
666 p = smb_buf(inbuf) + 1;
667 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
669 status_len = SVAL(p, 0);
672 /* dirtype &= ~aDIR; */
674 if (status_len == 0) {
675 SMB_STRUCT_STAT sbuf;
678 pstrcpy(directory,path);
680 unix_convert(directory,conn,0,&bad_path,&sbuf);
683 if (!check_name(directory,conn))
686 p = strrchr_m(dir2,'/');
695 p = strrchr_m(directory,'/');
701 if (strlen(directory) == 0)
702 pstrcpy(directory,".");
703 memset((char *)status,'\0',21);
704 SCVAL(status,0,(dirtype & 0x1F));
709 status_dirtype = CVAL(status,0) & 0x1F;
710 if (status_dirtype != (dirtype & 0x1F))
711 dirtype = status_dirtype;
713 conn->dirptr = dptr_fetch(status+12,&dptr_num);
716 string_set(&conn->dirpath,dptr_path(dptr_num));
717 pstrcpy(mask, dptr_wcard(dptr_num));
721 p = smb_buf(outbuf) + 3;
724 if (status_len == 0) {
725 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
728 END_PROFILE(SMBsearch);
729 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnofids);
731 END_PROFILE(SMBsearch);
732 return ERROR_DOS(ERRDOS,ERRnofids);
734 dptr_set_wcard(dptr_num, strdup(mask));
735 dptr_set_attr(dptr_num, dirtype);
737 dirtype = dptr_attr(dptr_num);
740 DEBUG(4,("dptr_num is %d\n",dptr_num));
743 if ((dirtype&0x1F) == aVOLID) {
745 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
746 dptr_fill(p+12,dptr_num);
747 if (dptr_zero(p+12) && (status_len==0))
751 p += DIR_STRUCT_SIZE;
753 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
754 conn->dirpath,lp_dontdescend(SNUM(conn))));
755 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
756 check_descend = True;
758 for (i=numentries;(i<maxentries) && !finished;i++) {
759 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
762 make_dir_struct(p,mask,fname,size,mode,date);
763 dptr_fill(p+12,dptr_num);
766 p += DIR_STRUCT_SIZE;
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 if (Protocol < PROTOCOL_NT1) {
781 SCVAL(outbuf,smb_rcls,ERRDOS);
782 SSVAL(outbuf,smb_err,ERRnofiles);
784 /* Also close the dptr - we know it's gone */
785 dptr_close(&dptr_num);
786 } else if (numentries == 0 || !ok) {
787 if (Protocol < PROTOCOL_NT1) {
788 SCVAL(outbuf,smb_rcls,ERRDOS);
789 SSVAL(outbuf,smb_err,ERRnofiles);
791 dptr_close(&dptr_num);
794 /* If we were called as SMBfunique, then we can close the dirptr now ! */
795 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
796 dptr_close(&dptr_num);
798 SSVAL(outbuf,smb_vwv0,numentries);
799 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
800 SCVAL(smb_buf(outbuf),0,5);
801 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
803 if (Protocol >= PROTOCOL_NT1)
804 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
806 outsize += DIR_STRUCT_SIZE*numentries;
807 smb_setlen(outbuf,outsize - 4);
809 if ((! *directory) && dptr_path(dptr_num))
810 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
812 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
813 smb_fn_name(CVAL(inbuf,smb_com)),
814 mask, directory, dirtype, numentries, maxentries ) );
816 END_PROFILE(SMBsearch);
820 /****************************************************************************
821 Reply to a fclose (stop directory search).
822 ****************************************************************************/
824 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
833 START_PROFILE(SMBfclose);
835 outsize = set_message(outbuf,1,0,True);
836 p = smb_buf(inbuf) + 1;
837 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
839 status_len = SVAL(p,0);
842 if (status_len == 0) {
843 END_PROFILE(SMBfclose);
844 return ERROR_DOS(ERRSRV,ERRsrverror);
849 if(dptr_fetch(status+12,&dptr_num)) {
850 /* Close the dptr - we know it's gone */
851 dptr_close(&dptr_num);
854 SSVAL(outbuf,smb_vwv0,0);
856 DEBUG(3,("search close\n"));
858 END_PROFILE(SMBfclose);
862 /****************************************************************************
864 ****************************************************************************/
866 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
876 SMB_STRUCT_STAT sbuf;
877 BOOL bad_path = False;
879 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
880 START_PROFILE(SMBopen);
882 share_mode = SVAL(inbuf,smb_vwv0);
884 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE);
886 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
888 unix_convert(fname,conn,0,&bad_path,&sbuf);
890 unixmode = unix_mode(conn,aARCH,fname);
892 fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
893 unixmode, oplock_request,&rmode,NULL);
896 END_PROFILE(SMBopen);
897 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
901 fmode = dos_mode(conn,fname,&sbuf);
902 mtime = sbuf.st_mtime;
905 DEBUG(3,("attempt to open a directory %s\n",fname));
906 close_file(fsp,False);
907 END_PROFILE(SMBopen);
908 return ERROR_DOS(ERRDOS,ERRnoaccess);
911 outsize = set_message(outbuf,7,0,True);
912 SSVAL(outbuf,smb_vwv0,fsp->fnum);
913 SSVAL(outbuf,smb_vwv1,fmode);
914 if(lp_dos_filetime_resolution(SNUM(conn)) )
915 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
917 put_dos_date3(outbuf,smb_vwv2,mtime);
918 SIVAL(outbuf,smb_vwv4,(uint32)size);
919 SSVAL(outbuf,smb_vwv6,rmode);
921 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
922 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
924 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
925 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
926 END_PROFILE(SMBopen);
930 /****************************************************************************
931 Reply to an open and X.
932 ****************************************************************************/
934 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
937 int smb_mode = SVAL(inbuf,smb_vwv3);
938 int smb_attr = SVAL(inbuf,smb_vwv5);
939 /* Breakout the oplock request bits so we can set the
940 reply bits separately. */
941 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
942 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
943 BOOL oplock_request = ex_oplock_request | core_oplock_request;
945 int open_flags = SVAL(inbuf,smb_vwv2);
946 int smb_sattr = SVAL(inbuf,smb_vwv4);
947 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
949 int smb_ofun = SVAL(inbuf,smb_vwv8);
952 int fmode=0,mtime=0,rmode=0;
953 SMB_STRUCT_STAT sbuf;
955 BOOL bad_path = False;
957 START_PROFILE(SMBopenX);
959 /* If it's an IPC, pass off the pipe handler. */
961 if (lp_nt_pipe_support()) {
962 END_PROFILE(SMBopenX);
963 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
965 END_PROFILE(SMBopenX);
966 return ERROR_DOS(ERRSRV,ERRaccess);
970 /* XXXX we need to handle passed times, sattr and flags */
971 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
973 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
975 unix_convert(fname,conn,0,&bad_path,&sbuf);
977 unixmode = unix_mode(conn,smb_attr | aARCH, fname);
979 fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
980 oplock_request, &rmode,&smb_action);
983 END_PROFILE(SMBopenX);
984 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
988 fmode = dos_mode(conn,fname,&sbuf);
989 mtime = sbuf.st_mtime;
991 close_file(fsp,False);
992 END_PROFILE(SMBopenX);
993 return ERROR_DOS(ERRDOS,ERRnoaccess);
996 /* If the caller set the extended oplock request bit
997 and we granted one (by whatever means) - set the
998 correct bit for extended oplock reply.
1001 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn)))
1002 smb_action |= EXTENDED_OPLOCK_GRANTED;
1004 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1005 smb_action |= EXTENDED_OPLOCK_GRANTED;
1007 /* If the caller set the core oplock request bit
1008 and we granted one (by whatever means) - set the
1009 correct bit for core oplock reply.
1012 if (core_oplock_request && lp_fake_oplocks(SNUM(conn)))
1013 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1015 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1016 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1018 set_message(outbuf,15,0,True);
1019 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1020 SSVAL(outbuf,smb_vwv3,fmode);
1021 if(lp_dos_filetime_resolution(SNUM(conn)) )
1022 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1024 put_dos_date3(outbuf,smb_vwv4,mtime);
1025 SIVAL(outbuf,smb_vwv6,(uint32)size);
1026 SSVAL(outbuf,smb_vwv8,rmode);
1027 SSVAL(outbuf,smb_vwv11,smb_action);
1029 END_PROFILE(SMBopenX);
1030 return chain_reply(inbuf,outbuf,length,bufsize);
1033 /****************************************************************************
1034 Reply to a SMBulogoffX.
1035 ****************************************************************************/
1037 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1039 uint16 vuid = SVAL(inbuf,smb_uid);
1040 user_struct *vuser = get_valid_user_struct(vuid);
1041 START_PROFILE(SMBulogoffX);
1044 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1046 /* in user level security we are supposed to close any files
1047 open by this user */
1048 if ((vuser != 0) && (lp_security() != SEC_SHARE))
1049 file_close_user(vuid);
1051 invalidate_vuid(vuid);
1053 set_message(outbuf,2,0,True);
1055 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1057 END_PROFILE(SMBulogoffX);
1058 return chain_reply(inbuf,outbuf,length,bufsize);
1061 /****************************************************************************
1062 Reply to a mknew or a create.
1063 ****************************************************************************/
1065 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1073 BOOL bad_path = False;
1075 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1076 SMB_STRUCT_STAT sbuf;
1077 START_PROFILE(SMBcreate);
1079 com = SVAL(inbuf,smb_com);
1081 createmode = SVAL(inbuf,smb_vwv0);
1082 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), STR_TERMINATE);
1084 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1086 unix_convert(fname,conn,0,&bad_path,&sbuf);
1088 if (createmode & aVOLID)
1089 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1091 unixmode = unix_mode(conn,createmode,fname);
1093 if(com == SMBmknew) {
1094 /* We should fail if file exists. */
1095 ofun = FILE_CREATE_IF_NOT_EXIST;
1097 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1098 ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
1101 /* Open file in dos compatibility share mode. */
1102 fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1103 ofun, unixmode, oplock_request, NULL, NULL);
1106 END_PROFILE(SMBcreate);
1107 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1110 outsize = set_message(outbuf,1,0,True);
1111 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1113 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1114 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1116 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1117 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1119 DEBUG( 2, ( "new file %s\n", fname ) );
1120 DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n", fname, fsp->fd, createmode, (int)unixmode ) );
1122 END_PROFILE(SMBcreate);
1126 /****************************************************************************
1127 Reply to a create temporary file.
1128 ****************************************************************************/
1130 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1136 BOOL bad_path = False;
1138 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1140 SMB_STRUCT_STAT sbuf;
1143 START_PROFILE(SMBctemp);
1145 createmode = SVAL(inbuf,smb_vwv0);
1146 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE);
1147 pstrcat(fname,"\\TMXXXXXX");
1149 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1151 unix_convert(fname,conn,0,&bad_path,&sbuf);
1153 unixmode = unix_mode(conn,createmode,fname);
1155 tmpfd = smb_mkstemp(fname);
1157 END_PROFILE(SMBctemp);
1158 return(UNIXERROR(ERRDOS,ERRnoaccess));
1161 SMB_VFS_STAT(conn,fname,&sbuf);
1163 /* Open file in dos compatibility share mode. */
1164 /* We should fail if file does not exist. */
1165 fsp = open_file_shared(conn,fname,&sbuf,
1166 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1167 FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
1168 unixmode, oplock_request, NULL, NULL);
1170 /* close fd from smb_mkstemp() */
1174 END_PROFILE(SMBctemp);
1175 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1178 outsize = set_message(outbuf,1,0,True);
1179 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1181 /* the returned filename is relative to the directory */
1182 s = strrchr_m(fname, '/');
1188 p = smb_buf(outbuf);
1189 SSVALS(p, 0, -1); /* what is this? not in spec */
1190 SSVAL(p, 2, strlen(s));
1192 p += srvstr_push(outbuf, p, s, -1, STR_ASCII);
1193 outsize = set_message_end(outbuf, p);
1195 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1196 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1198 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1199 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1201 DEBUG( 2, ( "created temp file %s\n", fname ) );
1202 DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
1203 fname, fsp->fd, createmode, (int)unixmode ) );
1205 END_PROFILE(SMBctemp);
1209 /*******************************************************************
1210 Check if a user is allowed to rename a file.
1211 ********************************************************************/
1213 static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT *pst)
1219 if (!CAN_WRITE(conn))
1220 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1222 if (S_ISDIR(pst->st_mode))
1223 return NT_STATUS_OK;
1225 /* We need a better way to return NT status codes from open... */
1229 fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1230 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1233 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1234 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1235 ret = NT_STATUS_SHARING_VIOLATION;
1240 close_file(fsp,False);
1241 return NT_STATUS_OK;
1244 /*******************************************************************
1245 Check if a user is allowed to delete a file.
1246 ********************************************************************/
1248 static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
1250 SMB_STRUCT_STAT sbuf;
1256 DEBUG(10,("can_delete: %s, dirtype = %d\n",
1259 if (!CAN_WRITE(conn))
1260 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1262 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0)
1263 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1265 fmode = dos_mode(conn,fname,&sbuf);
1267 /* Can't delete a directory. */
1269 return NT_STATUS_FILE_IS_A_DIRECTORY;
1271 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
1272 return NT_STATUS_OBJECT_NAME_INVALID;
1273 #endif /* JRATEST */
1275 if (!lp_delete_readonly(SNUM(conn))) {
1277 return NT_STATUS_CANNOT_DELETE;
1279 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1280 return NT_STATUS_NO_SUCH_FILE;
1282 /* We need a better way to return NT status codes from open... */
1286 fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1287 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
1290 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1291 if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
1292 ret = unix_ERR_ntstatus;
1293 else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1294 ret = NT_STATUS_SHARING_VIOLATION;
1297 unix_ERR_ntstatus = NT_STATUS_OK;
1300 close_file(fsp,False);
1301 return NT_STATUS_OK;
1304 /****************************************************************************
1305 The guts of the unlink command, split out so it may be called by the NT SMB
1307 ****************************************************************************/
1309 NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
1315 NTSTATUS error = NT_STATUS_OK;
1317 BOOL bad_path = False;
1319 SMB_STRUCT_STAT sbuf;
1321 *directory = *mask = 0;
1323 /* We must check for wildcards in the name given
1324 * directly by the client - before any unmangling.
1325 * This prevents an unmangling of a UNIX name containing
1326 * a DOS wildcard like '*' or '?' from unmangling into
1327 * a wildcard delete which was not intended.
1328 * FIX for #226. JRA.
1331 has_wild = ms_has_wild(name);
1333 rc = unix_convert(name,conn,0,&bad_path,&sbuf);
1335 p = strrchr_m(name,'/');
1337 pstrcpy(directory,".");
1341 pstrcpy(directory,name);
1346 * We should only check the mangled cache
1347 * here if unix_convert failed. This means
1348 * that the path in 'mask' doesn't exist
1349 * on the file system and so we need to look
1350 * for a possible mangle. This patch from
1351 * Tine Smukavec <valentin.smukavec@hermes.si>.
1354 if (!rc && mangle_is_mangled(mask))
1355 mangle_check_cache( mask );
1358 pstrcat(directory,"/");
1359 pstrcat(directory,mask);
1360 error = can_delete(directory,conn,dirtype);
1361 if (!NT_STATUS_IS_OK(error))
1364 if (SMB_VFS_UNLINK(conn,directory) == 0) {
1368 void *dirptr = NULL;
1371 if (check_name(directory,conn))
1372 dirptr = OpenDir(conn, directory, True);
1374 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1375 the pattern matches against the long name, otherwise the short name
1376 We don't implement this yet XXXX
1380 error = NT_STATUS_NO_SUCH_FILE;
1382 if (strequal(mask,"????????.???"))
1385 while ((dname = ReadDirName(dirptr))) {
1387 pstrcpy(fname,dname);
1389 if(!mask_match(fname, mask, case_sensitive))
1392 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
1393 error = can_delete(fname,conn,dirtype);
1394 if (!NT_STATUS_IS_OK(error))
1396 if (SMB_VFS_UNLINK(conn,fname) == 0)
1398 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
1404 if (count == 0 && NT_STATUS_IS_OK(error)) {
1405 error = map_nt_error_from_unix(errno);
1411 /****************************************************************************
1413 ****************************************************************************/
1415 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
1422 START_PROFILE(SMBunlink);
1424 dirtype = SVAL(inbuf,smb_vwv0);
1426 srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE);
1428 status = check_path_syntax(name);
1429 if (!NT_STATUS_IS_OK(status))
1430 return ERROR_NT(status);
1432 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
1434 DEBUG(3,("reply_unlink : %s\n",name));
1436 status = unlink_internals(conn, dirtype, name);
1437 if (!NT_STATUS_IS_OK(status))
1438 return ERROR_NT(status);
1441 * Win2k needs a changenotify request response before it will
1442 * update after a rename..
1444 process_pending_change_notify_queue((time_t)0);
1446 outsize = set_message(outbuf,0,0,True);
1448 END_PROFILE(SMBunlink);
1452 /****************************************************************************
1454 ****************************************************************************/
1456 void fail_readraw(void)
1459 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
1461 exit_server(errstr);
1464 /****************************************************************************
1465 Use sendfile in readbraw.
1466 ****************************************************************************/
1468 void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
1469 ssize_t mincount, char *outbuf)
1473 #if defined(WITH_SENDFILE)
1475 * We can only use sendfile on a non-chained packet and on a file
1476 * that is exclusively oplocked. reply_readbraw has already checked the length.
1479 if ((nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) &&
1480 EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_use_sendfile(SNUM(conn)) ) {
1483 _smb_setlen(outbuf,nread);
1484 header.data = outbuf;
1488 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
1490 * Special hack for broken Linux with no 64 bit clean sendfile. If we
1491 * return ENOSYS then pretend we just got a normal read.
1493 if (errno == ENOSYS)
1496 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
1497 fsp->fsp_name, strerror(errno) ));
1498 exit_server("send_file_readbraw sendfile failed");
1507 ret = read_file(fsp,outbuf+4,startpos,nread);
1512 _smb_setlen(outbuf,ret);
1513 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
1517 /****************************************************************************
1518 Reply to a readbraw (core+ protocol).
1519 ****************************************************************************/
1521 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
1523 extern struct current_user current_user;
1524 ssize_t maxcount,mincount;
1527 char *header = outbuf;
1529 START_PROFILE(SMBreadbraw);
1531 if (srv_is_signing_active()) {
1532 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
1536 * Special check if an oplock break has been issued
1537 * and the readraw request croses on the wire, we must
1538 * return a zero length response here.
1541 if(global_oplock_break) {
1542 _smb_setlen(header,0);
1543 if (write_data(smbd_server_fd(),header,4) != 4)
1545 DEBUG(5,("readbraw - oplock break finished\n"));
1546 END_PROFILE(SMBreadbraw);
1550 fsp = file_fsp(inbuf,smb_vwv0);
1552 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
1554 * fsp could be NULL here so use the value from the packet. JRA.
1556 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
1557 _smb_setlen(header,0);
1558 if (write_data(smbd_server_fd(),header,4) != 4)
1560 END_PROFILE(SMBreadbraw);
1564 CHECK_FSP(fsp,conn);
1566 flush_write_cache(fsp, READRAW_FLUSH);
1568 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
1569 if(CVAL(inbuf,smb_wct) == 10) {
1571 * This is a large offset (64 bit) read.
1573 #ifdef LARGE_SMB_OFF_T
1575 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
1577 #else /* !LARGE_SMB_OFF_T */
1580 * Ensure we haven't been sent a >32 bit offset.
1583 if(IVAL(inbuf,smb_vwv8) != 0) {
1584 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
1585 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
1586 _smb_setlen(header,0);
1587 if (write_data(smbd_server_fd(),header,4) != 4)
1589 END_PROFILE(SMBreadbraw);
1593 #endif /* LARGE_SMB_OFF_T */
1596 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
1597 _smb_setlen(header,0);
1598 if (write_data(smbd_server_fd(),header,4) != 4)
1600 END_PROFILE(SMBreadbraw);
1604 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
1605 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
1607 /* ensure we don't overrun the packet size */
1608 maxcount = MIN(65535,maxcount);
1609 maxcount = MAX(mincount,maxcount);
1611 if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1612 SMB_OFF_T size = fsp->size;
1613 SMB_OFF_T sizeneeded = startpos + maxcount;
1615 if (size < sizeneeded) {
1617 if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
1619 if (!fsp->can_write)
1623 if (startpos >= size)
1626 nread = MIN(maxcount,(size - startpos));
1629 if (nread < mincount)
1632 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
1633 (int)maxcount, (int)mincount, (int)nread ) );
1635 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf);
1637 DEBUG(5,("readbraw finished\n"));
1638 END_PROFILE(SMBreadbraw);
1642 /****************************************************************************
1643 Reply to a lockread (core+ protocol).
1644 ****************************************************************************/
1646 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
1654 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1655 START_PROFILE(SMBlockread);
1657 CHECK_FSP(fsp,conn);
1660 release_level_2_oplocks_on_change(fsp);
1662 numtoread = SVAL(inbuf,smb_vwv1);
1663 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1665 outsize = set_message(outbuf,5,3,True);
1666 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1667 data = smb_buf(outbuf) + 3;
1670 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
1671 * protocol request that predates the read/write lock concept.
1672 * Thus instead of asking for a read lock here we need to ask
1673 * for a write lock. JRA.
1676 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
1677 (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK);
1679 if (NT_STATUS_V(status)) {
1680 if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
1682 * A blocking lock was requested. Package up
1683 * this smb into a queued request and push it
1684 * onto the blocking lock queue.
1686 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)startpos,
1687 (SMB_BIG_UINT)numtoread)) {
1688 END_PROFILE(SMBlockread);
1692 END_PROFILE(SMBlockread);
1693 return ERROR_NT(status);
1696 nread = read_file(fsp,data,startpos,numtoread);
1699 END_PROFILE(SMBlockread);
1700 return(UNIXERROR(ERRDOS,ERRnoaccess));
1704 SSVAL(outbuf,smb_vwv0,nread);
1705 SSVAL(outbuf,smb_vwv5,nread+3);
1706 SSVAL(smb_buf(outbuf),1,nread);
1708 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
1709 fsp->fnum, (int)numtoread, (int)nread));
1711 END_PROFILE(SMBlockread);
1715 /****************************************************************************
1717 ****************************************************************************/
1719 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
1726 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1727 START_PROFILE(SMBread);
1729 CHECK_FSP(fsp,conn);
1732 numtoread = SVAL(inbuf,smb_vwv1);
1733 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1735 outsize = set_message(outbuf,5,3,True);
1736 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1737 data = smb_buf(outbuf) + 3;
1739 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1740 END_PROFILE(SMBread);
1741 return ERROR_DOS(ERRDOS,ERRlock);
1745 nread = read_file(fsp,data,startpos,numtoread);
1748 END_PROFILE(SMBread);
1749 return(UNIXERROR(ERRDOS,ERRnoaccess));
1753 SSVAL(outbuf,smb_vwv0,nread);
1754 SSVAL(outbuf,smb_vwv5,nread+3);
1755 SCVAL(smb_buf(outbuf),0,1);
1756 SSVAL(smb_buf(outbuf),1,nread);
1758 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
1759 fsp->fnum, (int)numtoread, (int)nread ) );
1761 END_PROFILE(SMBread);
1765 /****************************************************************************
1766 Reply to a read and X - possibly using sendfile.
1767 ****************************************************************************/
1769 int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length,
1770 files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
1773 char *data = smb_buf(outbuf);
1775 #if defined(WITH_SENDFILE)
1777 * We can only use sendfile on a non-chained packet and on a file
1778 * that is exclusively oplocked.
1781 if ((CVAL(inbuf,smb_vwv0) == 0xFF) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
1782 lp_use_sendfile(SNUM(conn)) && (lp_write_cache_size(SNUM(conn)) == 0) ) {
1783 SMB_STRUCT_STAT sbuf;
1786 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
1787 return(UNIXERROR(ERRDOS,ERRnoaccess));
1789 if (startpos > sbuf.st_size)
1792 if (smb_maxcnt > (sbuf.st_size - startpos))
1793 smb_maxcnt = (sbuf.st_size - startpos);
1795 if (smb_maxcnt == 0)
1799 * Set up the packet header before send. We
1800 * assume here the sendfile will work (get the
1801 * correct amount of data).
1804 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
1805 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
1806 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
1807 SCVAL(outbuf,smb_vwv0,0xFF);
1808 set_message(outbuf,12,smb_maxcnt,False);
1809 header.data = outbuf;
1810 header.length = data - outbuf;
1813 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
1815 * Special hack for broken Linux with no 64 bit clean sendfile. If we
1816 * return ENOSYS then pretend we just got a normal read.
1818 if (errno == ENOSYS)
1821 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
1822 fsp->fsp_name, strerror(errno) ));
1823 exit_server("send_file_readX sendfile failed");
1826 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
1827 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
1835 nread = read_file(fsp,data,startpos,smb_maxcnt);
1838 END_PROFILE(SMBreadX);
1839 return(UNIXERROR(ERRDOS,ERRnoaccess));
1842 SSVAL(outbuf,smb_vwv5,nread);
1843 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
1844 SSVAL(smb_buf(outbuf),-2,nread);
1846 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
1847 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
1852 /****************************************************************************
1853 Reply to a read and X.
1854 ****************************************************************************/
1856 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1858 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
1859 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
1861 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
1863 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
1866 START_PROFILE(SMBreadX);
1868 /* If it's an IPC, pass off the pipe handler. */
1870 END_PROFILE(SMBreadX);
1871 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
1874 CHECK_FSP(fsp,conn);
1877 set_message(outbuf,12,0,True);
1879 if(CVAL(inbuf,smb_wct) == 12) {
1880 #ifdef LARGE_SMB_OFF_T
1882 * This is a large offset (64 bit) read.
1884 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
1886 #else /* !LARGE_SMB_OFF_T */
1889 * Ensure we haven't been sent a >32 bit offset.
1892 if(IVAL(inbuf,smb_vwv10) != 0) {
1893 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
1894 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
1895 END_PROFILE(SMBreadX);
1896 return ERROR_DOS(ERRDOS,ERRbadaccess);
1899 #endif /* LARGE_SMB_OFF_T */
1903 if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
1904 END_PROFILE(SMBreadX);
1905 return ERROR_DOS(ERRDOS,ERRlock);
1908 nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt);
1910 nread = chain_reply(inbuf,outbuf,length,bufsize);
1912 END_PROFILE(SMBreadX);
1916 /****************************************************************************
1917 Reply to a writebraw (core+ or LANMAN1.0 protocol).
1918 ****************************************************************************/
1920 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
1923 ssize_t total_written=0;
1924 size_t numtowrite=0;
1929 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1931 START_PROFILE(SMBwritebraw);
1933 if (srv_is_signing_active()) {
1934 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
1937 CHECK_FSP(fsp,conn);
1940 tcount = IVAL(inbuf,smb_vwv1);
1941 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
1942 write_through = BITSETW(inbuf+smb_vwv7,0);
1944 /* We have to deal with slightly different formats depending
1945 on whether we are using the core+ or lanman1.0 protocol */
1947 if(Protocol <= PROTOCOL_COREPLUS) {
1948 numtowrite = SVAL(smb_buf(inbuf),-2);
1949 data = smb_buf(inbuf);
1951 numtowrite = SVAL(inbuf,smb_vwv10);
1952 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
1955 /* force the error type */
1956 SCVAL(inbuf,smb_com,SMBwritec);
1957 SCVAL(outbuf,smb_com,SMBwritec);
1959 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
1960 END_PROFILE(SMBwritebraw);
1961 return(ERROR_DOS(ERRDOS,ERRlock));
1965 nwritten = write_file(fsp,data,startpos,numtowrite);
1967 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
1968 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
1970 if (nwritten < (ssize_t)numtowrite) {
1971 END_PROFILE(SMBwritebraw);
1972 return(UNIXERROR(ERRHRD,ERRdiskfull));
1975 total_written = nwritten;
1977 /* Return a message to the redirector to tell it to send more bytes */
1978 SCVAL(outbuf,smb_com,SMBwritebraw);
1979 SSVALS(outbuf,smb_vwv0,-1);
1980 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
1981 if (!send_smb(smbd_server_fd(),outbuf))
1982 exit_server("reply_writebraw: send_smb failed.");
1984 /* Now read the raw data into the buffer and write it */
1985 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
1986 exit_server("secondary writebraw failed");
1989 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
1990 numtowrite = smb_len(inbuf);
1992 /* Set up outbuf to return the correct return */
1993 outsize = set_message(outbuf,1,0,True);
1994 SCVAL(outbuf,smb_com,SMBwritec);
1995 SSVAL(outbuf,smb_vwv0,total_written);
1997 if (numtowrite != 0) {
1999 if (numtowrite > BUFFER_SIZE) {
2000 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2001 (unsigned int)numtowrite ));
2002 exit_server("secondary writebraw failed");
2005 if (tcount > nwritten+numtowrite) {
2006 DEBUG(3,("Client overestimated the write %d %d %d\n",
2007 (int)tcount,(int)nwritten,(int)numtowrite));
2010 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
2011 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2013 exit_server("secondary writebraw failed");
2016 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
2018 if (nwritten < (ssize_t)numtowrite) {
2019 SCVAL(outbuf,smb_rcls,ERRHRD);
2020 SSVAL(outbuf,smb_err,ERRdiskfull);
2024 total_written += nwritten;
2027 if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
2028 sync_file(conn,fsp);
2030 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2031 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2033 /* we won't return a status if write through is not selected - this follows what WfWg does */
2034 END_PROFILE(SMBwritebraw);
2035 if (!write_through && total_written==tcount) {
2037 #if RABBIT_PELLET_FIX
2039 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2040 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2042 if (!send_keepalive(smbd_server_fd()))
2043 exit_server("reply_writebraw: send of keepalive failed");
2051 /****************************************************************************
2052 Reply to a writeunlock (core+).
2053 ****************************************************************************/
2055 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
2056 int size, int dum_buffsize)
2058 ssize_t nwritten = -1;
2063 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2065 START_PROFILE(SMBwriteunlock);
2067 CHECK_FSP(fsp,conn);
2070 numtowrite = SVAL(inbuf,smb_vwv1);
2071 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2072 data = smb_buf(inbuf) + 3;
2074 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
2075 WRITE_LOCK,False)) {
2076 END_PROFILE(SMBwriteunlock);
2077 return ERROR_DOS(ERRDOS,ERRlock);
2080 /* The special X/Open SMB protocol handling of
2081 zero length writes is *NOT* done for
2086 nwritten = write_file(fsp,data,startpos,numtowrite);
2088 if (lp_syncalways(SNUM(conn)))
2089 sync_file(conn,fsp);
2091 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2092 END_PROFILE(SMBwriteunlock);
2093 return(UNIXERROR(ERRHRD,ERRdiskfull));
2096 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
2097 (SMB_BIG_UINT)startpos);
2098 if (NT_STATUS_V(status)) {
2099 END_PROFILE(SMBwriteunlock);
2100 return ERROR_NT(status);
2103 outsize = set_message(outbuf,1,0,True);
2105 SSVAL(outbuf,smb_vwv0,nwritten);
2107 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2108 fsp->fnum, (int)numtowrite, (int)nwritten));
2110 END_PROFILE(SMBwriteunlock);
2114 /****************************************************************************
2116 ****************************************************************************/
2118 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
2121 ssize_t nwritten = -1;
2124 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2126 START_PROFILE(SMBwrite);
2128 /* If it's an IPC, pass off the pipe handler. */
2130 END_PROFILE(SMBwrite);
2131 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
2134 CHECK_FSP(fsp,conn);
2137 numtowrite = SVAL(inbuf,smb_vwv1);
2138 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2139 data = smb_buf(inbuf) + 3;
2141 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2142 END_PROFILE(SMBwrite);
2143 return ERROR_DOS(ERRDOS,ERRlock);
2147 * X/Open SMB protocol says that if smb_vwv1 is
2148 * zero then the file size should be extended or
2149 * truncated to the size given in smb_vwv[2-3].
2152 if(numtowrite == 0) {
2154 * This is actually an allocate call, and set EOF. JRA.
2156 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
2158 END_PROFILE(SMBwrite);
2159 return ERROR_NT(NT_STATUS_DISK_FULL);
2161 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
2163 END_PROFILE(SMBwrite);
2164 return ERROR_NT(NT_STATUS_DISK_FULL);
2167 nwritten = write_file(fsp,data,startpos,numtowrite);
2169 if (lp_syncalways(SNUM(conn)))
2170 sync_file(conn,fsp);
2172 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2173 END_PROFILE(SMBwrite);
2174 return(UNIXERROR(ERRHRD,ERRdiskfull));
2177 outsize = set_message(outbuf,1,0,True);
2179 SSVAL(outbuf,smb_vwv0,nwritten);
2181 if (nwritten < (ssize_t)numtowrite) {
2182 SCVAL(outbuf,smb_rcls,ERRHRD);
2183 SSVAL(outbuf,smb_err,ERRdiskfull);
2186 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
2188 END_PROFILE(SMBwrite);
2192 /****************************************************************************
2193 Reply to a write and X.
2194 ****************************************************************************/
2196 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2198 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2199 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2200 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2201 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2202 ssize_t nwritten = -1;
2203 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
2204 unsigned int smblen = smb_len(inbuf);
2206 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
2207 START_PROFILE(SMBwriteX);
2209 /* If it's an IPC, pass off the pipe handler. */
2211 END_PROFILE(SMBwriteX);
2212 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2215 CHECK_FSP(fsp,conn);
2218 /* Deal with possible LARGE_WRITEX */
2220 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
2222 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
2223 END_PROFILE(SMBwriteX);
2224 return ERROR_DOS(ERRDOS,ERRbadmem);
2227 data = smb_base(inbuf) + smb_doff;
2229 if(CVAL(inbuf,smb_wct) == 14) {
2230 #ifdef LARGE_SMB_OFF_T
2232 * This is a large offset (64 bit) write.
2234 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2236 #else /* !LARGE_SMB_OFF_T */
2239 * Ensure we haven't been sent a >32 bit offset.
2242 if(IVAL(inbuf,smb_vwv12) != 0) {
2243 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
2244 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
2245 END_PROFILE(SMBwriteX);
2246 return ERROR_DOS(ERRDOS,ERRbadaccess);
2249 #endif /* LARGE_SMB_OFF_T */
2252 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2253 END_PROFILE(SMBwriteX);
2254 return ERROR_DOS(ERRDOS,ERRlock);
2257 /* X/Open SMB protocol says that, unlike SMBwrite
2258 if the length is zero then NO truncation is
2259 done, just a write of zero. To truncate a file,
2265 nwritten = write_file(fsp,data,startpos,numtowrite);
2267 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2268 END_PROFILE(SMBwriteX);
2269 return(UNIXERROR(ERRHRD,ERRdiskfull));
2272 set_message(outbuf,6,0,True);
2274 SSVAL(outbuf,smb_vwv2,nwritten);
2276 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
2278 if (nwritten < (ssize_t)numtowrite) {
2279 SCVAL(outbuf,smb_rcls,ERRHRD);
2280 SSVAL(outbuf,smb_err,ERRdiskfull);
2283 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2284 fsp->fnum, (int)numtowrite, (int)nwritten));
2286 if (lp_syncalways(SNUM(conn)) || write_through)
2287 sync_file(conn,fsp);
2289 END_PROFILE(SMBwriteX);
2290 return chain_reply(inbuf,outbuf,length,bufsize);
2293 /****************************************************************************
2295 ****************************************************************************/
2297 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2303 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2304 START_PROFILE(SMBlseek);
2306 CHECK_FSP(fsp,conn);
2308 flush_write_cache(fsp, SEEK_FLUSH);
2310 mode = SVAL(inbuf,smb_vwv1) & 3;
2311 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
2312 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
2321 res = fsp->pos + startpos;
2332 if (umode == SEEK_END) {
2333 if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
2334 if(errno == EINVAL) {
2335 SMB_OFF_T current_pos = startpos;
2336 SMB_STRUCT_STAT sbuf;
2338 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
2339 END_PROFILE(SMBlseek);
2340 return(UNIXERROR(ERRDOS,ERRnoaccess));
2343 current_pos += sbuf.st_size;
2345 res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
2350 END_PROFILE(SMBlseek);
2351 return(UNIXERROR(ERRDOS,ERRnoaccess));
2357 outsize = set_message(outbuf,2,0,True);
2358 SIVAL(outbuf,smb_vwv0,res);
2360 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2361 fsp->fnum, (double)startpos, (double)res, mode));
2363 END_PROFILE(SMBlseek);
2367 /****************************************************************************
2369 ****************************************************************************/
2371 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2373 int outsize = set_message(outbuf,0,0,True);
2374 uint16 fnum = SVAL(inbuf,smb_vwv0);
2375 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2376 START_PROFILE(SMBflush);
2379 CHECK_FSP(fsp,conn);
2382 file_sync_all(conn);
2384 sync_file(conn,fsp);
2387 DEBUG(3,("flush\n"));
2388 END_PROFILE(SMBflush);
2392 /****************************************************************************
2394 ****************************************************************************/
2396 int reply_exit(connection_struct *conn,
2397 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2400 START_PROFILE(SMBexit);
2402 file_close_pid(SVAL(inbuf,smb_pid));
2404 outsize = set_message(outbuf,0,0,True);
2406 DEBUG(3,("exit\n"));
2408 END_PROFILE(SMBexit);
2412 /****************************************************************************
2413 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2414 ****************************************************************************/
2416 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
2419 extern struct current_user current_user;
2422 int32 eclass = 0, err = 0;
2423 files_struct *fsp = NULL;
2424 START_PROFILE(SMBclose);
2426 outsize = set_message(outbuf,0,0,True);
2428 /* If it's an IPC, pass off to the pipe handler. */
2430 END_PROFILE(SMBclose);
2431 return reply_pipe_close(conn, inbuf,outbuf);
2434 fsp = file_fsp(inbuf,smb_vwv0);
2437 * We can only use CHECK_FSP if we know it's not a directory.
2440 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
2441 END_PROFILE(SMBclose);
2442 return ERROR_DOS(ERRDOS,ERRbadfid);
2445 if(fsp->is_directory) {
2447 * Special case - close NT SMB directory handle.
2449 DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
2450 close_file(fsp,True);
2453 * Close ordinary file.
2458 /* Save the name for time set in close. */
2459 pstrcpy( file_name, fsp->fsp_name);
2461 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2463 conn->num_files_open));
2466 * close_file() returns the unix errno if an error
2467 * was detected on close - normally this is due to
2468 * a disk full error. If not then it was probably an I/O error.
2471 if((close_err = close_file(fsp,True)) != 0) {
2473 END_PROFILE(SMBclose);
2474 return (UNIXERROR(ERRHRD,ERRgeneral));
2478 * Now take care of any time sent in the close.
2481 mtime = make_unix_date3(inbuf+smb_vwv1);
2483 /* try and set the date */
2484 set_filetime(conn, file_name, mtime);
2488 /* We have a cached error */
2490 END_PROFILE(SMBclose);
2491 return ERROR_DOS(eclass,err);
2494 END_PROFILE(SMBclose);
2498 /****************************************************************************
2499 Reply to a writeclose (Core+ protocol).
2500 ****************************************************************************/
2502 int reply_writeclose(connection_struct *conn,
2503 char *inbuf,char *outbuf, int size, int dum_buffsize)
2506 ssize_t nwritten = -1;
2512 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2513 START_PROFILE(SMBwriteclose);
2515 CHECK_FSP(fsp,conn);
2518 numtowrite = SVAL(inbuf,smb_vwv1);
2519 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2520 mtime = make_unix_date3(inbuf+smb_vwv4);
2521 data = smb_buf(inbuf) + 1;
2523 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
2524 END_PROFILE(SMBwriteclose);
2525 return ERROR_DOS(ERRDOS,ERRlock);
2528 nwritten = write_file(fsp,data,startpos,numtowrite);
2530 set_filetime(conn, fsp->fsp_name,mtime);
2532 close_err = close_file(fsp,True);
2534 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2535 fsp->fnum, (int)numtowrite, (int)nwritten,
2536 conn->num_files_open));
2538 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2539 END_PROFILE(SMBwriteclose);
2540 return(UNIXERROR(ERRHRD,ERRdiskfull));
2543 if(close_err != 0) {
2545 END_PROFILE(SMBwriteclose);
2546 return(UNIXERROR(ERRHRD,ERRgeneral));
2549 outsize = set_message(outbuf,1,0,True);
2551 SSVAL(outbuf,smb_vwv0,nwritten);
2552 END_PROFILE(SMBwriteclose);
2556 /****************************************************************************
2558 ****************************************************************************/
2560 int reply_lock(connection_struct *conn,
2561 char *inbuf,char *outbuf, int length, int dum_buffsize)
2563 int outsize = set_message(outbuf,0,0,True);
2564 SMB_BIG_UINT count,offset;
2566 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2567 START_PROFILE(SMBlock);
2569 CHECK_FSP(fsp,conn);
2571 release_level_2_oplocks_on_change(fsp);
2573 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2574 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2576 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2577 fsp->fd, fsp->fnum, (double)offset, (double)count));
2579 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK);
2580 if (NT_STATUS_V(status)) {
2581 if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
2583 * A blocking lock was requested. Package up
2584 * this smb into a queued request and push it
2585 * onto the blocking lock queue.
2587 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), offset, count)) {
2588 END_PROFILE(SMBlock);
2592 END_PROFILE(SMBlock);
2593 return ERROR_NT(status);
2596 END_PROFILE(SMBlock);
2600 /****************************************************************************
2602 ****************************************************************************/
2604 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
2607 int outsize = set_message(outbuf,0,0,True);
2608 SMB_BIG_UINT count,offset;
2610 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2611 START_PROFILE(SMBunlock);
2613 CHECK_FSP(fsp,conn);
2615 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2616 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2618 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
2619 if (NT_STATUS_V(status)) {
2620 END_PROFILE(SMBunlock);
2621 return ERROR_NT(status);
2624 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2625 fsp->fd, fsp->fnum, (double)offset, (double)count ) );
2627 END_PROFILE(SMBunlock);
2631 /****************************************************************************
2633 ****************************************************************************/
2635 int reply_tdis(connection_struct *conn,
2636 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2638 int outsize = set_message(outbuf,0,0,True);
2640 START_PROFILE(SMBtdis);
2642 vuid = SVAL(inbuf,smb_uid);
2645 DEBUG(4,("Invalid connection in tdis\n"));
2646 END_PROFILE(SMBtdis);
2647 return ERROR_DOS(ERRSRV,ERRinvnid);
2652 close_cnum(conn,vuid);
2654 END_PROFILE(SMBtdis);
2658 /****************************************************************************
2660 ****************************************************************************/
2662 int reply_echo(connection_struct *conn,
2663 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2665 int smb_reverb = SVAL(inbuf,smb_vwv0);
2667 unsigned int data_len = smb_buflen(inbuf);
2668 int outsize = set_message(outbuf,1,data_len,True);
2669 START_PROFILE(SMBecho);
2671 data_len = MIN(data_len, (sizeof(inbuf)-(smb_buf(inbuf)-inbuf)));
2673 /* copy any incoming data back out */
2675 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
2677 if (smb_reverb > 100) {
2678 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
2682 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
2683 SSVAL(outbuf,smb_vwv0,seq_num);
2685 smb_setlen(outbuf,outsize - 4);
2687 if (!send_smb(smbd_server_fd(),outbuf))
2688 exit_server("reply_echo: send_smb failed.");
2691 DEBUG(3,("echo %d times\n", smb_reverb));
2695 END_PROFILE(SMBecho);
2699 /****************************************************************************
2700 Reply to a printopen.
2701 ****************************************************************************/
2703 int reply_printopen(connection_struct *conn,
2704 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2708 START_PROFILE(SMBsplopen);
2710 if (!CAN_PRINT(conn)) {
2711 END_PROFILE(SMBsplopen);
2712 return ERROR_DOS(ERRDOS,ERRnoaccess);
2715 /* Open for exclusive use, write only. */
2716 fsp = print_fsp_open(conn, NULL);
2719 END_PROFILE(SMBsplopen);
2720 return(UNIXERROR(ERRDOS,ERRnoaccess));
2723 outsize = set_message(outbuf,1,0,True);
2724 SSVAL(outbuf,smb_vwv0,fsp->fnum);
2726 DEBUG(3,("openprint fd=%d fnum=%d\n",
2727 fsp->fd, fsp->fnum));
2729 END_PROFILE(SMBsplopen);
2733 /****************************************************************************
2734 Reply to a printclose.
2735 ****************************************************************************/
2737 int reply_printclose(connection_struct *conn,
2738 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2740 int outsize = set_message(outbuf,0,0,True);
2741 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2743 START_PROFILE(SMBsplclose);
2745 CHECK_FSP(fsp,conn);
2747 if (!CAN_PRINT(conn)) {
2748 END_PROFILE(SMBsplclose);
2749 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
2752 DEBUG(3,("printclose fd=%d fnum=%d\n",
2753 fsp->fd,fsp->fnum));
2755 close_err = close_file(fsp,True);
2757 if(close_err != 0) {
2759 END_PROFILE(SMBsplclose);
2760 return(UNIXERROR(ERRHRD,ERRgeneral));
2763 END_PROFILE(SMBsplclose);
2767 /****************************************************************************
2768 Reply to a printqueue.
2769 ****************************************************************************/
2771 int reply_printqueue(connection_struct *conn,
2772 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2774 int outsize = set_message(outbuf,2,3,True);
2775 int max_count = SVAL(inbuf,smb_vwv0);
2776 int start_index = SVAL(inbuf,smb_vwv1);
2777 START_PROFILE(SMBsplretq);
2779 /* we used to allow the client to get the cnum wrong, but that
2780 is really quite gross and only worked when there was only
2781 one printer - I think we should now only accept it if they
2782 get it right (tridge) */
2783 if (!CAN_PRINT(conn)) {
2784 END_PROFILE(SMBsplretq);
2785 return ERROR_DOS(ERRDOS,ERRnoaccess);
2788 SSVAL(outbuf,smb_vwv0,0);
2789 SSVAL(outbuf,smb_vwv1,0);
2790 SCVAL(smb_buf(outbuf),0,1);
2791 SSVAL(smb_buf(outbuf),1,0);
2793 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
2794 start_index, max_count));
2797 print_queue_struct *queue = NULL;
2798 print_status_struct status;
2799 char *p = smb_buf(outbuf) + 3;
2800 int count = print_queue_status(SNUM(conn), &queue, &status);
2801 int num_to_get = ABS(max_count);
2802 int first = (max_count>0?start_index:start_index+max_count+1);
2808 num_to_get = MIN(num_to_get,count-first);
2811 for (i=first;i<first+num_to_get;i++) {
2812 put_dos_date2(p,0,queue[i].time);
2813 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
2814 SSVAL(p,5, queue[i].job);
2815 SIVAL(p,7,queue[i].size);
2817 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
2822 outsize = set_message(outbuf,2,28*count+3,False);
2823 SSVAL(outbuf,smb_vwv0,count);
2824 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
2825 SCVAL(smb_buf(outbuf),0,1);
2826 SSVAL(smb_buf(outbuf),1,28*count);
2831 DEBUG(3,("%d entries returned in queue\n",count));
2834 END_PROFILE(SMBsplretq);
2838 /****************************************************************************
2839 Reply to a printwrite.
2840 ****************************************************************************/
2842 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2845 int outsize = set_message(outbuf,0,0,True);
2847 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2849 START_PROFILE(SMBsplwr);
2851 if (!CAN_PRINT(conn)) {
2852 END_PROFILE(SMBsplwr);
2853 return ERROR_DOS(ERRDOS,ERRnoaccess);
2856 CHECK_FSP(fsp,conn);
2859 numtowrite = SVAL(smb_buf(inbuf),1);
2860 data = smb_buf(inbuf) + 3;
2862 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
2863 END_PROFILE(SMBsplwr);
2864 return(UNIXERROR(ERRHRD,ERRdiskfull));
2867 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
2869 END_PROFILE(SMBsplwr);
2873 /****************************************************************************
2874 The guts of the mkdir command, split out so it may be called by the NT SMB
2876 ****************************************************************************/
2878 NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
2880 BOOL bad_path = False;
2881 SMB_STRUCT_STAT sbuf;
2884 unix_convert(directory,conn,0,&bad_path,&sbuf);
2886 if (ms_has_wild(directory)) {
2887 return NT_STATUS_OBJECT_NAME_INVALID;
2890 if (check_name(directory, conn))
2891 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
2894 NTSTATUS nterr = NT_STATUS_OK;
2895 if(errno == ENOENT) {
2896 unix_ERR_class = ERRDOS;
2898 unix_ERR_code = ERRbadpath;
2899 nterr = NT_STATUS_OBJECT_PATH_NOT_FOUND;
2901 unix_ERR_code = ERRbadfile;
2902 nterr = NT_STATUS_OBJECT_NAME_NOT_FOUND;
2905 if (!NT_STATUS_IS_OK(nterr))
2907 return map_nt_error_from_unix(errno);
2910 return NT_STATUS_OK;
2913 /****************************************************************************
2915 ****************************************************************************/
2917 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2922 START_PROFILE(SMBmkdir);
2924 srvstr_pull_buf(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE);
2926 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
2928 status = mkdir_internal(conn, directory);
2929 if (!NT_STATUS_IS_OK(status))
2930 return ERROR_NT(status);
2932 outsize = set_message(outbuf,0,0,True);
2934 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
2936 END_PROFILE(SMBmkdir);
2940 /****************************************************************************
2941 Static function used by reply_rmdir to delete an entire directory
2942 tree recursively. Return False on ok, True on fail.
2943 ****************************************************************************/
2945 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
2947 const char *dname = NULL;
2949 void *dirptr = OpenDir(conn, directory, False);
2954 while((dname = ReadDirName(dirptr))) {
2958 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
2961 /* Construct the full name. */
2962 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
2968 pstrcpy(fullname, directory);
2969 pstrcat(fullname, "/");
2970 pstrcat(fullname, dname);
2972 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
2977 if(st.st_mode & S_IFDIR) {
2978 if(recursive_rmdir(conn, fullname)!=0) {
2982 if(SMB_VFS_RMDIR(conn,fullname) != 0) {
2986 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
2995 /****************************************************************************
2996 The internals of the rmdir code - called elsewhere.
2997 ****************************************************************************/
2999 BOOL rmdir_internals(connection_struct *conn, char *directory)
3003 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3004 if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
3006 * Check to see if the only thing in this directory are
3007 * vetoed files/directories. If so then delete them and
3008 * retry. If we fail to delete any of them (and we *don't*
3009 * do a recursive delete) then fail the rmdir.
3011 BOOL all_veto_files = True;
3013 void *dirptr = OpenDir(conn, directory, False);
3015 if(dirptr != NULL) {
3016 int dirpos = TellDir(dirptr);
3017 while ((dname = ReadDirName(dirptr))) {
3018 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3020 if(!IS_VETO_PATH(conn, dname)) {
3021 all_veto_files = False;
3026 if(all_veto_files) {
3027 SeekDir(dirptr,dirpos);
3028 while ((dname = ReadDirName(dirptr))) {
3032 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3035 /* Construct the full name. */
3036 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
3041 pstrcpy(fullname, directory);
3042 pstrcat(fullname, "/");
3043 pstrcat(fullname, dname);
3045 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
3047 if(st.st_mode & S_IFDIR) {
3048 if(lp_recursive_veto_delete(SNUM(conn))) {
3049 if(recursive_rmdir(conn, fullname) != 0)
3052 if(SMB_VFS_RMDIR(conn,fullname) != 0)
3054 } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
3058 /* Retry the rmdir */
3059 ok = (SMB_VFS_RMDIR(conn,directory) == 0);
3069 DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory,strerror(errno)));
3074 /****************************************************************************
3076 ****************************************************************************/
3078 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3083 BOOL bad_path = False;
3084 SMB_STRUCT_STAT sbuf;
3085 START_PROFILE(SMBrmdir);
3087 srvstr_pull_buf(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE);
3089 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
3091 unix_convert(directory,conn, NULL,&bad_path,&sbuf);
3093 if (check_name(directory,conn)) {
3094 dptr_closepath(directory,SVAL(inbuf,smb_pid));
3095 ok = rmdir_internals(conn, directory);
3099 END_PROFILE(SMBrmdir);
3100 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRbadpath);
3103 outsize = set_message(outbuf,0,0,True);
3105 DEBUG( 3, ( "rmdir %s\n", directory ) );
3107 END_PROFILE(SMBrmdir);
3111 /*******************************************************************
3112 Resolve wildcards in a filename rename.
3113 ********************************************************************/
3115 static BOOL resolve_wildcards(const char *name1, char *name2)
3117 fstring root1,root2;
3119 char *p,*p2, *pname1, *pname2;
3120 int available_space;
3123 pname1 = strrchr_m(name1,'/');
3124 pname2 = strrchr_m(name2,'/');
3126 if (!pname1 || !pname2)
3129 fstrcpy(root1,pname1);
3130 fstrcpy(root2,pname2);
3131 p = strrchr_m(root1,'.');
3138 p = strrchr_m(root2,'.');
3172 available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
3175 snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
3177 pstrcpy_base(pname2, root2, name2);
3183 /****************************************************************************
3184 Ensure open files have their names updates.
3185 ****************************************************************************/
3187 static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, char *newname)
3190 BOOL did_rename = False;
3192 for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
3193 DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
3194 fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode,
3195 fsp->fsp_name, newname ));
3196 string_set(&fsp->fsp_name, newname);
3201 DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
3202 (unsigned int)dev, (double)inode, newname ));
3205 /****************************************************************************
3206 Rename an open file - given an fsp.
3207 ****************************************************************************/
3209 NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, BOOL replace_if_exists)
3211 SMB_STRUCT_STAT sbuf;
3212 BOOL bad_path = False;
3213 pstring newname_last_component;
3214 NTSTATUS error = NT_STATUS_OK;
3218 unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf);
3220 /* Ensure newname contains a '/' */
3221 if(strrchr_m(newname,'/') == 0) {
3224 pstrcpy(tmpstr, "./");
3225 pstrcat(tmpstr, newname);
3226 pstrcpy(newname, tmpstr);
3230 * Check for special case with case preserving and not
3231 * case sensitive. If the old last component differs from the original
3232 * last component only by case, then we should allow
3233 * the rename (user is trying to change the case of the
3237 if((case_sensitive == False) && (case_preserve == True) &&
3238 strequal(newname, fsp->fsp_name)) {
3240 pstring newname_modified_last_component;
3243 * Get the last component of the modified name.
3244 * Note that we guarantee that newname contains a '/'
3247 p = strrchr_m(newname,'/');
3248 pstrcpy(newname_modified_last_component,p+1);
3250 if(strcsequal(newname_modified_last_component,
3251 newname_last_component) == False) {
3253 * Replace the modified last component with
3256 pstrcpy(p+1, newname_last_component);
3261 * If the src and dest names are identical - including case,
3262 * don't do the rename, just return success.
3265 if (strcsequal(fsp->fsp_name, newname)) {
3266 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
3268 return NT_STATUS_OK;
3271 dest_exists = vfs_object_exist(conn,newname,NULL);
3273 if(!replace_if_exists && dest_exists) {
3274 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
3275 fsp->fsp_name,newname));
3276 return NT_STATUS_OBJECT_NAME_COLLISION;
3279 error = can_rename(newname,conn,&sbuf);
3281 if (dest_exists && !NT_STATUS_IS_OK(error)) {
3282 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3283 nt_errstr(error), fsp->fsp_name,newname));
3284 if (NT_STATUS_EQUAL(error,NT_STATUS_SHARING_VIOLATION))
3285 error = NT_STATUS_ACCESS_DENIED;
3289 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
3290 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
3291 fsp->fsp_name,newname));
3292 rename_open_files(conn, fsp->dev, fsp->inode, newname);
3293 return NT_STATUS_OK;
3296 if (errno == ENOTDIR || errno == EISDIR)
3297 error = NT_STATUS_OBJECT_NAME_COLLISION;
3299 error = map_nt_error_from_unix(errno);
3301 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
3302 nt_errstr(error), fsp->fsp_name,newname));
3307 /****************************************************************************
3308 The guts of the rename command, split out so it may be called by the NT SMB
3310 ****************************************************************************/
3312 NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists)
3316 pstring newname_last_component;
3319 BOOL bad_path1 = False;
3320 BOOL bad_path2 = False;
3322 NTSTATUS error = NT_STATUS_OK;
3324 SMB_STRUCT_STAT sbuf1, sbuf2;
3326 *directory = *mask = 0;
3330 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
3331 unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2);
3334 * Split the old name into directory and last component
3335 * strings. Note that unix_convert may have stripped off a
3336 * leading ./ from both name and newname if the rename is
3337 * at the root of the share. We need to make sure either both
3338 * name and newname contain a / character or neither of them do
3339 * as this is checked in resolve_wildcards().
3342 p = strrchr_m(name,'/');
3344 pstrcpy(directory,".");
3348 pstrcpy(directory,name);
3350 *p = '/'; /* Replace needed for exceptional test below. */
3354 * We should only check the mangled cache
3355 * here if unix_convert failed. This means
3356 * that the path in 'mask' doesn't exist
3357 * on the file system and so we need to look
3358 * for a possible mangle. This patch from
3359 * Tine Smukavec <valentin.smukavec@hermes.si>.
3362 if (!rc && mangle_is_mangled(mask))
3363 mangle_check_cache( mask );
3365 has_wild = ms_has_wild(mask);
3369 * No wildcards - just process the one file.
3371 BOOL is_short_name = mangle_is_8_3(name, True);
3373 /* Add a terminating '/' to the directory name. */
3374 pstrcat(directory,"/");
3375 pstrcat(directory,mask);
3377 /* Ensure newname contains a '/' also */
3378 if(strrchr_m(newname,'/') == 0) {
3381 pstrcpy(tmpstr, "./");
3382 pstrcat(tmpstr, newname);
3383 pstrcpy(newname, tmpstr);
3386 DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
3387 directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
3388 case_sensitive, case_preserve, short_case_preserve, directory,
3389 newname, newname_last_component, is_short_name));
3392 * Check for special case with case preserving and not
3393 * case sensitive, if directory and newname are identical,
3394 * and the old last component differs from the original
3395 * last component only by case, then we should allow
3396 * the rename (user is trying to change the case of the
3399 if((case_sensitive == False) &&
3400 (((case_preserve == True) &&
3401 (is_short_name == False)) ||
3402 ((short_case_preserve == True) &&
3403 (is_short_name == True))) &&
3404 strcsequal(directory, newname)) {
3405 pstring newname_modified_last_component;
3408 * Get the last component of the modified name.
3409 * Note that we guarantee that newname contains a '/'
3412 p = strrchr_m(newname,'/');
3413 pstrcpy(newname_modified_last_component,p+1);
3415 if(strcsequal(newname_modified_last_component,
3416 newname_last_component) == False) {
3418 * Replace the modified last component with
3421 pstrcpy(p+1, newname_last_component);
3425 resolve_wildcards(directory,newname);
3428 * The source object must exist.
3431 if (!vfs_object_exist(conn, directory, &sbuf1)) {
3432 DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
3433 directory,newname));
3435 if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
3437 * Must return different errors depending on whether the parent
3438 * directory existed or not.
3441 p = strrchr_m(directory, '/');
3443 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3445 if (vfs_object_exist(conn, directory, NULL))
3446 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3447 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3449 error = map_nt_error_from_unix(errno);
3450 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3451 nt_errstr(error), directory,newname));
3456 error = can_rename(directory,conn,&sbuf1);
3458 if (!NT_STATUS_IS_OK(error)) {
3459 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3460 nt_errstr(error), directory,newname));
3465 * If the src and dest names are identical - including case,
3466 * don't do the rename, just return success.
3469 if (strcsequal(directory, newname)) {
3470 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3471 DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
3472 return NT_STATUS_OK;
3475 if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
3476 DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
3477 directory,newname));
3478 return NT_STATUS_OBJECT_NAME_COLLISION;
3481 if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
3482 DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
3483 directory,newname));
3484 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3485 return NT_STATUS_OK;
3488 if (errno == ENOTDIR || errno == EISDIR)
3489 error = NT_STATUS_OBJECT_NAME_COLLISION;
3491 error = map_nt_error_from_unix(errno);
3493 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
3494 nt_errstr(error), directory,newname));
3499 * Wildcards - process each file that matches.
3501 void *dirptr = NULL;
3505 if (check_name(directory,conn))
3506 dirptr = OpenDir(conn, directory, True);
3509 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3511 if (strequal(mask,"????????.???"))
3514 while ((dname = ReadDirName(dirptr))) {
3517 pstrcpy(fname,dname);
3519 if(!mask_match(fname, mask, case_sensitive))
3522 error = NT_STATUS_ACCESS_DENIED;
3523 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
3524 if (!vfs_object_exist(conn, fname, &sbuf1)) {
3525 error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3526 DEBUG(6,("rename %s failed. Error %s\n", fname, nt_errstr(error)));
3529 error = can_rename(fname,conn,&sbuf1);
3530 if (!NT_STATUS_IS_OK(error)) {
3531 DEBUG(6,("rename %s refused\n", fname));
3534 pstrcpy(destname,newname);
3536 if (!resolve_wildcards(fname,destname)) {
3537 DEBUG(6,("resolve_wildcards %s %s failed\n",
3542 if (!replace_if_exists &&
3543 vfs_file_exist(conn,destname, NULL)) {
3544 DEBUG(6,("file_exist %s\n", destname));
3545 error = NT_STATUS_OBJECT_NAME_COLLISION;
3549 if (!SMB_VFS_RENAME(conn,fname,destname)) {
3550 rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
3553 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
3559 if (count == 0 && NT_STATUS_IS_OK(error)) {
3560 error = map_nt_error_from_unix(errno);
3566 /****************************************************************************
3568 ****************************************************************************/
3570 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
3579 START_PROFILE(SMBmv);
3581 p = smb_buf(inbuf) + 1;
3582 p += srvstr_pull_buf(inbuf, name, p, sizeof(name), STR_TERMINATE);
3584 p += srvstr_pull_buf(inbuf, newname, p, sizeof(newname), STR_TERMINATE);
3586 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3587 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3589 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
3591 status = rename_internals(conn, name, newname, False);
3592 if (!NT_STATUS_IS_OK(status)) {
3593 return ERROR_NT(status);
3597 * Win2k needs a changenotify request response before it will
3598 * update after a rename..
3600 process_pending_change_notify_queue((time_t)0);
3601 outsize = set_message(outbuf,0,0,True);
3607 /*******************************************************************
3608 Copy a file as part of a reply_copy.
3609 ******************************************************************/
3611 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
3612 int count,BOOL target_is_directory, int *err_ret)
3615 SMB_STRUCT_STAT src_sbuf, sbuf2;
3617 files_struct *fsp1,*fsp2;
3622 pstrcpy(dest,dest1);
3623 if (target_is_directory) {
3624 char *p = strrchr_m(src,'/');
3633 if (!vfs_file_exist(conn,src,&src_sbuf))
3636 fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
3637 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
3642 if (!target_is_directory && count)
3643 ofun = FILE_EXISTS_OPEN;
3645 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
3646 ZERO_STRUCTP(&sbuf2);
3648 fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
3649 ofun,src_sbuf.st_mode,0,&Access,&action);
3652 close_file(fsp1,False);
3656 if ((ofun&3) == 1) {
3657 if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
3658 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
3660 * Stop the copy from occurring.
3663 src_sbuf.st_size = 0;
3667 if (src_sbuf.st_size)
3668 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
3670 close_file(fsp1,False);
3672 /* Ensure the modtime is set correctly on the destination file. */
3673 fsp2->pending_modtime = src_sbuf.st_mtime;
3676 * As we are opening fsp1 read-only we only expect
3677 * an error on close on fsp2 if we are out of space.
3678 * Thus we don't look at the error return from the
3681 *err_ret = close_file(fsp2,False);
3683 return(ret == (SMB_OFF_T)src_sbuf.st_size);
3686 /****************************************************************************
3687 Reply to a file copy.
3688 ****************************************************************************/
3690 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3695 pstring mask,newname;
3698 int error = ERRnoaccess;
3702 int tid2 = SVAL(inbuf,smb_vwv0);
3703 int ofun = SVAL(inbuf,smb_vwv1);
3704 int flags = SVAL(inbuf,smb_vwv2);
3705 BOOL target_is_directory=False;
3706 BOOL bad_path1 = False;
3707 BOOL bad_path2 = False;
3709 SMB_STRUCT_STAT sbuf1, sbuf2;
3711 START_PROFILE(SMBcopy);
3713 *directory = *mask = 0;
3716 p += srvstr_pull_buf(inbuf, name, p, sizeof(name), STR_TERMINATE);
3717 p += srvstr_pull_buf(inbuf, newname, p, sizeof(newname), STR_TERMINATE);
3719 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
3721 if (tid2 != conn->cnum) {
3722 /* can't currently handle inter share copies XXXX */
3723 DEBUG(3,("Rejecting inter-share copy\n"));
3724 END_PROFILE(SMBcopy);
3725 return ERROR_DOS(ERRSRV,ERRinvdevice);
3728 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
3729 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3731 rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
3732 unix_convert(newname,conn,0,&bad_path2,&sbuf2);
3734 target_is_directory = VALID_STAT_OF_DIR(sbuf2);
3736 if ((flags&1) && target_is_directory) {
3737 END_PROFILE(SMBcopy);
3738 return ERROR_DOS(ERRDOS,ERRbadfile);
3741 if ((flags&2) && !target_is_directory) {
3742 END_PROFILE(SMBcopy);
3743 return ERROR_DOS(ERRDOS,ERRbadpath);
3746 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
3747 /* wants a tree copy! XXXX */
3748 DEBUG(3,("Rejecting tree copy\n"));
3749 END_PROFILE(SMBcopy);
3750 return ERROR_DOS(ERRSRV,ERRerror);
3753 p = strrchr_m(name,'/');
3755 pstrcpy(directory,"./");
3759 pstrcpy(directory,name);
3764 * We should only check the mangled cache
3765 * here if unix_convert failed. This means
3766 * that the path in 'mask' doesn't exist
3767 * on the file system and so we need to look
3768 * for a possible mangle. This patch from
3769 * Tine Smukavec <valentin.smukavec@hermes.si>.
3772 if (!rc && mangle_is_mangled(mask))
3773 mangle_check_cache( mask );
3775 has_wild = ms_has_wild(mask);
3778 pstrcat(directory,"/");
3779 pstrcat(directory,mask);
3780 if (resolve_wildcards(directory,newname) &&
3781 copy_file(directory,newname,conn,ofun, count,target_is_directory,&err))
3785 END_PROFILE(SMBcopy);
3786 return(UNIXERROR(ERRHRD,ERRgeneral));
3789 exists = vfs_file_exist(conn,directory,NULL);
3792 void *dirptr = NULL;
3796 if (check_name(directory,conn))
3797 dirptr = OpenDir(conn, directory, True);
3802 if (strequal(mask,"????????.???"))
3805 while ((dname = ReadDirName(dirptr))) {
3807 pstrcpy(fname,dname);
3809 if(!mask_match(fname, mask, case_sensitive))
3812 error = ERRnoaccess;
3813 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
3814 pstrcpy(destname,newname);
3815 if (resolve_wildcards(fname,destname) &&
3816 copy_file(fname,destname,conn,ofun,
3817 count,target_is_directory,&err))
3819 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
3827 /* Error on close... */
3829 END_PROFILE(SMBcopy);
3830 return(UNIXERROR(ERRHRD,ERRgeneral));
3834 END_PROFILE(SMBcopy);
3835 return ERROR_DOS(ERRDOS,error);
3837 if((errno == ENOENT) && (bad_path1 || bad_path2)) {
3838 unix_ERR_class = ERRDOS;
3839 unix_ERR_code = ERRbadpath;
3841 END_PROFILE(SMBcopy);
3842 return(UNIXERROR(ERRDOS,error));
3846 outsize = set_message(outbuf,1,0,True);
3847 SSVAL(outbuf,smb_vwv0,count);
3849 END_PROFILE(SMBcopy);
3853 /****************************************************************************
3855 ****************************************************************************/
3857 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3864 START_PROFILE(pathworks_setdir);
3867 if (!CAN_SETDIR(snum)) {
3868 END_PROFILE(pathworks_setdir);
3869 return ERROR_DOS(ERRDOS,ERRnoaccess);
3872 srvstr_pull_buf(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), STR_TERMINATE);
3874 if (strlen(newdir) == 0) {
3877 ok = vfs_directory_exist(conn,newdir,NULL);
3879 string_set(&conn->connectpath,newdir);
3883 END_PROFILE(pathworks_setdir);
3884 return ERROR_DOS(ERRDOS,ERRbadpath);
3887 outsize = set_message(outbuf,0,0,True);
3888 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
3890 DEBUG(3,("setdir %s\n", newdir));
3892 END_PROFILE(pathworks_setdir);
3896 /****************************************************************************
3897 Get a lock pid, dealing with large count requests.
3898 ****************************************************************************/
3900 uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
3902 if(!large_file_format)
3903 return SVAL(data,SMB_LPID_OFFSET(data_offset));
3905 return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
3908 /****************************************************************************
3909 Get a lock count, dealing with large count requests.
3910 ****************************************************************************/
3912 SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
3914 SMB_BIG_UINT count = 0;
3916 if(!large_file_format) {
3917 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
3920 #if defined(HAVE_LONGLONG)
3921 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
3922 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
3923 #else /* HAVE_LONGLONG */
3926 * NT4.x seems to be broken in that it sends large file (64 bit)
3927 * lockingX calls even if the CAP_LARGE_FILES was *not*
3928 * negotiated. For boxes without large unsigned ints truncate the
3929 * lock count by dropping the top 32 bits.
3932 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
3933 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
3934 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
3935 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
3936 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
3939 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
3940 #endif /* HAVE_LONGLONG */
3946 #if !defined(HAVE_LONGLONG)
3947 /****************************************************************************
3948 Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
3949 ****************************************************************************/
3951 static uint32 map_lock_offset(uint32 high, uint32 low)
3955 uint32 highcopy = high;
3958 * Try and find out how many significant bits there are in high.
3961 for(i = 0; highcopy; i++)
3965 * We use 31 bits not 32 here as POSIX
3966 * lock offsets may not be negative.
3969 mask = (~0) << (31 - i);
3972 return 0; /* Fail. */
3978 #endif /* !defined(HAVE_LONGLONG) */
3980 /****************************************************************************
3981 Get a lock offset, dealing with large offset requests.
3982 ****************************************************************************/
3984 SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
3986 SMB_BIG_UINT offset = 0;
3990 if(!large_file_format) {
3991 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
3994 #if defined(HAVE_LONGLONG)
3995 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
3996 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
3997 #else /* HAVE_LONGLONG */
4000 * NT4.x seems to be broken in that it sends large file (64 bit)
4001 * lockingX calls even if the CAP_LARGE_FILES was *not*
4002 * negotiated. For boxes without large unsigned ints mangle the
4003 * lock offset by mapping the top 32 bits onto the lower 32.
4006 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
4007 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4008 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
4011 if((new_low = map_lock_offset(high, low)) == 0) {
4013 return (SMB_BIG_UINT)-1;
4016 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
4017 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
4018 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
4019 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
4022 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4023 #endif /* HAVE_LONGLONG */
4029 /****************************************************************************
4030 Reply to a lockingX request.
4031 ****************************************************************************/
4033 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4035 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
4036 unsigned char locktype = CVAL(inbuf,smb_vwv3);
4037 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
4038 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
4039 uint16 num_locks = SVAL(inbuf,smb_vwv7);
4040 SMB_BIG_UINT count = 0, offset = 0;
4042 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
4045 BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
4049 START_PROFILE(SMBlockingX);
4051 CHECK_FSP(fsp,conn);
4053 data = smb_buf(inbuf);
4055 if (locktype & (LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_CHANGE_LOCKTYPE)) {
4056 /* we don't support these - and CANCEL_LOCK makes w2k
4057 and XP reboot so I don't really want to be
4058 compatible! (tridge) */
4059 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4062 /* Check if this is an oplock break on a file
4063 we have granted an oplock on.
4065 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
4066 /* Client can insist on breaking to none. */
4067 BOOL break_to_none = (oplocklevel == 0);
4069 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
4070 (unsigned int)oplocklevel, fsp->fnum ));
4073 * Make sure we have granted an exclusive or batch oplock on this file.
4076 if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
4077 DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
4078 no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
4080 /* if this is a pure oplock break request then don't send a reply */
4081 if (num_locks == 0 && num_ulocks == 0) {
4082 END_PROFILE(SMBlockingX);
4085 END_PROFILE(SMBlockingX);
4086 return ERROR_DOS(ERRDOS,ERRlock);
4090 if (remove_oplock(fsp, break_to_none) == False) {
4091 DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
4095 /* if this is a pure oplock break request then don't send a reply */
4096 if (num_locks == 0 && num_ulocks == 0) {
4097 /* Sanity check - ensure a pure oplock break is not a
4099 if(CVAL(inbuf,smb_vwv0) != 0xff)
4100 DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
4101 (unsigned int)CVAL(inbuf,smb_vwv0) ));
4102 END_PROFILE(SMBlockingX);
4108 * We do this check *after* we have checked this is not a oplock break
4109 * response message. JRA.
4112 release_level_2_oplocks_on_change(fsp);
4114 /* Data now points at the beginning of the list
4115 of smb_unlkrng structs */
4116 for(i = 0; i < (int)num_ulocks; i++) {
4117 lock_pid = get_lock_pid( data, i, large_file_format);
4118 count = get_lock_count( data, i, large_file_format);
4119 offset = get_lock_offset( data, i, large_file_format, &err);
4122 * There is no error code marked "stupid client bug".... :-).
4125 END_PROFILE(SMBlockingX);
4126 return ERROR_DOS(ERRDOS,ERRnoaccess);
4129 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
4130 (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
4132 status = do_unlock(fsp,conn,lock_pid,count,offset);
4133 if (NT_STATUS_V(status)) {
4134 END_PROFILE(SMBlockingX);
4135 return ERROR_NT(status);
4139 /* Setup the timeout in seconds. */
4141 lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+499)/500);
4143 /* Now do any requested locks */
4144 data += ((large_file_format ? 20 : 10)*num_ulocks);
4146 /* Data now points at the beginning of the list
4147 of smb_lkrng structs */
4149 for(i = 0; i < (int)num_locks; i++) {
4150 lock_pid = get_lock_pid( data, i, large_file_format);
4151 count = get_lock_count( data, i, large_file_format);
4152 offset = get_lock_offset( data, i, large_file_format, &err);
4155 * There is no error code marked "stupid client bug".... :-).
4158 END_PROFILE(SMBlockingX);
4159 return ERROR_DOS(ERRDOS,ERRnoaccess);
4162 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
4163 (double)offset, (double)count, (unsigned int)lock_pid,
4164 fsp->fsp_name, (int)lock_timeout ));
4166 status = do_lock_spin(fsp,conn,lock_pid, count,offset,
4167 ((locktype & 1) ? READ_LOCK : WRITE_LOCK));
4168 if (NT_STATUS_V(status)) {
4169 if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
4171 * A blocking lock was requested. Package up
4172 * this smb into a queued request and push it
4173 * onto the blocking lock queue.
4175 if(push_blocking_lock_request(inbuf, length, lock_timeout, i, lock_pid, offset, count)) {
4176 END_PROFILE(SMBlockingX);
4184 /* If any of the above locks failed, then we must unlock
4185 all of the previous locks (X/Open spec). */
4186 if (i != num_locks && num_locks != 0) {
4188 * Ensure we don't do a remove on the lock that just failed,
4189 * as under POSIX rules, if we have a lock already there, we
4190 * will delete it (and we shouldn't) .....
4192 for(i--; i >= 0; i--) {
4193 lock_pid = get_lock_pid( data, i, large_file_format);
4194 count = get_lock_count( data, i, large_file_format);
4195 offset = get_lock_offset( data, i, large_file_format, &err);
4198 * There is no error code marked "stupid client bug".... :-).
4201 END_PROFILE(SMBlockingX);
4202 return ERROR_DOS(ERRDOS,ERRnoaccess);
4205 do_unlock(fsp,conn,lock_pid,count,offset);
4207 END_PROFILE(SMBlockingX);
4208 return ERROR_NT(status);
4211 set_message(outbuf,2,0,True);
4213 DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
4214 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
4216 END_PROFILE(SMBlockingX);
4217 return chain_reply(inbuf,outbuf,length,bufsize);
4220 /****************************************************************************
4221 Reply to a SMBreadbmpx (read block multiplex) request.
4222 ****************************************************************************/
4224 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4235 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4236 START_PROFILE(SMBreadBmpx);
4238 /* this function doesn't seem to work - disable by default */
4239 if (!lp_readbmpx()) {
4240 END_PROFILE(SMBreadBmpx);
4241 return ERROR_DOS(ERRSRV,ERRuseSTD);
4244 outsize = set_message(outbuf,8,0,True);
4246 CHECK_FSP(fsp,conn);
4249 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
4250 maxcount = SVAL(inbuf,smb_vwv3);
4252 data = smb_buf(outbuf);
4253 pad = ((long)data)%4;
4258 max_per_packet = bufsize-(outsize+pad);
4262 if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
4263 END_PROFILE(SMBreadBmpx);
4264 return ERROR_DOS(ERRDOS,ERRlock);
4268 size_t N = MIN(max_per_packet,tcount-total_read);
4270 nread = read_file(fsp,data,startpos,N);
4275 if (nread < (ssize_t)N)
4276 tcount = total_read + nread;
4278 set_message(outbuf,8,nread,False);
4279 SIVAL(outbuf,smb_vwv0,startpos);
4280 SSVAL(outbuf,smb_vwv2,tcount);
4281 SSVAL(outbuf,smb_vwv6,nread);
4282 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
4284 if (!send_smb(smbd_server_fd(),outbuf))
4285 exit_server("reply_readbmpx: send_smb failed.");
4287 total_read += nread;
4289 } while (total_read < (ssize_t)tcount);
4291 END_PROFILE(SMBreadBmpx);
4295 /****************************************************************************
4296 Reply to a SMBsetattrE.
4297 ****************************************************************************/
4299 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4301 struct utimbuf unix_times;
4303 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4304 START_PROFILE(SMBsetattrE);
4306 outsize = set_message(outbuf,0,0,True);
4308 if(!fsp || (fsp->conn != conn)) {
4309 END_PROFILE(SMBgetattrE);
4310 return ERROR_DOS(ERRDOS,ERRbadfid);
4314 * Convert the DOS times into unix times. Ignore create
4315 * time as UNIX can't set this.
4318 unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
4319 unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
4322 * Patch from Ray Frush <frush@engr.colostate.edu>
4323 * Sometimes times are sent as zero - ignore them.
4326 if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
4327 /* Ignore request */
4328 if( DEBUGLVL( 3 ) ) {
4329 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
4330 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
4332 END_PROFILE(SMBsetattrE);
4334 } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
4335 /* set modify time = to access time if modify time was 0 */
4336 unix_times.modtime = unix_times.actime;
4339 /* Set the date on this file */
4340 if(file_utime(conn, fsp->fsp_name, &unix_times)) {
4341 END_PROFILE(SMBsetattrE);
4342 return ERROR_DOS(ERRDOS,ERRnoaccess);
4345 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
4346 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
4348 END_PROFILE(SMBsetattrE);
4353 /* Back from the dead for OS/2..... JRA. */
4355 /****************************************************************************
4356 Reply to a SMBwritebmpx (write block multiplex primary) request.
4357 ****************************************************************************/
4359 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4362 ssize_t nwritten = -1;
4369 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4370 START_PROFILE(SMBwriteBmpx);
4372 CHECK_FSP(fsp,conn);
4376 tcount = SVAL(inbuf,smb_vwv1);
4377 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
4378 write_through = BITSETW(inbuf+smb_vwv7,0);
4379 numtowrite = SVAL(inbuf,smb_vwv10);
4380 smb_doff = SVAL(inbuf,smb_vwv11);
4382 data = smb_base(inbuf) + smb_doff;
4384 /* If this fails we need to send an SMBwriteC response,
4385 not an SMBwritebmpx - set this up now so we don't forget */
4386 SCVAL(outbuf,smb_com,SMBwritec);
4388 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
4389 END_PROFILE(SMBwriteBmpx);
4390 return(ERROR_DOS(ERRDOS,ERRlock));
4393 nwritten = write_file(fsp,data,startpos,numtowrite);
4395 if(lp_syncalways(SNUM(conn)) || write_through)
4396 sync_file(conn,fsp);
4398 if(nwritten < (ssize_t)numtowrite) {
4399 END_PROFILE(SMBwriteBmpx);
4400 return(UNIXERROR(ERRHRD,ERRdiskfull));
4403 /* If the maximum to be written to this file
4404 is greater than what we just wrote then set
4405 up a secondary struct to be attached to this
4406 fd, we will use this to cache error messages etc. */
4408 if((ssize_t)tcount > nwritten) {
4409 write_bmpx_struct *wbms;
4410 if(fsp->wbmpx_ptr != NULL)
4411 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
4413 wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
4415 DEBUG(0,("Out of memory in reply_readmpx\n"));
4416 END_PROFILE(SMBwriteBmpx);
4417 return(ERROR_DOS(ERRSRV,ERRnoresource));
4419 wbms->wr_mode = write_through;
4420 wbms->wr_discard = False; /* No errors yet */
4421 wbms->wr_total_written = nwritten;
4422 wbms->wr_errclass = 0;
4424 fsp->wbmpx_ptr = wbms;
4427 /* We are returning successfully, set the message type back to
4429 SCVAL(outbuf,smb_com,SMBwriteBmpx);
4431 outsize = set_message(outbuf,1,0,True);
4433 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
4435 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
4436 fsp->fnum, (int)numtowrite, (int)nwritten ) );
4438 if (write_through && tcount==nwritten) {
4439 /* We need to send both a primary and a secondary response */
4440 smb_setlen(outbuf,outsize - 4);
4441 if (!send_smb(smbd_server_fd(),outbuf))
4442 exit_server("reply_writebmpx: send_smb failed.");
4444 /* Now the secondary */
4445 outsize = set_message(outbuf,1,0,True);
4446 SCVAL(outbuf,smb_com,SMBwritec);
4447 SSVAL(outbuf,smb_vwv0,nwritten);
4450 END_PROFILE(SMBwriteBmpx);
4454 /****************************************************************************
4455 Reply to a SMBwritebs (write block multiplex secondary) request.
4456 ****************************************************************************/
4458 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4461 ssize_t nwritten = -1;
4468 write_bmpx_struct *wbms;
4469 BOOL send_response = False;
4470 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4471 START_PROFILE(SMBwriteBs);
4473 CHECK_FSP(fsp,conn);
4476 tcount = SVAL(inbuf,smb_vwv1);
4477 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
4478 numtowrite = SVAL(inbuf,smb_vwv6);
4479 smb_doff = SVAL(inbuf,smb_vwv7);
4481 data = smb_base(inbuf) + smb_doff;
4483 /* We need to send an SMBwriteC response, not an SMBwritebs */
4484 SCVAL(outbuf,smb_com,SMBwritec);
4486 /* This fd should have an auxiliary struct attached,
4487 check that it does */
4488 wbms = fsp->wbmpx_ptr;
4490 END_PROFILE(SMBwriteBs);
4494 /* If write through is set we can return errors, else we must cache them */
4495 write_through = wbms->wr_mode;
4497 /* Check for an earlier error */
4498 if(wbms->wr_discard) {
4499 END_PROFILE(SMBwriteBs);
4500 return -1; /* Just discard the packet */
4503 nwritten = write_file(fsp,data,startpos,numtowrite);
4505 if(lp_syncalways(SNUM(conn)) || write_through)
4506 sync_file(conn,fsp);
4508 if (nwritten < (ssize_t)numtowrite) {
4510 /* We are returning an error - we can delete the aux struct */
4513 fsp->wbmpx_ptr = NULL;
4514 END_PROFILE(SMBwriteBs);
4515 return(ERROR_DOS(ERRHRD,ERRdiskfull));
4517 END_PROFILE(SMBwriteBs);
4518 return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
4521 /* Increment the total written, if this matches tcount
4522 we can discard the auxiliary struct (hurrah !) and return a writeC */
4523 wbms->wr_total_written += nwritten;
4524 if(wbms->wr_total_written >= tcount) {
4525 if (write_through) {
4526 outsize = set_message(outbuf,1,0,True);
4527 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
4528 send_response = True;
4532 fsp->wbmpx_ptr = NULL;
4536 END_PROFILE(SMBwriteBs);
4540 END_PROFILE(SMBwriteBs);
4544 /****************************************************************************
4545 Reply to a SMBgetattrE.
4546 ****************************************************************************/
4548 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4550 SMB_STRUCT_STAT sbuf;
4553 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4554 START_PROFILE(SMBgetattrE);
4556 outsize = set_message(outbuf,11,0,True);
4558 if(!fsp || (fsp->conn != conn)) {
4559 END_PROFILE(SMBgetattrE);
4560 return ERROR_DOS(ERRDOS,ERRbadfid);
4563 /* Do an fstat on this file */
4564 if(fsp_stat(fsp, &sbuf)) {
4565 END_PROFILE(SMBgetattrE);
4566 return(UNIXERROR(ERRDOS,ERRnoaccess));
4569 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
4572 * Convert the times into dos times. Set create
4573 * date to be last modify date as UNIX doesn't save
4577 put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
4578 put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
4579 put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
4582 SIVAL(outbuf,smb_vwv6,0);
4583 SIVAL(outbuf,smb_vwv8,0);
4585 uint32 allocation_size = get_allocation_size(fsp, &sbuf);
4586 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
4587 SIVAL(outbuf,smb_vwv8,allocation_size);
4589 SSVAL(outbuf,smb_vwv10, mode);
4591 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
4593 END_PROFILE(SMBgetattrE);