2 Unix SMB/CIFS implementation.
3 Main SMB reply routines
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jeremy Allison 1992-2004.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 This file handles most of the reply_ calls that the server
24 makes to handle specific protocols
29 /* look in server.c for some explanation of these variables */
30 extern enum protocol_types Protocol;
33 extern char magic_char;
34 extern int global_oplock_break;
35 unsigned int smb_echo_count = 0;
36 extern uint32 global_client_caps;
38 extern BOOL global_encrypted_passwords_negotiated;
40 /****************************************************************************
41 Ensure we check the path in *exactly* the same way as W2K.
42 We're assuming here that '/' is not the second byte in any multibyte char
43 set (a safe assumption). '\\' *may* be the second byte in a multibyte char
45 ****************************************************************************/
47 NTSTATUS check_path_syntax(pstring destname, const pstring srcname, BOOL allow_wcard_names)
50 const char *s = srcname;
51 NTSTATUS ret = NT_STATUS_OK;
52 BOOL start_of_name_component = True;
53 unsigned int num_bad_components = 0;
56 if (IS_DIRECTORY_SEP(*s)) {
58 * Safe to assume is not the second part of a mb char as this is handled below.
60 /* Eat multiple '/' or '\\' */
61 while (IS_DIRECTORY_SEP(*s)) {
64 if ((d != destname) && (*s != '\0')) {
65 /* We only care about non-leading or trailing '/' or '\\' */
69 start_of_name_component = True;
73 if (start_of_name_component) {
74 if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
75 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
78 * No mb char starts with '.' so we're safe checking the directory separator here.
81 /* If we just added a '/' - delete it */
82 if ((d > destname) && (*(d-1) == '/')) {
87 /* Are we at the start ? Can't go back further if so. */
89 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
92 /* Go back one level... */
93 /* We know this is safe as '/' cannot be part of a mb sequence. */
94 /* NOTE - if this assumption is invalid we are not in good shape... */
95 /* Decrement d first as d points to the *next* char to write into. */
96 for (d--; d > destname; d--) {
100 s += 2; /* Else go past the .. */
101 /* We're still at the start of a name component, just the previous one. */
103 if (num_bad_components) {
104 /* Hmmm. Should we only decrement the bad_components if
105 we're removing a bad component ? Need to check this. JRA. */
106 num_bad_components--;
111 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_DIRECTORY_SEP(s[1]))) {
112 /* Component of pathname can't be "." only. */
113 ret = NT_STATUS_OBJECT_NAME_INVALID;
114 num_bad_components++;
121 if (allow_wcard_names) {
130 return NT_STATUS_OBJECT_NAME_INVALID;
137 switch(next_mb_char_size(s)) {
148 DEBUG(0,("check_path_syntax: character length assumptions invalid !\n"));
150 return NT_STATUS_INVALID_PARAMETER;
153 if (start_of_name_component && num_bad_components) {
154 num_bad_components++;
156 start_of_name_component = False;
159 if (NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_NAME_INVALID)) {
160 /* For some strange reason being called from findfirst changes
161 the num_components number to cause the error return to change. JRA. */
162 if (allow_wcard_names) {
163 if (num_bad_components > 2) {
164 ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
167 if (num_bad_components > 1) {
168 ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
177 /****************************************************************************
178 Pull a string and check the path - provide for error return.
179 ****************************************************************************/
181 size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err, BOOL allow_wcard_names)
184 char *tmppath_ptr = tmppath;
187 SMB_ASSERT(dest_len == sizeof(pstring));
191 ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags);
193 ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
195 *err = check_path_syntax(dest, tmppath, allow_wcard_names);
199 /****************************************************************************
200 Reply to a special message.
201 ****************************************************************************/
203 int reply_special(char *inbuf,char *outbuf)
206 int msg_type = CVAL(inbuf,0);
207 int msg_flags = CVAL(inbuf,1);
211 static BOOL already_got_session = False;
215 memset(outbuf,'\0',smb_size);
217 smb_setlen(outbuf,0);
220 case 0x81: /* session request */
222 if (already_got_session) {
223 exit_server("multiple session request not permitted");
226 SCVAL(outbuf,0,0x82);
228 if (name_len(inbuf+4) > 50 ||
229 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
230 DEBUG(0,("Invalid name length in session request\n"));
233 name_extract(inbuf,4,name1);
234 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
235 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
238 set_local_machine_name(name1, True);
239 set_remote_machine_name(name2, True);
241 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
242 get_local_machine_name(), get_remote_machine_name(),
245 if (name_type == 'R') {
246 /* We are being asked for a pathworks session ---
248 SCVAL(outbuf, 0,0x83);
252 /* only add the client's machine name to the list
253 of possibly valid usernames if we are operating
254 in share mode security */
255 if (lp_security() == SEC_SHARE) {
256 add_session_user(get_remote_machine_name());
259 reload_services(True);
262 already_got_session = True;
265 case 0x89: /* session keepalive request
266 (some old clients produce this?) */
267 SCVAL(outbuf,0,SMBkeepalive);
271 case 0x82: /* positive session response */
272 case 0x83: /* negative session response */
273 case 0x84: /* retarget session response */
274 DEBUG(0,("Unexpected session response\n"));
277 case SMBkeepalive: /* session keepalive */
282 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
283 msg_type, msg_flags));
288 /****************************************************************************
290 ****************************************************************************/
292 int reply_tcon(connection_struct *conn,
293 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
300 uint16 vuid = SVAL(inbuf,smb_uid);
304 DATA_BLOB password_blob;
306 START_PROFILE(SMBtcon);
308 *service_buf = *password = *dev = 0;
310 p = smb_buf(inbuf)+1;
311 p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
312 pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
314 p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
316 p = strrchr_m(service_buf,'\\');
320 service = service_buf;
323 password_blob = data_blob(password, pwlen+1);
325 conn = make_connection(service,password_blob,dev,vuid,&nt_status);
327 data_blob_clear_free(&password_blob);
330 END_PROFILE(SMBtcon);
331 return ERROR_NT(nt_status);
334 outsize = set_message(outbuf,2,0,True);
335 SSVAL(outbuf,smb_vwv0,max_recv);
336 SSVAL(outbuf,smb_vwv1,conn->cnum);
337 SSVAL(outbuf,smb_tid,conn->cnum);
339 DEBUG(3,("tcon service=%s cnum=%d\n",
340 service, conn->cnum));
342 END_PROFILE(SMBtcon);
346 /****************************************************************************
347 Reply to a tcon and X.
348 ****************************************************************************/
350 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
355 /* what the cleint thinks the device is */
356 fstring client_devicetype;
357 /* what the server tells the client the share represents */
358 const char *server_devicetype;
360 uint16 vuid = SVAL(inbuf,smb_uid);
361 int passlen = SVAL(inbuf,smb_vwv3);
364 extern BOOL global_encrypted_passwords_negotiated;
366 START_PROFILE(SMBtconX);
368 *service = *client_devicetype = 0;
370 /* we might have to close an old one */
371 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
372 close_cnum(conn,vuid);
375 if (passlen > MAX_PASS_LEN) {
376 return ERROR_DOS(ERRDOS,ERRbuftoosmall);
379 if (global_encrypted_passwords_negotiated) {
380 password = data_blob(smb_buf(inbuf),passlen);
382 password = data_blob(smb_buf(inbuf),passlen+1);
383 /* Ensure correct termination */
384 password.data[passlen]=0;
387 p = smb_buf(inbuf) + passlen;
388 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE);
391 * the service name can be either: \\server\share
392 * or share directly like on the DELL PowerVault 705
395 q = strchr_m(path+2,'\\');
397 END_PROFILE(SMBtconX);
398 return(ERROR_DOS(ERRDOS,ERRnosuchshare));
400 fstrcpy(service,q+1);
403 fstrcpy(service,path);
405 p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII);
407 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
409 conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
411 data_blob_clear_free(&password);
414 END_PROFILE(SMBtconX);
415 return ERROR_NT(nt_status);
419 server_devicetype = "IPC";
420 else if ( IS_PRINT(conn) )
421 server_devicetype = "LPT1:";
423 server_devicetype = "A:";
425 if (Protocol < PROTOCOL_NT1) {
426 set_message(outbuf,2,0,True);
428 p += srvstr_push(outbuf, p, server_devicetype, -1,
429 STR_TERMINATE|STR_ASCII);
430 set_message_end(outbuf,p);
432 /* NT sets the fstype of IPC$ to the null string */
433 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
435 set_message(outbuf,3,0,True);
438 p += srvstr_push(outbuf, p, server_devicetype, -1,
439 STR_TERMINATE|STR_ASCII);
440 p += srvstr_push(outbuf, p, fstype, -1,
443 set_message_end(outbuf,p);
445 /* what does setting this bit do? It is set by NT4 and
446 may affect the ability to autorun mounted cdroms */
447 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
448 (lp_csc_policy(SNUM(conn)) << 2));
450 init_dfsroot(conn, inbuf, outbuf);
454 DEBUG(3,("tconX service=%s \n",
457 /* set the incoming and outgoing tid to the just created one */
458 SSVAL(inbuf,smb_tid,conn->cnum);
459 SSVAL(outbuf,smb_tid,conn->cnum);
461 END_PROFILE(SMBtconX);
462 return chain_reply(inbuf,outbuf,length,bufsize);
465 /****************************************************************************
466 Reply to an unknown type.
467 ****************************************************************************/
469 int reply_unknown(char *inbuf,char *outbuf)
472 type = CVAL(inbuf,smb_com);
474 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
475 smb_fn_name(type), type, type));
477 return(ERROR_DOS(ERRSRV,ERRunknownsmb));
480 /****************************************************************************
482 ****************************************************************************/
484 int reply_ioctl(connection_struct *conn,
485 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
487 uint16 device = SVAL(inbuf,smb_vwv1);
488 uint16 function = SVAL(inbuf,smb_vwv2);
489 uint32 ioctl_code = (device << 16) + function;
490 int replysize, outsize;
492 START_PROFILE(SMBioctl);
494 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
496 switch (ioctl_code) {
497 case IOCTL_QUERY_JOB_INFO:
501 END_PROFILE(SMBioctl);
502 return(ERROR_DOS(ERRSRV,ERRnosupport));
505 outsize = set_message(outbuf,8,replysize+1,True);
506 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
507 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
508 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
509 p = smb_buf(outbuf) + 1; /* Allow for alignment */
511 switch (ioctl_code) {
512 case IOCTL_QUERY_JOB_INFO:
514 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
516 END_PROFILE(SMBioctl);
517 return(UNIXERROR(ERRDOS,ERRbadfid));
519 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */
520 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII);
522 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII);
528 END_PROFILE(SMBioctl);
532 /****************************************************************************
534 ****************************************************************************/
536 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
541 BOOL bad_path = False;
542 SMB_STRUCT_STAT sbuf;
545 START_PROFILE(SMBchkpth);
547 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, False);
548 if (!NT_STATUS_IS_OK(status)) {
549 END_PROFILE(SMBchkpth);
550 return ERROR_NT(status);
553 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
555 unix_convert(name,conn,0,&bad_path,&sbuf);
557 END_PROFILE(SMBchkpth);
558 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
561 if (check_name(name,conn)) {
562 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
563 if (!(ok = S_ISDIR(sbuf.st_mode))) {
564 END_PROFILE(SMBchkpth);
565 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath);
570 /* We special case this - as when a Windows machine
571 is parsing a path is steps through the components
572 one at a time - if a component fails it expects
573 ERRbadpath, not ERRbadfile.
575 if(errno == ENOENT) {
577 * Windows returns different error codes if
578 * the parent directory is valid but not the
579 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
580 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
581 * if the path is invalid. This is different from set_bad_path_error()
582 * in the non-NT error case.
584 END_PROFILE(SMBchkpth);
585 return ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpath);
588 END_PROFILE(SMBchkpth);
589 return(UNIXERROR(ERRDOS,ERRbadpath));
592 outsize = set_message(outbuf,0,0,True);
593 DEBUG(3,("chkpth %s mode=%d\n", name, (int)SVAL(inbuf,smb_vwv0)));
595 END_PROFILE(SMBchkpth);
599 /****************************************************************************
601 ****************************************************************************/
603 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
607 SMB_STRUCT_STAT sbuf;
612 BOOL bad_path = False;
616 START_PROFILE(SMBgetatr);
618 p = smb_buf(inbuf) + 1;
619 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status, False);
620 if (!NT_STATUS_IS_OK(status)) {
621 END_PROFILE(SMBgetatr);
622 return ERROR_NT(status);
625 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
627 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
628 under WfWg - weird! */
630 mode = aHIDDEN | aDIR;
631 if (!CAN_WRITE(conn))
637 unix_convert(fname,conn,0,&bad_path,&sbuf);
639 END_PROFILE(SMBgetatr);
640 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
642 if (check_name(fname,conn)) {
643 if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
644 mode = dos_mode(conn,fname,&sbuf);
646 mtime = sbuf.st_mtime;
651 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
657 END_PROFILE(SMBgetatr);
658 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadfile);
661 outsize = set_message(outbuf,10,0,True);
663 SSVAL(outbuf,smb_vwv0,mode);
664 if(lp_dos_filetime_resolution(SNUM(conn)) )
665 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
667 put_dos_date3(outbuf,smb_vwv1,mtime);
668 SIVAL(outbuf,smb_vwv3,(uint32)size);
670 if (Protocol >= PROTOCOL_NT1)
671 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
673 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
675 END_PROFILE(SMBgetatr);
679 /****************************************************************************
681 ****************************************************************************/
683 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
690 SMB_STRUCT_STAT sbuf;
691 BOOL bad_path = False;
695 START_PROFILE(SMBsetatr);
697 p = smb_buf(inbuf) + 1;
698 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status, False);
699 if (!NT_STATUS_IS_OK(status)) {
700 END_PROFILE(SMBsetatr);
701 return ERROR_NT(status);
704 unix_convert(fname,conn,0,&bad_path,&sbuf);
706 END_PROFILE(SMBsetatr);
707 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
710 mode = SVAL(inbuf,smb_vwv0);
711 mtime = make_unix_date3(inbuf+smb_vwv1);
713 if (mode != FILE_ATTRIBUTE_NORMAL) {
714 if (VALID_STAT_OF_DIR(sbuf))
719 if (check_name(fname,conn)) {
720 ok = (file_set_dosmode(conn,fname,mode,&sbuf,False) == 0);
727 ok = set_filetime(conn,fname,mtime);
730 END_PROFILE(SMBsetatr);
731 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
734 outsize = set_message(outbuf,0,0,True);
736 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
738 END_PROFILE(SMBsetatr);
742 /****************************************************************************
744 ****************************************************************************/
746 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
749 SMB_BIG_UINT dfree,dsize,bsize;
750 START_PROFILE(SMBdskattr);
752 SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
754 outsize = set_message(outbuf,5,0,True);
756 if (Protocol <= PROTOCOL_LANMAN2) {
757 double total_space, free_space;
758 /* we need to scale this to a number that DOS6 can handle. We
759 use floating point so we can handle large drives on systems
760 that don't have 64 bit integers
762 we end up displaying a maximum of 2G to DOS systems
764 total_space = dsize * (double)bsize;
765 free_space = dfree * (double)bsize;
767 dsize = (total_space+63*512) / (64*512);
768 dfree = (free_space+63*512) / (64*512);
770 if (dsize > 0xFFFF) dsize = 0xFFFF;
771 if (dfree > 0xFFFF) dfree = 0xFFFF;
773 SSVAL(outbuf,smb_vwv0,dsize);
774 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
775 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */
776 SSVAL(outbuf,smb_vwv3,dfree);
778 SSVAL(outbuf,smb_vwv0,dsize);
779 SSVAL(outbuf,smb_vwv1,bsize/512);
780 SSVAL(outbuf,smb_vwv2,512);
781 SSVAL(outbuf,smb_vwv3,dfree);
784 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
786 END_PROFILE(SMBdskattr);
790 /****************************************************************************
792 Can be called from SMBsearch, SMBffirst or SMBfunique.
793 ****************************************************************************/
795 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
805 unsigned int numentries = 0;
806 unsigned int maxentries = 0;
807 BOOL finished = False;
814 BOOL check_descend = False;
815 BOOL expect_close = False;
816 BOOL can_open = True;
817 BOOL bad_path = False;
819 START_PROFILE(SMBsearch);
821 *mask = *directory = *fname = 0;
823 /* If we were called as SMBffirst then we must expect close. */
824 if(CVAL(inbuf,smb_com) == SMBffirst)
827 outsize = set_message(outbuf,1,3,True);
828 maxentries = SVAL(inbuf,smb_vwv0);
829 dirtype = SVAL(inbuf,smb_vwv1);
830 p = smb_buf(inbuf) + 1;
831 p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status, True);
832 if (!NT_STATUS_IS_OK(nt_status)) {
833 END_PROFILE(SMBsearch);
834 return ERROR_NT(nt_status);
837 status_len = SVAL(p, 0);
840 /* dirtype &= ~aDIR; */
842 if (status_len == 0) {
843 SMB_STRUCT_STAT sbuf;
846 pstrcpy(directory,path);
848 unix_convert(directory,conn,0,&bad_path,&sbuf);
851 if (!check_name(directory,conn))
854 p = strrchr_m(dir2,'/');
863 p = strrchr_m(directory,'/');
869 if (strlen(directory) == 0)
870 pstrcpy(directory,".");
871 memset((char *)status,'\0',21);
872 SCVAL(status,0,(dirtype & 0x1F));
877 status_dirtype = CVAL(status,0) & 0x1F;
878 if (status_dirtype != (dirtype & 0x1F))
879 dirtype = status_dirtype;
881 conn->dirptr = dptr_fetch(status+12,&dptr_num);
884 string_set(&conn->dirpath,dptr_path(dptr_num));
885 pstrcpy(mask, dptr_wcard(dptr_num));
889 p = smb_buf(outbuf) + 3;
892 if (status_len == 0) {
893 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
896 END_PROFILE(SMBsearch);
897 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnofids);
899 END_PROFILE(SMBsearch);
900 return ERROR_DOS(ERRDOS,ERRnofids);
902 dptr_set_wcard(dptr_num, SMB_STRDUP(mask));
903 dptr_set_attr(dptr_num, dirtype);
905 dirtype = dptr_attr(dptr_num);
908 DEBUG(4,("dptr_num is %d\n",dptr_num));
911 if ((dirtype&0x1F) == aVOLID) {
913 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
914 dptr_fill(p+12,dptr_num);
915 if (dptr_zero(p+12) && (status_len==0))
919 p += DIR_STRUCT_SIZE;
922 maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
924 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
925 conn->dirpath,lp_dontdescend(SNUM(conn))));
926 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
927 check_descend = True;
929 for (i=numentries;(i<maxentries) && !finished;i++) {
930 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
933 make_dir_struct(p,mask,fname,size,mode,date);
934 dptr_fill(p+12,dptr_num);
936 p += DIR_STRUCT_SIZE;
946 /* If we were called as SMBffirst with smb_search_id == NULL
947 and no entries were found then return error and close dirptr
950 if (numentries == 0 || !ok) {
951 dptr_close(&dptr_num);
952 } else if(ok && expect_close && status_len == 0) {
953 /* Close the dptr - we know it's gone */
954 dptr_close(&dptr_num);
957 /* If we were called as SMBfunique, then we can close the dirptr now ! */
958 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique) {
959 dptr_close(&dptr_num);
962 if ((numentries == 0) && !ms_has_wild(mask)) {
963 return ERROR_BOTH(STATUS_NO_MORE_FILES,ERRDOS,ERRnofiles);
966 SSVAL(outbuf,smb_vwv0,numentries);
967 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
968 SCVAL(smb_buf(outbuf),0,5);
969 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
971 if (Protocol >= PROTOCOL_NT1)
972 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
974 outsize += DIR_STRUCT_SIZE*numentries;
975 smb_setlen(outbuf,outsize - 4);
977 if ((! *directory) && dptr_path(dptr_num))
978 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
980 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
981 smb_fn_name(CVAL(inbuf,smb_com)),
982 mask, directory, dirtype, numentries, maxentries ) );
984 END_PROFILE(SMBsearch);
988 /****************************************************************************
989 Reply to a fclose (stop directory search).
990 ****************************************************************************/
992 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1002 START_PROFILE(SMBfclose);
1004 outsize = set_message(outbuf,1,0,True);
1005 p = smb_buf(inbuf) + 1;
1006 p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err, True);
1007 if (!NT_STATUS_IS_OK(err)) {
1008 END_PROFILE(SMBfclose);
1009 return ERROR_NT(err);
1012 status_len = SVAL(p,0);
1015 if (status_len == 0) {
1016 END_PROFILE(SMBfclose);
1017 return ERROR_DOS(ERRSRV,ERRsrverror);
1020 memcpy(status,p,21);
1022 if(dptr_fetch(status+12,&dptr_num)) {
1023 /* Close the dptr - we know it's gone */
1024 dptr_close(&dptr_num);
1027 SSVAL(outbuf,smb_vwv0,0);
1029 DEBUG(3,("search close\n"));
1031 END_PROFILE(SMBfclose);
1035 /****************************************************************************
1037 ****************************************************************************/
1039 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1048 SMB_STRUCT_STAT sbuf;
1049 BOOL bad_path = False;
1051 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1052 uint16 dos_attr = SVAL(inbuf,smb_vwv1);
1054 START_PROFILE(SMBopen);
1056 share_mode = SVAL(inbuf,smb_vwv0);
1058 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
1059 if (!NT_STATUS_IS_OK(status)) {
1060 END_PROFILE(SMBopen);
1061 return ERROR_NT(status);
1064 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1066 unix_convert(fname,conn,0,&bad_path,&sbuf);
1068 END_PROFILE(SMBopen);
1069 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1072 fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1073 (uint32)dos_attr, oplock_request,&rmode,NULL);
1076 END_PROFILE(SMBopen);
1077 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1078 /* We have re-scheduled this call. */
1079 clear_cached_errors();
1082 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1085 size = sbuf.st_size;
1086 fmode = dos_mode(conn,fname,&sbuf);
1087 mtime = sbuf.st_mtime;
1090 DEBUG(3,("attempt to open a directory %s\n",fname));
1091 close_file(fsp,False);
1092 END_PROFILE(SMBopen);
1093 return ERROR_DOS(ERRDOS,ERRnoaccess);
1096 outsize = set_message(outbuf,7,0,True);
1097 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1098 SSVAL(outbuf,smb_vwv1,fmode);
1099 if(lp_dos_filetime_resolution(SNUM(conn)) )
1100 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
1102 put_dos_date3(outbuf,smb_vwv2,mtime);
1103 SIVAL(outbuf,smb_vwv4,(uint32)size);
1104 SSVAL(outbuf,smb_vwv6,rmode);
1106 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1107 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1109 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1110 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1111 END_PROFILE(SMBopen);
1115 /****************************************************************************
1116 Reply to an open and X.
1117 ****************************************************************************/
1119 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1122 int smb_mode = SVAL(inbuf,smb_vwv3);
1123 int smb_attr = SVAL(inbuf,smb_vwv5);
1124 /* Breakout the oplock request bits so we can set the
1125 reply bits separately. */
1126 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
1127 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1128 BOOL oplock_request = ex_oplock_request | core_oplock_request;
1130 int open_flags = SVAL(inbuf,smb_vwv2);
1131 int smb_sattr = SVAL(inbuf,smb_vwv4);
1132 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
1134 int smb_ofun = SVAL(inbuf,smb_vwv8);
1136 int fmode=0,mtime=0,rmode=0;
1137 SMB_STRUCT_STAT sbuf;
1139 BOOL bad_path = False;
1142 START_PROFILE(SMBopenX);
1144 /* If it's an IPC, pass off the pipe handler. */
1146 if (lp_nt_pipe_support()) {
1147 END_PROFILE(SMBopenX);
1148 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
1150 END_PROFILE(SMBopenX);
1151 return ERROR_DOS(ERRSRV,ERRaccess);
1155 /* XXXX we need to handle passed times, sattr and flags */
1156 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status, False);
1157 if (!NT_STATUS_IS_OK(status)) {
1158 END_PROFILE(SMBopenX);
1159 return ERROR_NT(status);
1162 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1164 unix_convert(fname,conn,0,&bad_path,&sbuf);
1166 END_PROFILE(SMBopenX);
1167 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1170 fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr,
1171 oplock_request, &rmode,&smb_action);
1174 END_PROFILE(SMBopenX);
1175 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1176 /* We have re-scheduled this call. */
1177 clear_cached_errors();
1180 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1183 size = sbuf.st_size;
1184 fmode = dos_mode(conn,fname,&sbuf);
1185 mtime = sbuf.st_mtime;
1187 close_file(fsp,False);
1188 END_PROFILE(SMBopenX);
1189 return ERROR_DOS(ERRDOS,ERRnoaccess);
1192 /* If the caller set the extended oplock request bit
1193 and we granted one (by whatever means) - set the
1194 correct bit for extended oplock reply.
1197 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn)))
1198 smb_action |= EXTENDED_OPLOCK_GRANTED;
1200 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1201 smb_action |= EXTENDED_OPLOCK_GRANTED;
1203 /* If the caller set the core oplock request bit
1204 and we granted one (by whatever means) - set the
1205 correct bit for core oplock reply.
1208 if (core_oplock_request && lp_fake_oplocks(SNUM(conn)))
1209 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1211 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1212 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1214 set_message(outbuf,15,0,True);
1215 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1216 SSVAL(outbuf,smb_vwv3,fmode);
1217 if(lp_dos_filetime_resolution(SNUM(conn)) )
1218 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1220 put_dos_date3(outbuf,smb_vwv4,mtime);
1221 SIVAL(outbuf,smb_vwv6,(uint32)size);
1222 SSVAL(outbuf,smb_vwv8,rmode);
1223 SSVAL(outbuf,smb_vwv11,smb_action);
1225 END_PROFILE(SMBopenX);
1226 return chain_reply(inbuf,outbuf,length,bufsize);
1229 /****************************************************************************
1230 Reply to a SMBulogoffX.
1231 ****************************************************************************/
1233 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1235 uint16 vuid = SVAL(inbuf,smb_uid);
1236 user_struct *vuser = get_valid_user_struct(vuid);
1237 START_PROFILE(SMBulogoffX);
1240 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1242 /* in user level security we are supposed to close any files
1243 open by this user */
1244 if ((vuser != 0) && (lp_security() != SEC_SHARE))
1245 file_close_user(vuid);
1247 invalidate_vuid(vuid);
1249 set_message(outbuf,2,0,True);
1251 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1253 END_PROFILE(SMBulogoffX);
1254 return chain_reply(inbuf,outbuf,length,bufsize);
1257 /****************************************************************************
1258 Reply to a mknew or a create.
1259 ****************************************************************************/
1261 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1268 BOOL bad_path = False;
1270 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1271 SMB_STRUCT_STAT sbuf;
1273 START_PROFILE(SMBcreate);
1275 com = SVAL(inbuf,smb_com);
1277 createmode = SVAL(inbuf,smb_vwv0);
1278 srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status, False);
1279 if (!NT_STATUS_IS_OK(status)) {
1280 END_PROFILE(SMBcreate);
1281 return ERROR_NT(status);
1284 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1286 unix_convert(fname,conn,0,&bad_path,&sbuf);
1288 END_PROFILE(SMBcreate);
1289 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1292 if (createmode & aVOLID)
1293 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1295 if(com == SMBmknew) {
1296 /* We should fail if file exists. */
1297 ofun = FILE_CREATE_IF_NOT_EXIST;
1299 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1300 ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
1303 /* Open file in dos compatibility share mode. */
1304 fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1305 ofun, (uint32)createmode, oplock_request, NULL, NULL);
1308 END_PROFILE(SMBcreate);
1309 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1310 /* We have re-scheduled this call. */
1311 clear_cached_errors();
1314 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1317 outsize = set_message(outbuf,1,0,True);
1318 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1320 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1321 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1323 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1324 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1326 DEBUG( 2, ( "new file %s\n", fname ) );
1327 DEBUG( 3, ( "mknew %s fd=%d dmode=%d\n", fname, fsp->fd, createmode ) );
1329 END_PROFILE(SMBcreate);
1333 /****************************************************************************
1334 Reply to a create temporary file.
1335 ****************************************************************************/
1337 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1342 BOOL bad_path = False;
1344 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1346 SMB_STRUCT_STAT sbuf;
1349 unsigned int namelen;
1351 START_PROFILE(SMBctemp);
1353 createattr = SVAL(inbuf,smb_vwv0);
1354 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
1355 if (!NT_STATUS_IS_OK(status)) {
1356 END_PROFILE(SMBctemp);
1357 return ERROR_NT(status);
1360 pstrcat(fname,"/TMXXXXXX");
1362 pstrcat(fname,"TMXXXXXX");
1365 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1367 unix_convert(fname,conn,0,&bad_path,&sbuf);
1369 END_PROFILE(SMBctemp);
1370 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1373 tmpfd = smb_mkstemp(fname);
1375 END_PROFILE(SMBctemp);
1376 return(UNIXERROR(ERRDOS,ERRnoaccess));
1379 SMB_VFS_STAT(conn,fname,&sbuf);
1381 /* Open file in dos compatibility share mode. */
1382 /* We should fail if file does not exist. */
1383 fsp = open_file_shared(conn,fname,&sbuf,
1384 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1385 FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
1386 (uint32)createattr, oplock_request, NULL, NULL);
1388 /* close fd from smb_mkstemp() */
1392 END_PROFILE(SMBctemp);
1393 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1394 /* We have re-scheduled this call. */
1395 clear_cached_errors();
1398 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
1401 outsize = set_message(outbuf,1,0,True);
1402 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1404 /* the returned filename is relative to the directory */
1405 s = strrchr_m(fname, '/');
1411 p = smb_buf(outbuf);
1413 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
1414 thing in the byte section. JRA */
1415 SSVALS(p, 0, -1); /* what is this? not in spec */
1417 namelen = srvstr_push(outbuf, p, s, -1, STR_ASCII|STR_TERMINATE);
1419 outsize = set_message_end(outbuf, p);
1421 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1422 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1424 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1425 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1427 DEBUG( 2, ( "created temp file %s\n", fname ) );
1428 DEBUG( 3, ( "ctemp %s fd=%d umode=%o\n",
1429 fname, fsp->fd, sbuf.st_mode ) );
1431 END_PROFILE(SMBctemp);
1435 /*******************************************************************
1436 Check if a user is allowed to rename a file.
1437 ********************************************************************/
1439 static NTSTATUS can_rename(char *fname,connection_struct *conn, uint16 dirtype, SMB_STRUCT_STAT *pst)
1446 if (!CAN_WRITE(conn))
1447 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1449 fmode = dos_mode(conn,fname,pst);
1450 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1451 return NT_STATUS_NO_SUCH_FILE;
1453 if (S_ISDIR(pst->st_mode))
1454 return NT_STATUS_OK;
1456 /* We need a better way to return NT status codes from open... */
1460 fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1461 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
1464 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1465 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1466 ret = NT_STATUS_SHARING_VIOLATION;
1469 unix_ERR_ntstatus = NT_STATUS_OK;
1472 close_file(fsp,False);
1473 return NT_STATUS_OK;
1476 /*******************************************************************
1477 Check if a user is allowed to delete a file.
1478 ********************************************************************/
1480 static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype, BOOL bad_path)
1482 SMB_STRUCT_STAT sbuf;
1488 DEBUG(10,("can_delete: %s, dirtype = %d\n",
1491 if (!CAN_WRITE(conn))
1492 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1494 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) {
1495 if(errno == ENOENT) {
1497 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1499 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1501 return map_nt_error_from_unix(errno);
1504 fmode = dos_mode(conn,fname,&sbuf);
1506 /* Can't delete a directory. */
1508 return NT_STATUS_FILE_IS_A_DIRECTORY;
1510 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
1511 return NT_STATUS_OBJECT_NAME_INVALID;
1512 #endif /* JRATEST */
1514 if (!lp_delete_readonly(SNUM(conn))) {
1516 return NT_STATUS_CANNOT_DELETE;
1518 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1519 return NT_STATUS_NO_SUCH_FILE;
1521 /* We need a better way to return NT status codes from open... */
1525 fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
1526 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
1529 NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
1530 if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
1531 ret = unix_ERR_ntstatus;
1532 else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1533 ret = NT_STATUS_SHARING_VIOLATION;
1536 unix_ERR_ntstatus = NT_STATUS_OK;
1539 close_file(fsp,False);
1540 return NT_STATUS_OK;
1543 /****************************************************************************
1544 The guts of the unlink command, split out so it may be called by the NT SMB
1546 ****************************************************************************/
1548 NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
1554 NTSTATUS error = NT_STATUS_OK;
1556 BOOL bad_path = False;
1558 SMB_STRUCT_STAT sbuf;
1560 *directory = *mask = 0;
1562 /* We must check for wildcards in the name given
1563 * directly by the client - before any unmangling.
1564 * This prevents an unmangling of a UNIX name containing
1565 * a DOS wildcard like '*' or '?' from unmangling into
1566 * a wildcard delete which was not intended.
1567 * FIX for #226. JRA.
1570 has_wild = ms_has_wild(name);
1572 rc = unix_convert(name,conn,0,&bad_path,&sbuf);
1574 p = strrchr_m(name,'/');
1576 pstrcpy(directory,".");
1580 pstrcpy(directory,name);
1585 * We should only check the mangled cache
1586 * here if unix_convert failed. This means
1587 * that the path in 'mask' doesn't exist
1588 * on the file system and so we need to look
1589 * for a possible mangle. This patch from
1590 * Tine Smukavec <valentin.smukavec@hermes.si>.
1593 if (!rc && mangle_is_mangled(mask))
1594 mangle_check_cache( mask, sizeof(pstring)-1 );
1597 pstrcat(directory,"/");
1598 pstrcat(directory,mask);
1599 error = can_delete(directory,conn,dirtype,bad_path);
1600 if (!NT_STATUS_IS_OK(error))
1603 if (SMB_VFS_UNLINK(conn,directory) == 0) {
1607 void *dirptr = NULL;
1610 if (check_name(directory,conn))
1611 dirptr = OpenDir(conn, directory, True);
1613 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1614 the pattern matches against the long name, otherwise the short name
1615 We don't implement this yet XXXX
1620 error = NT_STATUS_NO_SUCH_FILE;
1622 if (strequal(mask,"????????.???"))
1625 while ((dname = ReadDirName(dirptr, &offset))) {
1627 BOOL sys_direntry = False;
1628 pstrcpy(fname,dname);
1630 /* Quick check for "." and ".." */
1631 if (fname[0] == '.') {
1632 if (!fname[1] || (fname[1] == '.' && !fname[2])) {
1633 if ((dirtype & FILE_ATTRIBUTE_DIRECTORY) && (dirtype & FILE_ATTRIBUTE_SYSTEM)) {
1634 sys_direntry = True;
1641 if(!mask_match(fname, mask, conn->case_sensitive))
1645 error = NT_STATUS_OBJECT_NAME_INVALID;
1646 DEBUG(3,("unlink_internals: system directory delete denied [%s] mask [%s]\n",
1651 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
1652 error = can_delete(fname,conn,dirtype,bad_path);
1653 if (!NT_STATUS_IS_OK(error)) {
1656 if (SMB_VFS_UNLINK(conn,fname) == 0)
1658 DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
1664 if (count == 0 && NT_STATUS_IS_OK(error)) {
1665 error = map_nt_error_from_unix(errno);
1671 /****************************************************************************
1673 ****************************************************************************/
1675 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
1682 START_PROFILE(SMBunlink);
1684 dirtype = SVAL(inbuf,smb_vwv0);
1686 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, True);
1687 if (!NT_STATUS_IS_OK(status)) {
1688 END_PROFILE(SMBunlink);
1689 return ERROR_NT(status);
1692 RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
1694 DEBUG(3,("reply_unlink : %s\n",name));
1696 status = unlink_internals(conn, dirtype, name);
1697 if (!NT_STATUS_IS_OK(status)) {
1698 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1699 /* We have re-scheduled this call. */
1700 clear_cached_errors();
1703 return ERROR_NT(status);
1707 * Win2k needs a changenotify request response before it will
1708 * update after a rename..
1710 process_pending_change_notify_queue((time_t)0);
1712 outsize = set_message(outbuf,0,0,True);
1714 END_PROFILE(SMBunlink);
1718 /****************************************************************************
1720 ****************************************************************************/
1722 static void fail_readraw(void)
1725 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
1727 exit_server(errstr);
1730 #if defined(WITH_SENDFILE)
1731 /****************************************************************************
1732 Fake (read/write) sendfile. Returns -1 on read or write fail.
1733 ****************************************************************************/
1735 static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, int bufsize)
1739 /* Paranioa check... */
1740 if (nread > bufsize) {
1745 ret = read_file(fsp,buf,startpos,nread);
1751 /* If we had a short read, fill with zeros. */
1753 memset(buf, '\0', nread - ret);
1756 if (write_data(smbd_server_fd(),buf,nread) != nread) {
1760 return (ssize_t)nread;
1764 /****************************************************************************
1765 Use sendfile in readbraw.
1766 ****************************************************************************/
1768 void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
1769 ssize_t mincount, char *outbuf, int out_buffsize)
1773 #if defined(WITH_SENDFILE)
1775 * We can only use sendfile on a non-chained packet
1776 * but we can use on a non-oplocked file. tridge proved this
1777 * on a train in Germany :-). JRA.
1778 * reply_readbraw has already checked the length.
1781 if (chain_size ==0 && (nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) && lp_use_sendfile(SNUM(conn)) ) {
1784 _smb_setlen(outbuf,nread);
1785 header.data = outbuf;
1789 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
1790 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
1791 if (errno == ENOSYS) {
1792 goto normal_readbraw;
1796 * Special hack for broken Linux with no working sendfile. If we
1797 * return EINTR we sent the header but not the rest of the data.
1798 * Fake this up by doing read/write calls.
1800 if (errno == EINTR) {
1801 /* Ensure we don't do this again. */
1802 set_use_sendfile(SNUM(conn), False);
1803 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
1805 if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) {
1806 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
1807 fsp->fsp_name, strerror(errno) ));
1808 exit_server("send_file_readbraw fake_sendfile failed");
1813 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
1814 fsp->fsp_name, strerror(errno) ));
1815 exit_server("send_file_readbraw sendfile failed");
1825 ret = read_file(fsp,outbuf+4,startpos,nread);
1826 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
1835 _smb_setlen(outbuf,ret);
1836 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
1840 /****************************************************************************
1841 Reply to a readbraw (core+ protocol).
1842 ****************************************************************************/
1844 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
1846 extern struct current_user current_user;
1847 ssize_t maxcount,mincount;
1850 char *header = outbuf;
1852 START_PROFILE(SMBreadbraw);
1854 if (srv_is_signing_active()) {
1855 exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
1859 * Special check if an oplock break has been issued
1860 * and the readraw request croses on the wire, we must
1861 * return a zero length response here.
1864 if(global_oplock_break) {
1865 _smb_setlen(header,0);
1866 if (write_data(smbd_server_fd(),header,4) != 4)
1868 DEBUG(5,("readbraw - oplock break finished\n"));
1869 END_PROFILE(SMBreadbraw);
1873 fsp = file_fsp(inbuf,smb_vwv0);
1875 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
1877 * fsp could be NULL here so use the value from the packet. JRA.
1879 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
1880 _smb_setlen(header,0);
1881 if (write_data(smbd_server_fd(),header,4) != 4)
1883 END_PROFILE(SMBreadbraw);
1887 CHECK_FSP(fsp,conn);
1889 flush_write_cache(fsp, READRAW_FLUSH);
1891 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
1892 if(CVAL(inbuf,smb_wct) == 10) {
1894 * This is a large offset (64 bit) read.
1896 #ifdef LARGE_SMB_OFF_T
1898 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
1900 #else /* !LARGE_SMB_OFF_T */
1903 * Ensure we haven't been sent a >32 bit offset.
1906 if(IVAL(inbuf,smb_vwv8) != 0) {
1907 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
1908 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
1909 _smb_setlen(header,0);
1910 if (write_data(smbd_server_fd(),header,4) != 4)
1912 END_PROFILE(SMBreadbraw);
1916 #endif /* LARGE_SMB_OFF_T */
1919 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
1920 _smb_setlen(header,0);
1921 if (write_data(smbd_server_fd(),header,4) != 4)
1923 END_PROFILE(SMBreadbraw);
1927 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
1928 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
1930 /* ensure we don't overrun the packet size */
1931 maxcount = MIN(65535,maxcount);
1933 if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
1934 SMB_OFF_T size = fsp->size;
1935 SMB_OFF_T sizeneeded = startpos + maxcount;
1937 if (size < sizeneeded) {
1939 if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
1941 if (!fsp->can_write)
1945 if (startpos >= size)
1948 nread = MIN(maxcount,(size - startpos));
1951 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
1952 if (nread < mincount)
1956 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
1957 (int)maxcount, (int)mincount, (int)nread ) );
1959 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
1961 DEBUG(5,("readbraw finished\n"));
1962 END_PROFILE(SMBreadbraw);
1966 /****************************************************************************
1967 Reply to a lockread (core+ protocol).
1968 ****************************************************************************/
1970 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
1978 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
1979 BOOL my_lock_ctx = False;
1980 START_PROFILE(SMBlockread);
1982 CHECK_FSP(fsp,conn);
1985 release_level_2_oplocks_on_change(fsp);
1987 numtoread = SVAL(inbuf,smb_vwv1);
1988 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
1990 outsize = set_message(outbuf,5,3,True);
1991 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
1992 data = smb_buf(outbuf) + 3;
1995 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
1996 * protocol request that predates the read/write lock concept.
1997 * Thus instead of asking for a read lock here we need to ask
1998 * for a write lock. JRA.
1999 * Note that the requested lock size is unaffected by max_recv.
2002 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid),
2003 (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &my_lock_ctx);
2005 if (NT_STATUS_V(status)) {
2008 * We used to make lockread a blocking lock. It turns out
2009 * that this isn't on W2k. Found by the Samba 4 RAW-READ torture
2013 if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
2015 * A blocking lock was requested. Package up
2016 * this smb into a queued request and push it
2017 * onto the blocking lock queue.
2019 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)startpos,
2020 (SMB_BIG_UINT)numtoread)) {
2021 END_PROFILE(SMBlockread);
2026 END_PROFILE(SMBlockread);
2027 return ERROR_NT(status);
2031 * However the requested READ size IS affected by max_recv. Insanity.... JRA.
2034 if (numtoread > max_recv) {
2035 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \
2036 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2037 (unsigned int)numtoread, (unsigned int)max_recv ));
2038 numtoread = MIN(numtoread,max_recv);
2040 nread = read_file(fsp,data,startpos,numtoread);
2043 END_PROFILE(SMBlockread);
2044 return(UNIXERROR(ERRDOS,ERRnoaccess));
2048 SSVAL(outbuf,smb_vwv0,nread);
2049 SSVAL(outbuf,smb_vwv5,nread+3);
2050 SSVAL(smb_buf(outbuf),1,nread);
2052 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
2053 fsp->fnum, (int)numtoread, (int)nread));
2055 END_PROFILE(SMBlockread);
2059 /****************************************************************************
2061 ****************************************************************************/
2063 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2070 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2071 START_PROFILE(SMBread);
2073 CHECK_FSP(fsp,conn);
2076 numtoread = SVAL(inbuf,smb_vwv1);
2077 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2079 outsize = set_message(outbuf,5,3,True);
2080 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2082 * The requested read size cannot be greater than max_recv. JRA.
2084 if (numtoread > max_recv) {
2085 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \
2086 Returning short read of maximum allowed for compatibility with Windows 2000.\n",
2087 (unsigned int)numtoread, (unsigned int)max_recv ));
2088 numtoread = MIN(numtoread,max_recv);
2091 data = smb_buf(outbuf) + 3;
2093 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2094 END_PROFILE(SMBread);
2095 return ERROR_DOS(ERRDOS,ERRlock);
2099 nread = read_file(fsp,data,startpos,numtoread);
2102 END_PROFILE(SMBread);
2103 return(UNIXERROR(ERRDOS,ERRnoaccess));
2107 SSVAL(outbuf,smb_vwv0,nread);
2108 SSVAL(outbuf,smb_vwv5,nread+3);
2109 SCVAL(smb_buf(outbuf),0,1);
2110 SSVAL(smb_buf(outbuf),1,nread);
2112 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
2113 fsp->fnum, (int)numtoread, (int)nread ) );
2115 END_PROFILE(SMBread);
2119 /****************************************************************************
2120 Reply to a read and X - possibly using sendfile.
2121 ****************************************************************************/
2123 int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, int len_outbuf,
2124 files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
2128 char *data = smb_buf(outbuf);
2130 #if defined(WITH_SENDFILE)
2132 * We can only use sendfile on a non-chained packet
2133 * but we can use on a non-oplocked file. tridge proved this
2134 * on a train in Germany :-). JRA.
2137 if (chain_size ==0 && (CVAL(inbuf,smb_vwv0) == 0xFF) && lp_use_sendfile(SNUM(conn)) &&
2138 (lp_write_cache_size(SNUM(conn)) == 0) ) {
2139 SMB_STRUCT_STAT sbuf;
2142 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
2143 return(UNIXERROR(ERRDOS,ERRnoaccess));
2145 if (startpos > sbuf.st_size)
2148 if (smb_maxcnt > (sbuf.st_size - startpos))
2149 smb_maxcnt = (sbuf.st_size - startpos);
2151 if (smb_maxcnt == 0)
2155 * Set up the packet header before send. We
2156 * assume here the sendfile will work (get the
2157 * correct amount of data).
2160 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2161 SSVAL(outbuf,smb_vwv5,smb_maxcnt);
2162 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2163 SSVAL(outbuf,smb_vwv7,((smb_maxcnt >> 16) & 1));
2164 SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
2165 SCVAL(outbuf,smb_vwv0,0xFF);
2166 set_message(outbuf,12,smb_maxcnt,False);
2167 header.data = outbuf;
2168 header.length = data - outbuf;
2171 if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt)) == -1) {
2172 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
2173 if (errno == ENOSYS) {
2178 * Special hack for broken Linux with no working sendfile. If we
2179 * return EINTR we sent the header but not the rest of the data.
2180 * Fake this up by doing read/write calls.
2183 if (errno == EINTR) {
2184 /* Ensure we don't do this again. */
2185 set_use_sendfile(SNUM(conn), False);
2186 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
2188 if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
2189 len_outbuf - (data-outbuf))) == -1) {
2190 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
2191 fsp->fsp_name, strerror(errno) ));
2192 exit_server("send_file_readX: fake_sendfile failed");
2194 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
2195 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2196 /* Returning -1 here means successful sendfile. */
2200 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
2201 fsp->fsp_name, strerror(errno) ));
2202 exit_server("send_file_readX sendfile failed");
2205 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
2206 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2207 /* Returning -1 here means successful sendfile. */
2215 nread = read_file(fsp,data,startpos,smb_maxcnt);
2218 END_PROFILE(SMBreadX);
2219 return(UNIXERROR(ERRDOS,ERRnoaccess));
2222 outsize = set_message(outbuf,12,nread,False);
2223 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
2224 SSVAL(outbuf,smb_vwv5,nread);
2225 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2226 SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1));
2227 SSVAL(smb_buf(outbuf),-2,nread);
2229 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
2230 fsp->fnum, (int)smb_maxcnt, (int)nread ) );
2232 /* Returning the number of bytes we want to send back - including header. */
2236 /****************************************************************************
2237 Reply to a read and X.
2238 ****************************************************************************/
2240 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2242 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2243 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2245 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
2247 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
2250 START_PROFILE(SMBreadX);
2252 /* If it's an IPC, pass off the pipe handler. */
2254 END_PROFILE(SMBreadX);
2255 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
2258 CHECK_FSP(fsp,conn);
2261 set_message(outbuf,12,0,True);
2263 if (global_client_caps & CAP_LARGE_READX) {
2264 if (SVAL(inbuf,smb_vwv7) == 1) {
2265 smb_maxcnt |= (1<<16);
2267 if (smb_maxcnt > BUFFER_SIZE) {
2268 DEBUG(0,("reply_read_and_X - read too large (%u) for reply buffer %u\n",
2269 (unsigned int)smb_maxcnt, (unsigned int)BUFFER_SIZE));
2270 END_PROFILE(SMBreadX);
2271 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2275 if(CVAL(inbuf,smb_wct) == 12) {
2276 #ifdef LARGE_SMB_OFF_T
2278 * This is a large offset (64 bit) read.
2280 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
2282 #else /* !LARGE_SMB_OFF_T */
2285 * Ensure we haven't been sent a >32 bit offset.
2288 if(IVAL(inbuf,smb_vwv10) != 0) {
2289 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2290 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
2291 END_PROFILE(SMBreadX);
2292 return ERROR_DOS(ERRDOS,ERRbadaccess);
2295 #endif /* LARGE_SMB_OFF_T */
2299 if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
2300 END_PROFILE(SMBreadX);
2301 return ERROR_DOS(ERRDOS,ERRlock);
2304 nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
2306 nread = chain_reply(inbuf,outbuf,length,bufsize);
2308 END_PROFILE(SMBreadX);
2312 /****************************************************************************
2313 Reply to a writebraw (core+ or LANMAN1.0 protocol).
2314 ****************************************************************************/
2316 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2319 ssize_t total_written=0;
2320 size_t numtowrite=0;
2325 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2327 START_PROFILE(SMBwritebraw);
2329 if (srv_is_signing_active()) {
2330 exit_server("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
2333 CHECK_FSP(fsp,conn);
2336 tcount = IVAL(inbuf,smb_vwv1);
2337 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2338 write_through = BITSETW(inbuf+smb_vwv7,0);
2340 /* We have to deal with slightly different formats depending
2341 on whether we are using the core+ or lanman1.0 protocol */
2343 if(Protocol <= PROTOCOL_COREPLUS) {
2344 numtowrite = SVAL(smb_buf(inbuf),-2);
2345 data = smb_buf(inbuf);
2347 numtowrite = SVAL(inbuf,smb_vwv10);
2348 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
2351 /* force the error type */
2352 SCVAL(inbuf,smb_com,SMBwritec);
2353 SCVAL(outbuf,smb_com,SMBwritec);
2355 if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2356 END_PROFILE(SMBwritebraw);
2357 return(ERROR_DOS(ERRDOS,ERRlock));
2361 nwritten = write_file(fsp,data,startpos,numtowrite);
2363 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2364 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
2366 if (nwritten < (ssize_t)numtowrite) {
2367 END_PROFILE(SMBwritebraw);
2368 return(UNIXERROR(ERRHRD,ERRdiskfull));
2371 total_written = nwritten;
2373 /* Return a message to the redirector to tell it to send more bytes */
2374 SCVAL(outbuf,smb_com,SMBwritebraw);
2375 SSVALS(outbuf,smb_vwv0,-1);
2376 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
2377 if (!send_smb(smbd_server_fd(),outbuf))
2378 exit_server("reply_writebraw: send_smb failed.");
2380 /* Now read the raw data into the buffer and write it */
2381 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
2382 exit_server("secondary writebraw failed");
2385 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
2386 numtowrite = smb_len(inbuf);
2388 /* Set up outbuf to return the correct return */
2389 outsize = set_message(outbuf,1,0,True);
2390 SCVAL(outbuf,smb_com,SMBwritec);
2391 SSVAL(outbuf,smb_vwv0,total_written);
2393 if (numtowrite != 0) {
2395 if (numtowrite > BUFFER_SIZE) {
2396 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
2397 (unsigned int)numtowrite ));
2398 exit_server("secondary writebraw failed");
2401 if (tcount > nwritten+numtowrite) {
2402 DEBUG(3,("Client overestimated the write %d %d %d\n",
2403 (int)tcount,(int)nwritten,(int)numtowrite));
2406 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
2407 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
2409 exit_server("secondary writebraw failed");
2412 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
2414 if (nwritten < (ssize_t)numtowrite) {
2415 SCVAL(outbuf,smb_rcls,ERRHRD);
2416 SSVAL(outbuf,smb_err,ERRdiskfull);
2420 total_written += nwritten;
2423 if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
2424 sync_file(conn,fsp);
2426 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2427 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2429 /* we won't return a status if write through is not selected - this follows what WfWg does */
2430 END_PROFILE(SMBwritebraw);
2431 if (!write_through && total_written==tcount) {
2433 #if RABBIT_PELLET_FIX
2435 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
2436 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
2438 if (!send_keepalive(smbd_server_fd()))
2439 exit_server("reply_writebraw: send of keepalive failed");
2447 /****************************************************************************
2448 Reply to a writeunlock (core+).
2449 ****************************************************************************/
2451 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
2452 int size, int dum_buffsize)
2454 ssize_t nwritten = -1;
2458 NTSTATUS status = NT_STATUS_OK;
2459 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2461 START_PROFILE(SMBwriteunlock);
2463 CHECK_FSP(fsp,conn);
2466 numtowrite = SVAL(inbuf,smb_vwv1);
2467 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2468 data = smb_buf(inbuf) + 3;
2470 if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2471 END_PROFILE(SMBwriteunlock);
2472 return ERROR_DOS(ERRDOS,ERRlock);
2475 /* The special X/Open SMB protocol handling of
2476 zero length writes is *NOT* done for
2481 nwritten = write_file(fsp,data,startpos,numtowrite);
2483 if (lp_syncalways(SNUM(conn)))
2484 sync_file(conn,fsp);
2486 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2487 END_PROFILE(SMBwriteunlock);
2488 return(UNIXERROR(ERRHRD,ERRdiskfull));
2492 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
2493 (SMB_BIG_UINT)startpos);
2494 if (NT_STATUS_V(status)) {
2495 END_PROFILE(SMBwriteunlock);
2496 return ERROR_NT(status);
2500 outsize = set_message(outbuf,1,0,True);
2502 SSVAL(outbuf,smb_vwv0,nwritten);
2504 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
2505 fsp->fnum, (int)numtowrite, (int)nwritten));
2507 END_PROFILE(SMBwriteunlock);
2511 /****************************************************************************
2513 ****************************************************************************/
2515 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
2518 ssize_t nwritten = -1;
2521 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2523 START_PROFILE(SMBwrite);
2525 /* If it's an IPC, pass off the pipe handler. */
2527 END_PROFILE(SMBwrite);
2528 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
2531 CHECK_FSP(fsp,conn);
2534 numtowrite = SVAL(inbuf,smb_vwv1);
2535 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2536 data = smb_buf(inbuf) + 3;
2538 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2539 END_PROFILE(SMBwrite);
2540 return ERROR_DOS(ERRDOS,ERRlock);
2544 * X/Open SMB protocol says that if smb_vwv1 is
2545 * zero then the file size should be extended or
2546 * truncated to the size given in smb_vwv[2-3].
2549 if(numtowrite == 0) {
2551 * This is actually an allocate call, and set EOF. JRA.
2553 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
2555 END_PROFILE(SMBwrite);
2556 return ERROR_NT(NT_STATUS_DISK_FULL);
2558 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
2560 END_PROFILE(SMBwrite);
2561 return ERROR_NT(NT_STATUS_DISK_FULL);
2564 nwritten = write_file(fsp,data,startpos,numtowrite);
2566 if (lp_syncalways(SNUM(conn)))
2567 sync_file(conn,fsp);
2569 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2570 END_PROFILE(SMBwrite);
2571 return(UNIXERROR(ERRHRD,ERRdiskfull));
2574 outsize = set_message(outbuf,1,0,True);
2576 SSVAL(outbuf,smb_vwv0,nwritten);
2578 if (nwritten < (ssize_t)numtowrite) {
2579 SCVAL(outbuf,smb_rcls,ERRHRD);
2580 SSVAL(outbuf,smb_err,ERRdiskfull);
2583 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
2585 END_PROFILE(SMBwrite);
2589 /****************************************************************************
2590 Reply to a write and X.
2591 ****************************************************************************/
2593 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2595 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2596 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
2597 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2598 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2599 ssize_t nwritten = -1;
2600 unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
2601 unsigned int smblen = smb_len(inbuf);
2603 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
2604 START_PROFILE(SMBwriteX);
2606 /* If it's an IPC, pass off the pipe handler. */
2608 END_PROFILE(SMBwriteX);
2609 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2612 CHECK_FSP(fsp,conn);
2615 /* Deal with possible LARGE_WRITEX */
2617 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
2619 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
2620 END_PROFILE(SMBwriteX);
2621 return ERROR_DOS(ERRDOS,ERRbadmem);
2624 data = smb_base(inbuf) + smb_doff;
2626 if(CVAL(inbuf,smb_wct) == 14) {
2627 #ifdef LARGE_SMB_OFF_T
2629 * This is a large offset (64 bit) write.
2631 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2633 #else /* !LARGE_SMB_OFF_T */
2636 * Ensure we haven't been sent a >32 bit offset.
2639 if(IVAL(inbuf,smb_vwv12) != 0) {
2640 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
2641 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
2642 END_PROFILE(SMBwriteX);
2643 return ERROR_DOS(ERRDOS,ERRbadaccess);
2646 #endif /* LARGE_SMB_OFF_T */
2649 if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2650 END_PROFILE(SMBwriteX);
2651 return ERROR_DOS(ERRDOS,ERRlock);
2654 /* X/Open SMB protocol says that, unlike SMBwrite
2655 if the length is zero then NO truncation is
2656 done, just a write of zero. To truncate a file,
2662 nwritten = write_file(fsp,data,startpos,numtowrite);
2664 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2665 END_PROFILE(SMBwriteX);
2666 return(UNIXERROR(ERRHRD,ERRdiskfull));
2669 set_message(outbuf,6,0,True);
2671 SSVAL(outbuf,smb_vwv2,nwritten);
2673 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
2675 if (nwritten < (ssize_t)numtowrite) {
2676 SCVAL(outbuf,smb_rcls,ERRHRD);
2677 SSVAL(outbuf,smb_err,ERRdiskfull);
2680 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2681 fsp->fnum, (int)numtowrite, (int)nwritten));
2683 if (lp_syncalways(SNUM(conn)) || write_through)
2684 sync_file(conn,fsp);
2686 END_PROFILE(SMBwriteX);
2687 return chain_reply(inbuf,outbuf,length,bufsize);
2690 /****************************************************************************
2692 ****************************************************************************/
2694 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2700 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2701 START_PROFILE(SMBlseek);
2703 CHECK_FSP(fsp,conn);
2705 flush_write_cache(fsp, SEEK_FLUSH);
2707 mode = SVAL(inbuf,smb_vwv1) & 3;
2708 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
2709 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
2718 res = fsp->pos + startpos;
2729 if (umode == SEEK_END) {
2730 if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
2731 if(errno == EINVAL) {
2732 SMB_OFF_T current_pos = startpos;
2733 SMB_STRUCT_STAT sbuf;
2735 if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
2736 END_PROFILE(SMBlseek);
2737 return(UNIXERROR(ERRDOS,ERRnoaccess));
2740 current_pos += sbuf.st_size;
2742 res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
2747 END_PROFILE(SMBlseek);
2748 return(UNIXERROR(ERRDOS,ERRnoaccess));
2754 outsize = set_message(outbuf,2,0,True);
2755 SIVAL(outbuf,smb_vwv0,res);
2757 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2758 fsp->fnum, (double)startpos, (double)res, mode));
2760 END_PROFILE(SMBlseek);
2764 /****************************************************************************
2766 ****************************************************************************/
2768 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2770 int outsize = set_message(outbuf,0,0,True);
2771 uint16 fnum = SVAL(inbuf,smb_vwv0);
2772 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2773 START_PROFILE(SMBflush);
2776 CHECK_FSP(fsp,conn);
2779 file_sync_all(conn);
2781 sync_file(conn,fsp);
2784 DEBUG(3,("flush\n"));
2785 END_PROFILE(SMBflush);
2789 /****************************************************************************
2791 ****************************************************************************/
2793 int reply_exit(connection_struct *conn,
2794 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2797 START_PROFILE(SMBexit);
2799 file_close_pid(SVAL(inbuf,smb_pid));
2801 outsize = set_message(outbuf,0,0,True);
2803 DEBUG(3,("exit\n"));
2805 END_PROFILE(SMBexit);
2809 /****************************************************************************
2810 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2811 ****************************************************************************/
2813 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
2816 extern struct current_user current_user;
2819 int32 eclass = 0, err = 0;
2820 files_struct *fsp = NULL;
2821 START_PROFILE(SMBclose);
2823 outsize = set_message(outbuf,0,0,True);
2825 /* If it's an IPC, pass off to the pipe handler. */
2827 END_PROFILE(SMBclose);
2828 return reply_pipe_close(conn, inbuf,outbuf);
2831 fsp = file_fsp(inbuf,smb_vwv0);
2834 * We can only use CHECK_FSP if we know it's not a directory.
2837 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
2838 END_PROFILE(SMBclose);
2839 return ERROR_DOS(ERRDOS,ERRbadfid);
2842 if(fsp->is_directory) {
2844 * Special case - close NT SMB directory handle.
2846 DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
2847 close_file(fsp,True);
2850 * Close ordinary file.
2855 /* Save the name for time set in close. */
2856 pstrcpy( file_name, fsp->fsp_name);
2858 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2860 conn->num_files_open));
2863 * close_file() returns the unix errno if an error
2864 * was detected on close - normally this is due to
2865 * a disk full error. If not then it was probably an I/O error.
2868 if((close_err = close_file(fsp,True)) != 0) {
2870 END_PROFILE(SMBclose);
2871 return (UNIXERROR(ERRHRD,ERRgeneral));
2875 * Now take care of any time sent in the close.
2878 mtime = make_unix_date3(inbuf+smb_vwv1);
2880 /* try and set the date */
2881 set_filetime(conn, file_name, mtime);
2885 /* We have a cached error */
2887 END_PROFILE(SMBclose);
2888 return ERROR_DOS(eclass,err);
2891 END_PROFILE(SMBclose);
2895 /****************************************************************************
2896 Reply to a writeclose (Core+ protocol).
2897 ****************************************************************************/
2899 int reply_writeclose(connection_struct *conn,
2900 char *inbuf,char *outbuf, int size, int dum_buffsize)
2903 ssize_t nwritten = -1;
2909 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2910 START_PROFILE(SMBwriteclose);
2912 CHECK_FSP(fsp,conn);
2915 numtowrite = SVAL(inbuf,smb_vwv1);
2916 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
2917 mtime = make_unix_date3(inbuf+smb_vwv4);
2918 data = smb_buf(inbuf) + 1;
2920 if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
2921 END_PROFILE(SMBwriteclose);
2922 return ERROR_DOS(ERRDOS,ERRlock);
2925 nwritten = write_file(fsp,data,startpos,numtowrite);
2927 set_filetime(conn, fsp->fsp_name,mtime);
2930 * More insanity. W2K only closes the file if writelen > 0.
2935 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
2937 close_err = close_file(fsp,True);
2940 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2941 fsp->fnum, (int)numtowrite, (int)nwritten,
2942 conn->num_files_open));
2944 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
2945 END_PROFILE(SMBwriteclose);
2946 return(UNIXERROR(ERRHRD,ERRdiskfull));
2949 if(close_err != 0) {
2951 END_PROFILE(SMBwriteclose);
2952 return(UNIXERROR(ERRHRD,ERRgeneral));
2955 outsize = set_message(outbuf,1,0,True);
2957 SSVAL(outbuf,smb_vwv0,nwritten);
2958 END_PROFILE(SMBwriteclose);
2962 /****************************************************************************
2964 ****************************************************************************/
2966 int reply_lock(connection_struct *conn,
2967 char *inbuf,char *outbuf, int length, int dum_buffsize)
2969 int outsize = set_message(outbuf,0,0,True);
2970 SMB_BIG_UINT count,offset;
2972 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2973 BOOL my_lock_ctx = False;
2975 START_PROFILE(SMBlock);
2977 CHECK_FSP(fsp,conn);
2979 release_level_2_oplocks_on_change(fsp);
2981 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
2982 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
2984 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2985 fsp->fd, fsp->fnum, (double)offset, (double)count));
2987 status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &my_lock_ctx);
2988 if (NT_STATUS_V(status)) {
2990 /* Tests using Samba4 against W2K show this call never creates a blocking lock. */
2991 if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
2993 * A blocking lock was requested. Package up
2994 * this smb into a queued request and push it
2995 * onto the blocking lock queue.
2997 if(push_blocking_lock_request(inbuf, length, -1, 0, SVAL(inbuf,smb_pid), offset, count)) {
2998 END_PROFILE(SMBlock);
3003 END_PROFILE(SMBlock);
3004 return ERROR_NT(status);
3007 END_PROFILE(SMBlock);
3011 /****************************************************************************
3013 ****************************************************************************/
3015 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
3018 int outsize = set_message(outbuf,0,0,True);
3019 SMB_BIG_UINT count,offset;
3021 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3022 START_PROFILE(SMBunlock);
3024 CHECK_FSP(fsp,conn);
3026 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
3027 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
3029 status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
3030 if (NT_STATUS_V(status)) {
3031 END_PROFILE(SMBunlock);
3032 return ERROR_NT(status);
3035 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3036 fsp->fd, fsp->fnum, (double)offset, (double)count ) );
3038 END_PROFILE(SMBunlock);
3042 /****************************************************************************
3044 ****************************************************************************/
3046 int reply_tdis(connection_struct *conn,
3047 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3049 int outsize = set_message(outbuf,0,0,True);
3051 START_PROFILE(SMBtdis);
3053 vuid = SVAL(inbuf,smb_uid);
3056 DEBUG(4,("Invalid connection in tdis\n"));
3057 END_PROFILE(SMBtdis);
3058 return ERROR_DOS(ERRSRV,ERRinvnid);
3063 close_cnum(conn,vuid);
3065 END_PROFILE(SMBtdis);
3069 /****************************************************************************
3071 ****************************************************************************/
3073 int reply_echo(connection_struct *conn,
3074 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3076 int smb_reverb = SVAL(inbuf,smb_vwv0);
3078 unsigned int data_len = smb_buflen(inbuf);
3079 int outsize = set_message(outbuf,1,data_len,True);
3080 START_PROFILE(SMBecho);
3082 if (data_len > BUFFER_SIZE) {
3083 DEBUG(0,("reply_echo: data_len too large.\n"));
3084 END_PROFILE(SMBecho);
3088 /* copy any incoming data back out */
3090 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
3092 if (smb_reverb > 100) {
3093 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
3097 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
3098 SSVAL(outbuf,smb_vwv0,seq_num);
3100 smb_setlen(outbuf,outsize - 4);
3102 if (!send_smb(smbd_server_fd(),outbuf))
3103 exit_server("reply_echo: send_smb failed.");
3106 DEBUG(3,("echo %d times\n", smb_reverb));
3110 END_PROFILE(SMBecho);
3114 /****************************************************************************
3115 Reply to a printopen.
3116 ****************************************************************************/
3118 int reply_printopen(connection_struct *conn,
3119 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3123 START_PROFILE(SMBsplopen);
3125 if (!CAN_PRINT(conn)) {
3126 END_PROFILE(SMBsplopen);
3127 return ERROR_DOS(ERRDOS,ERRnoaccess);
3130 /* Open for exclusive use, write only. */
3131 fsp = print_fsp_open(conn, NULL);
3134 END_PROFILE(SMBsplopen);
3135 return(UNIXERROR(ERRDOS,ERRnoaccess));
3138 outsize = set_message(outbuf,1,0,True);
3139 SSVAL(outbuf,smb_vwv0,fsp->fnum);
3141 DEBUG(3,("openprint fd=%d fnum=%d\n",
3142 fsp->fd, fsp->fnum));
3144 END_PROFILE(SMBsplopen);
3148 /****************************************************************************
3149 Reply to a printclose.
3150 ****************************************************************************/
3152 int reply_printclose(connection_struct *conn,
3153 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3155 int outsize = set_message(outbuf,0,0,True);
3156 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3158 START_PROFILE(SMBsplclose);
3160 CHECK_FSP(fsp,conn);
3162 if (!CAN_PRINT(conn)) {
3163 END_PROFILE(SMBsplclose);
3164 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
3167 DEBUG(3,("printclose fd=%d fnum=%d\n",
3168 fsp->fd,fsp->fnum));
3170 close_err = close_file(fsp,True);
3172 if(close_err != 0) {
3174 END_PROFILE(SMBsplclose);
3175 return(UNIXERROR(ERRHRD,ERRgeneral));
3178 END_PROFILE(SMBsplclose);
3182 /****************************************************************************
3183 Reply to a printqueue.
3184 ****************************************************************************/
3186 int reply_printqueue(connection_struct *conn,
3187 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3189 int outsize = set_message(outbuf,2,3,True);
3190 int max_count = SVAL(inbuf,smb_vwv0);
3191 int start_index = SVAL(inbuf,smb_vwv1);
3192 START_PROFILE(SMBsplretq);
3194 /* we used to allow the client to get the cnum wrong, but that
3195 is really quite gross and only worked when there was only
3196 one printer - I think we should now only accept it if they
3197 get it right (tridge) */
3198 if (!CAN_PRINT(conn)) {
3199 END_PROFILE(SMBsplretq);
3200 return ERROR_DOS(ERRDOS,ERRnoaccess);
3203 SSVAL(outbuf,smb_vwv0,0);
3204 SSVAL(outbuf,smb_vwv1,0);
3205 SCVAL(smb_buf(outbuf),0,1);
3206 SSVAL(smb_buf(outbuf),1,0);
3208 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
3209 start_index, max_count));
3212 print_queue_struct *queue = NULL;
3213 print_status_struct status;
3214 char *p = smb_buf(outbuf) + 3;
3215 int count = print_queue_status(SNUM(conn), &queue, &status);
3216 int num_to_get = ABS(max_count);
3217 int first = (max_count>0?start_index:start_index+max_count+1);
3223 num_to_get = MIN(num_to_get,count-first);
3226 for (i=first;i<first+num_to_get;i++) {
3227 put_dos_date2(p,0,queue[i].time);
3228 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
3229 SSVAL(p,5, queue[i].job);
3230 SIVAL(p,7,queue[i].size);
3232 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII);
3237 outsize = set_message(outbuf,2,28*count+3,False);
3238 SSVAL(outbuf,smb_vwv0,count);
3239 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
3240 SCVAL(smb_buf(outbuf),0,1);
3241 SSVAL(smb_buf(outbuf),1,28*count);
3246 DEBUG(3,("%d entries returned in queue\n",count));
3249 END_PROFILE(SMBsplretq);
3253 /****************************************************************************
3254 Reply to a printwrite.
3255 ****************************************************************************/
3257 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3260 int outsize = set_message(outbuf,0,0,True);
3262 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3264 START_PROFILE(SMBsplwr);
3266 if (!CAN_PRINT(conn)) {
3267 END_PROFILE(SMBsplwr);
3268 return ERROR_DOS(ERRDOS,ERRnoaccess);
3271 CHECK_FSP(fsp,conn);
3274 numtowrite = SVAL(smb_buf(inbuf),1);
3275 data = smb_buf(inbuf) + 3;
3277 if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
3278 END_PROFILE(SMBsplwr);
3279 return(UNIXERROR(ERRHRD,ERRdiskfull));
3282 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
3284 END_PROFILE(SMBsplwr);
3288 /****************************************************************************
3289 The guts of the mkdir command, split out so it may be called by the NT SMB
3291 ****************************************************************************/
3293 NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
3295 BOOL bad_path = False;
3296 SMB_STRUCT_STAT sbuf;
3299 unix_convert(directory,conn,0,&bad_path,&sbuf);
3301 if( strchr_m(directory, ':')) {
3302 return NT_STATUS_NOT_A_DIRECTORY;
3305 if (ms_has_wild(directory)) {
3306 return NT_STATUS_OBJECT_NAME_INVALID;
3310 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3313 if (check_name(directory, conn))
3314 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
3317 if(errno == ENOENT) {
3318 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3320 return map_nt_error_from_unix(errno);
3323 return NT_STATUS_OK;
<