49687d4cca0bfdf4d6810f6c9008a34e927c78f5
[tprouty/samba.git] / source / smbd / trans2.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    SMB transaction2 handling
5    Copyright (C) Jeremy Allison 1994-1998
6
7    Extensively modified by Andrew Tridgell, 1995
8
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.
13    
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.
18    
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.
22 */
23
24 #include "includes.h"
25 #include "trans2.h"
26
27 extern int DEBUGLEVEL;
28 extern int Protocol;
29 extern BOOL case_sensitive;
30 extern int Client;
31 extern int oplock_sock;
32 extern int smb_read_error;
33 extern fstring local_machine;
34 extern int global_oplock_break;
35
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)
44 {
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 */
50
51   extern int max_send;
52   int data_to_send = datasize;
53   int params_to_send = paramsize;
54   int useable_space;
55   char *pp = params;
56   char *pd = pdata;
57   int params_sent_thistime, data_sent_thistime, total_sent_thistime;
58   int alignment_offset = 3;
59   int data_alignment_offset = 0;
60
61   /* Initially set the wcnt area to be 10 - this is true for all
62      trans2 replies */
63   set_message(outbuf,10,0,True);
64
65   /* If there genuinely are no parameters or data to send just send
66      the empty packet */
67   if(params_to_send == 0 && data_to_send == 0)
68   {
69     send_smb(Client,outbuf);
70     return 0;
71   }
72
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);
78
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) - 
84                     outbuf);
85
86   /* useable_space can never be more than max_send minus the
87      alignment offset. */
88   useable_space = MIN(useable_space, 
89                       max_send - (alignment_offset+data_alignment_offset));
90
91
92   while (params_to_send || data_to_send)
93   {
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);
99
100     set_message(outbuf, 10, total_sent_thistime, True);
101
102     /* Set total params and data to be sent */
103     SSVAL(outbuf,smb_tprcnt,paramsize);
104     SSVAL(outbuf,smb_tdrcnt,datasize);
105
106     /* Calculate how many parameters and data we can fit into
107        this packet. Parameters get precedence */
108
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);
112
113     SSVAL(outbuf,smb_prcnt, params_sent_thistime);
114     if(params_sent_thistime == 0)
115     {
116       SSVAL(outbuf,smb_proff,0);
117       SSVAL(outbuf,smb_prdisp,0);
118     }
119     else
120     {
121       /* smb_proff is the offset from the start of the SMB header to the
122          parameter bytes, however the first 4 bytes of outbuf are
123          the Netbios over TCP header. Thus use smb_base() to subtract
124          them from the calculation */
125       SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
126       /* Absolute displacement of param bytes sent in this packet */
127       SSVAL(outbuf,smb_prdisp,pp - params);
128     }
129
130     SSVAL(outbuf,smb_drcnt, data_sent_thistime);
131     if(data_sent_thistime == 0)
132     {
133       SSVAL(outbuf,smb_droff,0);
134       SSVAL(outbuf,smb_drdisp, 0);
135     }
136     else
137     {
138       /* The offset of the data bytes is the offset of the
139          parameter bytes plus the number of parameters being sent this time */
140       SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) - 
141             smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
142       SSVAL(outbuf,smb_drdisp, pd - pdata);
143     }
144
145     /* Copy the param bytes into the packet */
146     if(params_sent_thistime)
147       memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
148     /* Copy in the data bytes */
149     if(data_sent_thistime)
150       memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
151              data_alignment_offset,pd,data_sent_thistime);
152
153     DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
154           params_sent_thistime, data_sent_thistime, useable_space));
155     DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
156           params_to_send, data_to_send, paramsize, datasize));
157
158     /* Send the packet */
159     send_smb(Client,outbuf);
160
161     pp += params_sent_thistime;
162     pd += data_sent_thistime;
163
164     params_to_send -= params_sent_thistime;
165     data_to_send -= data_sent_thistime;
166
167     /* Sanity check */
168     if(params_to_send < 0 || data_to_send < 0)
169     {
170       DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
171             params_to_send, data_to_send));
172       return -1;
173     }
174   }
175
176   return 0;
177 }
178
179
180 /****************************************************************************
181   reply to a TRANSACT2_OPEN
182 ****************************************************************************/
183 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, 
184                            int bufsize,  
185                            char **pparams, char **ppdata)
186 {
187   char *params = *pparams;
188   int16 open_mode = SVAL(params, 2);
189   int16 open_attr = SVAL(params,6);
190   BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
191 #if 0
192   BOOL return_additional_info = BITSETW(params,0);
193   int16 open_sattr = SVAL(params, 4);
194   time_t open_time = make_unix_date3(params+8);
195 #endif
196   int16 open_ofun = SVAL(params,12);
197   int32 open_size = IVAL(params,14);
198   char *pname = &params[28];
199   int16 namelen = strlen(pname)+1;
200
201   pstring fname;
202   mode_t unixmode;
203   SMB_OFF_T size=0;
204   int fmode=0,mtime=0,rmode;
205   SMB_INO_T inode = 0;
206   SMB_STRUCT_STAT sbuf;
207   int smb_action = 0;
208   BOOL bad_path = False;
209   files_struct *fsp;
210
211   StrnCpy(fname,pname,namelen);
212
213   DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
214            fname,open_mode, open_attr, open_ofun, open_size));
215
216   /* XXXX we need to handle passed times, sattr and flags */
217
218   unix_convert(fname,conn,0,&bad_path,NULL);
219     
220   fsp = file_new();
221   if (!fsp)
222     return(ERROR(ERRSRV,ERRnofids));
223
224   if (!check_name(fname,conn))
225   {
226     if((errno == ENOENT) && bad_path)
227     {
228       unix_ERR_class = ERRDOS;
229       unix_ERR_code = ERRbadpath;
230     }
231     file_free(fsp);
232     return(UNIXERROR(ERRDOS,ERRnoaccess));
233   }
234
235   unixmode = unix_mode(conn,open_attr | aARCH);
236       
237   open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
238                    oplock_request, &rmode,&smb_action);
239       
240   if (!fsp->open)
241   {
242     if((errno == ENOENT) && bad_path)
243     {
244       unix_ERR_class = ERRDOS;
245       unix_ERR_code = ERRbadpath;
246     }
247     file_free(fsp);
248     return(UNIXERROR(ERRDOS,ERRnoaccess));
249   }
250
251   if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
252     close_file(fsp,False);
253     return(ERROR(ERRDOS,ERRnoaccess));
254   }
255     
256   size = sbuf.st_size;
257   fmode = dos_mode(conn,fname,&sbuf);
258   mtime = sbuf.st_mtime;
259   inode = sbuf.st_ino;
260   if (fmode & aDIR) {
261     close_file(fsp,False);
262     return(ERROR(ERRDOS,ERRnoaccess));
263   }
264
265   /* Realloc the size of parameters and data we will return */
266   params = *pparams = Realloc(*pparams, 28);
267   if(params == NULL)
268     return(ERROR(ERRDOS,ERRnomem));
269
270   bzero(params,28);
271   SSVAL(params,0,fsp->fnum);
272   SSVAL(params,2,fmode);
273   put_dos_date2(params,4, mtime);
274   SIVAL(params,8, (uint32)size);
275   SSVAL(params,12,rmode);
276
277   if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
278     smb_action |= EXTENDED_OPLOCK_GRANTED;
279   }
280
281   SSVAL(params,18,smb_action);
282   /*
283    * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
284    */
285   SIVAL(params,20,inode);
286  
287   /* Send the required number of replies */
288   send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
289
290   return -1;
291 }
292
293 /****************************************************************************
294   get a level dependent lanman2 dir entry.
295 ****************************************************************************/
296 static int get_lanman2_dir_entry(connection_struct *conn,
297                                  char *path_mask,int dirtype,int info_level,
298                                  int requires_resume_key,
299                                  BOOL dont_descend,char **ppdata, 
300                                  char *base_data, int space_remaining, 
301                                  BOOL *out_of_space,
302                                  int *last_name_off)
303 {
304   char *dname;
305   BOOL found = False;
306   SMB_STRUCT_STAT sbuf;
307   pstring mask;
308   pstring pathreal;
309   pstring fname;
310   char *p, *pdata = *ppdata;
311   uint32 reskey=0;
312   int prev_dirpos=0;
313   int mode=0;
314   SMB_OFF_T size = 0;
315   uint32 len;
316   time_t mdate=0, adate=0, cdate=0;
317   char *nameptr;
318   BOOL isrootdir = (strequal(conn->dirpath,"./") ||
319                     strequal(conn->dirpath,".") ||
320                     strequal(conn->dirpath,"/"));
321   BOOL was_8_3;
322   int nt_extmode; /* Used for NT connections instead of mode */
323   BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
324
325   *fname = 0;
326   *out_of_space = False;
327
328   if (!conn->dirptr)
329     return(False);
330
331   p = strrchr(path_mask,'/');
332   if(p != NULL)
333   {
334     if(p[1] == '\0')
335       pstrcpy(mask,"*.*");
336     else
337       pstrcpy(mask, p+1);
338   }
339   else
340     pstrcpy(mask, path_mask);
341
342   while (!found)
343   {
344     /* Needed if we run out of space */
345     prev_dirpos = TellDir(conn->dirptr);
346     dname = ReadDirName(conn->dirptr);
347
348     /*
349      * Due to bugs in NT client redirectors we are not using
350      * resume keys any more - set them to zero.
351      * Check out the related comments in findfirst/findnext.
352      * JRA.
353      */
354
355     reskey = 0;
356
357     DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
358       (unsigned)conn->dirptr,TellDir(conn->dirptr)));
359       
360     if (!dname) 
361       return(False);
362
363     pstrcpy(fname,dname);      
364
365     if(mask_match(fname, mask, case_sensitive, True))
366     {
367       BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
368       if (dont_descend && !isdots)
369         continue;
370           
371       if (isrootdir && isdots)
372         continue;
373
374       pstrcpy(pathreal,conn->dirpath);
375       if(needslash)
376         pstrcat(pathreal,"/");
377       pstrcat(pathreal,dname);
378       if (dos_stat(pathreal,&sbuf) != 0) 
379       {
380         DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
381         continue;
382       }
383
384       mode = dos_mode(conn,pathreal,&sbuf);
385
386       if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
387         DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
388         continue;
389       }
390
391       size = sbuf.st_size;
392       mdate = sbuf.st_mtime;
393       adate = sbuf.st_atime;
394       cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
395       if(mode & aDIR)
396         size = 0;
397
398       DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
399           
400       found = True;
401     }
402   }
403
404   name_map_mangle(fname,False,SNUM(conn));
405
406   p = pdata;
407   nameptr = p;
408
409   nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
410
411   switch (info_level)
412   {
413     case 1:
414       if(requires_resume_key) {
415         SIVAL(p,0,reskey);
416         p += 4;
417       }
418       put_dos_date2(p,l1_fdateCreation,cdate);
419       put_dos_date2(p,l1_fdateLastAccess,adate);
420       put_dos_date2(p,l1_fdateLastWrite,mdate);
421       SIVAL(p,l1_cbFile,(uint32)size);
422       SIVAL(p,l1_cbFileAlloc,ROUNDUP(size,1024));
423       SSVAL(p,l1_attrFile,mode);
424       SCVAL(p,l1_cchName,strlen(fname));
425       pstrcpy(p + l1_achName, fname);
426       nameptr = p + l1_achName;
427       p += l1_achName + strlen(fname) + 1;
428       break;
429
430     case 2:
431       /* info_level 2 */
432       if(requires_resume_key) {
433         SIVAL(p,0,reskey);
434         p += 4;
435       }
436       put_dos_date2(p,l2_fdateCreation,cdate);
437       put_dos_date2(p,l2_fdateLastAccess,adate);
438       put_dos_date2(p,l2_fdateLastWrite,mdate);
439       SIVAL(p,l2_cbFile,(uint32)size);
440       SIVAL(p,l2_cbFileAlloc,ROUNDUP(size,1024));
441       SSVAL(p,l2_attrFile,mode);
442       SIVAL(p,l2_cbList,0); /* No extended attributes */
443       SCVAL(p,l2_cchName,strlen(fname));
444       pstrcpy(p + l2_achName, fname);
445       nameptr = p + l2_achName;
446       p += l2_achName + strlen(fname) + 1;
447       break;
448
449     case 3:
450       SIVAL(p,0,reskey);
451       put_dos_date2(p,4,cdate);
452       put_dos_date2(p,8,adate);
453       put_dos_date2(p,12,mdate);
454       SIVAL(p,16,(uint32)size);
455       SIVAL(p,20,ROUNDUP(size,1024));
456       SSVAL(p,24,mode);
457       SIVAL(p,26,4);
458       CVAL(p,30) = strlen(fname);
459       pstrcpy(p+31, fname);
460       nameptr = p+31;
461       p += 31 + strlen(fname) + 1;
462       break;
463
464     case 4:
465       if(requires_resume_key) {
466         SIVAL(p,0,reskey);
467         p += 4;
468       }
469       SIVAL(p,0,33+strlen(fname)+1);
470       put_dos_date2(p,4,cdate);
471       put_dos_date2(p,8,adate);
472       put_dos_date2(p,12,mdate);
473       SIVAL(p,16,(uint32)size);
474       SIVAL(p,20,ROUNDUP(size,1024));
475       SSVAL(p,24,mode);
476       CVAL(p,32) = strlen(fname);
477       pstrcpy(p + 33, fname);
478       nameptr = p+33;
479       p += 33 + strlen(fname) + 1;
480       break;
481
482     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
483       was_8_3 = is_8_3(fname, True);
484       len = 94+strlen(fname);
485       len = (len + 3) & ~3;
486       SIVAL(p,0,len); p += 4;
487       SIVAL(p,0,reskey); p += 4;
488       put_long_date(p,cdate); p += 8;
489       put_long_date(p,adate); p += 8;
490       put_long_date(p,mdate); p += 8;
491       put_long_date(p,mdate); p += 8;
492       SIVAL(p,0,size);
493       SIVAL(p,8,size);
494 #ifdef LARGE_SMB_OFF_T
495       SIVAL(p,4,size >> 32);
496       SIVAL(p,12,size >> 32);
497 #endif /* LARGE_SMB_OFF_T */
498       p += 16;
499       SIVAL(p,0,nt_extmode); p += 4;
500       SIVAL(p,0,strlen(fname)); p += 4;
501       SIVAL(p,0,0); p += 4;
502       if (!was_8_3) {
503         pstrcpy(p+2,fname);
504         if (!name_map_mangle(p+2,True,SNUM(conn)))
505           (p+2)[12] = 0;
506       } else
507         *(p+2) = 0;
508       strupper(p+2);
509       SSVAL(p,0,strlen(p+2));
510       p += 2 + 24;
511       /* nameptr = p;  */
512       pstrcpy(p,fname); p += strlen(p);
513       p = pdata + len;
514       break;
515
516     case SMB_FIND_FILE_DIRECTORY_INFO:
517       len = 64+strlen(fname);
518       len = (len + 3) & ~3;
519       SIVAL(p,0,len); p += 4;
520       SIVAL(p,0,reskey); p += 4;
521       put_long_date(p,cdate); p += 8;
522       put_long_date(p,adate); p += 8;
523       put_long_date(p,mdate); p += 8;
524       put_long_date(p,mdate); p += 8;
525       SIVAL(p,0,size);
526       SIVAL(p,8,size);
527 #ifdef LARGE_SMB_OFF_T
528       SIVAL(p,4,size >> 32);
529       SIVAL(p,12,size >> 32);
530 #endif /* LARGE_SMB_OFF_T */
531       p += 16;
532       SIVAL(p,0,nt_extmode); p += 4;
533       SIVAL(p,0,strlen(fname)); p += 4;
534       pstrcpy(p,fname);
535       p = pdata + len;
536       break;
537       
538       
539     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
540       len = 68+strlen(fname);
541       len = (len + 3) & ~3;
542       SIVAL(p,0,len); p += 4;
543       SIVAL(p,0,reskey); p += 4;
544       put_long_date(p,cdate); p += 8;
545       put_long_date(p,adate); p += 8;
546       put_long_date(p,mdate); p += 8;
547       put_long_date(p,mdate); p += 8;
548       SIVAL(p,0,size); 
549       SIVAL(p,8,size);
550 #ifdef LARGE_SMB_OFF_T
551       SIVAL(p,4,size >> 32);
552       SIVAL(p,12,size >> 32);
553 #endif /* LARGE_SMB_OFF_T */
554       p += 16;
555       SIVAL(p,0,nt_extmode); p += 4;
556       SIVAL(p,0,strlen(fname)); p += 4;
557       SIVAL(p,0,0); p += 4;
558       pstrcpy(p,fname);
559       p = pdata + len;
560       break;
561
562     case SMB_FIND_FILE_NAMES_INFO:
563       len = 12+strlen(fname);
564       len = (len + 3) & ~3;
565       SIVAL(p,0,len); p += 4;
566       SIVAL(p,0,reskey); p += 4;
567       SIVAL(p,0,strlen(fname)); p += 4;
568       pstrcpy(p,fname);
569       p = pdata + len;
570       break;
571
572     default:      
573       return(False);
574     }
575
576
577   if (PTR_DIFF(p,pdata) > space_remaining) {
578     /* Move the dirptr back to prev_dirpos */
579     SeekDir(conn->dirptr, prev_dirpos);
580     *out_of_space = True;
581     DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
582     return False; /* Not finished - just out of space */
583   }
584
585   /* Setup the last_filename pointer, as an offset from base_data */
586   *last_name_off = PTR_DIFF(nameptr,base_data);
587   /* Advance the data pointer to the next slot */
588   *ppdata = p;
589   return(found);
590 }
591   
592 /****************************************************************************
593  Convert the directory masks formated for the wire.
594 ****************************************************************************/
595
596 void mask_convert( char *mask)
597 {
598   /*
599    * We know mask is a pstring.
600    */
601   char *p = mask;
602   while (*p) {
603     if (*p == '<') {
604       pstring expnd;
605       if(p[1] != '"' && p[1] != '.') {
606         pstrcpy( expnd, p+1 );
607         *p++ = '*';
608         *p = '.';
609         safe_strcpy( p+1, expnd, sizeof(pstring) - (p - mask) - 2);
610       } else
611         *p = '*';
612     }
613     if (*p == '>') *p = '?';
614     if (*p == '"') *p = '.';
615     p++;
616   }
617 }
618
619 /****************************************************************************
620   reply to a TRANS2_FINDFIRST
621 ****************************************************************************/
622 static int call_trans2findfirst(connection_struct *conn,
623                                 char *inbuf, char *outbuf, int bufsize,  
624                                 char **pparams, char **ppdata)
625 {
626   /* We must be careful here that we don't return more than the
627      allowed number of data bytes. If this means returning fewer than
628      maxentries then so be it. We assume that the redirector has
629      enough room for the fixed number of parameter bytes it has
630      requested. */
631   uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
632   char *params = *pparams;
633   char *pdata = *ppdata;
634   int dirtype = SVAL(params,0);
635   int maxentries = SVAL(params,2);
636   BOOL close_after_first = BITSETW(params+4,0);
637   BOOL close_if_end = BITSETW(params+4,1);
638   BOOL requires_resume_key = BITSETW(params+4,2);
639   int info_level = SVAL(params,6);
640   pstring directory;
641   pstring mask;
642   char *p, *wcard;
643   int last_name_off=0;
644   int dptr_num = -1;
645   int numentries = 0;
646   int i;
647   BOOL finished = False;
648   BOOL dont_descend = False;
649   BOOL out_of_space = False;
650   int space_remaining;
651   BOOL bad_path = False;
652
653   *directory = *mask = 0;
654
655   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",
656            dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
657            info_level, max_data_bytes));
658   
659   switch (info_level) 
660     {
661     case 1:
662     case 2:
663     case 3:
664     case 4:
665     case SMB_FIND_FILE_DIRECTORY_INFO:
666     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
667     case SMB_FIND_FILE_NAMES_INFO:
668     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
669       break;
670     default:
671       return(ERROR(ERRDOS,ERRunknownlevel));
672     }
673
674   pstrcpy(directory, params + 12); /* Complete directory path with 
675                                      wildcard mask appended */
676
677   DEBUG(5,("path=%s\n",directory));
678
679   unix_convert(directory,conn,0,&bad_path,NULL);
680   if(!check_name(directory,conn)) {
681     if((errno == ENOENT) && bad_path)
682     {
683       unix_ERR_class = ERRDOS;
684       unix_ERR_code = ERRbadpath;
685     }
686
687 #if 0
688     /* Ugly - NT specific hack - maybe not needed ? (JRA) */
689     if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && 
690        (get_remote_arch() == RA_WINNT))
691     {
692       unix_ERR_class = ERRDOS;
693       unix_ERR_code = ERRbaddirectory;
694     }
695 #endif 
696
697     return(ERROR(ERRDOS,ERRbadpath));
698   }
699
700   p = strrchr(directory,'/');
701   if(p == NULL) {
702     pstrcpy(mask,directory);
703     pstrcpy(directory,"./");
704   } else {
705     pstrcpy(mask,p+1);
706     *p = 0;
707   }
708
709   DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
710
711   pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
712   if(!*ppdata)
713     return(ERROR(ERRDOS,ERRnomem));
714   bzero(pdata,max_data_bytes);
715
716   /* Realloc the params space */
717   params = *pparams = Realloc(*pparams, 10);
718   if(params == NULL)
719     return(ERROR(ERRDOS,ERRnomem));
720
721   dptr_num = dptr_create(conn,directory, True ,SVAL(inbuf,smb_pid));
722   if (dptr_num < 0)
723     return(ERROR(ERRDOS,ERRbadfile));
724
725   /* Convert the formatted mask. */
726   mask_convert(mask);
727
728 #if 0 /* JRA */
729   /*
730    * Now we have a working mask_match in util.c, I believe
731    * we no longer need these hacks (in fact they break
732    * things). JRA. 
733    */
734
735   /* a special case for 16 bit apps */
736   if (strequal(mask,"????????.???")) pstrcpy(mask,"*");
737
738   /* handle broken clients that send us old 8.3 format */
739   string_sub(mask,"????????","*");
740   string_sub(mask,".???",".*");
741 #endif /* JRA */
742
743   /* Save the wildcard match and attribs we are using on this directory - 
744      needed as lanman2 assumes these are being saved between calls */
745
746   if(!(wcard = strdup(mask))) {
747     dptr_close(dptr_num);
748     return(ERROR(ERRDOS,ERRnomem));
749   }
750
751   dptr_set_wcard(dptr_num, wcard);
752   dptr_set_attr(dptr_num, dirtype);
753
754   DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
755
756   /* We don't need to check for VOL here as this is returned by 
757      a different TRANS2 call. */
758   
759   DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
760            conn->dirpath,lp_dontdescend(SNUM(conn))));
761   if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
762     dont_descend = True;
763     
764   p = pdata;
765   space_remaining = max_data_bytes;
766   out_of_space = False;
767
768   for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
769     {
770
771       /* this is a heuristic to avoid seeking the dirptr except when 
772          absolutely necessary. It allows for a filename of about 40 chars */
773       if (space_remaining < DIRLEN_GUESS && numentries > 0)
774         {
775           out_of_space = True;
776           finished = False;
777         }
778       else
779         {
780           finished = 
781             !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
782                                    requires_resume_key,dont_descend,
783                                    &p,pdata,space_remaining, &out_of_space,
784                                    &last_name_off);
785         }
786
787       if (finished && out_of_space)
788         finished = False;
789
790       if (!finished && !out_of_space)
791         numentries++;
792       space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
793     }
794   
795   /* Check if we can close the dirptr */
796   if(close_after_first || (finished && close_if_end))
797     {
798       dptr_close(dptr_num);
799       DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
800       dptr_num = -1;
801     }
802
803   /* 
804    * If there are no matching entries we must return ERRDOS/ERRbadfile - 
805    * from observation of NT.
806    */
807
808   if(numentries == 0)
809     return(ERROR(ERRDOS,ERRbadfile));
810
811   /* At this point pdata points to numentries directory entries. */
812
813   /* Set up the return parameter block */
814   SSVAL(params,0,dptr_num);
815   SSVAL(params,2,numentries);
816   SSVAL(params,4,finished);
817   SSVAL(params,6,0); /* Never an EA error */
818   SSVAL(params,8,last_name_off);
819
820   send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
821
822   if ((! *directory) && dptr_path(dptr_num))
823     slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
824
825   DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
826             smb_fn_name(CVAL(inbuf,smb_com)), 
827             mask, directory, dirtype, numentries ) );
828
829   return(-1);
830 }
831
832
833 /****************************************************************************
834   reply to a TRANS2_FINDNEXT
835 ****************************************************************************/
836 static int call_trans2findnext(connection_struct *conn, 
837                                char *inbuf, char *outbuf, 
838                                int length, int bufsize,
839                                char **pparams, char **ppdata)
840 {
841   /* We must be careful here that we don't return more than the
842      allowed number of data bytes. If this means returning fewer than
843      maxentries then so be it. We assume that the redirector has
844      enough room for the fixed number of parameter bytes it has
845      requested. */
846   int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
847   char *params = *pparams;
848   char *pdata = *ppdata;
849   int16 dptr_num = SVAL(params,0);
850   int maxentries = SVAL(params,2);
851   uint16 info_level = SVAL(params,4);
852   uint32 resume_key = IVAL(params,6);
853   BOOL close_after_request = BITSETW(params+10,0);
854   BOOL close_if_end = BITSETW(params+10,1);
855   BOOL requires_resume_key = BITSETW(params+10,2);
856   BOOL continue_bit = BITSETW(params+10,3);
857   pstring resume_name;
858   pstring mask;
859   pstring directory;
860   char *p;
861   uint16 dirtype;
862   int numentries = 0;
863   int i, last_name_off=0;
864   BOOL finished = False;
865   BOOL dont_descend = False;
866   BOOL out_of_space = False;
867   int space_remaining;
868
869   *mask = *directory = *resume_name = 0;
870
871   pstrcpy( resume_name, params+12);
872
873   DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
874 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
875 resume_key = %d resume name = %s continue=%d level = %d\n",
876            dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
877            requires_resume_key, resume_key, resume_name, continue_bit, info_level));
878
879   switch (info_level) 
880     {
881     case 1:
882     case 2:
883     case 3:
884     case 4:
885     case SMB_FIND_FILE_DIRECTORY_INFO:
886     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
887     case SMB_FIND_FILE_NAMES_INFO:
888     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
889       break;
890     default:
891       return(ERROR(ERRDOS,ERRunknownlevel));
892     }
893
894   pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
895   if(!*ppdata)
896     return(ERROR(ERRDOS,ERRnomem));
897   bzero(pdata,max_data_bytes);
898
899   /* Realloc the params space */
900   params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
901   if(!params)
902     return(ERROR(ERRDOS,ERRnomem));
903
904   /* Check that the dptr is valid */
905   if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
906     return(ERROR(ERRDOS,ERRnofiles));
907
908   string_set(&conn->dirpath,dptr_path(dptr_num));
909
910   /* Get the wildcard mask from the dptr */
911   if((p = dptr_wcard(dptr_num))== NULL) {
912     DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
913     return (ERROR(ERRDOS,ERRnofiles));
914   }
915   pstrcpy(mask, p);
916   pstrcpy(directory,conn->dirpath);
917
918   /* Get the attr mask from the dptr */
919   dirtype = dptr_attr(dptr_num);
920
921   DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
922            dptr_num, mask, dirtype, 
923            (unsigned)conn->dirptr,
924            TellDir(conn->dirptr)));
925
926   /* We don't need to check for VOL here as this is returned by 
927      a different TRANS2 call. */
928
929   DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
930   if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
931     dont_descend = True;
932     
933   p = pdata;
934   space_remaining = max_data_bytes;
935   out_of_space = False;
936
937   /* 
938    * Seek to the correct position. We no longer use the resume key but
939    * depend on the last file name instead.
940    */
941   if(requires_resume_key && *resume_name && !continue_bit)
942   {
943     /*
944      * Fix for NT redirector problem triggered by resume key indexes
945      * changing between directory scans. We now return a resume key of 0
946      * and instead look for the filename to continue from (also given
947      * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
948      * findfirst/findnext (as is usual) then the directory pointer
949      * should already be at the correct place. Check this by scanning
950      * backwards looking for an exact (ie. case sensitive) filename match. 
951      * If we get to the beginning of the directory and haven't found it then scan
952      * forwards again looking for a match. JRA.
953      */
954
955     int current_pos, start_pos;
956     char *dname = NULL;
957     void *dirptr = conn->dirptr;
958     start_pos = TellDir(dirptr);
959     for(current_pos = start_pos; current_pos >= 0; current_pos--)
960     {
961       DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
962
963       SeekDir(dirptr, current_pos);
964       dname = ReadDirName(dirptr);
965
966       /*
967        * Remember, name_map_mangle is called by
968        * get_lanman2_dir_entry(), so the resume name
969        * could be mangled. Ensure we do the same
970        * here.
971        */
972
973       if(dname != NULL)
974         name_map_mangle( dname, False, SNUM(conn));
975
976       if(dname && strcsequal( resume_name, dname))
977       {
978         SeekDir(dirptr, current_pos+1);
979         DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
980         break;
981       }
982     }
983
984     /*
985      * Scan forward from start if not found going backwards.
986      */
987
988     if(current_pos < 0)
989     {
990       DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
991       SeekDir(dirptr, start_pos);
992       for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
993       {
994         /*
995          * Remember, name_map_mangle is called by
996          * get_lanman2_dir_entry(), so the resume name
997          * could be mangled. Ensure we do the same
998          * here.
999          */
1000
1001         if(dname != NULL)
1002           name_map_mangle( dname, False, SNUM(conn));
1003
1004         if(dname && strcsequal( resume_name, dname))
1005         {
1006           SeekDir(dirptr, current_pos+1);
1007           DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1008           break;
1009         }
1010       } /* end for */
1011     } /* end if current_pos */
1012   } /* end if requires_resume_key && !continue_bit */
1013
1014   for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1015     {
1016       /* this is a heuristic to avoid seeking the dirptr except when 
1017          absolutely necessary. It allows for a filename of about 40 chars */
1018       if (space_remaining < DIRLEN_GUESS && numentries > 0)
1019         {
1020           out_of_space = True;
1021           finished = False;
1022         }
1023       else
1024         {
1025           finished = 
1026             !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1027                                    requires_resume_key,dont_descend,
1028                                    &p,pdata,space_remaining, &out_of_space,
1029                                    &last_name_off);
1030         }
1031
1032       if (finished && out_of_space)
1033         finished = False;
1034
1035       if (!finished && !out_of_space)
1036         numentries++;
1037       space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1038     }
1039   
1040   /* Check if we can close the dirptr */
1041   if(close_after_request || (finished && close_if_end))
1042     {
1043       dptr_close(dptr_num); /* This frees up the saved mask */
1044       DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1045       dptr_num = -1;
1046     }
1047
1048
1049   /* Set up the return parameter block */
1050   SSVAL(params,0,numentries);
1051   SSVAL(params,2,finished);
1052   SSVAL(params,4,0); /* Never an EA error */
1053   SSVAL(params,6,last_name_off);
1054
1055   send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1056
1057   if ((! *directory) && dptr_path(dptr_num))
1058     slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1059
1060   DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1061             smb_fn_name(CVAL(inbuf,smb_com)), 
1062             mask, directory, dirtype, numentries ) );
1063
1064   return(-1);
1065 }
1066
1067 /****************************************************************************
1068   reply to a TRANS2_QFSINFO (query filesystem info)
1069 ****************************************************************************/
1070
1071 static int call_trans2qfsinfo(connection_struct *conn, 
1072                               char *inbuf, char *outbuf, 
1073                               int length, int bufsize,
1074                               char **pparams, char **ppdata)
1075 {
1076   char *pdata = *ppdata;
1077   char *params = *pparams;
1078   uint16 info_level = SVAL(params,0);
1079   int data_len;
1080   SMB_STRUCT_STAT st;
1081   char *vname = volume_label(SNUM(conn));
1082   int snum = SNUM(conn);
1083  
1084   DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1085
1086   if(dos_stat(".",&st)!=0) {
1087     DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1088     return (ERROR(ERRSRV,ERRinvdevice));
1089   }
1090
1091   pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
1092
1093   switch (info_level) 
1094   {
1095     case 1:
1096     {
1097       SMB_BIG_UINT dfree,dsize,bsize;
1098       data_len = 18;
1099       sys_disk_free(".",&bsize,&dfree,&dsize);  
1100       SIVAL(pdata,l1_idFileSystem,st.st_dev);
1101       SIVAL(pdata,l1_cSectorUnit,bsize/512);
1102       SIVAL(pdata,l1_cUnit,dsize);
1103       SIVAL(pdata,l1_cUnitAvail,dfree);
1104       SSVAL(pdata,l1_cbSector,512);
1105       DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1106                  (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1107          (unsigned int)dfree, 512));
1108       break;
1109     }
1110     case 2:
1111     { 
1112       /* Return volume name */
1113       int volname_len = MIN(strlen(vname),11);
1114       data_len = l2_vol_szVolLabel + volname_len + 1;
1115       /* 
1116        * Add volume serial number - hash of a combination of
1117        * the called hostname and the service name.
1118        */
1119       SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1120       SCVAL(pdata,l2_vol_cch,volname_len);
1121       StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1122       DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1123                (unsigned)st.st_ctime, volname_len,
1124                pdata+l2_vol_szVolLabel));
1125       break;
1126     }
1127     case SMB_QUERY_FS_ATTRIBUTE_INFO:
1128       data_len = 12 + 2*strlen(FSTYPE_STRING);
1129       SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES); /* FS ATTRIBUTES */
1130 #if 0 /* Old code. JRA. */
1131       SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1132 #endif /* Old code. */
1133       SIVAL(pdata,4,128); /* Max filename component length */
1134       SIVAL(pdata,8,2*strlen(FSTYPE_STRING));
1135       PutUniCode(pdata+12,FSTYPE_STRING);
1136       SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1137       break;
1138     case SMB_QUERY_FS_LABEL_INFO:
1139       data_len = 4 + strlen(vname);
1140       SIVAL(pdata,0,strlen(vname));
1141       pstrcpy(pdata+4,vname);      
1142       break;
1143     case SMB_QUERY_FS_VOLUME_INFO:      
1144
1145       /*
1146        * NB: The earlier CIFS spec that says this always  
1147        * uses UNICODE is incorrect ! JRA.
1148        */
1149
1150       data_len = 18 + strlen(vname);
1151
1152       /* 
1153        * Add volume serial number - hash of a combination of
1154        * the called hostname and the service name.
1155        */
1156       SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1157       SIVAL(pdata,12,strlen(vname));
1158       pstrcpy(pdata+18,vname);      
1159       DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),
1160                vname));
1161       break;
1162     case SMB_QUERY_FS_SIZE_INFO:
1163     {
1164       SMB_BIG_UINT dfree,dsize,bsize;
1165       data_len = 24;
1166       sys_disk_free(".",&bsize,&dfree,&dsize);  
1167       SIVAL(pdata,0,dsize);
1168       SIVAL(pdata,8,dfree);
1169       SIVAL(pdata,16,bsize/512);
1170       SIVAL(pdata,20,512);
1171       break;
1172     }
1173     case SMB_QUERY_FS_DEVICE_INFO:
1174       data_len = 8;
1175       SIVAL(pdata,0,0); /* dev type */
1176       SIVAL(pdata,4,0); /* characteristics */
1177       break;
1178     default:
1179       return(ERROR(ERRDOS,ERRunknownlevel));
1180   }
1181
1182
1183   send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1184
1185   DEBUG( 4, ( "%s info_level = %d\n",
1186             smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1187
1188   return -1;
1189 }
1190
1191 /****************************************************************************
1192   reply to a TRANS2_SETFSINFO (set filesystem info)
1193 ****************************************************************************/
1194 static int call_trans2setfsinfo(connection_struct *conn,
1195                                 char *inbuf, char *outbuf, int length, 
1196                                 int bufsize,
1197                                 char **pparams, char **ppdata)
1198 {
1199   /* Just say yes we did it - there is nothing that
1200      can be set here so it doesn't matter. */
1201   int outsize;
1202   DEBUG(3,("call_trans2setfsinfo\n"));
1203
1204   if (!CAN_WRITE(conn))
1205     return(ERROR(ERRSRV,ERRaccess));
1206
1207   outsize = set_message(outbuf,10,0,True);
1208
1209   return outsize;
1210 }
1211
1212 /****************************************************************************
1213   Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1214   file name or file id).
1215 ****************************************************************************/
1216
1217 static int call_trans2qfilepathinfo(connection_struct *conn,
1218                                     char *inbuf, char *outbuf, int length, 
1219                                     int bufsize,
1220                                     char **pparams,char **ppdata,
1221                                     int total_data)
1222 {
1223   char *params = *pparams;
1224   char *pdata = *ppdata;
1225   uint16 tran_call = SVAL(inbuf, smb_setup0);
1226   uint16 info_level;
1227   int mode=0;
1228   SMB_OFF_T size=0;
1229   unsigned int data_size;
1230   SMB_STRUCT_STAT sbuf;
1231   pstring fname1;
1232   char *fname;
1233   char *p;
1234   int l;
1235   SMB_OFF_T pos;
1236   BOOL bad_path = False;
1237
1238   if (tran_call == TRANSACT2_QFILEINFO) {
1239     files_struct *fsp = file_fsp(params,0);
1240     info_level = SVAL(params,2);
1241
1242     CHECK_FSP(fsp,conn);
1243     CHECK_ERROR(fsp);
1244
1245     fname = fsp->fsp_name;
1246     if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1247       DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1248       return(UNIXERROR(ERRDOS,ERRbadfid));
1249     }
1250     pos = sys_lseek(fsp->fd_ptr->fd,0,SEEK_CUR);
1251   } else {
1252     /* qpathinfo */
1253     info_level = SVAL(params,0);
1254     fname = &fname1[0];
1255     pstrcpy(fname,&params[6]);
1256     unix_convert(fname,conn,0,&bad_path,&sbuf);
1257     if (!check_name(fname,conn) || (!VALID_STAT(sbuf) && dos_stat(fname,&sbuf))) {
1258       DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1259       if((errno == ENOENT) && bad_path)
1260       {
1261         unix_ERR_class = ERRDOS;
1262         unix_ERR_code = ERRbadpath;
1263       }
1264       return(UNIXERROR(ERRDOS,ERRbadpath));
1265     }
1266     pos = 0;
1267   }
1268
1269
1270   DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1271            fname,info_level,tran_call,total_data));
1272
1273   p = strrchr(fname,'/'); 
1274   if (!p) 
1275     p = fname;
1276   else
1277     p++;
1278   l = strlen(p);  
1279   mode = dos_mode(conn,fname,&sbuf);
1280   size = sbuf.st_size;
1281   if (mode & aDIR) size = 0;
1282
1283   /* from now on we only want the part after the / */
1284   fname = p;
1285   
1286   params = *pparams = Realloc(*pparams,2); bzero(params,2);
1287   data_size = 1024;
1288   pdata = *ppdata = Realloc(*ppdata, data_size); 
1289
1290   if (total_data > 0 && IVAL(pdata,0) == total_data) {
1291     /* uggh, EAs for OS2 */
1292     DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1293     return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1294   }
1295
1296   bzero(pdata,data_size);
1297
1298   switch (info_level) 
1299     {
1300     case SMB_INFO_STANDARD:
1301     case SMB_INFO_QUERY_EA_SIZE:
1302       data_size = (info_level==1?22:26);
1303       put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1304       put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1305       put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1306       SIVAL(pdata,l1_cbFile,(uint32)size);
1307       SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
1308       SSVAL(pdata,l1_attrFile,mode);
1309       SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1310       break;
1311
1312     case SMB_INFO_QUERY_EAS_FROM_LIST:
1313       data_size = 24;
1314       put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1315       put_dos_date2(pdata,4,sbuf.st_atime);
1316       put_dos_date2(pdata,8,sbuf.st_mtime);
1317       SIVAL(pdata,12,(uint32)size);
1318       SIVAL(pdata,16,ROUNDUP(size,1024));
1319       SIVAL(pdata,20,mode);
1320       break;
1321
1322     case SMB_INFO_QUERY_ALL_EAS:
1323       data_size = 4;
1324       SIVAL(pdata,0,data_size);
1325       break;
1326
1327     case 6:
1328       return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */      
1329
1330     case SMB_QUERY_FILE_BASIC_INFO:
1331       data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1332       put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1333       put_long_date(pdata+8,sbuf.st_atime);
1334       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1335       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1336       SIVAL(pdata,32,mode);
1337
1338       DEBUG(5,("SMB_QFBI - "));
1339       {
1340         time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1341         DEBUG(5,("create: %s ", ctime(&create_time)));
1342       }
1343       DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1344       DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1345       DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1346       DEBUG(5,("mode: %x\n", mode));
1347
1348       break;
1349
1350     case SMB_QUERY_FILE_STANDARD_INFO:
1351       data_size = 22;
1352       SIVAL(pdata,0,size);
1353       SIVAL(pdata,8,size);
1354 #ifdef LARGE_SMB_OFF_T
1355       SIVAL(pdata,4,size>>32);
1356       SIVAL(pdata,12,size>>32);
1357 #endif /* LARGE_SMB_OFF_T */
1358       SIVAL(pdata,16,sbuf.st_nlink);
1359       CVAL(pdata,20) = 0;
1360       CVAL(pdata,21) = (mode&aDIR)?1:0;
1361       break;
1362
1363     case SMB_QUERY_FILE_EA_INFO:
1364       data_size = 4;
1365       break;
1366
1367     /* Get the 8.3 name - used if NT SMB was negotiated. */
1368     case SMB_QUERY_FILE_ALT_NAME_INFO:
1369       {
1370         pstring short_name;
1371         pstrcpy(short_name,p);
1372         /* Mangle if not already 8.3 */
1373         if(!is_8_3(short_name, True))
1374         {
1375           if(!name_map_mangle(short_name,True,SNUM(conn)))
1376             *short_name = '\0';
1377         }
1378         strupper(short_name);
1379         l = strlen(short_name);
1380         PutUniCode(pdata + 4, short_name);
1381         data_size = 4 + (2*l);
1382         SIVAL(pdata,0,2*l);
1383       }
1384       break;
1385
1386     case SMB_QUERY_FILE_NAME_INFO:
1387       data_size = 4 + l;
1388       SIVAL(pdata,0,l);
1389       pstrcpy(pdata+4,fname);
1390       break;
1391
1392     case SMB_QUERY_FILE_ALLOCATION_INFO:
1393     case SMB_QUERY_FILE_END_OF_FILEINFO:
1394       data_size = 8;
1395       SIVAL(pdata,0,size);
1396 #ifdef LARGE_SMB_OFF_T
1397       SIVAL(pdata,4,size >> 32);
1398 #endif /* LARGE_SMB_OFF_T */
1399       break;
1400
1401     case SMB_QUERY_FILE_ALL_INFO:
1402       put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1403       put_long_date(pdata+8,sbuf.st_atime);
1404       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1405       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1406       SIVAL(pdata,32,mode);
1407       pdata += 40;
1408       SIVAL(pdata,0,size);
1409       SIVAL(pdata,8,size);
1410 #ifdef LARGE_SMB_OFF_T
1411       SIVAL(pdata,4,size >> 32);
1412       SIVAL(pdata,12,size >> 32);
1413 #endif /* LARGE_SMB_OFF_T */
1414       SIVAL(pdata,16,sbuf.st_nlink);
1415       CVAL(pdata,20) = 0;
1416       CVAL(pdata,21) = (mode&aDIR)?1:0;
1417       pdata += 24;
1418       pdata += 8; /* index number */
1419       pdata += 4; /* EA info */
1420       if (mode & aRONLY)
1421         SIVAL(pdata,0,0xA9);
1422       else
1423         SIVAL(pdata,0,0xd01BF);
1424       pdata += 4;
1425       SIVAL(pdata,0,pos); /* current offset */
1426       pdata += 8;
1427       SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1428       pdata += 4;
1429       pdata += 4; /* alignment */
1430       SIVAL(pdata,0,l);
1431       pstrcpy(pdata+4,fname);
1432       pdata += 4 + l;
1433       data_size = PTR_DIFF(pdata,(*ppdata));
1434       break;
1435
1436 #if 0
1437       /* NT4 server just returns "invalid query" to this - if we try to answer 
1438          it then NTws gets a BSOD! (tridge) */
1439     case SMB_QUERY_FILE_STREAM_INFO:
1440       data_size = 24 + l;
1441       SIVAL(pdata,0,pos);
1442       SIVAL(pdata,4,size);
1443       SIVAL(pdata,12,size);
1444       SIVAL(pdata,20,l);        
1445       pstrcpy(pdata+24,fname);
1446       break;
1447 #endif
1448
1449     default:
1450       return(ERROR(ERRDOS,ERRunknownlevel));
1451     }
1452
1453   send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1454
1455   return(-1);
1456 }
1457
1458 /****************************************************************************
1459   reply to a TRANS2_SETFILEINFO (set file info by fileid)
1460 ****************************************************************************/
1461 static int call_trans2setfilepathinfo(connection_struct *conn,
1462                                       char *inbuf, char *outbuf, int length, 
1463                                       int bufsize, char **pparams, 
1464                                       char **ppdata, int total_data)
1465 {
1466   char *params = *pparams;
1467   char *pdata = *ppdata;
1468   uint16 tran_call = SVAL(inbuf, smb_setup0);
1469   uint16 info_level;
1470   int mode=0;
1471   SMB_OFF_T size=0;
1472   struct utimbuf tvs;
1473   SMB_STRUCT_STAT st;
1474   pstring fname1;
1475   char *fname;
1476   int fd = -1;
1477   BOOL bad_path = False;
1478
1479   if (!CAN_WRITE(conn))
1480     return(ERROR(ERRSRV,ERRaccess));
1481
1482   if (tran_call == TRANSACT2_SETFILEINFO) {
1483     files_struct *fsp = file_fsp(params,0);
1484     info_level = SVAL(params,2);    
1485
1486     CHECK_FSP(fsp,conn);
1487     CHECK_ERROR(fsp);
1488
1489     fname = fsp->fsp_name;
1490     fd = fsp->fd_ptr->fd;
1491
1492     if(sys_fstat(fd,&st)!=0) {
1493       DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
1494       return(ERROR(ERRDOS,ERRbadpath));
1495     }
1496   } else {
1497     /* set path info */
1498     info_level = SVAL(params,0);    
1499     fname = fname1;
1500     pstrcpy(fname,&params[6]);
1501     unix_convert(fname,conn,0,&bad_path,&st);
1502     if(!check_name(fname, conn))
1503     {
1504       if((errno == ENOENT) && bad_path)
1505       {
1506         unix_ERR_class = ERRDOS;
1507         unix_ERR_code = ERRbadpath;
1508       }
1509       return(UNIXERROR(ERRDOS,ERRbadpath));
1510     }
1511  
1512     if(!VALID_STAT(st) && dos_stat(fname,&st)!=0) {
1513       DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1514       if((errno == ENOENT) && bad_path)
1515       {
1516         unix_ERR_class = ERRDOS;
1517         unix_ERR_code = ERRbadpath;
1518       }
1519       return(UNIXERROR(ERRDOS,ERRbadpath));
1520     }    
1521   }
1522
1523   DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1524            tran_call,fname,info_level,total_data));
1525
1526   /* Realloc the parameter and data sizes */
1527   params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
1528   if(params == NULL)
1529     return(ERROR(ERRDOS,ERRnomem));
1530
1531   size = st.st_size;
1532   tvs.modtime = st.st_mtime;
1533   tvs.actime = st.st_atime;
1534   mode = dos_mode(conn,fname,&st);
1535
1536   if (total_data > 0 && IVAL(pdata,0) == total_data) {
1537     /* uggh, EAs for OS2 */
1538     DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1539     return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1540   }
1541
1542   switch (info_level)
1543   {
1544     case SMB_INFO_STANDARD:
1545     case SMB_INFO_QUERY_EA_SIZE:
1546     {
1547       /* access time */
1548       tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1549
1550       /* write time */
1551       tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1552
1553       mode = SVAL(pdata,l1_attrFile);
1554       size = IVAL(pdata,l1_cbFile);
1555       break;
1556     }
1557
1558     /* XXXX um, i don't think this is right.
1559        it's also not in the cifs6.txt spec.
1560      */
1561     case SMB_INFO_QUERY_EAS_FROM_LIST:
1562       tvs.actime = make_unix_date2(pdata+8);
1563       tvs.modtime = make_unix_date2(pdata+12);
1564       size = IVAL(pdata,16);
1565       mode = IVAL(pdata,24);
1566       break;
1567
1568     /* XXXX nor this.  not in cifs6.txt, either. */
1569     case SMB_INFO_QUERY_ALL_EAS:
1570       tvs.actime = make_unix_date2(pdata+8);
1571       tvs.modtime = make_unix_date2(pdata+12);
1572       size = IVAL(pdata,16);
1573       mode = IVAL(pdata,24);
1574       break;
1575
1576     case SMB_SET_FILE_BASIC_INFO:
1577     {
1578       /* Ignore create time at offset pdata. */
1579
1580       /* access time */
1581       tvs.actime = interpret_long_date(pdata+8);
1582
1583       /* write time + changed time, combined. */
1584       tvs.modtime=MAX(interpret_long_date(pdata+16),
1585                       interpret_long_date(pdata+24));
1586
1587 #if 0 /* Needs more testing... */
1588       /* Test from Luke to prevent Win95 from
1589          setting incorrect values here.
1590        */
1591       if (tvs.actime < tvs.modtime)
1592         return(ERROR(ERRDOS,ERRnoaccess));
1593 #endif /* Needs more testing... */
1594
1595       /* attributes */
1596       mode = IVAL(pdata,32);
1597       break;
1598     }
1599
1600     case SMB_SET_FILE_END_OF_FILE_INFO:
1601     {
1602       size = IVAL(pdata,0);
1603 #ifdef LARGE_SMB_OFF_T
1604       size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1605 #else /* LARGE_SMB_OFF_T */
1606       if (IVAL(pdata,4) != 0)   /* more than 32 bits? */
1607          return(ERROR(ERRDOS,ERRunknownlevel));
1608 #endif /* LARGE_SMB_OFF_T */
1609       break;
1610     }
1611
1612     case SMB_SET_FILE_ALLOCATION_INFO:
1613       break; /* We don't need to do anything for this call. */
1614
1615     case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1616     {
1617       if (tran_call == TRANSACT2_SETFILEINFO) {
1618         files_struct *fsp = file_fsp(params,0);
1619         if(fsp->is_directory)
1620           return(ERROR(ERRDOS,ERRnoaccess));
1621         /*
1622          * TODO - check here is this means set
1623          * this flag bit on all open files that
1624          * reference this particular dev/inode pair.
1625          * If so we'll need to search the open
1626          * file entries here and set this flag on 
1627          * all of them that match. JRA.
1628          */
1629         fsp->delete_on_close = CVAL(pdata,0);
1630       } else
1631         return(ERROR(ERRDOS,ERRunknownlevel));
1632       break;
1633     }
1634
1635     default:
1636     {
1637       return(ERROR(ERRDOS,ERRunknownlevel));
1638     }
1639   }
1640
1641   DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1642   DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1643   DEBUG(6,("size: %.0f ", (double)size));
1644   DEBUG(6,("mode: %x\n"  , mode));
1645
1646   /* get some defaults (no modifications) if any info is zero. */
1647   if (!tvs.actime) tvs.actime = st.st_atime;
1648   if (!tvs.modtime) tvs.modtime = st.st_mtime;
1649   if (!size) size = st.st_size;
1650
1651   /* Try and set the times, size and mode of this file -
1652      if they are different from the current values
1653    */
1654   if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
1655   {
1656     if(file_utime(conn, fname, &tvs)!=0)
1657     {
1658       return(ERROR(ERRDOS,ERRnoaccess));
1659     }
1660   }
1661
1662   /* check the mode isn't different, before changing it */
1663   if (mode != dos_mode(conn, fname, &st) && file_chmod(conn, fname, mode, NULL))
1664   {
1665     DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1666     return(ERROR(ERRDOS,ERRnoaccess));
1667   }
1668
1669   if(size != st.st_size)
1670   {
1671     if (fd == -1)
1672     {
1673       fd = dos_open(fname,O_RDWR,0);
1674       if (fd == -1)
1675       {
1676         return(ERROR(ERRDOS,ERRbadpath));
1677       }
1678       set_filelen(fd, size);
1679       close(fd);
1680     }
1681     else
1682     {
1683       set_filelen(fd, size);
1684     }
1685   }
1686
1687   SSVAL(params,0,0);
1688
1689   send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1690   
1691   return(-1);
1692 }
1693
1694 /****************************************************************************
1695   reply to a TRANS2_MKDIR (make directory with extended attributes).
1696 ****************************************************************************/
1697 static int call_trans2mkdir(connection_struct *conn,
1698                             char *inbuf, char *outbuf, int length, int bufsize,
1699                             char **pparams, char **ppdata)
1700 {
1701   char *params = *pparams;
1702   pstring directory;
1703   int ret = -1;
1704   BOOL bad_path = False;
1705
1706   if (!CAN_WRITE(conn))
1707     return(ERROR(ERRSRV,ERRaccess));
1708
1709   pstrcpy(directory, &params[4]);
1710
1711   DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
1712
1713   unix_convert(directory,conn,0,&bad_path,NULL);
1714   if (check_name(directory,conn))
1715     ret = dos_mkdir(directory,unix_mode(conn,aDIR));
1716   
1717   if(ret < 0)
1718     {
1719       DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
1720       if((errno == ENOENT) && bad_path)
1721       {
1722         unix_ERR_class = ERRDOS;
1723         unix_ERR_code = ERRbadpath;
1724       }
1725       return(UNIXERROR(ERRDOS,ERRnoaccess));
1726     }
1727
1728   /* Realloc the parameter and data sizes */
1729   params = *pparams = Realloc(*pparams,2);
1730   if(params == NULL)
1731     return(ERROR(ERRDOS,ERRnomem));
1732
1733   SSVAL(params,0,0);
1734
1735   send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1736   
1737   return(-1);
1738 }
1739
1740 /****************************************************************************
1741   reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1742   We don't actually do this - we just send a null response.
1743 ****************************************************************************/
1744 static int call_trans2findnotifyfirst(connection_struct *conn,
1745                                       char *inbuf, char *outbuf, 
1746                                       int length, int bufsize,
1747                                       char **pparams, char **ppdata)
1748 {
1749   static uint16 fnf_handle = 257;
1750   char *params = *pparams;
1751   uint16 info_level = SVAL(params,4);
1752
1753   DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
1754
1755   switch (info_level) 
1756     {
1757     case 1:
1758     case 2:
1759       break;
1760     default:
1761       return(ERROR(ERRDOS,ERRunknownlevel));
1762     }
1763
1764   /* Realloc the parameter and data sizes */
1765   params = *pparams = Realloc(*pparams,6);
1766   if(params == NULL)
1767     return(ERROR(ERRDOS,ERRnomem));
1768
1769   SSVAL(params,0,fnf_handle);
1770   SSVAL(params,2,0); /* No changes */
1771   SSVAL(params,4,0); /* No EA errors */
1772
1773   fnf_handle++;
1774
1775   if(fnf_handle == 0)
1776     fnf_handle = 257;
1777
1778   send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
1779   
1780   return(-1);
1781 }
1782
1783 /****************************************************************************
1784   reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
1785   changes). Currently this does nothing.
1786 ****************************************************************************/
1787 static int call_trans2findnotifynext(connection_struct *conn,
1788                                      char *inbuf, char *outbuf, 
1789                                      int length, int bufsize,
1790                                      char **pparams, char **ppdata)
1791 {
1792   char *params = *pparams;
1793
1794   DEBUG(3,("call_trans2findnotifynext\n"));
1795
1796   /* Realloc the parameter and data sizes */
1797   params = *pparams = Realloc(*pparams,4);
1798   if(params == NULL)
1799     return(ERROR(ERRDOS,ERRnomem));
1800
1801   SSVAL(params,0,0); /* No changes */
1802   SSVAL(params,2,0); /* No EA errors */
1803
1804   send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
1805   
1806   return(-1);
1807 }
1808
1809 /****************************************************************************
1810   reply to a SMBfindclose (stop trans2 directory search)
1811 ****************************************************************************/
1812 int reply_findclose(connection_struct *conn,
1813                     char *inbuf,char *outbuf,int length,int bufsize)
1814 {
1815         int outsize = 0;
1816         int16 dptr_num=SVALS(inbuf,smb_vwv0);
1817
1818         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
1819
1820         dptr_close(dptr_num);
1821
1822         outsize = set_message(outbuf,0,0,True);
1823
1824         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
1825
1826         return(outsize);
1827 }
1828
1829 /****************************************************************************
1830   reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1831 ****************************************************************************/
1832 int reply_findnclose(connection_struct *conn, 
1833                      char *inbuf,char *outbuf,int length,int bufsize)
1834 {
1835         int outsize = 0;
1836         int dptr_num= -1;
1837         
1838         dptr_num = SVAL(inbuf,smb_vwv0);
1839
1840         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
1841
1842         /* We never give out valid handles for a 
1843            findnotifyfirst - so any dptr_num is ok here. 
1844            Just ignore it. */
1845
1846         outsize = set_message(outbuf,0,0,True);
1847
1848         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
1849
1850         return(outsize);
1851 }
1852
1853
1854 /****************************************************************************
1855   reply to a SMBtranss2 - just ignore it!
1856 ****************************************************************************/
1857 int reply_transs2(connection_struct *conn,
1858                   char *inbuf,char *outbuf,int length,int bufsize)
1859 {
1860         DEBUG(4,("Ignoring transs2 of length %d\n",length));
1861         return(-1);
1862 }
1863
1864 /****************************************************************************
1865   reply to a SMBtrans2
1866 ****************************************************************************/
1867 int reply_trans2(connection_struct *conn,
1868                  char *inbuf,char *outbuf,int length,int bufsize)
1869 {
1870         int outsize = 0;
1871         unsigned int total_params = SVAL(inbuf, smb_tpscnt);
1872         unsigned int total_data =SVAL(inbuf, smb_tdscnt);
1873 #if 0
1874         unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
1875         unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
1876         unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
1877         BOOL close_tid = BITSETW(inbuf+smb_flags,0);
1878         BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
1879         int32 timeout = IVALS(inbuf,smb_timeout);
1880 #endif
1881         unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
1882         unsigned int tran_call = SVAL(inbuf, smb_setup0);
1883         char *params = NULL, *data = NULL;
1884         int num_params, num_params_sofar, num_data, num_data_sofar;
1885
1886         if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
1887                 /* Queue this open message as we are the process of an
1888                  * oplock break.  */
1889
1890                 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
1891                 DEBUGADD(2,( "in oplock break state.\n"));
1892
1893                 push_oplock_pending_smb_message(inbuf, length);
1894                 return -1;
1895         }
1896         
1897         outsize = set_message(outbuf,0,0,True);
1898
1899         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1900            is so as a sanity check */
1901         if (suwcnt != 1) {
1902                 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1903                 return(ERROR(ERRSRV,ERRerror));
1904         }
1905     
1906         /* Allocate the space for the maximum needed parameters and data */
1907         if (total_params > 0)
1908                 params = (char *)malloc(total_params);
1909         if (total_data > 0)
1910                 data = (char *)malloc(total_data);
1911   
1912         if ((total_params && !params)  || (total_data && !data)) {
1913                 DEBUG(2,("Out of memory in reply_trans2\n"));
1914                 return(ERROR(ERRDOS,ERRnomem));
1915         }
1916
1917         /* Copy the param and data bytes sent with this request into
1918            the params buffer */
1919         num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
1920         num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
1921
1922         if (num_params > total_params || num_data > total_data)
1923                 exit_server("invalid params in reply_trans2");
1924
1925         if(params)
1926                 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
1927         if(data)
1928                 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
1929
1930         if(num_data_sofar < total_data || num_params_sofar < total_params)  {
1931                 /* We need to send an interim response then receive the rest
1932                    of the parameter/data bytes */
1933                 outsize = set_message(outbuf,0,0,True);
1934                 send_smb(Client,outbuf);
1935
1936                 while (num_data_sofar < total_data || 
1937                        num_params_sofar < total_params) {
1938                         BOOL ret;
1939
1940                         ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
1941                                                SMB_SECONDARY_WAIT);
1942                         
1943                         if ((ret && 
1944                              (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
1945                                 outsize = set_message(outbuf,0,0,True);
1946                                 if(ret)
1947                                         DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
1948                                 else
1949                                         DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
1950                                                  (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
1951                                 if(params)
1952                                         free(params);
1953                                 if(data)
1954                                         free(data);
1955                                 return(ERROR(ERRSRV,ERRerror));
1956                         }
1957       
1958                         /* Revise total_params and total_data in case
1959                            they have changed downwards */
1960                         total_params = SVAL(inbuf, smb_tpscnt);
1961                         total_data = SVAL(inbuf, smb_tdscnt);
1962                         num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
1963                         num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
1964                         if (num_params_sofar > total_params || num_data_sofar > total_data)
1965                                 exit_server("data overflow in trans2");
1966                         
1967                         memcpy( &params[ SVAL(inbuf, smb_spsdisp)], 
1968                                 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
1969                         memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
1970                                 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
1971                 }
1972         }
1973         
1974         if (Protocol >= PROTOCOL_NT1) {
1975                 uint16 flg2 = SVAL(outbuf,smb_flg2);
1976                 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1977         }
1978
1979         /* Now we must call the relevant TRANS2 function */
1980         switch(tran_call)  {
1981         case TRANSACT2_OPEN:
1982                 outsize = call_trans2open(conn, 
1983                                           inbuf, outbuf, bufsize, 
1984                                           &params, &data);
1985                 break;
1986
1987         case TRANSACT2_FINDFIRST:
1988                 outsize = call_trans2findfirst(conn, inbuf, outbuf, 
1989                                                bufsize, &params, &data);
1990                 break;
1991
1992         case TRANSACT2_FINDNEXT:
1993                 outsize = call_trans2findnext(conn, inbuf, outbuf, 
1994                                               length, bufsize, 
1995                                               &params, &data);
1996                 break;
1997
1998         case TRANSACT2_QFSINFO:
1999             outsize = call_trans2qfsinfo(conn, inbuf, outbuf, 
2000                                          length, bufsize, &params, 
2001                                          &data);
2002             break;
2003
2004         case TRANSACT2_SETFSINFO:
2005                 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, 
2006                                                length, bufsize, 
2007                                                &params, &data);
2008                 break;
2009
2010         case TRANSACT2_QPATHINFO:
2011         case TRANSACT2_QFILEINFO:
2012                 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, 
2013                                                    length, bufsize, 
2014                                                    &params, &data, total_data);
2015                 break;
2016         case TRANSACT2_SETPATHINFO:
2017         case TRANSACT2_SETFILEINFO:
2018                 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, 
2019                                                      length, bufsize, 
2020                                                      &params, &data, 
2021                                                      total_data);
2022                 break;
2023
2024         case TRANSACT2_FINDNOTIFYFIRST:
2025                 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, 
2026                                                      length, bufsize, 
2027                                                      &params, &data);
2028                 break;
2029
2030         case TRANSACT2_FINDNOTIFYNEXT:
2031                 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, 
2032                                                     length, bufsize, 
2033                                                     &params, &data);
2034                 break;
2035         case TRANSACT2_MKDIR:
2036                 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, 
2037                                            bufsize, &params, &data);
2038                 break;
2039         default:
2040                 /* Error in request */
2041                 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2042                 if(params)
2043                         free(params);
2044                 if(data)
2045                         free(data);
2046                 return (ERROR(ERRSRV,ERRerror));
2047         }
2048         
2049         /* As we do not know how many data packets will need to be
2050            returned here the various call_trans2xxxx calls
2051            must send their own. Thus a call_trans2xxx routine only
2052            returns a value other than -1 when it wants to send
2053            an error packet. 
2054         */
2055         
2056         if(params)
2057                 free(params);
2058         if(data)
2059                 free(data);
2060         return outsize; /* If a correct response was needed the
2061                            call_trans2xxx calls have already sent
2062                            it. If outsize != -1 then it is returning */
2063 }