2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1997
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int DEBUGLEVEL;
29 extern connection_struct Connections[];
30 extern files_struct Files[];
31 extern BOOL case_sensitive;
33 extern int oplock_sock;
34 extern int smb_read_error;
36 /****************************************************************************
37 Send the required number of replies back.
38 We assume all fields other than the data fields are
39 set correctly for the type of call.
40 HACK ! Always assumes smb_setup field is zero.
41 ****************************************************************************/
42 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
43 int paramsize, char *pdata, int datasize)
45 /* As we are using a protocol > LANMAN1 then the max_send
46 variable must have been set in the sessetupX call.
47 This takes precedence over the max_xmit field in the
48 global struct. These different max_xmit variables should
49 be merged as this is now too confusing */
52 int data_to_send = datasize;
53 int params_to_send = paramsize;
57 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
58 int alignment_offset = 1;
60 /* Initially set the wcnt area to be 10 - this is true for all
62 set_message(outbuf,10,0,True);
64 /* If there genuinely are no parameters or data to send just send
66 if(params_to_send == 0 && data_to_send == 0)
68 send_smb(Client,outbuf);
72 /* Space is bufsize minus Netbios over TCP header minus SMB header */
73 /* The alignment_offset is to align the param and data bytes on an even byte
74 boundary. NT 4.0 Beta needs this to work correctly. */
75 useable_space = bufsize - ((smb_buf(outbuf)+alignment_offset) - outbuf);
76 /* useable_space can never be more than max_send minus the
78 useable_space = MIN(useable_space, max_send - alignment_offset);
80 while( params_to_send || data_to_send)
82 /* Calculate whether we will totally or partially fill this packet */
83 total_sent_thistime = params_to_send + data_to_send + alignment_offset;
84 /* We can never send more than useable_space */
85 total_sent_thistime = MIN(total_sent_thistime, useable_space);
87 set_message(outbuf, 10, total_sent_thistime, True);
89 /* Set total params and data to be sent */
90 SSVAL(outbuf,smb_tprcnt,paramsize);
91 SSVAL(outbuf,smb_tdrcnt,datasize);
93 /* Calculate how many parameters and data we can fit into
94 this packet. Parameters get precedence */
96 params_sent_thistime = MIN(params_to_send,useable_space);
97 data_sent_thistime = useable_space - params_sent_thistime;
98 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
100 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
101 if(params_sent_thistime == 0)
103 SSVAL(outbuf,smb_proff,0);
104 SSVAL(outbuf,smb_prdisp,0);
106 /* smb_proff is the offset from the start of the SMB header to the
107 parameter bytes, however the first 4 bytes of outbuf are
108 the Netbios over TCP header. Thus use smb_base() to subtract
109 them from the calculation */
110 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
111 /* Absolute displacement of param bytes sent in this packet */
112 SSVAL(outbuf,smb_prdisp,pp - params);
115 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
116 if(data_sent_thistime == 0)
118 SSVAL(outbuf,smb_droff,0);
119 SSVAL(outbuf,smb_drdisp, 0);
121 /* The offset of the data bytes is the offset of the
122 parameter bytes plus the number of parameters being sent this time */
123 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
124 smb_base(outbuf)) + params_sent_thistime);
125 SSVAL(outbuf,smb_drdisp, pd - pdata);
128 /* Copy the param bytes into the packet */
129 if(params_sent_thistime)
130 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
131 /* Copy in the data bytes */
132 if(data_sent_thistime)
133 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime,pd,data_sent_thistime);
135 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
136 params_sent_thistime, data_sent_thistime, useable_space));
137 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
138 params_to_send, data_to_send, paramsize, datasize));
140 /* Send the packet */
141 send_smb(Client,outbuf);
143 pp += params_sent_thistime;
144 pd += data_sent_thistime;
146 params_to_send -= params_sent_thistime;
147 data_to_send -= data_sent_thistime;
150 if(params_to_send < 0 || data_to_send < 0)
152 DEBUG(2,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
153 params_to_send, data_to_send));
162 /****************************************************************************
163 reply to a TRANSACT2_OPEN
164 ****************************************************************************/
165 static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
166 char **pparams, char **ppdata)
168 char *params = *pparams;
169 int16 open_mode = SVAL(params, 2);
170 int16 open_attr = SVAL(params,6);
171 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
173 BOOL return_additional_info = BITSETW(params,0);
174 int16 open_sattr = SVAL(params, 4);
175 time_t open_time = make_unix_date3(params+8);
177 int16 open_ofun = SVAL(params,12);
178 int32 open_size = IVAL(params,14);
179 char *pname = ¶ms[28];
180 int16 namelen = strlen(pname)+1;
185 int size=0,fmode=0,mtime=0,rmode;
189 BOOL bad_path = False;
191 StrnCpy(fname,pname,namelen);
193 DEBUG(3,("trans2open %s cnum=%d mode=%d attr=%d ofun=%d size=%d\n",
194 fname,cnum,open_mode, open_attr, open_ofun, open_size));
196 /* XXXX we need to handle passed times, sattr and flags */
198 unix_convert(fname,cnum,0,&bad_path);
200 fnum = find_free_file();
202 return(ERROR(ERRSRV,ERRnofids));
204 if (!check_name(fname,cnum))
206 if((errno == ENOENT) && bad_path)
208 unix_ERR_class = ERRDOS;
209 unix_ERR_code = ERRbadpath;
211 return(UNIXERROR(ERRDOS,ERRnoaccess));
214 unixmode = unix_mode(cnum,open_attr | aARCH);
217 open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
218 oplock_request, &rmode,&smb_action);
220 if (!Files[fnum].open)
222 if((errno == ENOENT) && bad_path)
224 unix_ERR_class = ERRDOS;
225 unix_ERR_code = ERRbadpath;
227 return(UNIXERROR(ERRDOS,ERRnoaccess));
230 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
231 close_file(fnum,False);
232 return(ERROR(ERRDOS,ERRnoaccess));
236 fmode = dos_mode(cnum,fname,&sbuf);
237 mtime = sbuf.st_mtime;
240 close_file(fnum,False);
241 return(ERROR(ERRDOS,ERRnoaccess));
244 /* Realloc the size of parameters and data we will return */
245 params = *pparams = Realloc(*pparams, 28);
247 return(ERROR(ERRDOS,ERRnomem));
250 SSVAL(params,0,fnum);
251 SSVAL(params,2,fmode);
252 put_dos_date2(params,4, mtime);
253 SIVAL(params,8, size);
254 SSVAL(params,12,rmode);
256 if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
257 smb_action |= EXTENDED_OPLOCK_GRANTED;
260 SSVAL(params,18,smb_action);
261 SIVAL(params,20,inode);
263 /* Send the required number of replies */
264 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
269 /****************************************************************************
270 get a level dependent lanman2 dir entry.
271 ****************************************************************************/
272 static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_level,
273 int requires_resume_key,
274 BOOL dont_descend,char **ppdata,
275 char *base_data, int space_remaining,
286 char *p, *pdata = *ppdata;
287 int reskey=0, prev_dirpos=0;
290 uint32 mdate=0, adate=0, cdate=0;
292 BOOL isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
293 strequal(Connections[cnum].dirpath,".") ||
294 strequal(Connections[cnum].dirpath,"/"));
296 int nt_extmode; /* Used for NT connections instead of mode */
297 BOOL needslash = ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/');
300 *out_of_space = False;
302 if (!Connections[cnum].dirptr)
305 p = strrchr(path_mask,'/');
314 pstrcpy(mask, path_mask);
318 /* Needed if we run out of space */
319 prev_dirpos = TellDir(Connections[cnum].dirptr);
320 dname = ReadDirName(Connections[cnum].dirptr);
322 reskey = TellDir(Connections[cnum].dirptr);
324 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
325 Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
332 pstrcpy(fname,dname);
334 if(mask_match(fname, mask, case_sensitive, True))
336 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
337 if (dont_descend && !isdots)
340 if (isrootdir && isdots)
343 pstrcpy(pathreal,Connections[cnum].dirpath);
345 strcat(pathreal,"/");
346 strcat(pathreal,dname);
347 if (sys_stat(pathreal,&sbuf) != 0)
349 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
353 mode = dos_mode(cnum,pathreal,&sbuf);
355 if (!dir_check_ftype(cnum,mode,&sbuf,dirtype)) {
356 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
361 mdate = sbuf.st_mtime;
362 adate = sbuf.st_atime;
363 cdate = sbuf.st_ctime;
367 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
373 name_map_mangle(fname,False,SNUM(cnum));
378 nt_extmode = mode ? mode : NT_FILE_ATTRIBUTE_NORMAL;
383 if(requires_resume_key) {
387 put_dos_date2(p,l1_fdateCreation,cdate);
388 put_dos_date2(p,l1_fdateLastAccess,adate);
389 put_dos_date2(p,l1_fdateLastWrite,mdate);
390 SIVAL(p,l1_cbFile,size);
391 SIVAL(p,l1_cbFileAlloc,ROUNDUP(size,1024));
392 SSVAL(p,l1_attrFile,mode);
393 SCVAL(p,l1_cchName,strlen(fname));
394 strcpy(p + l1_achName, fname);
395 nameptr = p + l1_achName;
396 p += l1_achName + strlen(fname) + 1;
401 if(requires_resume_key) {
405 put_dos_date2(p,l2_fdateCreation,cdate);
406 put_dos_date2(p,l2_fdateLastAccess,adate);
407 put_dos_date2(p,l2_fdateLastWrite,mdate);
408 SIVAL(p,l2_cbFile,size);
409 SIVAL(p,l2_cbFileAlloc,ROUNDUP(size,1024));
410 SSVAL(p,l2_attrFile,mode);
411 SIVAL(p,l2_cbList,0); /* No extended attributes */
412 SCVAL(p,l2_cchName,strlen(fname));
413 strcpy(p + l2_achName, fname);
414 nameptr = p + l2_achName;
415 p += l2_achName + strlen(fname) + 1;
420 put_dos_date2(p,4,cdate);
421 put_dos_date2(p,8,adate);
422 put_dos_date2(p,12,mdate);
424 SIVAL(p,20,ROUNDUP(size,1024));
427 CVAL(p,30) = strlen(fname);
430 p += 31 + strlen(fname) + 1;
434 if(requires_resume_key) {
438 SIVAL(p,0,33+strlen(fname)+1);
439 put_dos_date2(p,4,cdate);
440 put_dos_date2(p,8,adate);
441 put_dos_date2(p,12,mdate);
443 SIVAL(p,20,ROUNDUP(size,1024));
445 CVAL(p,32) = strlen(fname);
446 strcpy(p + 33, fname);
448 p += 33 + strlen(fname) + 1;
451 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
452 was_8_3 = is_8_3(fname, True);
453 len = 94+strlen(fname);
454 len = (len + 3) & ~3;
455 SIVAL(p,0,len); p += 4;
456 SIVAL(p,0,reskey); p += 4;
457 put_long_date(p,cdate); p += 8;
458 put_long_date(p,adate); p += 8;
459 put_long_date(p,mdate); p += 8;
460 put_long_date(p,mdate); p += 8;
461 SIVAL(p,0,size); p += 8;
462 SIVAL(p,0,size); p += 8;
463 SIVAL(p,0,nt_extmode); p += 4;
464 SIVAL(p,0,strlen(fname)); p += 4;
465 SIVAL(p,0,0); p += 4;
468 if (!name_map_mangle(p+2,True,SNUM(cnum)))
473 SSVAL(p,0,strlen(p+2));
476 strcpy(p,fname); p += strlen(p);
480 case SMB_FIND_FILE_DIRECTORY_INFO:
481 len = 64+strlen(fname);
482 len = (len + 3) & ~3;
483 SIVAL(p,0,len); p += 4;
484 SIVAL(p,0,reskey); p += 4;
485 put_long_date(p,cdate); p += 8;
486 put_long_date(p,adate); p += 8;
487 put_long_date(p,mdate); p += 8;
488 put_long_date(p,mdate); p += 8;
489 SIVAL(p,0,size); p += 8;
490 SIVAL(p,0,size); p += 8;
491 SIVAL(p,0,nt_extmode); p += 4;
492 SIVAL(p,0,strlen(fname)); p += 4;
498 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
499 len = 68+strlen(fname);
500 len = (len + 3) & ~3;
501 SIVAL(p,0,len); p += 4;
502 SIVAL(p,0,reskey); p += 4;
503 put_long_date(p,cdate); p += 8;
504 put_long_date(p,adate); p += 8;
505 put_long_date(p,mdate); p += 8;
506 put_long_date(p,mdate); p += 8;
507 SIVAL(p,0,size); p += 8;
508 SIVAL(p,0,size); p += 8;
509 SIVAL(p,0,nt_extmode); p += 4;
510 SIVAL(p,0,strlen(fname)); p += 4;
511 SIVAL(p,0,0); p += 4;
516 case SMB_FIND_FILE_NAMES_INFO:
517 len = 12+strlen(fname);
518 len = (len + 3) & ~3;
519 SIVAL(p,0,len); p += 4;
520 SIVAL(p,0,reskey); p += 4;
521 SIVAL(p,0,strlen(fname)); p += 4;
531 if (PTR_DIFF(p,pdata) > space_remaining) {
532 /* Move the dirptr back to prev_dirpos */
533 SeekDir(Connections[cnum].dirptr, prev_dirpos);
534 *out_of_space = True;
535 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
536 return False; /* Not finished - just out of space */
539 /* Setup the last_filename pointer, as an offset from base_data */
540 *last_name_off = PTR_DIFF(nameptr,base_data);
541 /* Advance the data pointer to the next slot */
546 /****************************************************************************
547 reply to a TRANS2_FINDFIRST
548 ****************************************************************************/
549 static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum,
550 char **pparams, char **ppdata)
552 /* We must be careful here that we don't return more than the
553 allowed number of data bytes. If this means returning fewer than
554 maxentries then so be it. We assume that the redirector has
555 enough room for the fixed number of parameter bytes it has
557 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
558 char *params = *pparams;
559 char *pdata = *ppdata;
560 int dirtype = SVAL(params,0);
561 int maxentries = SVAL(params,2);
562 BOOL close_after_first = BITSETW(params+4,0);
563 BOOL close_if_end = BITSETW(params+4,1);
564 BOOL requires_resume_key = BITSETW(params+4,2);
565 int info_level = SVAL(params,6);
573 BOOL finished = False;
574 BOOL dont_descend = False;
575 BOOL out_of_space = False;
577 BOOL bad_path = False;
579 *directory = *mask = 0;
581 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
582 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
583 info_level, max_data_bytes));
591 case SMB_FIND_FILE_DIRECTORY_INFO:
592 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
593 case SMB_FIND_FILE_NAMES_INFO:
594 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
597 return(ERROR(ERRDOS,ERRunknownlevel));
600 pstrcpy(directory, params + 12); /* Complete directory path with
601 wildcard mask appended */
603 DEBUG(5,("path=%s\n",directory));
605 unix_convert(directory,cnum,0,&bad_path);
606 if(!check_name(directory,cnum)) {
607 if((errno == ENOENT) && bad_path)
609 unix_ERR_class = ERRDOS;
610 unix_ERR_code = ERRbadpath;
614 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
615 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
616 (get_remote_arch() == RA_WINNT))
618 unix_ERR_class = ERRDOS;
619 unix_ERR_code = ERRbaddirectory;
623 return(ERROR(ERRDOS,ERRbadpath));
626 p = strrchr(directory,'/');
628 strcpy(mask,directory);
629 strcpy(directory,"./");
635 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
637 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
639 return(ERROR(ERRDOS,ERRnomem));
640 bzero(pdata,max_data_bytes);
642 /* Realloc the params space */
643 params = *pparams = Realloc(*pparams, 10);
645 return(ERROR(ERRDOS,ERRnomem));
647 dptr_num = dptr_create(cnum,directory, True ,SVAL(inbuf,smb_pid));
652 if((errno == ENOENT) && bad_path)
654 unix_ERR_class = ERRDOS;
655 unix_ERR_code = ERRbadpath;
659 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
660 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
661 (get_remote_arch() == RA_WINNT))
663 unix_ERR_class = ERRDOS;
664 unix_ERR_code = ERRbaddirectory;
668 return (UNIXERROR(ERRDOS,ERRbadpath));
670 return(ERROR(ERRDOS,ERRbadpath));
673 /* convert the formatted masks */
677 if (*p == '<') *p = '*';
678 if (*p == '>') *p = '?';
679 if (*p == '"') *p = '.';
684 /* a special case for 16 bit apps */
685 if (strequal(mask,"????????.???")) strcpy(mask,"*");
687 /* handle broken clients that send us old 8.3 format */
688 string_sub(mask,"????????","*");
689 string_sub(mask,".???",".*");
691 /* Save the wildcard match and attribs we are using on this directory -
692 needed as lanman2 assumes these are being saved between calls */
694 if(!(wcard = strdup(mask))) {
695 dptr_close(dptr_num);
696 return(ERROR(ERRDOS,ERRnomem));
699 dptr_set_wcard(dptr_num, wcard);
700 dptr_set_attr(dptr_num, dirtype);
702 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
704 /* We don't need to check for VOL here as this is returned by
705 a different TRANS2 call. */
707 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
708 Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
709 if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
713 space_remaining = max_data_bytes;
714 out_of_space = False;
716 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
719 /* this is a heuristic to avoid seeking the dirptr except when
720 absolutely necessary. It allows for a filename of about 40 chars */
721 if (space_remaining < DIRLEN_GUESS && numentries > 0)
729 !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
730 requires_resume_key,dont_descend,
731 &p,pdata,space_remaining, &out_of_space,
735 if (finished && out_of_space)
738 if (!finished && !out_of_space)
740 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
743 /* Check if we can close the dirptr */
744 if(close_after_first || (finished && close_if_end))
746 dptr_close(dptr_num);
747 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
751 /* At this point pdata points to numentries directory entries. */
753 /* Set up the return parameter block */
754 SSVAL(params,0,dptr_num);
755 SSVAL(params,2,numentries);
756 SSVAL(params,4,finished);
757 SSVAL(params,6,0); /* Never an EA error */
758 SSVAL(params,8,last_name_off);
760 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
762 if ((! *directory) && dptr_path(dptr_num))
763 sprintf(directory,"(%s)",dptr_path(dptr_num));
765 DEBUG(4,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
767 smb_fn_name(CVAL(inbuf,smb_com)),
768 mask,directory,cnum,dirtype,numentries));
774 /****************************************************************************
775 reply to a TRANS2_FINDNEXT
776 ****************************************************************************/
777 static int call_trans2findnext(char *inbuf, char *outbuf, int length, int bufsize,
778 int cnum, char **pparams, char **ppdata)
780 /* We must be careful here that we don't return more than the
781 allowed number of data bytes. If this means returning fewer than
782 maxentries then so be it. We assume that the redirector has
783 enough room for the fixed number of parameter bytes it has
785 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
786 char *params = *pparams;
787 char *pdata = *ppdata;
788 int16 dptr_num = SVAL(params,0);
789 int maxentries = SVAL(params,2);
790 uint16 info_level = SVAL(params,4);
791 uint32 resume_key = IVAL(params,6);
792 BOOL close_after_request = BITSETW(params+10,0);
793 BOOL close_if_end = BITSETW(params+10,1);
794 BOOL requires_resume_key = BITSETW(params+10,2);
795 BOOL continue_bit = BITSETW(params+10,3);
801 int i, last_name_off=0;
802 BOOL finished = False;
803 BOOL dont_descend = False;
804 BOOL out_of_space = False;
807 *mask = *directory = 0;
809 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, close_after_request=%d, close_if_end = %d requires_resume_key = %d resume_key = %d continue=%d level = %d\n",
810 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
811 requires_resume_key, resume_key, continue_bit, info_level));
819 case SMB_FIND_FILE_DIRECTORY_INFO:
820 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
821 case SMB_FIND_FILE_NAMES_INFO:
822 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
825 return(ERROR(ERRDOS,ERRunknownlevel));
828 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
830 return(ERROR(ERRDOS,ERRnomem));
831 bzero(pdata,max_data_bytes);
833 /* Realloc the params space */
834 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
836 return(ERROR(ERRDOS,ERRnomem));
838 /* Check that the dptr is valid */
839 if(!(Connections[cnum].dirptr = dptr_fetch_lanman2(params, dptr_num)))
840 return(ERROR(ERRDOS,ERRnofiles));
842 string_set(&Connections[cnum].dirpath,dptr_path(dptr_num));
844 /* Get the wildcard mask from the dptr */
845 if((p = dptr_wcard(dptr_num))== NULL) {
846 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
847 return (ERROR(ERRDOS,ERRnofiles));
850 strcpy(directory,Connections[cnum].dirpath);
852 /* Get the attr mask from the dptr */
853 dirtype = dptr_attr(dptr_num);
855 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
856 dptr_num, mask, dirtype,
857 Connections[cnum].dirptr,
858 TellDir(Connections[cnum].dirptr)));
860 /* We don't need to check for VOL here as this is returned by
861 a different TRANS2 call. */
863 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
864 if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
868 space_remaining = max_data_bytes;
869 out_of_space = False;
871 /* If we have a resume key - seek to the correct position. */
872 if(requires_resume_key && !continue_bit)
873 SeekDir(Connections[cnum].dirptr, resume_key);
875 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
877 /* this is a heuristic to avoid seeking the dirptr except when
878 absolutely necessary. It allows for a filename of about 40 chars */
879 if (space_remaining < DIRLEN_GUESS && numentries > 0)
887 !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
888 requires_resume_key,dont_descend,
889 &p,pdata,space_remaining, &out_of_space,
893 if (finished && out_of_space)
896 if (!finished && !out_of_space)
898 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
901 /* Check if we can close the dirptr */
902 if(close_after_request || (finished && close_if_end))
904 dptr_close(dptr_num); /* This frees up the saved mask */
905 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
910 /* Set up the return parameter block */
911 SSVAL(params,0,numentries);
912 SSVAL(params,2,finished);
913 SSVAL(params,4,0); /* Never an EA error */
914 SSVAL(params,6,last_name_off);
916 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
918 if ((! *directory) && dptr_path(dptr_num))
919 sprintf(directory,"(%s)",dptr_path(dptr_num));
921 DEBUG(3,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
923 smb_fn_name(CVAL(inbuf,smb_com)),
924 mask,directory,cnum,dirtype,numentries));
929 /****************************************************************************
930 reply to a TRANS2_QFSINFO (query filesystem info)
931 ****************************************************************************/
932 static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
933 int cnum, char **pparams, char **ppdata)
935 char *pdata = *ppdata;
936 char *params = *pparams;
937 uint16 info_level = SVAL(params,0);
940 char *vname = volume_label(SNUM(cnum));
942 DEBUG(3,("call_trans2qfsinfo: cnum = %d, level = %d\n", cnum, info_level));
944 if(sys_stat(".",&st)!=0) {
945 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
946 return (ERROR(ERRSRV,ERRinvdevice));
949 pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
955 int dfree,dsize,bsize;
957 sys_disk_free(".",&bsize,&dfree,&dsize);
958 SIVAL(pdata,l1_idFileSystem,st.st_dev);
959 SIVAL(pdata,l1_cSectorUnit,bsize/512);
960 SIVAL(pdata,l1_cUnit,dsize);
961 SIVAL(pdata,l1_cUnitAvail,dfree);
962 SSVAL(pdata,l1_cbSector,512);
963 DEBUG(5,("call_trans2qfsinfo : bsize=%d, id=%x, cSectorUnit=%d, cUnit=%d, cUnitAvail=%d, cbSector=%d\n",
964 bsize, st.st_dev, bsize/512, dsize, dfree, 512));
969 /* Return volume name */
970 int volname_len = MIN(strlen(vname),11);
971 data_len = l2_vol_szVolLabel + volname_len + 1;
972 put_dos_date2(pdata,l2_vol_fdateCreation,st.st_ctime);
973 SCVAL(pdata,l2_vol_cch,volname_len);
974 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
975 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len,
976 pdata+l2_vol_szVolLabel));
979 case SMB_QUERY_FS_ATTRIBUTE_INFO:
980 data_len = 12 + 2*strlen(FSTYPE_STRING);
981 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
982 SIVAL(pdata,4,128); /* Max filename component length */
983 SIVAL(pdata,8,2*strlen(FSTYPE_STRING));
984 PutUniCode(pdata+12,FSTYPE_STRING);
986 case SMB_QUERY_FS_LABEL_INFO:
987 data_len = 4 + strlen(vname);
988 SIVAL(pdata,0,strlen(vname));
989 strcpy(pdata+4,vname);
991 case SMB_QUERY_FS_VOLUME_INFO:
992 data_len = 18 + 2*strlen(vname);
993 SIVAL(pdata,12,2*strlen(vname));
994 PutUniCode(pdata+18,vname);
995 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),
998 case SMB_QUERY_FS_SIZE_INFO:
1000 int dfree,dsize,bsize;
1002 sys_disk_free(".",&bsize,&dfree,&dsize);
1003 SIVAL(pdata,0,dsize);
1004 SIVAL(pdata,8,dfree);
1005 SIVAL(pdata,16,bsize/512);
1006 SIVAL(pdata,20,512);
1009 case SMB_QUERY_FS_DEVICE_INFO:
1011 SIVAL(pdata,0,0); /* dev type */
1012 SIVAL(pdata,4,0); /* characteristics */
1015 return(ERROR(ERRDOS,ERRunknownlevel));
1019 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1021 DEBUG(4,("%s %s info_level =%d\n",timestring(),smb_fn_name(CVAL(inbuf,smb_com)), info_level));
1026 /****************************************************************************
1027 reply to a TRANS2_SETFSINFO (set filesystem info)
1028 ****************************************************************************/
1029 static int call_trans2setfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
1030 int cnum, char **pparams, char **ppdata)
1032 /* Just say yes we did it - there is nothing that
1033 can be set here so it doesn't matter. */
1035 DEBUG(3,("call_trans2setfsinfo\n"));
1037 if (!CAN_WRITE(cnum))
1038 return(ERROR(ERRSRV,ERRaccess));
1040 outsize = set_message(outbuf,10,0,True);
1045 /****************************************************************************
1046 reply to a TRANS2_QFILEINFO (query file info by fileid)
1047 ****************************************************************************/
1048 static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length,
1049 int bufsize,int cnum,
1050 char **pparams,char **ppdata,
1053 char *params = *pparams;
1054 char *pdata = *ppdata;
1055 uint16 tran_call = SVAL(inbuf, smb_setup0);
1059 unsigned int data_size;
1065 BOOL bad_path = False;
1067 if (tran_call == TRANSACT2_QFILEINFO) {
1068 int16 fnum = SVALS(params,0);
1069 info_level = SVAL(params,2);
1071 CHECK_FNUM(fnum,cnum);
1074 fname = Files[fnum].name;
1075 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
1076 DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
1077 return(UNIXERROR(ERRDOS,ERRbadfid));
1079 pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR);
1082 info_level = SVAL(params,0);
1084 pstrcpy(fname,¶ms[6]);
1085 unix_convert(fname,cnum,0,&bad_path);
1086 if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) {
1087 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1088 if((errno == ENOENT) && bad_path)
1090 unix_ERR_class = ERRDOS;
1091 unix_ERR_code = ERRbadpath;
1093 return(UNIXERROR(ERRDOS,ERRbadpath));
1099 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1100 fname,info_level,tran_call,total_data));
1102 p = strrchr(fname,'/');
1108 mode = dos_mode(cnum,fname,&sbuf);
1109 size = sbuf.st_size;
1110 if (mode & aDIR) size = 0;
1112 params = *pparams = Realloc(*pparams,2); bzero(params,2);
1114 pdata = *ppdata = Realloc(*ppdata, data_size);
1116 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1117 /* uggh, EAs for OS2 */
1118 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1119 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1122 bzero(pdata,data_size);
1126 case SMB_INFO_STANDARD:
1127 case SMB_INFO_QUERY_EA_SIZE:
1128 data_size = (info_level==1?22:26);
1129 put_dos_date2(pdata,l1_fdateCreation,sbuf.st_ctime); /* create = inode mod */
1130 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); /* access time */
1131 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1132 SIVAL(pdata,l1_cbFile,size);
1133 SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
1134 SSVAL(pdata,l1_attrFile,mode);
1135 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1138 case SMB_INFO_QUERY_EAS_FROM_LIST:
1140 put_dos_date2(pdata,0,sbuf.st_ctime); /* create time = inode mod time */
1141 put_dos_date2(pdata,4,sbuf.st_atime);
1142 put_dos_date2(pdata,8,sbuf.st_mtime);
1143 SIVAL(pdata,12,size);
1144 SIVAL(pdata,16,ROUNDUP(size,1024));
1145 SIVAL(pdata,20,mode);
1148 case SMB_INFO_QUERY_ALL_EAS:
1150 SIVAL(pdata,0,data_size);
1154 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1156 case SMB_QUERY_FILE_BASIC_INFO:
1157 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1158 put_long_date(pdata,sbuf.st_ctime); /* create time = inode mod time */
1159 put_long_date(pdata+8,sbuf.st_atime); /* access time */
1160 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1161 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1162 SIVAL(pdata,32,mode);
1164 DEBUG(5,("SMB_QFBI - "));
1165 DEBUG(5,("create: %s ", ctime(&sbuf.st_ctime)));
1166 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1167 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1168 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1169 DEBUG(5,("mode: %x\n", mode));
1173 case SMB_QUERY_FILE_STANDARD_INFO:
1175 SIVAL(pdata,0,size);
1176 SIVAL(pdata,8,size);
1177 SIVAL(pdata,16,sbuf.st_nlink);
1179 CVAL(pdata,21) = (mode&aDIR)?1:0;
1182 case SMB_QUERY_FILE_EA_INFO:
1186 /* Get the 8.3 name - used if NT SMB was negotiated. */
1187 case SMB_QUERY_FILE_ALT_NAME_INFO:
1190 pstrcpy(short_name,fname);
1191 /* Mangle if not already 8.3 */
1192 if(!is_8_3(short_name, True))
1194 if(!name_map_mangle(short_name,True,SNUM(cnum)))
1197 strncpy(pdata + 4,short_name,12);
1198 (pdata + 4)[12] = 0;
1199 strupper(pdata + 4);
1200 l = strlen(pdata + 4);
1206 case SMB_QUERY_FILE_NAME_INFO:
1209 pstrcpy(pdata+4,fname);
1212 case SMB_QUERY_FILE_ALLOCATION_INFO:
1213 case SMB_QUERY_FILE_END_OF_FILEINFO:
1215 SIVAL(pdata,0,size);
1218 case SMB_QUERY_FILE_ALL_INFO:
1219 put_long_date(pdata,sbuf.st_ctime); /* create time = inode mod time */
1220 put_long_date(pdata+8,sbuf.st_atime); /* access time */
1221 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1222 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1223 SIVAL(pdata,32,mode);
1225 SIVAL(pdata,0,size);
1226 SIVAL(pdata,8,size);
1227 SIVAL(pdata,16,sbuf.st_nlink);
1229 CVAL(pdata,21) = (mode&aDIR)?1:0;
1231 pdata += 8; /* index number */
1232 pdata += 4; /* EA info */
1234 SIVAL(pdata,0,0xA9);
1236 SIVAL(pdata,0,0xd01BF);
1238 SIVAL(pdata,0,pos); /* current offset */
1240 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1242 pdata += 4; /* alignment */
1244 pstrcpy(pdata+4,fname);
1246 data_size = PTR_DIFF(pdata,(*ppdata));
1249 case SMB_QUERY_FILE_STREAM_INFO:
1252 SIVAL(pdata,4,size);
1253 SIVAL(pdata,12,size);
1255 pstrcpy(pdata+24,fname);
1258 return(ERROR(ERRDOS,ERRunknownlevel));
1261 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1266 /****************************************************************************
1267 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1268 ****************************************************************************/
1269 static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
1270 int bufsize, int cnum, char **pparams,
1271 char **ppdata, int total_data)
1273 char *params = *pparams;
1274 char *pdata = *ppdata;
1275 uint16 tran_call = SVAL(inbuf, smb_setup0);
1284 BOOL bad_path = False;
1286 if (!CAN_WRITE(cnum))
1287 return(ERROR(ERRSRV,ERRaccess));
1289 if (tran_call == TRANSACT2_SETFILEINFO) {
1290 int16 fnum = SVALS(params,0);
1291 info_level = SVAL(params,2);
1293 CHECK_FNUM(fnum,cnum);
1296 fname = Files[fnum].name;
1297 fd = Files[fnum].fd_ptr->fd;
1299 if(fstat(fd,&st)!=0) {
1300 DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
1301 return(ERROR(ERRDOS,ERRbadpath));
1305 info_level = SVAL(params,0);
1307 pstrcpy(fname,¶ms[6]);
1308 unix_convert(fname,cnum,0,&bad_path);
1309 if(!check_name(fname, cnum))
1311 if((errno == ENOENT) && bad_path)
1313 unix_ERR_class = ERRDOS;
1314 unix_ERR_code = ERRbadpath;
1316 return(UNIXERROR(ERRDOS,ERRbadpath));
1319 if(sys_stat(fname,&st)!=0) {
1320 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1321 if((errno == ENOENT) && bad_path)
1323 unix_ERR_class = ERRDOS;
1324 unix_ERR_code = ERRbadpath;
1326 return(UNIXERROR(ERRDOS,ERRbadpath));
1330 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1331 tran_call,fname,info_level,total_data));
1333 /* Realloc the parameter and data sizes */
1334 params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
1336 return(ERROR(ERRDOS,ERRnomem));
1339 tvs.modtime = st.st_mtime;
1340 tvs.actime = st.st_atime;
1341 mode = dos_mode(cnum,fname,&st);
1343 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1344 /* uggh, EAs for OS2 */
1345 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1346 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1351 case SMB_INFO_STANDARD:
1352 case SMB_INFO_QUERY_EA_SIZE:
1355 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1358 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1360 mode = SVAL(pdata,l1_attrFile);
1361 size = IVAL(pdata,l1_cbFile);
1365 /* XXXX um, i don't think this is right.
1366 it's also not in the cifs6.txt spec.
1368 case SMB_INFO_QUERY_EAS_FROM_LIST:
1369 tvs.actime = make_unix_date2(pdata+8);
1370 tvs.modtime = make_unix_date2(pdata+12);
1371 size = IVAL(pdata,16);
1372 mode = IVAL(pdata,24);
1375 /* XXXX nor this. not in cifs6.txt, either. */
1376 case SMB_INFO_QUERY_ALL_EAS:
1377 tvs.actime = make_unix_date2(pdata+8);
1378 tvs.modtime = make_unix_date2(pdata+12);
1379 size = IVAL(pdata,16);
1380 mode = IVAL(pdata,24);
1383 case SMB_SET_FILE_BASIC_INFO:
1385 /* Ignore create time at offset pdata. */
1388 tvs.actime = interpret_long_date(pdata+8);
1390 /* write time + changed time, combined. */
1391 tvs.modtime=MAX(interpret_long_date(pdata+16),
1392 interpret_long_date(pdata+24));
1394 #if 0 /* Needs more testing... */
1395 /* Test from Luke to prevent Win95 from
1396 setting incorrect values here.
1398 if (tvs.actime < tvs.modtime)
1399 return(ERROR(ERRDOS,ERRnoaccess));
1400 #endif /* Needs more testing... */
1403 mode = IVAL(pdata,32);
1407 case SMB_SET_FILE_END_OF_FILE_INFO:
1409 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1410 return(ERROR(ERRDOS,ERRunknownlevel));
1411 size = IVAL(pdata,0);
1415 case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
1416 case SMB_SET_FILE_ALLOCATION_INFO: /* not supported yet */
1419 return(ERROR(ERRDOS,ERRunknownlevel));
1423 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1424 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1425 DEBUG(6,("size: %x " , size));
1426 DEBUG(6,("mode: %x\n" , mode));
1428 /* get some defaults (no modifications) if any info is zero. */
1429 if (!tvs.actime) tvs.actime = st.st_atime;
1430 if (!tvs.modtime) tvs.modtime = st.st_mtime;
1431 if (!size) size = st.st_size;
1433 /* Try and set the times, size and mode of this file -
1434 if they are different from the current values
1436 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
1438 if(file_utime(cnum, fname, &tvs)!=0)
1440 return(ERROR(ERRDOS,ERRnoaccess));
1444 /* check the mode isn't different, before changing it */
1445 if (mode != dos_mode(cnum, fname, &st) && dos_chmod(cnum, fname, mode, NULL))
1447 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1448 return(ERROR(ERRDOS,ERRnoaccess));
1451 if(size != st.st_size)
1455 fd = sys_open(fname,O_RDWR,0);
1458 return(ERROR(ERRDOS,ERRbadpath));
1460 set_filelen(fd, size);
1465 set_filelen(fd, size);
1471 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1476 /****************************************************************************
1477 reply to a TRANS2_MKDIR (make directory with extended attributes).
1478 ****************************************************************************/
1479 static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize,
1480 int cnum, char **pparams, char **ppdata)
1482 char *params = *pparams;
1485 BOOL bad_path = False;
1487 if (!CAN_WRITE(cnum))
1488 return(ERROR(ERRSRV,ERRaccess));
1490 pstrcpy(directory, ¶ms[4]);
1492 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
1494 unix_convert(directory,cnum,0,&bad_path);
1495 if (check_name(directory,cnum))
1496 ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
1500 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
1501 if((errno == ENOENT) && bad_path)
1503 unix_ERR_class = ERRDOS;
1504 unix_ERR_code = ERRbadpath;
1506 return(UNIXERROR(ERRDOS,ERRnoaccess));
1509 /* Realloc the parameter and data sizes */
1510 params = *pparams = Realloc(*pparams,2);
1512 return(ERROR(ERRDOS,ERRnomem));
1516 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1521 /****************************************************************************
1522 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1523 We don't actually do this - we just send a null response.
1524 ****************************************************************************/
1525 static int call_trans2findnotifyfirst(char *inbuf, char *outbuf, int length, int bufsize,
1526 int cnum, char **pparams, char **ppdata)
1528 static uint16 fnf_handle = 257;
1529 char *params = *pparams;
1530 uint16 info_level = SVAL(params,4);
1532 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
1540 return(ERROR(ERRDOS,ERRunknownlevel));
1543 /* Realloc the parameter and data sizes */
1544 params = *pparams = Realloc(*pparams,6);
1546 return(ERROR(ERRDOS,ERRnomem));
1548 SSVAL(params,0,fnf_handle);
1549 SSVAL(params,2,0); /* No changes */
1550 SSVAL(params,4,0); /* No EA errors */
1557 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
1562 /****************************************************************************
1563 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
1564 changes). Currently this does nothing.
1565 ****************************************************************************/
1566 static int call_trans2findnotifynext(char *inbuf, char *outbuf, int length, int bufsize,
1567 int cnum, char **pparams, char **ppdata)
1569 char *params = *pparams;
1571 DEBUG(3,("call_trans2findnotifynext\n"));
1573 /* Realloc the parameter and data sizes */
1574 params = *pparams = Realloc(*pparams,4);
1576 return(ERROR(ERRDOS,ERRnomem));
1578 SSVAL(params,0,0); /* No changes */
1579 SSVAL(params,2,0); /* No EA errors */
1581 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
1586 /****************************************************************************
1587 reply to a SMBfindclose (stop trans2 directory search)
1588 ****************************************************************************/
1589 int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize)
1593 int16 dptr_num=SVALS(inbuf,smb_vwv0);
1595 cnum = SVAL(inbuf,smb_tid);
1597 DEBUG(3,("reply_findclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1599 dptr_close(dptr_num);
1601 outsize = set_message(outbuf,0,0,True);
1603 DEBUG(3,("%s SMBfindclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1608 /****************************************************************************
1609 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1610 ****************************************************************************/
1611 int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize)
1617 cnum = SVAL(inbuf,smb_tid);
1618 dptr_num = SVAL(inbuf,smb_vwv0);
1620 DEBUG(3,("reply_findnclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1622 /* We never give out valid handles for a
1623 findnotifyfirst - so any dptr_num is ok here.
1626 outsize = set_message(outbuf,0,0,True);
1628 DEBUG(3,("%s SMB_findnclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1634 /****************************************************************************
1635 reply to a SMBtranss2 - just ignore it!
1636 ****************************************************************************/
1637 int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize)
1639 DEBUG(4,("Ignoring transs2 of length %d\n",length));
1643 /****************************************************************************
1644 reply to a SMBtrans2
1645 ****************************************************************************/
1646 int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
1649 int cnum = SVAL(inbuf,smb_tid);
1650 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
1651 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
1653 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
1654 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
1655 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
1656 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
1657 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
1658 int32 timeout = IVALS(inbuf,smb_timeout);
1660 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
1661 unsigned int tran_call = SVAL(inbuf, smb_setup0);
1662 char *params = NULL, *data = NULL;
1663 int num_params, num_params_sofar, num_data, num_data_sofar;
1665 outsize = set_message(outbuf,0,0,True);
1667 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1668 is so as a sanity check */
1671 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1672 return(ERROR(ERRSRV,ERRerror));
1675 /* Allocate the space for the maximum needed parameters and data */
1676 if (total_params > 0)
1677 params = (char *)malloc(total_params);
1679 data = (char *)malloc(total_data);
1681 if ((total_params && !params) || (total_data && !data))
1683 DEBUG(2,("Out of memory in reply_trans2\n"));
1684 return(ERROR(ERRDOS,ERRnomem));
1687 /* Copy the param and data bytes sent with this request into
1688 the params buffer */
1689 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
1690 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
1692 if (num_params > total_params || num_data > total_data)
1693 exit_server("invalid params in reply_trans2");
1695 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
1696 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
1698 if(num_data_sofar < total_data || num_params_sofar < total_params)
1700 /* We need to send an interim response then receive the rest
1701 of the parameter/data bytes */
1702 outsize = set_message(outbuf,0,0,True);
1703 send_smb(Client,outbuf);
1705 while( num_data_sofar < total_data || num_params_sofar < total_params)
1709 ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
1710 SMB_SECONDARY_WAIT);
1712 if((ret && (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret)
1714 outsize = set_message(outbuf,0,0,True);
1716 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
1718 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
1719 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
1722 return(ERROR(ERRSRV,ERRerror));
1725 /* Revise total_params and total_data in case they have changed downwards */
1726 total_params = SVAL(inbuf, smb_tpscnt);
1727 total_data = SVAL(inbuf, smb_tdscnt);
1728 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
1729 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
1730 if (num_params_sofar > total_params || num_data_sofar > total_data)
1731 exit_server("data overflow in trans2");
1733 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
1734 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
1735 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
1736 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
1740 if (Protocol >= PROTOCOL_NT1) {
1741 uint16 flg2 = SVAL(outbuf,smb_flg2);
1742 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1745 /* Now we must call the relevant TRANS2 function */
1748 case TRANSACT2_OPEN:
1749 outsize = call_trans2open(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1751 case TRANSACT2_FINDFIRST:
1752 outsize = call_trans2findfirst(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1754 case TRANSACT2_FINDNEXT:
1755 outsize = call_trans2findnext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1757 case TRANSACT2_QFSINFO:
1758 outsize = call_trans2qfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1760 case TRANSACT2_SETFSINFO:
1761 outsize = call_trans2setfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1763 case TRANSACT2_QPATHINFO:
1764 case TRANSACT2_QFILEINFO:
1765 outsize = call_trans2qfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1767 case TRANSACT2_SETPATHINFO:
1768 case TRANSACT2_SETFILEINFO:
1769 outsize = call_trans2setfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1771 case TRANSACT2_FINDNOTIFYFIRST:
1772 outsize = call_trans2findnotifyfirst(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1774 case TRANSACT2_FINDNOTIFYNEXT:
1775 outsize = call_trans2findnotifynext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1777 case TRANSACT2_MKDIR:
1778 outsize = call_trans2mkdir(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1781 /* Error in request */
1782 DEBUG(2,("%s Unknown request %d in trans2 call\n",timestring(), tran_call));
1787 return (ERROR(ERRSRV,ERRerror));
1790 /* As we do not know how many data packets will need to be
1791 returned here the various call_trans2xxxx calls
1792 must send their own. Thus a call_trans2xxx routine only
1793 returns a value other than -1 when it wants to send
1801 return outsize; /* If a correct response was needed the call_trans2xxx
1802 calls have already sent it. If outsize != -1 then it is
1803 returning an error packet. */