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