2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1998
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 = 3;
59 int data_alignment_offset = 0;
61 /* Initially set the wcnt area to be 10 - this is true for all
63 set_message(outbuf,10,0,True);
65 /* If there genuinely are no parameters or data to send just send
67 if(params_to_send == 0 && data_to_send == 0)
69 send_smb(Client,outbuf);
73 /* When sending params and data ensure that both are nicely aligned */
74 /* Only do this alignment when there is also data to send - else
75 can cause NT redirector problems. */
76 if (((params_to_send % 4) != 0) && (data_to_send != 0))
77 data_alignment_offset = 4 - (params_to_send % 4);
79 /* Space is bufsize minus Netbios over TCP header minus SMB header */
80 /* The alignment_offset is to align the param bytes on an even byte
81 boundary. NT 4.0 Beta needs this to work correctly. */
82 useable_space = bufsize - ((smb_buf(outbuf)+
83 alignment_offset+data_alignment_offset) -
86 /* useable_space can never be more than max_send minus the
88 useable_space = MIN(useable_space,
89 max_send - (alignment_offset+data_alignment_offset));
92 while (params_to_send || data_to_send)
94 /* Calculate whether we will totally or partially fill this packet */
95 total_sent_thistime = params_to_send + data_to_send +
96 alignment_offset + data_alignment_offset;
97 /* We can never send more than useable_space */
98 total_sent_thistime = MIN(total_sent_thistime, useable_space);
100 set_message(outbuf, 10, total_sent_thistime, True);
102 /* Set total params and data to be sent */
103 SSVAL(outbuf,smb_tprcnt,paramsize);
104 SSVAL(outbuf,smb_tdrcnt,datasize);
106 /* Calculate how many parameters and data we can fit into
107 this packet. Parameters get precedence */
109 params_sent_thistime = MIN(params_to_send,useable_space);
110 data_sent_thistime = useable_space - params_sent_thistime;
111 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
113 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
114 if(params_sent_thistime == 0)
116 SSVAL(outbuf,smb_proff,0);
117 SSVAL(outbuf,smb_prdisp,0);
119 /* smb_proff is the offset from the start of the SMB header to the
120 parameter bytes, however the first 4 bytes of outbuf are
121 the Netbios over TCP header. Thus use smb_base() to subtract
122 them from the calculation */
123 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
124 /* Absolute displacement of param bytes sent in this packet */
125 SSVAL(outbuf,smb_prdisp,pp - params);
128 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
129 if(data_sent_thistime == 0)
131 SSVAL(outbuf,smb_droff,0);
132 SSVAL(outbuf,smb_drdisp, 0);
134 /* The offset of the data bytes is the offset of the
135 parameter bytes plus the number of parameters being sent this time */
136 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
138 params_sent_thistime + data_alignment_offset);
139 SSVAL(outbuf,smb_drdisp, pd - pdata);
142 /* Copy the param bytes into the packet */
143 if(params_sent_thistime)
144 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
145 /* Copy in the data bytes */
146 if(data_sent_thistime)
147 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+data_alignment_offset,pd,data_sent_thistime);
149 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
150 params_sent_thistime, data_sent_thistime, useable_space));
151 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
152 params_to_send, data_to_send, paramsize, datasize));
154 /* Send the packet */
155 send_smb(Client,outbuf);
157 pp += params_sent_thistime;
158 pd += data_sent_thistime;
160 params_to_send -= params_sent_thistime;
161 data_to_send -= data_sent_thistime;
164 if(params_to_send < 0 || data_to_send < 0)
166 DEBUG(2,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
167 params_to_send, data_to_send));
176 /****************************************************************************
177 reply to a TRANSACT2_OPEN
178 ****************************************************************************/
179 static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
180 char **pparams, char **ppdata)
182 char *params = *pparams;
183 int16 open_mode = SVAL(params, 2);
184 int16 open_attr = SVAL(params,6);
185 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
187 BOOL return_additional_info = BITSETW(params,0);
188 int16 open_sattr = SVAL(params, 4);
189 time_t open_time = make_unix_date3(params+8);
191 int16 open_ofun = SVAL(params,12);
192 int32 open_size = IVAL(params,14);
193 char *pname = ¶ms[28];
194 int16 namelen = strlen(pname)+1;
199 int size=0,fmode=0,mtime=0,rmode;
203 BOOL bad_path = False;
205 StrnCpy(fname,pname,namelen);
207 DEBUG(3,("trans2open %s cnum=%d mode=%d attr=%d ofun=%d size=%d\n",
208 fname,cnum,open_mode, open_attr, open_ofun, open_size));
210 /* XXXX we need to handle passed times, sattr and flags */
212 unix_convert(fname,cnum,0,&bad_path);
214 fnum = find_free_file();
216 return(ERROR(ERRSRV,ERRnofids));
218 if (!check_name(fname,cnum))
220 if((errno == ENOENT) && bad_path)
222 unix_ERR_class = ERRDOS;
223 unix_ERR_code = ERRbadpath;
225 Files[fnum].reserved = False;
226 return(UNIXERROR(ERRDOS,ERRnoaccess));
229 unixmode = unix_mode(cnum,open_attr | aARCH);
232 open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
233 oplock_request, &rmode,&smb_action);
235 if (!Files[fnum].open)
237 if((errno == ENOENT) && bad_path)
239 unix_ERR_class = ERRDOS;
240 unix_ERR_code = ERRbadpath;
242 Files[fnum].reserved = False;
243 return(UNIXERROR(ERRDOS,ERRnoaccess));
246 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
247 close_file(fnum,False);
248 return(ERROR(ERRDOS,ERRnoaccess));
252 fmode = dos_mode(cnum,fname,&sbuf);
253 mtime = sbuf.st_mtime;
256 close_file(fnum,False);
257 return(ERROR(ERRDOS,ERRnoaccess));
260 /* Realloc the size of parameters and data we will return */
261 params = *pparams = Realloc(*pparams, 28);
263 return(ERROR(ERRDOS,ERRnomem));
266 SSVAL(params,0,fnum);
267 SSVAL(params,2,fmode);
268 put_dos_date2(params,4, mtime);
269 SIVAL(params,8, size);
270 SSVAL(params,12,rmode);
272 if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
273 smb_action |= EXTENDED_OPLOCK_GRANTED;
276 SSVAL(params,18,smb_action);
277 SIVAL(params,20,inode);
279 /* Send the required number of replies */
280 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
285 /****************************************************************************
286 get a level dependent lanman2 dir entry.
287 ****************************************************************************/
288 static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_level,
289 int requires_resume_key,
290 BOOL dont_descend,char **ppdata,
291 char *base_data, int space_remaining,
302 char *p, *pdata = *ppdata;
303 int reskey=0, prev_dirpos=0;
306 uint32 mdate=0, adate=0, cdate=0;
308 BOOL isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
309 strequal(Connections[cnum].dirpath,".") ||
310 strequal(Connections[cnum].dirpath,"/"));
312 int nt_extmode; /* Used for NT connections instead of mode */
313 BOOL needslash = ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/');
316 *out_of_space = False;
318 if (!Connections[cnum].dirptr)
321 p = strrchr(path_mask,'/');
330 pstrcpy(mask, path_mask);
334 /* Needed if we run out of space */
335 prev_dirpos = TellDir(Connections[cnum].dirptr);
336 dname = ReadDirName(Connections[cnum].dirptr);
338 reskey = TellDir(Connections[cnum].dirptr);
340 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
341 Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
348 pstrcpy(fname,dname);
350 if(mask_match(fname, mask, case_sensitive, True))
352 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
353 if (dont_descend && !isdots)
356 if (isrootdir && isdots)
359 pstrcpy(pathreal,Connections[cnum].dirpath);
361 strcat(pathreal,"/");
362 strcat(pathreal,dname);
363 if (sys_stat(pathreal,&sbuf) != 0)
365 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
369 mode = dos_mode(cnum,pathreal,&sbuf);
371 if (!dir_check_ftype(cnum,mode,&sbuf,dirtype)) {
372 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
377 mdate = sbuf.st_mtime;
378 adate = get_access_time(&sbuf);
379 cdate = get_create_time(&sbuf);
383 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
389 name_map_mangle(fname,False,SNUM(cnum));
394 nt_extmode = mode ? mode : NT_FILE_ATTRIBUTE_NORMAL;
399 if(requires_resume_key) {
403 put_dos_date2(p,l1_fdateCreation,cdate);
404 put_dos_date2(p,l1_fdateLastAccess,adate);
405 put_dos_date2(p,l1_fdateLastWrite,mdate);
406 SIVAL(p,l1_cbFile,size);
407 SIVAL(p,l1_cbFileAlloc,ROUNDUP(size,1024));
408 SSVAL(p,l1_attrFile,mode);
409 SCVAL(p,l1_cchName,strlen(fname));
410 strcpy(p + l1_achName, fname);
411 nameptr = p + l1_achName;
412 p += l1_achName + strlen(fname) + 1;
417 if(requires_resume_key) {
421 put_dos_date2(p,l2_fdateCreation,cdate);
422 put_dos_date2(p,l2_fdateLastAccess,adate);
423 put_dos_date2(p,l2_fdateLastWrite,mdate);
424 SIVAL(p,l2_cbFile,size);
425 SIVAL(p,l2_cbFileAlloc,ROUNDUP(size,1024));
426 SSVAL(p,l2_attrFile,mode);
427 SIVAL(p,l2_cbList,0); /* No extended attributes */
428 SCVAL(p,l2_cchName,strlen(fname));
429 strcpy(p + l2_achName, fname);
430 nameptr = p + l2_achName;
431 p += l2_achName + strlen(fname) + 1;
436 put_dos_date2(p,4,cdate);
437 put_dos_date2(p,8,adate);
438 put_dos_date2(p,12,mdate);
440 SIVAL(p,20,ROUNDUP(size,1024));
443 CVAL(p,30) = strlen(fname);
446 p += 31 + strlen(fname) + 1;
450 if(requires_resume_key) {
454 SIVAL(p,0,33+strlen(fname)+1);
455 put_dos_date2(p,4,cdate);
456 put_dos_date2(p,8,adate);
457 put_dos_date2(p,12,mdate);
459 SIVAL(p,20,ROUNDUP(size,1024));
461 CVAL(p,32) = strlen(fname);
462 strcpy(p + 33, fname);
464 p += 33 + strlen(fname) + 1;
467 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
468 was_8_3 = is_8_3(fname, True);
469 len = 94+strlen(fname);
470 len = (len + 3) & ~3;
471 SIVAL(p,0,len); p += 4;
472 SIVAL(p,0,reskey); p += 4;
473 put_long_date(p,cdate); p += 8;
474 put_long_date(p,adate); p += 8;
475 put_long_date(p,mdate); p += 8;
476 put_long_date(p,mdate); p += 8;
477 SIVAL(p,0,size); p += 8;
478 SIVAL(p,0,size); p += 8;
479 SIVAL(p,0,nt_extmode); p += 4;
480 SIVAL(p,0,strlen(fname)); p += 4;
481 SIVAL(p,0,0); p += 4;
484 if (!name_map_mangle(p+2,True,SNUM(cnum)))
489 SSVAL(p,0,strlen(p+2));
492 strcpy(p,fname); p += strlen(p);
496 case SMB_FIND_FILE_DIRECTORY_INFO:
497 len = 64+strlen(fname);
498 len = (len + 3) & ~3;
499 SIVAL(p,0,len); p += 4;
500 SIVAL(p,0,reskey); p += 4;
501 put_long_date(p,cdate); p += 8;
502 put_long_date(p,adate); p += 8;
503 put_long_date(p,mdate); p += 8;
504 put_long_date(p,mdate); p += 8;
505 SIVAL(p,0,size); p += 8;
506 SIVAL(p,0,size); p += 8;
507 SIVAL(p,0,nt_extmode); p += 4;
508 SIVAL(p,0,strlen(fname)); p += 4;
514 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
515 len = 68+strlen(fname);
516 len = (len + 3) & ~3;
517 SIVAL(p,0,len); p += 4;
518 SIVAL(p,0,reskey); p += 4;
519 put_long_date(p,cdate); p += 8;
520 put_long_date(p,adate); p += 8;
521 put_long_date(p,mdate); p += 8;
522 put_long_date(p,mdate); p += 8;
523 SIVAL(p,0,size); p += 8;
524 SIVAL(p,0,size); p += 8;
525 SIVAL(p,0,nt_extmode); p += 4;
526 SIVAL(p,0,strlen(fname)); p += 4;
527 SIVAL(p,0,0); p += 4;
532 case SMB_FIND_FILE_NAMES_INFO:
533 len = 12+strlen(fname);
534 len = (len + 3) & ~3;
535 SIVAL(p,0,len); p += 4;
536 SIVAL(p,0,reskey); p += 4;
537 SIVAL(p,0,strlen(fname)); p += 4;
547 if (PTR_DIFF(p,pdata) > space_remaining) {
548 /* Move the dirptr back to prev_dirpos */
549 SeekDir(Connections[cnum].dirptr, prev_dirpos);
550 *out_of_space = True;
551 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
552 return False; /* Not finished - just out of space */
555 /* Setup the last_filename pointer, as an offset from base_data */
556 *last_name_off = PTR_DIFF(nameptr,base_data);
557 /* Advance the data pointer to the next slot */
562 /****************************************************************************
563 reply to a TRANS2_FINDFIRST
564 ****************************************************************************/
565 static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum,
566 char **pparams, char **ppdata)
568 /* We must be careful here that we don't return more than the
569 allowed number of data bytes. If this means returning fewer than
570 maxentries then so be it. We assume that the redirector has
571 enough room for the fixed number of parameter bytes it has
573 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
574 char *params = *pparams;
575 char *pdata = *ppdata;
576 int dirtype = SVAL(params,0);
577 int maxentries = SVAL(params,2);
578 BOOL close_after_first = BITSETW(params+4,0);
579 BOOL close_if_end = BITSETW(params+4,1);
580 BOOL requires_resume_key = BITSETW(params+4,2);
581 int info_level = SVAL(params,6);
589 BOOL finished = False;
590 BOOL dont_descend = False;
591 BOOL out_of_space = False;
593 BOOL bad_path = False;
595 *directory = *mask = 0;
597 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",
598 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
599 info_level, max_data_bytes));
607 case SMB_FIND_FILE_DIRECTORY_INFO:
608 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
609 case SMB_FIND_FILE_NAMES_INFO:
610 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
613 return(ERROR(ERRDOS,ERRunknownlevel));
616 pstrcpy(directory, params + 12); /* Complete directory path with
617 wildcard mask appended */
619 DEBUG(5,("path=%s\n",directory));
621 unix_convert(directory,cnum,0,&bad_path);
622 if(!check_name(directory,cnum)) {
623 if((errno == ENOENT) && bad_path)
625 unix_ERR_class = ERRDOS;
626 unix_ERR_code = ERRbadpath;
630 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
631 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
632 (get_remote_arch() == RA_WINNT))
634 unix_ERR_class = ERRDOS;
635 unix_ERR_code = ERRbaddirectory;
639 return(ERROR(ERRDOS,ERRbadpath));
642 p = strrchr(directory,'/');
644 strcpy(mask,directory);
645 strcpy(directory,"./");
651 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
653 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
655 return(ERROR(ERRDOS,ERRnomem));
656 bzero(pdata,max_data_bytes);
658 /* Realloc the params space */
659 params = *pparams = Realloc(*pparams, 10);
661 return(ERROR(ERRDOS,ERRnomem));
663 dptr_num = dptr_create(cnum,directory, True ,SVAL(inbuf,smb_pid));
665 return(ERROR(ERRDOS,ERRbadfile));
667 /* convert the formatted masks */
671 if (*p == '<') *p = '*';
672 if (*p == '>') *p = '?';
673 if (*p == '"') *p = '.';
678 /* a special case for 16 bit apps */
679 if (strequal(mask,"????????.???")) strcpy(mask,"*");
681 /* handle broken clients that send us old 8.3 format */
682 string_sub(mask,"????????","*");
683 string_sub(mask,".???",".*");
685 /* Save the wildcard match and attribs we are using on this directory -
686 needed as lanman2 assumes these are being saved between calls */
688 if(!(wcard = strdup(mask))) {
689 dptr_close(dptr_num);
690 return(ERROR(ERRDOS,ERRnomem));
693 dptr_set_wcard(dptr_num, wcard);
694 dptr_set_attr(dptr_num, dirtype);
696 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
698 /* We don't need to check for VOL here as this is returned by
699 a different TRANS2 call. */
701 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
702 Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
703 if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
707 space_remaining = max_data_bytes;
708 out_of_space = False;
710 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
713 /* this is a heuristic to avoid seeking the dirptr except when
714 absolutely necessary. It allows for a filename of about 40 chars */
715 if (space_remaining < DIRLEN_GUESS && numentries > 0)
723 !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
724 requires_resume_key,dont_descend,
725 &p,pdata,space_remaining, &out_of_space,
729 if (finished && out_of_space)
732 if (!finished && !out_of_space)
734 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
737 /* Check if we can close the dirptr */
738 if(close_after_first || (finished && close_if_end))
740 dptr_close(dptr_num);
741 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
746 * If there are no matching entries we must return ERRDOS/ERRbadfile -
747 * from observation of NT.
751 return(ERROR(ERRDOS,ERRbadfile));
753 /* At this point pdata points to numentries directory entries. */
755 /* Set up the return parameter block */
756 SSVAL(params,0,dptr_num);
757 SSVAL(params,2,numentries);
758 SSVAL(params,4,finished);
759 SSVAL(params,6,0); /* Never an EA error */
760 SSVAL(params,8,last_name_off);
762 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
764 if ((! *directory) && dptr_path(dptr_num))
765 sprintf(directory,"(%s)",dptr_path(dptr_num));
767 DEBUG(4,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
769 smb_fn_name(CVAL(inbuf,smb_com)),
770 mask,directory,cnum,dirtype,numentries));
776 /****************************************************************************
777 reply to a TRANS2_FINDNEXT
778 ****************************************************************************/
779 static int call_trans2findnext(char *inbuf, char *outbuf, int length, int bufsize,
780 int cnum, char **pparams, char **ppdata)
782 /* We must be careful here that we don't return more than the
783 allowed number of data bytes. If this means returning fewer than
784 maxentries then so be it. We assume that the redirector has
785 enough room for the fixed number of parameter bytes it has
787 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
788 char *params = *pparams;
789 char *pdata = *ppdata;
790 int16 dptr_num = SVAL(params,0);
791 int maxentries = SVAL(params,2);
792 uint16 info_level = SVAL(params,4);
793 uint32 resume_key = IVAL(params,6);
794 BOOL close_after_request = BITSETW(params+10,0);
795 BOOL close_if_end = BITSETW(params+10,1);
796 BOOL requires_resume_key = BITSETW(params+10,2);
797 BOOL continue_bit = BITSETW(params+10,3);
803 int i, last_name_off=0;
804 BOOL finished = False;
805 BOOL dont_descend = False;
806 BOOL out_of_space = False;
809 *mask = *directory = 0;
811 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",
812 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
813 requires_resume_key, resume_key, continue_bit, info_level));
821 case SMB_FIND_FILE_DIRECTORY_INFO:
822 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
823 case SMB_FIND_FILE_NAMES_INFO:
824 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
827 return(ERROR(ERRDOS,ERRunknownlevel));
830 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
832 return(ERROR(ERRDOS,ERRnomem));
833 bzero(pdata,max_data_bytes);
835 /* Realloc the params space */
836 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
838 return(ERROR(ERRDOS,ERRnomem));
840 /* Check that the dptr is valid */
841 if(!(Connections[cnum].dirptr = dptr_fetch_lanman2(params, dptr_num)))
842 return(ERROR(ERRDOS,ERRnofiles));
844 string_set(&Connections[cnum].dirpath,dptr_path(dptr_num));
846 /* Get the wildcard mask from the dptr */
847 if((p = dptr_wcard(dptr_num))== NULL) {
848 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
849 return (ERROR(ERRDOS,ERRnofiles));
852 strcpy(directory,Connections[cnum].dirpath);
854 /* Get the attr mask from the dptr */
855 dirtype = dptr_attr(dptr_num);
857 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
858 dptr_num, mask, dirtype,
859 Connections[cnum].dirptr,
860 TellDir(Connections[cnum].dirptr)));
862 /* We don't need to check for VOL here as this is returned by
863 a different TRANS2 call. */
865 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
866 if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
870 space_remaining = max_data_bytes;
871 out_of_space = False;
873 /* If we have a resume key - seek to the correct position. */
874 if(requires_resume_key && !continue_bit)
875 SeekDir(Connections[cnum].dirptr, resume_key);
877 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
879 /* this is a heuristic to avoid seeking the dirptr except when
880 absolutely necessary. It allows for a filename of about 40 chars */
881 if (space_remaining < DIRLEN_GUESS && numentries > 0)
889 !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
890 requires_resume_key,dont_descend,
891 &p,pdata,space_remaining, &out_of_space,
895 if (finished && out_of_space)
898 if (!finished && !out_of_space)
900 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
903 /* Check if we can close the dirptr */
904 if(close_after_request || (finished && close_if_end))
906 dptr_close(dptr_num); /* This frees up the saved mask */
907 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
912 /* Set up the return parameter block */
913 SSVAL(params,0,numentries);
914 SSVAL(params,2,finished);
915 SSVAL(params,4,0); /* Never an EA error */
916 SSVAL(params,6,last_name_off);
918 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
920 if ((! *directory) && dptr_path(dptr_num))
921 sprintf(directory,"(%s)",dptr_path(dptr_num));
923 DEBUG(3,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
925 smb_fn_name(CVAL(inbuf,smb_com)),
926 mask,directory,cnum,dirtype,numentries));
931 /****************************************************************************
932 reply to a TRANS2_QFSINFO (query filesystem info)
933 ****************************************************************************/
934 static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
935 int cnum, char **pparams, char **ppdata)
937 char *pdata = *ppdata;
938 char *params = *pparams;
939 uint16 info_level = SVAL(params,0);
942 char *vname = volume_label(SNUM(cnum));
944 DEBUG(3,("call_trans2qfsinfo: cnum = %d, level = %d\n", cnum, info_level));
946 if(sys_stat(".",&st)!=0) {
947 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
948 return (ERROR(ERRSRV,ERRinvdevice));
951 pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
957 int dfree,dsize,bsize;
959 sys_disk_free(".",&bsize,&dfree,&dsize);
960 SIVAL(pdata,l1_idFileSystem,st.st_dev);
961 SIVAL(pdata,l1_cSectorUnit,bsize/512);
962 SIVAL(pdata,l1_cUnit,dsize);
963 SIVAL(pdata,l1_cUnitAvail,dfree);
964 SSVAL(pdata,l1_cbSector,512);
965 DEBUG(5,("call_trans2qfsinfo : bsize=%d, id=%x, cSectorUnit=%d, cUnit=%d, cUnitAvail=%d, cbSector=%d\n",
966 bsize, st.st_dev, bsize/512, dsize, dfree, 512));
971 /* Return volume name */
972 int volname_len = MIN(strlen(vname),11);
973 data_len = l2_vol_szVolLabel + volname_len + 1;
974 put_dos_date2(pdata,l2_vol_fdateCreation,st.st_ctime);
975 SCVAL(pdata,l2_vol_cch,volname_len);
976 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
977 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len,
978 pdata+l2_vol_szVolLabel));
981 case SMB_QUERY_FS_ATTRIBUTE_INFO:
982 data_len = 12 + 2*strlen(FSTYPE_STRING);
983 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
984 SIVAL(pdata,4,128); /* Max filename component length */
985 SIVAL(pdata,8,2*strlen(FSTYPE_STRING));
986 PutUniCode(pdata+12,FSTYPE_STRING);
988 case SMB_QUERY_FS_LABEL_INFO:
989 data_len = 4 + strlen(vname);
990 SIVAL(pdata,0,strlen(vname));
991 strcpy(pdata+4,vname);
993 case SMB_QUERY_FS_VOLUME_INFO:
994 data_len = 18 + 2*strlen(vname);
995 SIVAL(pdata,12,2*strlen(vname));
996 PutUniCode(pdata+18,vname);
997 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),
1000 case SMB_QUERY_FS_SIZE_INFO:
1002 int dfree,dsize,bsize;
1004 sys_disk_free(".",&bsize,&dfree,&dsize);
1005 SIVAL(pdata,0,dsize);
1006 SIVAL(pdata,8,dfree);
1007 SIVAL(pdata,16,bsize/512);
1008 SIVAL(pdata,20,512);
1011 case SMB_QUERY_FS_DEVICE_INFO:
1013 SIVAL(pdata,0,0); /* dev type */
1014 SIVAL(pdata,4,0); /* characteristics */
1017 return(ERROR(ERRDOS,ERRunknownlevel));
1021 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1023 DEBUG(4,("%s %s info_level =%d\n",timestring(),smb_fn_name(CVAL(inbuf,smb_com)), info_level));
1028 /****************************************************************************
1029 reply to a TRANS2_SETFSINFO (set filesystem info)
1030 ****************************************************************************/
1031 static int call_trans2setfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
1032 int cnum, char **pparams, char **ppdata)
1034 /* Just say yes we did it - there is nothing that
1035 can be set here so it doesn't matter. */
1037 DEBUG(3,("call_trans2setfsinfo\n"));
1039 if (!CAN_WRITE(cnum))
1040 return(ERROR(ERRSRV,ERRaccess));
1042 outsize = set_message(outbuf,10,0,True);
1047 /****************************************************************************
1048 reply to a TRANS2_QFILEINFO (query file info by fileid)
1049 ****************************************************************************/
1050 static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length,
1051 int bufsize,int cnum,
1052 char **pparams,char **ppdata,
1055 char *params = *pparams;
1056 char *pdata = *ppdata;
1057 uint16 tran_call = SVAL(inbuf, smb_setup0);
1061 unsigned int data_size;
1067 BOOL bad_path = False;
1069 if (tran_call == TRANSACT2_QFILEINFO) {
1070 int16 fnum = SVALS(params,0);
1071 info_level = SVAL(params,2);
1073 CHECK_FNUM(fnum,cnum);
1076 fname = Files[fnum].name;
1077 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
1078 DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
1079 return(UNIXERROR(ERRDOS,ERRbadfid));
1081 pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR);
1084 info_level = SVAL(params,0);
1086 pstrcpy(fname,¶ms[6]);
1087 unix_convert(fname,cnum,0,&bad_path);
1088 if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) {
1089 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1090 if((errno == ENOENT) && bad_path)
1092 unix_ERR_class = ERRDOS;
1093 unix_ERR_code = ERRbadpath;
1095 return(UNIXERROR(ERRDOS,ERRbadpath));
1101 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1102 fname,info_level,tran_call,total_data));
1104 p = strrchr(fname,'/');
1110 mode = dos_mode(cnum,fname,&sbuf);
1111 size = sbuf.st_size;
1112 if (mode & aDIR) size = 0;
1114 params = *pparams = Realloc(*pparams,2); bzero(params,2);
1116 pdata = *ppdata = Realloc(*ppdata, data_size);
1118 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1119 /* uggh, EAs for OS2 */
1120 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1121 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1124 bzero(pdata,data_size);
1128 case SMB_INFO_STANDARD:
1129 case SMB_INFO_QUERY_EA_SIZE:
1130 data_size = (info_level==1?22:26);
1131 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf));
1132 put_dos_date2(pdata,l1_fdateLastAccess,get_access_time(&sbuf));
1133 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1134 SIVAL(pdata,l1_cbFile,size);
1135 SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
1136 SSVAL(pdata,l1_attrFile,mode);
1137 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1140 case SMB_INFO_QUERY_EAS_FROM_LIST:
1142 put_dos_date2(pdata,0,get_create_time(&sbuf));
1143 put_dos_date2(pdata,4,get_access_time(&sbuf));
1144 put_dos_date2(pdata,8,sbuf.st_mtime);
1145 SIVAL(pdata,12,size);
1146 SIVAL(pdata,16,ROUNDUP(size,1024));
1147 SIVAL(pdata,20,mode);
1150 case SMB_INFO_QUERY_ALL_EAS:
1152 SIVAL(pdata,0,data_size);
1156 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1158 case SMB_QUERY_FILE_BASIC_INFO:
1159 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1160 put_long_date(pdata,get_create_time(&sbuf));
1161 put_long_date(pdata+8,get_access_time(&sbuf));
1162 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1163 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1164 SIVAL(pdata,32,mode);
1166 DEBUG(5,("SMB_QFBI - "));
1168 time_t create_time = get_create_time(&sbuf);
1169 DEBUG(5,("create: %s ", ctime(&create_time)));
1170 create_time = get_access_time(&sbuf);
1171 DEBUG(5,("access: %s ", ctime(&create_time)));
1173 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1174 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1175 DEBUG(5,("mode: %x\n", mode));
1179 case SMB_QUERY_FILE_STANDARD_INFO:
1181 SIVAL(pdata,0,size);
1182 SIVAL(pdata,8,size);
1183 SIVAL(pdata,16,sbuf.st_nlink);
1185 CVAL(pdata,21) = (mode&aDIR)?1:0;
1188 case SMB_QUERY_FILE_EA_INFO:
1192 /* Get the 8.3 name - used if NT SMB was negotiated. */
1193 case SMB_QUERY_FILE_ALT_NAME_INFO:
1196 pstrcpy(short_name,fname);
1197 /* Mangle if not already 8.3 */
1198 if(!is_8_3(short_name, True))
1200 if(!name_map_mangle(short_name,True,SNUM(cnum)))
1203 strncpy(pdata + 4,short_name,12);
1204 (pdata + 4)[12] = 0;
1205 strupper(pdata + 4);
1206 l = strlen(pdata + 4);
1212 case SMB_QUERY_FILE_NAME_INFO:
1215 pstrcpy(pdata+4,fname);
1218 case SMB_QUERY_FILE_ALLOCATION_INFO:
1219 case SMB_QUERY_FILE_END_OF_FILEINFO:
1221 SIVAL(pdata,0,size);
1224 case SMB_QUERY_FILE_ALL_INFO:
1225 put_long_date(pdata,get_create_time(&sbuf));
1226 put_long_date(pdata+8,get_access_time(&sbuf));
1227 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1228 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1229 SIVAL(pdata,32,mode);
1231 SIVAL(pdata,0,size);
1232 SIVAL(pdata,8,size);
1233 SIVAL(pdata,16,sbuf.st_nlink);
1235 CVAL(pdata,21) = (mode&aDIR)?1:0;
1237 pdata += 8; /* index number */
1238 pdata += 4; /* EA info */
1240 SIVAL(pdata,0,0xA9);
1242 SIVAL(pdata,0,0xd01BF);
1244 SIVAL(pdata,0,pos); /* current offset */
1246 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1248 pdata += 4; /* alignment */
1250 pstrcpy(pdata+4,fname);
1252 data_size = PTR_DIFF(pdata,(*ppdata));
1255 case SMB_QUERY_FILE_STREAM_INFO:
1258 SIVAL(pdata,4,size);
1259 SIVAL(pdata,12,size);
1261 pstrcpy(pdata+24,fname);
1264 return(ERROR(ERRDOS,ERRunknownlevel));
1267 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1272 /****************************************************************************
1273 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1274 ****************************************************************************/
1275 static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
1276 int bufsize, int cnum, char **pparams,
1277 char **ppdata, int total_data)
1279 char *params = *pparams;
1280 char *pdata = *ppdata;
1281 uint16 tran_call = SVAL(inbuf, smb_setup0);
1290 BOOL bad_path = False;
1292 if (!CAN_WRITE(cnum))
1293 return(ERROR(ERRSRV,ERRaccess));
1295 if (tran_call == TRANSACT2_SETFILEINFO) {
1296 int16 fnum = SVALS(params,0);
1297 info_level = SVAL(params,2);
1299 CHECK_FNUM(fnum,cnum);
1302 fname = Files[fnum].name;
1303 fd = Files[fnum].fd_ptr->fd;
1305 if(fstat(fd,&st)!=0) {
1306 DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
1307 return(ERROR(ERRDOS,ERRbadpath));
1311 info_level = SVAL(params,0);
1313 pstrcpy(fname,¶ms[6]);
1314 unix_convert(fname,cnum,0,&bad_path);
1315 if(!check_name(fname, cnum))
1317 if((errno == ENOENT) && bad_path)
1319 unix_ERR_class = ERRDOS;
1320 unix_ERR_code = ERRbadpath;
1322 return(UNIXERROR(ERRDOS,ERRbadpath));
1325 if(sys_stat(fname,&st)!=0) {
1326 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1327 if((errno == ENOENT) && bad_path)
1329 unix_ERR_class = ERRDOS;
1330 unix_ERR_code = ERRbadpath;
1332 return(UNIXERROR(ERRDOS,ERRbadpath));
1336 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1337 tran_call,fname,info_level,total_data));
1339 /* Realloc the parameter and data sizes */
1340 params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
1342 return(ERROR(ERRDOS,ERRnomem));
1345 tvs.modtime = st.st_mtime;
1346 tvs.actime = st.st_atime;
1347 mode = dos_mode(cnum,fname,&st);
1349 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1350 /* uggh, EAs for OS2 */
1351 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1352 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1357 case SMB_INFO_STANDARD:
1358 case SMB_INFO_QUERY_EA_SIZE:
1361 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1364 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1366 mode = SVAL(pdata,l1_attrFile);
1367 size = IVAL(pdata,l1_cbFile);
1371 /* XXXX um, i don't think this is right.
1372 it's also not in the cifs6.txt spec.
1374 case SMB_INFO_QUERY_EAS_FROM_LIST:
1375 tvs.actime = make_unix_date2(pdata+8);
1376 tvs.modtime = make_unix_date2(pdata+12);
1377 size = IVAL(pdata,16);
1378 mode = IVAL(pdata,24);
1381 /* XXXX nor this. not in cifs6.txt, either. */
1382 case SMB_INFO_QUERY_ALL_EAS:
1383 tvs.actime = make_unix_date2(pdata+8);
1384 tvs.modtime = make_unix_date2(pdata+12);
1385 size = IVAL(pdata,16);
1386 mode = IVAL(pdata,24);
1389 case SMB_SET_FILE_BASIC_INFO:
1391 /* Ignore create time at offset pdata. */
1394 tvs.actime = interpret_long_date(pdata+8);
1396 /* write time + changed time, combined. */
1397 tvs.modtime=MAX(interpret_long_date(pdata+16),
1398 interpret_long_date(pdata+24));
1400 #if 0 /* Needs more testing... */
1401 /* Test from Luke to prevent Win95 from
1402 setting incorrect values here.
1404 if (tvs.actime < tvs.modtime)
1405 return(ERROR(ERRDOS,ERRnoaccess));
1406 #endif /* Needs more testing... */
1409 mode = IVAL(pdata,32);
1413 case SMB_SET_FILE_END_OF_FILE_INFO:
1415 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1416 return(ERROR(ERRDOS,ERRunknownlevel));
1417 size = IVAL(pdata,0);
1421 case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
1422 case SMB_SET_FILE_ALLOCATION_INFO: /* not supported yet */
1425 return(ERROR(ERRDOS,ERRunknownlevel));
1429 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1430 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1431 DEBUG(6,("size: %x " , size));
1432 DEBUG(6,("mode: %x\n" , mode));
1434 /* get some defaults (no modifications) if any info is zero. */
1435 if (!tvs.actime) tvs.actime = st.st_atime;
1436 if (!tvs.modtime) tvs.modtime = st.st_mtime;
1437 if (!size) size = st.st_size;
1439 /* Try and set the times, size and mode of this file -
1440 if they are different from the current values
1442 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
1444 if(file_utime(cnum, fname, &tvs)!=0)
1446 return(ERROR(ERRDOS,ERRnoaccess));
1450 /* check the mode isn't different, before changing it */
1451 if (mode != dos_mode(cnum, fname, &st) && dos_chmod(cnum, fname, mode, NULL))
1453 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1454 return(ERROR(ERRDOS,ERRnoaccess));
1457 if(size != st.st_size)
1461 fd = sys_open(fname,O_RDWR,0);
1464 return(ERROR(ERRDOS,ERRbadpath));
1466 set_filelen(fd, size);
1471 set_filelen(fd, size);
1477 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1482 /****************************************************************************
1483 reply to a TRANS2_MKDIR (make directory with extended attributes).
1484 ****************************************************************************/
1485 static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize,
1486 int cnum, char **pparams, char **ppdata)
1488 char *params = *pparams;
1491 BOOL bad_path = False;
1493 if (!CAN_WRITE(cnum))
1494 return(ERROR(ERRSRV,ERRaccess));
1496 pstrcpy(directory, ¶ms[4]);
1498 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
1500 unix_convert(directory,cnum,0,&bad_path);
1501 if (check_name(directory,cnum))
1502 ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
1506 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
1507 if((errno == ENOENT) && bad_path)
1509 unix_ERR_class = ERRDOS;
1510 unix_ERR_code = ERRbadpath;
1512 return(UNIXERROR(ERRDOS,ERRnoaccess));
1515 /* Realloc the parameter and data sizes */
1516 params = *pparams = Realloc(*pparams,2);
1518 return(ERROR(ERRDOS,ERRnomem));
1522 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1527 /****************************************************************************
1528 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1529 We don't actually do this - we just send a null response.
1530 ****************************************************************************/
1531 static int call_trans2findnotifyfirst(char *inbuf, char *outbuf, int length, int bufsize,
1532 int cnum, char **pparams, char **ppdata)
1534 static uint16 fnf_handle = 257;
1535 char *params = *pparams;
1536 uint16 info_level = SVAL(params,4);
1538 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
1546 return(ERROR(ERRDOS,ERRunknownlevel));
1549 /* Realloc the parameter and data sizes */
1550 params = *pparams = Realloc(*pparams,6);
1552 return(ERROR(ERRDOS,ERRnomem));
1554 SSVAL(params,0,fnf_handle);
1555 SSVAL(params,2,0); /* No changes */
1556 SSVAL(params,4,0); /* No EA errors */
1563 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
1568 /****************************************************************************
1569 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
1570 changes). Currently this does nothing.
1571 ****************************************************************************/
1572 static int call_trans2findnotifynext(char *inbuf, char *outbuf, int length, int bufsize,
1573 int cnum, char **pparams, char **ppdata)
1575 char *params = *pparams;
1577 DEBUG(3,("call_trans2findnotifynext\n"));
1579 /* Realloc the parameter and data sizes */
1580 params = *pparams = Realloc(*pparams,4);
1582 return(ERROR(ERRDOS,ERRnomem));
1584 SSVAL(params,0,0); /* No changes */
1585 SSVAL(params,2,0); /* No EA errors */
1587 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
1592 /****************************************************************************
1593 reply to a SMBfindclose (stop trans2 directory search)
1594 ****************************************************************************/
1595 int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize)
1599 int16 dptr_num=SVALS(inbuf,smb_vwv0);
1601 cnum = SVAL(inbuf,smb_tid);
1603 DEBUG(3,("reply_findclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1605 dptr_close(dptr_num);
1607 outsize = set_message(outbuf,0,0,True);
1609 DEBUG(3,("%s SMBfindclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1614 /****************************************************************************
1615 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1616 ****************************************************************************/
1617 int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize)
1623 cnum = SVAL(inbuf,smb_tid);
1624 dptr_num = SVAL(inbuf,smb_vwv0);
1626 DEBUG(3,("reply_findnclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1628 /* We never give out valid handles for a
1629 findnotifyfirst - so any dptr_num is ok here.
1632 outsize = set_message(outbuf,0,0,True);
1634 DEBUG(3,("%s SMB_findnclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1640 /****************************************************************************
1641 reply to a SMBtranss2 - just ignore it!
1642 ****************************************************************************/
1643 int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize)
1645 DEBUG(4,("Ignoring transs2 of length %d\n",length));
1649 /****************************************************************************
1650 reply to a SMBtrans2
1651 ****************************************************************************/
1652 int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
1655 int cnum = SVAL(inbuf,smb_tid);
1656 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
1657 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
1659 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
1660 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
1661 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
1662 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
1663 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
1664 int32 timeout = IVALS(inbuf,smb_timeout);
1666 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
1667 unsigned int tran_call = SVAL(inbuf, smb_setup0);
1668 char *params = NULL, *data = NULL;
1669 int num_params, num_params_sofar, num_data, num_data_sofar;
1671 outsize = set_message(outbuf,0,0,True);
1673 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1674 is so as a sanity check */
1677 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1678 return(ERROR(ERRSRV,ERRerror));
1681 /* Allocate the space for the maximum needed parameters and data */
1682 if (total_params > 0)
1683 params = (char *)malloc(total_params);
1685 data = (char *)malloc(total_data);
1687 if ((total_params && !params) || (total_data && !data))
1689 DEBUG(2,("Out of memory in reply_trans2\n"));
1690 return(ERROR(ERRDOS,ERRnomem));
1693 /* Copy the param and data bytes sent with this request into
1694 the params buffer */
1695 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
1696 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
1698 if (num_params > total_params || num_data > total_data)
1699 exit_server("invalid params in reply_trans2");
1701 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
1702 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
1704 if(num_data_sofar < total_data || num_params_sofar < total_params)
1706 /* We need to send an interim response then receive the rest
1707 of the parameter/data bytes */
1708 outsize = set_message(outbuf,0,0,True);
1709 send_smb(Client,outbuf);
1711 while( num_data_sofar < total_data || num_params_sofar < total_params)
1715 ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
1716 SMB_SECONDARY_WAIT);
1718 if((ret && (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret)
1720 outsize = set_message(outbuf,0,0,True);
1722 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
1724 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
1725 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
1728 return(ERROR(ERRSRV,ERRerror));
1731 /* Revise total_params and total_data in case they have changed downwards */
1732 total_params = SVAL(inbuf, smb_tpscnt);
1733 total_data = SVAL(inbuf, smb_tdscnt);
1734 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
1735 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
1736 if (num_params_sofar > total_params || num_data_sofar > total_data)
1737 exit_server("data overflow in trans2");
1739 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
1740 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
1741 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
1742 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
1746 if (Protocol >= PROTOCOL_NT1) {
1747 uint16 flg2 = SVAL(outbuf,smb_flg2);
1748 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1751 /* Now we must call the relevant TRANS2 function */
1754 case TRANSACT2_OPEN:
1755 outsize = call_trans2open(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1757 case TRANSACT2_FINDFIRST:
1758 outsize = call_trans2findfirst(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1760 case TRANSACT2_FINDNEXT:
1761 outsize = call_trans2findnext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1763 case TRANSACT2_QFSINFO:
1764 outsize = call_trans2qfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1766 case TRANSACT2_SETFSINFO:
1767 outsize = call_trans2setfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1769 case TRANSACT2_QPATHINFO:
1770 case TRANSACT2_QFILEINFO:
1771 outsize = call_trans2qfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1773 case TRANSACT2_SETPATHINFO:
1774 case TRANSACT2_SETFILEINFO:
1775 outsize = call_trans2setfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1777 case TRANSACT2_FINDNOTIFYFIRST:
1778 outsize = call_trans2findnotifyfirst(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1780 case TRANSACT2_FINDNOTIFYNEXT:
1781 outsize = call_trans2findnotifynext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1783 case TRANSACT2_MKDIR:
1784 outsize = call_trans2mkdir(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1787 /* Error in request */
1788 DEBUG(2,("%s Unknown request %d in trans2 call\n",timestring(), tran_call));
1793 return (ERROR(ERRSRV,ERRerror));
1796 /* As we do not know how many data packets will need to be
1797 returned here the various call_trans2xxxx calls
1798 must send their own. Thus a call_trans2xxx routine only
1799 returns a value other than -1 when it wants to send
1807 return outsize; /* If a correct response was needed the call_trans2xxx
1808 calls have already sent it. If outsize != -1 then it is
1809 returning an error packet. */