converted a bunch more trans2 calls for unicode. This got quite tricky :(
[sfrench/samba-autobuild/.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
26 extern int DEBUGLEVEL;
27 extern int Protocol;
28 extern BOOL case_sensitive;
29 extern int smb_read_error;
30 extern fstring local_machine;
31 extern int global_oplock_break;
32 extern uint32 global_client_caps;
33
34 /****************************************************************************
35   Send the required number of replies back.
36   We assume all fields other than the data fields are
37   set correctly for the type of call.
38   HACK ! Always assumes smb_setup field is zero.
39 ****************************************************************************/
40 static int send_trans2_replies(char *outbuf, int bufsize, char *params, 
41                                int paramsize, char *pdata, int datasize)
42 {
43   /* As we are using a protocol > LANMAN1 then the max_send
44      variable must have been set in the sessetupX call.
45      This takes precedence over the max_xmit field in the
46      global struct. These different max_xmit variables should
47      be merged as this is now too confusing */
48
49   extern int max_send;
50   int data_to_send = datasize;
51   int params_to_send = paramsize;
52   int useable_space;
53   char *pp = params;
54   char *pd = pdata;
55   int params_sent_thistime, data_sent_thistime, total_sent_thistime;
56   int alignment_offset = 3;
57   int data_alignment_offset = 0;
58
59   /* Initially set the wcnt area to be 10 - this is true for all
60      trans2 replies */
61   set_message(outbuf,10,0,True);
62
63   /* If there genuinely are no parameters or data to send just send
64      the empty packet */
65   if(params_to_send == 0 && data_to_send == 0)
66   {
67     send_smb(smbd_server_fd(),outbuf);
68     return 0;
69   }
70
71   /* When sending params and data ensure that both are nicely aligned */
72   /* Only do this alignment when there is also data to send - else
73      can cause NT redirector problems. */
74   if (((params_to_send % 4) != 0) && (data_to_send != 0))
75     data_alignment_offset = 4 - (params_to_send % 4);
76
77   /* Space is bufsize minus Netbios over TCP header minus SMB header */
78   /* The alignment_offset is to align the param bytes on an even byte
79      boundary. NT 4.0 Beta needs this to work correctly. */
80   useable_space = bufsize - ((smb_buf(outbuf)+
81                     alignment_offset+data_alignment_offset) - 
82                     outbuf);
83
84   /* useable_space can never be more than max_send minus the
85      alignment offset. */
86   useable_space = MIN(useable_space, 
87                       max_send - (alignment_offset+data_alignment_offset));
88
89
90   while (params_to_send || data_to_send)
91   {
92     /* Calculate whether we will totally or partially fill this packet */
93     total_sent_thistime = params_to_send + data_to_send + 
94                             alignment_offset + data_alignment_offset;
95     /* We can never send more than useable_space */
96     /*
97      * Note that 'useable_space' does not include the alignment offsets,
98      * but we must include the alignment offsets in the calculation of
99      * the length of the data we send over the wire, as the alignment offsets
100      * are sent here. Fix from Marc_Jacobsen@hp.com.
101      */
102     total_sent_thistime = MIN(total_sent_thistime, useable_space+
103                                 alignment_offset + data_alignment_offset);
104
105     set_message(outbuf, 10, total_sent_thistime, True);
106
107     /* Set total params and data to be sent */
108     SSVAL(outbuf,smb_tprcnt,paramsize);
109     SSVAL(outbuf,smb_tdrcnt,datasize);
110
111     /* Calculate how many parameters and data we can fit into
112        this packet. Parameters get precedence */
113
114     params_sent_thistime = MIN(params_to_send,useable_space);
115     data_sent_thistime = useable_space - params_sent_thistime;
116     data_sent_thistime = MIN(data_sent_thistime,data_to_send);
117
118     SSVAL(outbuf,smb_prcnt, params_sent_thistime);
119
120     /* smb_proff is the offset from the start of the SMB header to the
121        parameter bytes, however the first 4 bytes of outbuf are
122        the Netbios over TCP header. Thus use smb_base() to subtract
123        them from the calculation */
124
125     SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
126
127     if(params_sent_thistime == 0)
128       SSVAL(outbuf,smb_prdisp,0);
129     else
130       /* Absolute displacement of param bytes sent in this packet */
131       SSVAL(outbuf,smb_prdisp,pp - params);
132
133     SSVAL(outbuf,smb_drcnt, data_sent_thistime);
134     if(data_sent_thistime == 0)
135     {
136       SSVAL(outbuf,smb_droff,0);
137       SSVAL(outbuf,smb_drdisp, 0);
138     }
139     else
140     {
141       /* The offset of the data bytes is the offset of the
142          parameter bytes plus the number of parameters being sent this time */
143       SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) - 
144             smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
145       SSVAL(outbuf,smb_drdisp, pd - pdata);
146     }
147
148     /* Copy the param bytes into the packet */
149     if(params_sent_thistime)
150       memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
151     /* Copy in the data bytes */
152     if(data_sent_thistime)
153       memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
154              data_alignment_offset,pd,data_sent_thistime);
155
156     DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
157           params_sent_thistime, data_sent_thistime, useable_space));
158     DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
159           params_to_send, data_to_send, paramsize, datasize));
160
161     /* Send the packet */
162     send_smb(smbd_server_fd(),outbuf);
163
164     pp += params_sent_thistime;
165     pd += data_sent_thistime;
166
167     params_to_send -= params_sent_thistime;
168     data_to_send -= data_sent_thistime;
169
170     /* Sanity check */
171     if(params_to_send < 0 || data_to_send < 0)
172     {
173       DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
174             params_to_send, data_to_send));
175       return -1;
176     }
177   }
178
179   return 0;
180 }
181
182
183 /****************************************************************************
184   reply to a TRANSACT2_OPEN
185 ****************************************************************************/
186 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, 
187                            int bufsize,  
188                            char **pparams, char **ppdata)
189 {
190   char *params = *pparams;
191   int16 open_mode = SVAL(params, 2);
192   int16 open_attr = SVAL(params,6);
193   BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
194 #if 0
195   BOOL return_additional_info = BITSETW(params,0);
196   int16 open_sattr = SVAL(params, 4);
197   time_t open_time = make_unix_date3(params+8);
198 #endif
199   int16 open_ofun = SVAL(params,12);
200   int32 open_size = IVAL(params,14);
201   char *pname = &params[28];
202   pstring fname;
203   mode_t unixmode;
204   SMB_OFF_T size=0;
205   int fmode=0,mtime=0,rmode;
206   SMB_INO_T inode = 0;
207   SMB_STRUCT_STAT sbuf;
208   int smb_action = 0;
209   BOOL bad_path = False;
210   files_struct *fsp;
211
212   srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
213
214   DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
215            fname,open_mode, open_attr, open_ofun, open_size));
216
217   if (IS_IPC(conn)) {
218                 return(ERROR(ERRSRV,ERRaccess));
219   }
220
221   /* XXXX we need to handle passed times, sattr and flags */
222
223   unix_convert(fname,conn,0,&bad_path,&sbuf);
224     
225   if (!check_name(fname,conn))
226   {
227     if((errno == ENOENT) && bad_path)
228     {
229       unix_ERR_class = ERRDOS;
230       unix_ERR_code = ERRbadpath;
231     }
232     return(UNIXERROR(ERRDOS,ERRnoaccess));
233   }
234
235   unixmode = unix_mode(conn,open_attr | aARCH, fname);
236       
237   fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
238                    oplock_request, &rmode,&smb_action);
239       
240   if (!fsp)
241   {
242     if((errno == ENOENT) && bad_path)
243     {
244       unix_ERR_class = ERRDOS;
245       unix_ERR_code = ERRbadpath;
246     }
247     return(UNIXERROR(ERRDOS,ERRnoaccess));
248   }
249
250   size = sbuf.st_size;
251   fmode = dos_mode(conn,fname,&sbuf);
252   mtime = sbuf.st_mtime;
253   inode = sbuf.st_ino;
254   if (fmode & aDIR) {
255     close_file(fsp,False);
256     return(ERROR(ERRDOS,ERRnoaccess));
257   }
258
259   /* Realloc the size of parameters and data we will return */
260   params        = Realloc(*pparams, 28);
261   if( params == NULL ) {
262     return(ERROR(ERRDOS,ERRnomem));
263   }
264   *pparams      = params;
265
266   memset((char *)params,'\0',28);
267   SSVAL(params,0,fsp->fnum);
268   SSVAL(params,2,fmode);
269   put_dos_date2(params,4, mtime);
270   SIVAL(params,8, (uint32)size);
271   SSVAL(params,12,rmode);
272
273   if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
274     smb_action |= EXTENDED_OPLOCK_GRANTED;
275   }
276
277   SSVAL(params,18,smb_action);
278   /*
279    * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
280    */
281   SIVAL(params,20,inode);
282  
283   /* Send the required number of replies */
284   send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
285
286   return -1;
287 }
288
289 /*********************************************************
290 * Routine to check if a given string matches exactly.
291 * as a special case a mask of "." does NOT match. That
292 * is required for correct wildcard semantics
293 * Case can be significant or not.
294 **********************************************************/
295 static BOOL exact_match(char *str,char *mask, BOOL case_sig) 
296 {
297         if (mask[0] == '.' && mask[1] == 0) return False;
298         if (case_sig) return strcmp(str,mask)==0;
299         return strcasecmp(str,mask) == 0;
300 }
301
302 /****************************************************************************
303   get a level dependent lanman2 dir entry.
304 ****************************************************************************/
305 static BOOL get_lanman2_dir_entry(connection_struct *conn,
306                                   void *inbuf, void *outbuf,
307                                  char *path_mask,int dirtype,int info_level,
308                                  int requires_resume_key,
309                                  BOOL dont_descend,char **ppdata, 
310                                  char *base_data, int space_remaining, 
311                                  BOOL *out_of_space, BOOL *got_exact_match,
312                                  int *last_name_off)
313 {
314   char *dname;
315   BOOL found = False;
316   SMB_STRUCT_STAT sbuf;
317   pstring mask;
318   pstring pathreal;
319   pstring fname;
320   char *p, *q, *pdata = *ppdata;
321   uint32 reskey=0;
322   int prev_dirpos=0;
323   int mode=0;
324   SMB_OFF_T size = 0;
325   uint32 len;
326   time_t mdate=0, adate=0, cdate=0;
327   char *nameptr;
328   BOOL was_8_3;
329   int nt_extmode; /* Used for NT connections instead of mode */
330   BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
331
332   *fname = 0;
333   *out_of_space = False;
334   *got_exact_match = False;
335
336   if (!conn->dirptr)
337     return(False);
338
339   p = strrchr(path_mask,'/');
340   if(p != NULL)
341   {
342     if(p[1] == '\0')
343       pstrcpy(mask,"*.*");
344     else
345       pstrcpy(mask, p+1);
346   }
347   else
348     pstrcpy(mask, path_mask);
349
350   while (!found)
351   {
352     BOOL got_match;
353
354     /* Needed if we run out of space */
355     prev_dirpos = TellDir(conn->dirptr);
356     dname = ReadDirName(conn->dirptr);
357
358     /*
359      * Due to bugs in NT client redirectors we are not using
360      * resume keys any more - set them to zero.
361      * Check out the related comments in findfirst/findnext.
362      * JRA.
363      */
364
365     reskey = 0;
366
367     DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
368       (long)conn->dirptr,TellDir(conn->dirptr)));
369       
370     if (!dname) 
371       return(False);
372
373     pstrcpy(fname,dname);      
374
375     if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive))) {
376         got_match = mask_match(fname, mask, case_sensitive);
377     }
378
379     if(!got_match && !is_8_3(fname, False)) {
380
381       /*
382        * It turns out that NT matches wildcards against
383        * both long *and* short names. This may explain some
384        * of the wildcard wierdness from old DOS clients
385        * that some people have been seeing.... JRA.
386        */
387
388       pstring newname;
389       pstrcpy( newname, fname);
390       name_map_mangle( newname, True, False, SNUM(conn));
391       if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
392         got_match = mask_match(newname, mask, case_sensitive);
393     }
394
395     if(got_match)
396     {
397       BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
398       if (dont_descend && !isdots)
399         continue;
400           
401       pstrcpy(pathreal,conn->dirpath);
402       if(needslash)
403         pstrcat(pathreal,"/");
404       pstrcat(pathreal,dname);
405       if (vfs_stat(conn,pathreal,&sbuf) != 0) 
406       {
407         /* Needed to show the msdfs symlinks as directories */
408         if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn)) 
409            || !is_msdfs_link(conn, pathreal))
410           {
411             DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
412                      pathreal,strerror(errno)));
413             continue;
414           }
415         else
416           {
417             DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
418             sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
419           }
420       }
421
422       mode = dos_mode(conn,pathreal,&sbuf);
423
424       if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
425         DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
426         continue;
427       }
428
429       size = sbuf.st_size;
430       mdate = sbuf.st_mtime;
431       adate = sbuf.st_atime;
432       cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
433       if(mode & aDIR)
434         size = 0;
435
436       DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
437           
438       found = True;
439     }
440   }
441
442   name_map_mangle(fname,False,True,SNUM(conn));
443
444   p = pdata;
445   nameptr = p;
446
447   nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
448
449   switch (info_level)
450   {
451     case 1:
452       if(requires_resume_key) {
453         SIVAL(p,0,reskey);
454         p += 4;
455       }
456       put_dos_date2(p,l1_fdateCreation,cdate);
457       put_dos_date2(p,l1_fdateLastAccess,adate);
458       put_dos_date2(p,l1_fdateLastWrite,mdate);
459       SIVAL(p,l1_cbFile,(uint32)size);
460       SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
461       SSVAL(p,l1_attrFile,mode);
462       p += l1_achName;
463       nameptr = p;
464       len = srvstr_push(outbuf, p, fname, -1, 
465                         STR_TERMINATE|STR_CONVERT);
466       SCVAL(p, -1, len);
467       p += len;
468       break;
469
470     case 2:
471       /* info_level 2 */
472       if(requires_resume_key) {
473         SIVAL(p,0,reskey);
474         p += 4;
475       }
476       put_dos_date2(p,l2_fdateCreation,cdate);
477       put_dos_date2(p,l2_fdateLastAccess,adate);
478       put_dos_date2(p,l2_fdateLastWrite,mdate);
479       SIVAL(p,l2_cbFile,(uint32)size);
480       SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
481       SSVAL(p,l2_attrFile,mode);
482       SIVAL(p,l2_cbList,0); /* No extended attributes */
483       p += l2_achName;
484       nameptr = p;
485       len = srvstr_push(outbuf, p, fname, -1, 
486                         STR_TERMINATE|STR_CONVERT);
487       SCVAL(p, -1, len);
488       p += len;
489       break;
490
491     case 3:
492       SIVAL(p,0,reskey);
493       put_dos_date2(p,4,cdate);
494       put_dos_date2(p,8,adate);
495       put_dos_date2(p,12,mdate);
496       SIVAL(p,16,(uint32)size);
497       SIVAL(p,20,SMB_ROUNDUP(size,1024));
498       SSVAL(p,24,mode);
499       SIVAL(p,26,4);
500       p += 31;
501       nameptr = p;
502       len = srvstr_push(outbuf, p, fname, -1, 
503                         STR_TERMINATE|STR_CONVERT);
504       SCVAL(p, -1, len);
505       p += len;
506       break;
507
508     case 4:
509       if(requires_resume_key) {
510         SIVAL(p,0,reskey);
511         p += 4;
512       }
513       q = p;
514       put_dos_date2(p,4,cdate);
515       put_dos_date2(p,8,adate);
516       put_dos_date2(p,12,mdate);
517       SIVAL(p,16,(uint32)size);
518       SIVAL(p,20,SMB_ROUNDUP(size,1024));
519       SSVAL(p,24,mode);
520       p += 33;
521       nameptr = p;
522       len = srvstr_push(outbuf, p, fname, -1, 
523                         STR_TERMINATE|STR_CONVERT);
524       SCVAL(p, -1, len);
525       p += len;
526       SIVAL(q,4,PTR_DIFF(p, q));
527
528       break;
529
530     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
531       was_8_3 = is_8_3(fname, True);
532       p += 4;
533       SIVAL(p,0,reskey); p += 4;
534       put_long_date(p,cdate); p += 8;
535       put_long_date(p,adate); p += 8;
536       put_long_date(p,mdate); p += 8;
537       put_long_date(p,mdate); p += 8;
538       SOFF_T(p,0,size);
539       SOFF_T(p,8,size);
540       p += 16;
541       SIVAL(p,0,nt_extmode); p += 4;
542       q = p; p += 4;
543       SIVAL(p,0,0); p += 4;
544       if (!was_8_3) {
545               pstring mangled_name;
546               pstrcpy(mangled_name, fname);
547               name_map_mangle(mangled_name,True,True,SNUM(conn));
548               mangled_name[12] = 0;
549               len = srvstr_push(outbuf, p+2, mangled_name, 24, 
550                                 STR_CONVERT|STR_UPPER);
551               SSVAL(p, 0, len);
552       } else {
553               SSVAL(p,0,0);
554               *(p+2) = 0;
555       }
556       p += 2 + 24;
557       len = srvstr_push(outbuf, p, fname, -1, 
558                         STR_TERMINATE|STR_CONVERT);
559       SIVAL(q,0,len);
560       p += len;
561       len = PTR_DIFF(p, pdata);
562       len = (len + 3) & ~3;
563       SIVAL(pdata,0,len);
564       p = pdata + len;
565       break;
566
567     case SMB_FIND_FILE_DIRECTORY_INFO:
568       p += 4;
569       SIVAL(p,0,reskey); p += 4;
570       put_long_date(p,cdate); p += 8;
571       put_long_date(p,adate); p += 8;
572       put_long_date(p,mdate); p += 8;
573       put_long_date(p,mdate); p += 8;
574       SOFF_T(p,0,size);
575       SOFF_T(p,8,size);
576       p += 16;
577       SIVAL(p,0,nt_extmode); p += 4;
578       p += 4;
579       len = srvstr_push(outbuf, p, fname, -1, 
580                         STR_TERMINATE|STR_CONVERT);
581       SIVAL(p, -4, len);
582       p += len;
583       len = PTR_DIFF(p, pdata);
584       len = (len + 3) & ~3;
585       SIVAL(pdata,0,len);
586       p = pdata + len;
587       break;
588       
589       
590     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
591       p += 4;
592       SIVAL(p,0,reskey); p += 4;
593       put_long_date(p,cdate); p += 8;
594       put_long_date(p,adate); p += 8;
595       put_long_date(p,mdate); p += 8;
596       put_long_date(p,mdate); p += 8;
597       SOFF_T(p,0,size); 
598       SOFF_T(p,8,size);
599       p += 16;
600       SIVAL(p,0,nt_extmode); p += 4;
601       p += 4;
602       SIVAL(p,0,0); p += 4;
603
604       len = srvstr_push(outbuf, p, fname, -1, 
605                         STR_TERMINATE|STR_CONVERT);
606       SIVAL(p, -4, len);
607       p += len;
608
609       len = PTR_DIFF(p, pdata);
610       len = (len + 3) & ~3;
611       SIVAL(pdata,0,len);
612       p = pdata + len;
613       break;
614
615     case SMB_FIND_FILE_NAMES_INFO:
616       p += 4;
617       SIVAL(p,0,reskey); p += 4;
618       p += 4;
619       len = srvstr_push(outbuf, p, fname, -1, 
620                         STR_TERMINATE|STR_CONVERT);
621       SIVAL(p, -4, len);
622       p += len;
623       len = PTR_DIFF(p, pdata);
624       len = (len + 3) & ~3;
625       SIVAL(pdata,0,len);
626       p = pdata + len;
627       break;
628
629     default:      
630       return(False);
631     }
632
633
634   if (PTR_DIFF(p,pdata) > space_remaining) {
635     /* Move the dirptr back to prev_dirpos */
636     SeekDir(conn->dirptr, prev_dirpos);
637     *out_of_space = True;
638     DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
639     return False; /* Not finished - just out of space */
640   }
641
642   /* Setup the last_filename pointer, as an offset from base_data */
643   *last_name_off = PTR_DIFF(nameptr,base_data);
644   /* Advance the data pointer to the next slot */
645   *ppdata = p;
646
647   return(found);
648 }
649   
650
651 /****************************************************************************
652  Reply to a TRANS2_FINDFIRST.
653 ****************************************************************************/
654
655 static int call_trans2findfirst(connection_struct *conn,
656                                 char *inbuf, char *outbuf, int bufsize,  
657                                 char **pparams, char **ppdata)
658 {
659   /* We must be careful here that we don't return more than the
660      allowed number of data bytes. If this means returning fewer than
661      maxentries then so be it. We assume that the redirector has
662      enough room for the fixed number of parameter bytes it has
663      requested. */
664   uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
665   char *params = *pparams;
666   char *pdata = *ppdata;
667   int dirtype = SVAL(params,0);
668   int maxentries = SVAL(params,2);
669   BOOL close_after_first = BITSETW(params+4,0);
670   BOOL close_if_end = BITSETW(params+4,1);
671   BOOL requires_resume_key = BITSETW(params+4,2);
672   int info_level = SVAL(params,6);
673   pstring directory;
674   pstring mask;
675   char *p, *wcard;
676   int last_name_off=0;
677   int dptr_num = -1;
678   int numentries = 0;
679   int i;
680   BOOL finished = False;
681   BOOL dont_descend = False;
682   BOOL out_of_space = False;
683   int space_remaining;
684   BOOL bad_path = False;
685   SMB_STRUCT_STAT sbuf;
686
687   *directory = *mask = 0;
688
689   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",
690            dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
691            info_level, max_data_bytes));
692   
693   switch (info_level) 
694     {
695     case 1:
696     case 2:
697     case 3:
698     case 4:
699     case SMB_FIND_FILE_DIRECTORY_INFO:
700     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
701     case SMB_FIND_FILE_NAMES_INFO:
702     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
703       break;
704     default:
705       return(ERROR(ERRDOS,ERRunknownlevel));
706     }
707
708   srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
709
710   RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
711
712   unix_convert(directory,conn,0,&bad_path,&sbuf);
713   if(!check_name(directory,conn)) {
714     if((errno == ENOENT) && bad_path)
715     {
716       unix_ERR_class = ERRDOS;
717       unix_ERR_code = ERRbadpath;
718     }
719
720 #if 0
721     /* Ugly - NT specific hack - maybe not needed ? (JRA) */
722     if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && 
723        (get_remote_arch() == RA_WINNT))
724     {
725       unix_ERR_class = ERRDOS;
726       unix_ERR_code = ERRbaddirectory;
727     }
728 #endif 
729
730     return(UNIXERROR(ERRDOS,ERRbadpath));
731   }
732
733   p = strrchr(directory,'/');
734   if(p == NULL) {
735     pstrcpy(mask,directory);
736     pstrcpy(directory,"./");
737   } else {
738     pstrcpy(mask,p+1);
739     *p = 0;
740   }
741
742   DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
743
744   pdata = Realloc(*ppdata, max_data_bytes + 1024);
745   if( pdata == NULL ) {
746     return(ERROR(ERRDOS,ERRnomem));
747   }
748   *ppdata       = pdata;
749   memset((char *)pdata,'\0',max_data_bytes + 1024);
750
751   /* Realloc the params space */
752   params = Realloc(*pparams, 10);
753   if( params == NULL ) {
754     return(ERROR(ERRDOS,ERRnomem));
755   }
756   *pparams      = params;
757
758   dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
759   if (dptr_num < 0)
760     return(UNIXERROR(ERRDOS,ERRbadfile));
761
762   /* Save the wildcard match and attribs we are using on this directory - 
763      needed as lanman2 assumes these are being saved between calls */
764
765   if(!(wcard = strdup(mask))) {
766     dptr_close(&dptr_num);
767     return(ERROR(ERRDOS,ERRnomem));
768   }
769
770   dptr_set_wcard(dptr_num, wcard);
771   dptr_set_attr(dptr_num, dirtype);
772
773   DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
774
775   /* We don't need to check for VOL here as this is returned by 
776      a different TRANS2 call. */
777   
778   DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
779            conn->dirpath,lp_dontdescend(SNUM(conn))));
780   if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
781     dont_descend = True;
782     
783   p = pdata;
784   space_remaining = max_data_bytes;
785   out_of_space = False;
786
787   for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
788   {
789     BOOL got_exact_match = False;
790
791     /* this is a heuristic to avoid seeking the dirptr except when 
792        absolutely necessary. It allows for a filename of about 40 chars */
793     if (space_remaining < DIRLEN_GUESS && numentries > 0)
794     {
795       out_of_space = True;
796       finished = False;
797     }
798     else
799     {
800       finished = !get_lanman2_dir_entry(conn,
801                                         inbuf, outbuf,
802                                         mask,dirtype,info_level,
803                                         requires_resume_key,dont_descend,
804                                         &p,pdata,space_remaining, &out_of_space, &got_exact_match,
805                                         &last_name_off);
806     }
807
808     if (finished && out_of_space)
809       finished = False;
810
811     if (!finished && !out_of_space)
812       numentries++;
813
814     /*
815      * As an optimisation if we know we aren't looking
816      * for a wildcard name (ie. the name matches the wildcard exactly)
817      * then we can finish on any (first) match.
818      * This speeds up large directory searches. JRA.
819      */
820
821     if(got_exact_match)
822       finished = True;
823
824     space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
825   }
826   
827   /* Check if we can close the dirptr */
828   if(close_after_first || (finished && close_if_end))
829   {
830     DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
831     dptr_close(&dptr_num);
832   }
833
834   /* 
835    * If there are no matching entries we must return ERRDOS/ERRbadfile - 
836    * from observation of NT.
837    */
838
839   if(numentries == 0)
840   {
841     dptr_close(&dptr_num);
842     return(ERROR(ERRDOS,ERRbadfile));
843   }
844
845   /* At this point pdata points to numentries directory entries. */
846
847   /* Set up the return parameter block */
848   SSVAL(params,0,dptr_num);
849   SSVAL(params,2,numentries);
850   SSVAL(params,4,finished);
851   SSVAL(params,6,0); /* Never an EA error */
852   SSVAL(params,8,last_name_off);
853
854   send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
855
856   if ((! *directory) && dptr_path(dptr_num))
857     slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
858
859   DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
860             smb_fn_name(CVAL(inbuf,smb_com)), 
861             mask, directory, dirtype, numentries ) );
862
863   /* 
864    * Force a name mangle here to ensure that the
865    * mask as an 8.3 name is top of the mangled cache.
866    * The reasons for this are subtle. Don't remove
867    * this code unless you know what you are doing
868    * (see PR#13758). JRA.
869    */
870
871   if(!is_8_3( mask, False))
872     name_map_mangle(mask, True, True, SNUM(conn));
873
874   return(-1);
875 }
876
877
878 /****************************************************************************
879   reply to a TRANS2_FINDNEXT
880 ****************************************************************************/
881 static int call_trans2findnext(connection_struct *conn, 
882                                char *inbuf, char *outbuf, 
883                                int length, int bufsize,
884                                char **pparams, char **ppdata)
885 {
886   /* We must be careful here that we don't return more than the
887      allowed number of data bytes. If this means returning fewer than
888      maxentries then so be it. We assume that the redirector has
889      enough room for the fixed number of parameter bytes it has
890      requested. */
891   int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
892   char *params = *pparams;
893   char *pdata = *ppdata;
894   int dptr_num = SVAL(params,0);
895   int maxentries = SVAL(params,2);
896   uint16 info_level = SVAL(params,4);
897   uint32 resume_key = IVAL(params,6);
898   BOOL close_after_request = BITSETW(params+10,0);
899   BOOL close_if_end = BITSETW(params+10,1);
900   BOOL requires_resume_key = BITSETW(params+10,2);
901   BOOL continue_bit = BITSETW(params+10,3);
902   pstring resume_name;
903   pstring mask;
904   pstring directory;
905   char *p;
906   uint16 dirtype;
907   int numentries = 0;
908   int i, last_name_off=0;
909   BOOL finished = False;
910   BOOL dont_descend = False;
911   BOOL out_of_space = False;
912   int space_remaining;
913
914   *mask = *directory = *resume_name = 0;
915
916   srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE|STR_CONVERT);
917
918   DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
919 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
920 resume_key = %d resume name = %s continue=%d level = %d\n",
921            dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
922            requires_resume_key, resume_key, resume_name, continue_bit, info_level));
923
924   switch (info_level) 
925     {
926     case 1:
927     case 2:
928     case 3:
929     case 4:
930     case SMB_FIND_FILE_DIRECTORY_INFO:
931     case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
932     case SMB_FIND_FILE_NAMES_INFO:
933     case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
934       break;
935     default:
936       return(ERROR(ERRDOS,ERRunknownlevel));
937     }
938
939   pdata = Realloc( *ppdata, max_data_bytes + 1024);
940   if(pdata == NULL) {
941     return(ERROR(ERRDOS,ERRnomem));
942   }
943   *ppdata       = pdata;
944   memset((char *)pdata,'\0',max_data_bytes + 1024);
945
946   /* Realloc the params space */
947   params = Realloc(*pparams, 6*SIZEOFWORD);
948   if( params == NULL ) {
949     return(ERROR(ERRDOS,ERRnomem));
950   }
951   *pparams      = params;
952
953   /* Check that the dptr is valid */
954   if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
955     return(ERROR(ERRDOS,ERRnofiles));
956
957   string_set(&conn->dirpath,dptr_path(dptr_num));
958
959   /* Get the wildcard mask from the dptr */
960   if((p = dptr_wcard(dptr_num))== NULL) {
961     DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
962     return (ERROR(ERRDOS,ERRnofiles));
963   }
964   pstrcpy(mask, p);
965   pstrcpy(directory,conn->dirpath);
966
967   /* Get the attr mask from the dptr */
968   dirtype = dptr_attr(dptr_num);
969
970   DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
971            dptr_num, mask, dirtype, 
972            (long)conn->dirptr,
973            TellDir(conn->dirptr)));
974
975   /* We don't need to check for VOL here as this is returned by 
976      a different TRANS2 call. */
977
978   DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
979   if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
980     dont_descend = True;
981     
982   p = pdata;
983   space_remaining = max_data_bytes;
984   out_of_space = False;
985
986   /* 
987    * Seek to the correct position. We no longer use the resume key but
988    * depend on the last file name instead.
989    */
990   if(requires_resume_key && *resume_name && !continue_bit)
991   {
992     /*
993      * Fix for NT redirector problem triggered by resume key indexes
994      * changing between directory scans. We now return a resume key of 0
995      * and instead look for the filename to continue from (also given
996      * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
997      * findfirst/findnext (as is usual) then the directory pointer
998      * should already be at the correct place. Check this by scanning
999      * backwards looking for an exact (ie. case sensitive) filename match. 
1000      * If we get to the beginning of the directory and haven't found it then scan
1001      * forwards again looking for a match. JRA.
1002      */
1003
1004     int current_pos, start_pos;
1005     char *dname = NULL;
1006     void *dirptr = conn->dirptr;
1007     start_pos = TellDir(dirptr);
1008     for(current_pos = start_pos; current_pos >= 0; current_pos--)
1009     {
1010       DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1011
1012       SeekDir(dirptr, current_pos);
1013       dname = ReadDirName(dirptr);
1014
1015       /*
1016        * Remember, name_map_mangle is called by
1017        * get_lanman2_dir_entry(), so the resume name
1018        * could be mangled. Ensure we do the same
1019        * here.
1020        */
1021
1022       if(dname != NULL)
1023         name_map_mangle( dname, False, True, SNUM(conn));
1024
1025       if(dname && strcsequal( resume_name, dname))
1026       {
1027         SeekDir(dirptr, current_pos+1);
1028         DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1029         break;
1030       }
1031     }
1032
1033     /*
1034      * Scan forward from start if not found going backwards.
1035      */
1036
1037     if(current_pos < 0)
1038     {
1039       DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1040       SeekDir(dirptr, start_pos);
1041       for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1042       {
1043         /*
1044          * Remember, name_map_mangle is called by
1045          * get_lanman2_dir_entry(), so the resume name
1046          * could be mangled. Ensure we do the same
1047          * here.
1048          */
1049
1050         if(dname != NULL)
1051           name_map_mangle( dname, False, True, SNUM(conn));
1052
1053         if(dname && strcsequal( resume_name, dname))
1054         {
1055           SeekDir(dirptr, current_pos+1);
1056           DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1057           break;
1058         }
1059       } /* end for */
1060     } /* end if current_pos */
1061   } /* end if requires_resume_key && !continue_bit */
1062
1063   for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1064   {
1065     BOOL got_exact_match = False;
1066
1067     /* this is a heuristic to avoid seeking the dirptr except when 
1068        absolutely necessary. It allows for a filename of about 40 chars */
1069     if (space_remaining < DIRLEN_GUESS && numentries > 0)
1070     {
1071       out_of_space = True;
1072       finished = False;
1073     }
1074     else
1075     {
1076       finished = !get_lanman2_dir_entry(conn,
1077                                         inbuf, outbuf,
1078                                         mask,dirtype,info_level,
1079                                         requires_resume_key,dont_descend,
1080                                         &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1081                                         &last_name_off);
1082     }
1083
1084     if (finished && out_of_space)
1085       finished = False;
1086
1087     if (!finished && !out_of_space)
1088       numentries++;
1089
1090     /*
1091      * As an optimisation if we know we aren't looking
1092      * for a wildcard name (ie. the name matches the wildcard exactly)
1093      * then we can finish on any (first) match.
1094      * This speeds up large directory searches. JRA.
1095      */
1096
1097     if(got_exact_match)
1098       finished = True;
1099
1100     space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1101   }
1102   
1103   /* Check if we can close the dirptr */
1104   if(close_after_request || (finished && close_if_end))
1105   {
1106     DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1107     dptr_close(&dptr_num); /* This frees up the saved mask */
1108   }
1109
1110
1111   /* Set up the return parameter block */
1112   SSVAL(params,0,numentries);
1113   SSVAL(params,2,finished);
1114   SSVAL(params,4,0); /* Never an EA error */
1115   SSVAL(params,6,last_name_off);
1116
1117   send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1118
1119   if ((! *directory) && dptr_path(dptr_num))
1120     slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1121
1122   DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1123             smb_fn_name(CVAL(inbuf,smb_com)), 
1124             mask, directory, dirtype, numentries ) );
1125
1126   return(-1);
1127 }
1128
1129 /****************************************************************************
1130   reply to a TRANS2_QFSINFO (query filesystem info)
1131 ****************************************************************************/
1132
1133 static int call_trans2qfsinfo(connection_struct *conn, 
1134                               char *inbuf, char *outbuf, 
1135                               int length, int bufsize,
1136                               char **pparams, char **ppdata)
1137 {
1138   int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1139   char *pdata = *ppdata;
1140   char *params = *pparams;
1141   uint16 info_level = SVAL(params,0);
1142   int data_len, len;
1143   SMB_STRUCT_STAT st;
1144   char *vname = volume_label(SNUM(conn));
1145   int snum = SNUM(conn);
1146   char *fstype = lp_fstype(SNUM(conn));
1147
1148   DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1149
1150   if(vfs_stat(conn,".",&st)!=0) {
1151     DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1152     return (ERROR(ERRSRV,ERRinvdevice));
1153   }
1154
1155   pdata = Realloc(*ppdata, max_data_bytes + 1024);
1156   if ( pdata == NULL ) {
1157     return(ERROR(ERRDOS,ERRnomem));
1158   }
1159   *ppdata       = pdata;
1160   memset((char *)pdata,'\0',max_data_bytes + 1024);
1161
1162   switch (info_level) 
1163   {
1164     case 1:
1165     {
1166       SMB_BIG_UINT dfree,dsize,bsize;
1167       data_len = 18;
1168       conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);     
1169       SIVAL(pdata,l1_idFileSystem,st.st_dev);
1170       SIVAL(pdata,l1_cSectorUnit,bsize/512);
1171       SIVAL(pdata,l1_cUnit,dsize);
1172       SIVAL(pdata,l1_cUnitAvail,dfree);
1173       SSVAL(pdata,l1_cbSector,512);
1174       DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1175                  (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1176          (unsigned int)dfree, 512));
1177       break;
1178     }
1179     case 2:
1180             /* Return volume name */
1181             /* 
1182              * Add volume serial number - hash of a combination of
1183              * the called hostname and the service name.
1184              */
1185             SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1186             len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, 
1187                               STR_TERMINATE|STR_CONVERT);
1188             SCVAL(pdata,l2_vol_cch,len);
1189             data_len = l2_vol_szVolLabel + len;
1190             DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1191                      (unsigned)st.st_ctime, len, vname));
1192             break;
1193
1194     case SMB_QUERY_FS_ATTRIBUTE_INFO:
1195             SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1196                   FILE_DEVICE_IS_MOUNTED|
1197                   (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1198             SIVAL(pdata,4,128); /* Max filename component length */
1199             len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE|STR_CONVERT);
1200             SIVAL(pdata,8,len);
1201             data_len = 12 + len;
1202             break;
1203
1204     case SMB_QUERY_FS_LABEL_INFO:
1205             len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE|STR_CONVERT);
1206             data_len = 4 + len;
1207             SIVAL(pdata,0,len);
1208             break;
1209     case SMB_QUERY_FS_VOLUME_INFO:      
1210             /* 
1211              * Add volume serial number - hash of a combination of
1212              * the called hostname and the service name.
1213              */
1214             SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ 
1215                   (str_checksum(local_machine)<<16));
1216
1217             len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE|STR_CONVERT);
1218             SIVAL(pdata,12,len);
1219             data_len = 18+len;
1220             DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", 
1221                      (int)strlen(vname),vname));
1222             break;
1223     case SMB_QUERY_FS_SIZE_INFO:
1224     {
1225       SMB_BIG_UINT dfree,dsize,bsize;
1226       data_len = 24;
1227       conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);     
1228       SBIG_UINT(pdata,0,dsize);
1229       SBIG_UINT(pdata,8,dfree);
1230       SIVAL(pdata,16,bsize/512);
1231       SIVAL(pdata,20,512);
1232       break;
1233     }
1234     case SMB_QUERY_FS_DEVICE_INFO:
1235       data_len = 8;
1236       SIVAL(pdata,0,0); /* dev type */
1237       SIVAL(pdata,4,0); /* characteristics */
1238       break;
1239     case SMB_MAC_QUERY_FS_INFO:
1240             /*
1241              * Thursby MAC extension... ONLY on NTFS filesystems
1242              * once we do streams then we don't need this
1243              */
1244             if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1245                     data_len = 88;
1246                     SIVAL(pdata,84,0x100); /* Don't support mac... */
1247                     break;
1248             }
1249             /* drop through */
1250   default:
1251           return(ERROR(ERRDOS,ERRunknownlevel));
1252   }
1253
1254
1255   send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1256
1257   DEBUG( 4, ( "%s info_level = %d\n",
1258             smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1259
1260   return -1;
1261 }
1262
1263 /****************************************************************************
1264   reply to a TRANS2_SETFSINFO (set filesystem info)
1265 ****************************************************************************/
1266 static int call_trans2setfsinfo(connection_struct *conn,
1267                                 char *inbuf, char *outbuf, int length, 
1268                                 int bufsize,
1269                                 char **pparams, char **ppdata)
1270 {
1271   /* Just say yes we did it - there is nothing that
1272      can be set here so it doesn't matter. */
1273   int outsize;
1274   DEBUG(3,("call_trans2setfsinfo\n"));
1275
1276   if (!CAN_WRITE(conn))
1277     return(ERROR(ERRSRV,ERRaccess));
1278
1279   outsize = set_message(outbuf,10,0,True);
1280
1281   return outsize;
1282 }
1283
1284 /****************************************************************************
1285   Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1286   file name or file id).
1287 ****************************************************************************/
1288
1289 static int call_trans2qfilepathinfo(connection_struct *conn,
1290                                     char *inbuf, char *outbuf, int length, 
1291                                     int bufsize,
1292                                     char **pparams,char **ppdata,
1293                                     int total_data)
1294 {
1295   int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1296   char *params = *pparams;
1297   char *pdata = *ppdata;
1298   uint16 tran_call = SVAL(inbuf, smb_setup0);
1299   uint16 info_level;
1300   int mode=0;
1301   SMB_OFF_T size=0;
1302   unsigned int data_size;
1303   SMB_STRUCT_STAT sbuf;
1304   pstring fname;
1305   char *base_name;
1306   char *p;
1307   SMB_OFF_T pos = 0;
1308   BOOL bad_path = False;
1309   BOOL delete_pending = False;
1310   int len;
1311
1312   if (tran_call == TRANSACT2_QFILEINFO) {
1313           files_struct *fsp = file_fsp(params,0);
1314           info_level = SVAL(params,2);
1315
1316           DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", 
1317                    info_level));
1318
1319           if(fsp && (fsp->is_directory || fsp->stat_open)) {
1320                   /*
1321                    * This is actually a QFILEINFO on a directory
1322                    * handle (returned from an NT SMB). NT5.0 seems
1323                    * to do this call. JRA.
1324                    */
1325                   pstrcpy(fname, fsp->fsp_name);
1326                   unix_convert(fname,conn,0,&bad_path,&sbuf);
1327                   if (!check_name(fname,conn) || 
1328                       (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1329                           DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1330                           if((errno == ENOENT) && bad_path) {
1331                                   unix_ERR_class = ERRDOS;
1332                                   unix_ERR_code = ERRbadpath;
1333                           }
1334                           return(UNIXERROR(ERRDOS,ERRbadpath));
1335                   }
1336                   
1337                   delete_pending = fsp->directory_delete_on_close;
1338           } else {
1339                   /*
1340                    * Original code - this is an open file.
1341                    */
1342                   CHECK_FSP(fsp,conn);
1343                   CHECK_ERROR(fsp);
1344
1345                   pstrcpy(fname, fsp->fsp_name);
1346                   if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1347                           DEBUG(3,("fstat of fnum %d failed (%s)\n",
1348                                    fsp->fnum, strerror(errno)));
1349                           return(UNIXERROR(ERRDOS,ERRbadfid));
1350                   }
1351                   if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1352                           return(UNIXERROR(ERRDOS,ERRnoaccess));
1353
1354                   delete_pending = fsp->delete_on_close;
1355           }
1356   } else {
1357           /* qpathinfo */
1358           info_level = SVAL(params,0);
1359
1360           DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", 
1361                    info_level));
1362
1363           srvstr_pull(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE);
1364
1365           RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1366
1367           unix_convert(fname,conn,0,&bad_path,&sbuf);
1368           if (!check_name(fname,conn) || 
1369               (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1370                   DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1371                   if((errno == ENOENT) && bad_path) {
1372                           unix_ERR_class = ERRDOS;
1373                           unix_ERR_code = ERRbadpath;
1374                   }
1375                   return(UNIXERROR(ERRDOS,ERRbadpath));
1376           }
1377   }
1378
1379
1380   DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1381            fname,info_level,tran_call,total_data));
1382
1383   p = strrchr(fname,'/'); 
1384   if (!p) {
1385           base_name = fname;
1386   } else {
1387           base_name = p+1;
1388   }
1389
1390   mode = dos_mode(conn,fname,&sbuf);
1391   size = sbuf.st_size;
1392   if (mode & aDIR) size = 0;
1393
1394   params = Realloc(*pparams,2);
1395   if (params == NULL) {
1396           return(ERROR(ERRDOS,ERRnomem));
1397   }
1398   *pparams      = params;
1399   memset((char *)params,'\0',2);
1400   data_size = max_data_bytes + 1024;
1401   pdata = Realloc(*ppdata, data_size); 
1402   if ( pdata == NULL ) {
1403     return(ERROR(ERRDOS,ERRnomem));
1404   }
1405   *ppdata = pdata;
1406
1407   if (total_data > 0 && IVAL(pdata,0) == total_data) {
1408     /* uggh, EAs for OS2 */
1409     DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1410     return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1411   }
1412
1413   memset((char *)pdata,'\0',data_size);
1414
1415   switch (info_level) 
1416     {
1417     case SMB_INFO_STANDARD:
1418     case SMB_INFO_QUERY_EA_SIZE:
1419       data_size = (info_level==1?22:26);
1420       put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1421       put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1422       put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1423       SIVAL(pdata,l1_cbFile,(uint32)size);
1424       SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1425       SSVAL(pdata,l1_attrFile,mode);
1426       SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1427       break;
1428
1429     case SMB_INFO_QUERY_EAS_FROM_LIST:
1430       data_size = 24;
1431       put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1432       put_dos_date2(pdata,4,sbuf.st_atime);
1433       put_dos_date2(pdata,8,sbuf.st_mtime);
1434       SIVAL(pdata,12,(uint32)size);
1435       SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1436       SIVAL(pdata,20,mode);
1437       break;
1438
1439     case SMB_INFO_QUERY_ALL_EAS:
1440       data_size = 4;
1441       SIVAL(pdata,0,data_size);
1442       break;
1443
1444     case 6:
1445       return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */      
1446
1447     case SMB_QUERY_FILE_BASIC_INFO:
1448       data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1449       put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1450       put_long_date(pdata+8,sbuf.st_atime);
1451       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1452       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1453       SIVAL(pdata,32,mode);
1454
1455       DEBUG(5,("SMB_QFBI - "));
1456       {
1457         time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1458         DEBUG(5,("create: %s ", ctime(&create_time)));
1459       }
1460       DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1461       DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1462       DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1463       DEBUG(5,("mode: %x\n", mode));
1464
1465       break;
1466
1467     case SMB_QUERY_FILE_STANDARD_INFO:
1468       data_size = 22;
1469       SOFF_T(pdata,0,size);
1470       SOFF_T(pdata,8,size);
1471       SIVAL(pdata,16,sbuf.st_nlink);
1472       CVAL(pdata,20) = 0;
1473       CVAL(pdata,21) = (mode&aDIR)?1:0;
1474       break;
1475
1476     case SMB_QUERY_FILE_EA_INFO:
1477       data_size = 4;
1478       break;
1479
1480     /* Get the 8.3 name - used if NT SMB was negotiated. */
1481     case SMB_QUERY_FILE_ALT_NAME_INFO:
1482       {
1483         pstring short_name;
1484
1485         pstrcpy(short_name,base_name);
1486         /* Mangle if not already 8.3 */
1487         if(!is_8_3(short_name, True))
1488         {
1489           if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1490             *short_name = '\0';
1491         }
1492         len = srvstr_push(outbuf, pdata+4, short_name, -1, 
1493                           STR_TERMINATE|STR_CONVERT|STR_UPPER);
1494         data_size = 4 + len;
1495         SIVAL(pdata,0,len);
1496       }
1497       break;
1498
1499     case SMB_QUERY_FILE_NAME_INFO:
1500             /*
1501              * The first part of this code is essential
1502              * to get security descriptors to work on mapped
1503              * drives. Don't ask how I discovered this unless
1504              * you like hearing about me suffering.... :-). JRA.
1505              */
1506             if(strequal(".", fname)) {
1507                     len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE|STR_CONVERT);
1508             } else {
1509                     len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE|STR_CONVERT);
1510             }
1511             data_size = 4 + len;
1512             SIVAL(pdata,0,len);
1513             break;
1514
1515     case SMB_QUERY_FILE_ALLOCATION_INFO:
1516     case SMB_QUERY_FILE_END_OF_FILEINFO:
1517             data_size = 8;
1518             SOFF_T(pdata,0,size);
1519             break;
1520
1521     case SMB_QUERY_FILE_ALL_INFO:
1522       put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1523       put_long_date(pdata+8,sbuf.st_atime);
1524       put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1525       put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1526       SIVAL(pdata,32,mode);
1527       pdata += 40;
1528       SOFF_T(pdata,0,size);
1529       SOFF_T(pdata,8,size);
1530       SIVAL(pdata,16,sbuf.st_nlink);
1531       CVAL(pdata,20) = delete_pending;
1532       CVAL(pdata,21) = (mode&aDIR)?1:0;
1533       pdata += 24;
1534       SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); 
1535       pdata += 8; /* index number */
1536       pdata += 4; /* EA info */
1537       if (mode & aRONLY)
1538         SIVAL(pdata,0,0xA9);
1539       else
1540         SIVAL(pdata,0,0xd01BF);
1541       pdata += 4;
1542       SOFF_T(pdata,0,pos); /* current offset */
1543       pdata += 8;
1544       SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1545       pdata += 4;
1546       pdata += 4; /* alignment */
1547       len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE|STR_CONVERT);
1548       SIVAL(pdata,0,len);
1549       pdata += 4 + len;
1550       data_size = PTR_DIFF(pdata,(*ppdata));
1551       break;
1552
1553 #if 0
1554       /* NT4 server just returns "invalid query" to this - if we try to answer 
1555          it then NTws gets a BSOD! (tridge) */
1556     case SMB_QUERY_FILE_STREAM_INFO:
1557       SIVAL(pdata,0,pos);
1558       SIVAL(pdata,4,size);
1559       SIVAL(pdata,12,size);
1560       len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE|STR_CONVERT);
1561       SIVAL(pdata,20,len);
1562       data_size = 24 + len;
1563       break;
1564 #endif
1565
1566     default:
1567       return(ERROR(ERRDOS,ERRunknownlevel));
1568     }
1569
1570   send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1571
1572   return(-1);
1573 }
1574
1575 /****************************************************************************
1576   reply to a TRANS2_SETFILEINFO (set file info by fileid)
1577 ****************************************************************************/
1578 static int call_trans2setfilepathinfo(connection_struct *conn,
1579                                       char *inbuf, char *outbuf, int length, 
1580                                       int bufsize, char **pparams, 
1581                                       char **ppdata, int total_data)
1582 {
1583   char *params = *pparams;
1584   char *pdata = *ppdata;
1585   uint16 tran_call = SVAL(inbuf, smb_setup0);
1586   uint16 info_level;
1587   int mode=0;
1588   SMB_OFF_T size=0;
1589   struct utimbuf tvs;
1590   SMB_STRUCT_STAT sbuf;
1591   pstring fname1;
1592   char *fname;
1593   int fd = -1;
1594   BOOL bad_path = False;
1595   files_struct *fsp = NULL;
1596
1597   if (tran_call == TRANSACT2_SETFILEINFO) {
1598     fsp = file_fsp(params,0);
1599     info_level = SVAL(params,2);    
1600
1601     if(fsp && (fsp->is_directory || fsp->stat_open)) {
1602       /*
1603        * This is actually a SETFILEINFO on a directory
1604        * handle (returned from an NT SMB). NT5.0 seems
1605        * to do this call. JRA.
1606        */
1607       fname = fsp->fsp_name;
1608       unix_convert(fname,conn,0,&bad_path,&sbuf);
1609       if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1610         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1611         if((errno == ENOENT) && bad_path)
1612         {
1613           unix_ERR_class = ERRDOS;
1614           unix_ERR_code = ERRbadpath;
1615         }
1616         return(UNIXERROR(ERRDOS,ERRbadpath));
1617       }
1618     } else if (fsp->print_file) {
1619         /*
1620          * Doing a DELETE_ON_CLOSE should cancel a print job.
1621          */
1622         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1623           fsp->share_mode = FILE_DELETE_ON_CLOSE;
1624
1625           DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1626                fsp->fsp_name ));
1627
1628           SSVAL(params,0,0);
1629           send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1630           return(-1);
1631         }
1632     } else {
1633       /*
1634        * Original code - this is an open file.
1635        */
1636       CHECK_FSP(fsp,conn);
1637       CHECK_ERROR(fsp);
1638
1639       fname = fsp->fsp_name;
1640       fd = fsp->fd;
1641
1642       if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1643         DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1644         return(UNIXERROR(ERRDOS,ERRbadfid));
1645       }
1646     }
1647   } else {
1648     /* set path info */
1649     info_level = SVAL(params,0);    
1650     fname = fname1;
1651     pstrcpy(fname,&params[6]);
1652     unix_convert(fname,conn,0,&bad_path,&sbuf);
1653     if(!check_name(fname, conn))
1654     {
1655       if((errno == ENOENT) && bad_path)
1656       {
1657         unix_ERR_class = ERRDOS;
1658         unix_ERR_code = ERRbadpath;
1659       }
1660       return(UNIXERROR(ERRDOS,ERRbadpath));
1661     }
1662  
1663     if(!VALID_STAT(sbuf)) {
1664       DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1665       if((errno == ENOENT) && bad_path)
1666       {
1667         unix_ERR_class = ERRDOS;
1668         unix_ERR_code = ERRbadpath;
1669       }
1670       return(UNIXERROR(ERRDOS,ERRbadpath));
1671     }    
1672   }
1673
1674   if (!CAN_WRITE(conn))
1675     return(ERROR(ERRSRV,ERRaccess));
1676
1677   DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1678            tran_call,fname,info_level,total_data));
1679
1680   /* Realloc the parameter and data sizes */
1681   params = Realloc(*pparams,2);
1682   if(params == NULL) {
1683     return(ERROR(ERRDOS,ERRnomem));
1684   }
1685   *pparams      = params;
1686
1687   SSVAL(params,0,0);
1688
1689   size = sbuf.st_size;
1690   tvs.modtime = sbuf.st_mtime;
1691   tvs.actime = sbuf.st_atime;
1692   mode = dos_mode(conn,fname,&sbuf);
1693
1694   if (total_data > 0 && IVAL(pdata,0) == total_data) {
1695     /* uggh, EAs for OS2 */
1696     DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1697     return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1698   }
1699
1700   switch (info_level)
1701   {
1702     case SMB_INFO_STANDARD:
1703     case SMB_INFO_QUERY_EA_SIZE:
1704     {
1705       /* access time */
1706       tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1707
1708       /* write time */
1709       tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1710
1711       mode = SVAL(pdata,l1_attrFile);
1712       size = IVAL(pdata,l1_cbFile);
1713       break;
1714     }
1715
1716     /* XXXX um, i don't think this is right.
1717        it's also not in the cifs6.txt spec.
1718      */
1719     case SMB_INFO_QUERY_EAS_FROM_LIST:
1720       tvs.actime = make_unix_date2(pdata+8);
1721       tvs.modtime = make_unix_date2(pdata+12);
1722       size = IVAL(pdata,16);
1723       mode = IVAL(pdata,24);
1724       break;
1725
1726     /* XXXX nor this.  not in cifs6.txt, either. */
1727     case SMB_INFO_QUERY_ALL_EAS:
1728       tvs.actime = make_unix_date2(pdata+8);
1729       tvs.modtime = make_unix_date2(pdata+12);
1730       size = IVAL(pdata,16);
1731       mode = IVAL(pdata,24);
1732       break;
1733
1734     case SMB_SET_FILE_BASIC_INFO:
1735     {
1736       /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1737       time_t write_time;
1738       time_t changed_time;
1739
1740       /* Ignore create time at offset pdata. */
1741
1742       /* access time */
1743       tvs.actime = interpret_long_date(pdata+8);
1744
1745       write_time = interpret_long_date(pdata+16);
1746       changed_time = interpret_long_date(pdata+24);
1747
1748       tvs.modtime = MIN(write_time, changed_time);
1749
1750       /* Prefer a defined time to an undefined one. */
1751       if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1752        tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1753                       ? changed_time
1754                       : write_time);
1755
1756 #if 0 /* Needs more testing... */
1757       /* Test from Luke to prevent Win95 from
1758          setting incorrect values here.
1759        */
1760       if (tvs.actime < tvs.modtime)
1761         return(ERROR(ERRDOS,ERRnoaccess));
1762 #endif /* Needs more testing... */
1763
1764       /* attributes */
1765       mode = IVAL(pdata,32);
1766       break;
1767     }
1768
1769     /*
1770      * NT seems to use this call with a size of zero
1771      * to mean truncate the file. JRA.
1772      */
1773
1774     case SMB_SET_FILE_ALLOCATION_INFO:
1775     {
1776       SMB_OFF_T newsize = IVAL(pdata,0);
1777 #ifdef LARGE_SMB_OFF_T
1778       newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1779 #else /* LARGE_SMB_OFF_T */
1780       if (IVAL(pdata,4) != 0)   /* more than 32 bits? */
1781          return(ERROR(ERRDOS,ERRunknownlevel));
1782 #endif /* LARGE_SMB_OFF_T */
1783       DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1784       if(newsize == 0)
1785         size = 0;
1786       break;
1787     }
1788
1789     case SMB_SET_FILE_END_OF_FILE_INFO:
1790     {
1791       size = IVAL(pdata,0);
1792 #ifdef LARGE_SMB_OFF_T
1793       size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1794 #else /* LARGE_SMB_OFF_T */
1795       if (IVAL(pdata,4) != 0)   /* more than 32 bits? */
1796          return(ERROR(ERRDOS,ERRunknownlevel));
1797 #endif /* LARGE_SMB_OFF_T */
1798       DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1799       break;
1800     }
1801
1802     case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1803     {
1804       if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1805       {
1806         BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1807
1808         if(fsp->is_directory)
1809         {
1810           fsp->directory_delete_on_close = delete_on_close;
1811           DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1812                 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1813
1814         }
1815         else if(fsp->stat_open)
1816         {
1817           DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1818                 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1819         }
1820         else
1821         {
1822
1823           /*
1824            * We can only set the delete on close flag if
1825            * the share mode contained ALLOW_SHARE_DELETE
1826            */
1827
1828           if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1829             return(ERROR(ERRDOS,ERRnoaccess));
1830
1831           /*
1832            * If the flag has been set then
1833            * modify the share mode entry for all files we have open
1834            * on this device and inode to tell other smbds we have 
1835            * changed the delete on close flag.
1836            */
1837
1838           if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1839           {
1840             int i;
1841             files_struct *iterate_fsp;
1842             SMB_DEV_T dev = fsp->dev;
1843             SMB_INO_T inode = fsp->inode;
1844             int num_share_modes;
1845             share_mode_entry *current_shares = NULL;
1846
1847             if (lock_share_entry_fsp(fsp) == False)
1848               return(ERROR(ERRDOS,ERRnoaccess));
1849
1850             /*
1851              * Before we allow this we need to ensure that all current opens
1852              * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1853              * do not then we deny this (as we are essentially deleting the
1854              * file at this point.
1855              */
1856
1857             num_share_modes = get_share_modes(conn, dev, inode, &current_shares);
1858             for(i = 0; i < num_share_modes; i++)
1859             {
1860               if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1861               {
1862                 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1863 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1864                       fsp->fnum, fsp->fsp_name ));
1865                 /*
1866                  * Release the lock.
1867                  */
1868
1869                 unlock_share_entry_fsp(fsp);
1870
1871                 /*
1872                  * current_shares was malloced by get_share_modes - free it here.
1873                  */
1874
1875                 free((char *)current_shares);
1876
1877                 /*
1878                  * Even though share violation would be more appropriate here,
1879                  * return ERRnoaccess as that's what NT does.
1880                  */
1881
1882                 return(ERROR(ERRDOS,ERRnoaccess));
1883               }
1884             }
1885
1886             /*
1887              * current_shares was malloced by get_share_modes - free it here.
1888              */
1889
1890             free((char *)current_shares);
1891
1892             DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1893                  delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1894
1895             /*
1896              * Go through all files we have open on the same device and
1897              * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1898              * Other smbd's that have this file open will have to fend for themselves. We
1899              * take care of this (rare) case in close_file(). See the comment there.
1900              */
1901
1902             for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1903                                   iterate_fsp = file_find_di_next(iterate_fsp))
1904             {
1905               int new_share_mode = (delete_on_close ? 
1906                                     (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1907                                     (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1908
1909               DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1910 dev = %x, inode = %.0f from %x to %x\n", 
1911                     iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev, 
1912                     (double)inode, iterate_fsp->share_mode, new_share_mode ));
1913
1914               if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1915                 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1916 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1917             }
1918
1919             /*
1920              * Set the delete on close flag in the reference
1921              * counted struct. Delete when the last reference
1922              * goes away.
1923              */
1924            fsp->delete_on_close = delete_on_close;
1925
1926            unlock_share_entry_fsp(fsp);
1927
1928            DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1929                  delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1930
1931           } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1932         } /* end if is_directory. */
1933       } else
1934         return(ERROR(ERRDOS,ERRunknownlevel));
1935       break;
1936     }
1937
1938     default:
1939     {
1940       return(ERROR(ERRDOS,ERRunknownlevel));
1941     }
1942   }
1943
1944   /* get some defaults (no modifications) if any info is zero or -1. */
1945   if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1946     tvs.actime = sbuf.st_atime;
1947
1948   if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1949     tvs.modtime = sbuf.st_mtime;
1950
1951   DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1952   DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1953   DEBUG(6,("size: %.0f ", (double)size));
1954   DEBUG(6,("mode: %x\n"  , mode));
1955
1956   if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1957      (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1958     /*
1959      * Only do this test if we are not explicitly
1960      * changing the size of a file.
1961      */
1962     if (!size)
1963       size = sbuf.st_size;
1964   }
1965
1966   /* Try and set the times, size and mode of this file -
1967      if they are different from the current values
1968    */
1969   if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
1970     if(fsp != NULL) {
1971       /*
1972        * This was a setfileinfo on an open file.
1973        * NT does this a lot. It's actually pointless
1974        * setting the time here, as it will be overwritten
1975        * on the next write, so we save the request
1976        * away and will set it on file code. JRA.
1977        */
1978
1979        if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1980          DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1981             ctime(&tvs.modtime) ));
1982          fsp->pending_modtime = tvs.modtime;
1983        }
1984
1985     } else {
1986
1987       DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1988
1989       if(file_utime(conn, fname, &tvs)!=0)
1990         return(UNIXERROR(ERRDOS,ERRnoaccess));
1991     }
1992   }
1993
1994   /* check the mode isn't different, before changing it */
1995   if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
1996
1997     DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1998           fname, mode ));
1999
2000     if(file_chmod(conn, fname, mode, NULL)) {
2001       DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2002       return(UNIXERROR(ERRDOS,ERRnoaccess));
2003     }
2004   }
2005
2006   if(size != sbuf.st_size) {
2007
2008     DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2009           fname, (double)size ));
2010
2011     if (fd == -1) {
2012       files_struct *new_fsp = NULL;
2013       int access_mode = 0;
2014       int action = 0;
2015
2016       if(global_oplock_break) {
2017         /* Queue this file modify as we are the process of an oplock break.  */
2018
2019         DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2020         DEBUGADD(2,( "in oplock break state.\n"));
2021
2022         push_oplock_pending_smb_message(inbuf, length);
2023         return -1;
2024       }
2025
2026       new_fsp = open_file_shared(conn, fname, &sbuf,
2027                            SET_OPEN_MODE(DOS_OPEN_RDWR),
2028                            (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2029                            0, 0, &access_mode, &action);
2030         
2031       if (new_fsp == NULL)
2032         return(UNIXERROR(ERRDOS,ERRbadpath));
2033       vfs_set_filelen(new_fsp, size);
2034       close_file(new_fsp,True);
2035     } else {
2036         vfs_set_filelen(fsp, size);
2037     }
2038   }
2039
2040   SSVAL(params,0,0);
2041
2042   send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2043   
2044   return(-1);
2045 }
2046
2047 /****************************************************************************
2048   reply to a TRANS2_MKDIR (make directory with extended attributes).
2049 ****************************************************************************/
2050 static int call_trans2mkdir(connection_struct *conn,
2051                             char *inbuf, char *outbuf, int length, int bufsize,
2052                             char **pparams, char **ppdata)
2053 {
2054   char *params = *pparams;
2055   pstring directory;
2056   int ret = -1;
2057   SMB_STRUCT_STAT sbuf;
2058   BOOL bad_path = False;
2059
2060   if (!CAN_WRITE(conn))
2061     return(ERROR(ERRSRV,ERRaccess));
2062
2063   pstrcpy(directory, &params[4]);
2064
2065   DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2066
2067   unix_convert(directory,conn,0,&bad_path,&sbuf);
2068   if (check_name(directory,conn))
2069     ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2070   
2071   if(ret < 0)
2072     {
2073       DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2074       if((errno == ENOENT) && bad_path)
2075       {
2076         unix_ERR_class = ERRDOS;
2077         unix_ERR_code = ERRbadpath;
2078       }
2079       return(UNIXERROR(ERRDOS,ERRnoaccess));
2080     }
2081
2082   /* Realloc the parameter and data sizes */
2083   params = Realloc(*pparams,2);
2084   if(params == NULL) {
2085     return(ERROR(ERRDOS,ERRnomem));
2086   }
2087   *pparams      = params;
2088
2089   SSVAL(params,0,0);
2090
2091   send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2092   
2093   return(-1);
2094 }
2095
2096 /****************************************************************************
2097   reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2098   We don't actually do this - we just send a null response.
2099 ****************************************************************************/
2100 static int call_trans2findnotifyfirst(connection_struct *conn,
2101                                       char *inbuf, char *outbuf, 
2102                                       int length, int bufsize,
2103                                       char **pparams, char **ppdata)
2104 {
2105   static uint16 fnf_handle = 257;
2106   char *params = *pparams;
2107   uint16 info_level = SVAL(params,4);
2108
2109   DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2110
2111   switch (info_level) 
2112     {
2113     case 1:
2114     case 2:
2115       break;
2116     default:
2117       return(ERROR(ERRDOS,ERRunknownlevel));
2118     }
2119
2120   /* Realloc the parameter and data sizes */
2121   params = Realloc(*pparams,6);
2122   if(params == NULL) {
2123     return(ERROR(ERRDOS,ERRnomem));
2124   }
2125   *pparams      = params;
2126
2127   SSVAL(params,0,fnf_handle);
2128   SSVAL(params,2,0); /* No changes */
2129   SSVAL(params,4,0); /* No EA errors */
2130
2131   fnf_handle++;
2132
2133   if(fnf_handle == 0)
2134     fnf_handle = 257;
2135
2136   send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2137   
2138   return(-1);
2139 }
2140
2141 /****************************************************************************
2142   reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
2143   changes). Currently this does nothing.
2144 ****************************************************************************/
2145 static int call_trans2findnotifynext(connection_struct *conn,
2146                                      char *inbuf, char *outbuf, 
2147                                      int length, int bufsize,
2148                                      char **pparams, char **ppdata)
2149 {
2150   char *params = *pparams;
2151
2152   DEBUG(3,("call_trans2findnotifynext\n"));
2153
2154   /* Realloc the parameter and data sizes */
2155   params = Realloc(*pparams,4);
2156   if(params == NULL) {
2157     return(ERROR(ERRDOS,ERRnomem));
2158   }
2159   *pparams      = params;
2160
2161   SSVAL(params,0,0); /* No changes */
2162   SSVAL(params,2,0); /* No EA errors */
2163
2164   send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2165   
2166   return(-1);
2167 }
2168
2169 /****************************************************************************
2170   reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2171 ****************************************************************************/
2172 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2173                                      char* outbuf, int length, int bufsize,
2174                                      char** pparams, char** ppdata)
2175 {
2176   char *params = *pparams;
2177   enum remote_arch_types ra_type = get_remote_arch();
2178   BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2179   pstring pathname;
2180   int reply_size = 0;
2181   int max_referral_level = SVAL(params,0);
2182
2183
2184   DEBUG(10,("call_trans2getdfsreferral\n"));
2185
2186   if(!lp_host_msdfs())
2187     return(ERROR(ERRDOS,ERRbadfunc));
2188
2189   /* if pathname is in UNICODE, convert to DOS */
2190   /* NT always sends in UNICODE, may not set UNICODE flag */
2191   if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2192     {
2193       unistr_to_dos(pathname, &params[2], sizeof(pathname));
2194       DEBUG(10,("UNICODE referral for %s\n",pathname));
2195     }
2196   else
2197     pstrcpy(pathname,&params[2]);
2198
2199   if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2200     return(ERROR(ERRDOS,ERRbadfile));
2201     
2202   SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS | 
2203         FLAGS2_DFS_PATHNAMES);
2204   send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2205
2206   return(-1);
2207 }
2208
2209
2210 /****************************************************************************
2211   reply to a SMBfindclose (stop trans2 directory search)
2212 ****************************************************************************/
2213 int reply_findclose(connection_struct *conn,
2214                     char *inbuf,char *outbuf,int length,int bufsize)
2215 {
2216         int outsize = 0;
2217         int dptr_num=SVALS(inbuf,smb_vwv0);
2218         START_PROFILE(SMBfindclose);
2219
2220         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2221
2222         dptr_close(&dptr_num);
2223
2224         outsize = set_message(outbuf,0,0,True);
2225
2226         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2227
2228         END_PROFILE(SMBfindclose);
2229         return(outsize);
2230 }
2231
2232 /****************************************************************************
2233   reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2234 ****************************************************************************/
2235 int reply_findnclose(connection_struct *conn, 
2236                      char *inbuf,char *outbuf,int length,int bufsize)
2237 {
2238         int outsize = 0;
2239         int dptr_num= -1;
2240         START_PROFILE(SMBfindnclose);
2241         
2242         dptr_num = SVAL(inbuf,smb_vwv0);
2243
2244         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2245
2246         /* We never give out valid handles for a 
2247            findnotifyfirst - so any dptr_num is ok here. 
2248            Just ignore it. */
2249
2250         outsize = set_message(outbuf,0,0,True);
2251
2252         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2253
2254         END_PROFILE(SMBfindnclose);
2255         return(outsize);
2256 }
2257
2258
2259 /****************************************************************************
2260   reply to a SMBtranss2 - just ignore it!
2261 ****************************************************************************/
2262 int reply_transs2(connection_struct *conn,
2263                   char *inbuf,char *outbuf,int length,int bufsize)
2264 {
2265         START_PROFILE(SMBtranss2);
2266         DEBUG(4,("Ignoring transs2 of length %d\n",length));
2267         END_PROFILE(SMBtranss2);
2268         return(-1);
2269 }
2270
2271 /****************************************************************************
2272   reply to a SMBtrans2
2273 ****************************************************************************/
2274 int reply_trans2(connection_struct *conn,
2275                  char *inbuf,char *outbuf,int length,int bufsize)
2276 {
2277         int outsize = 0;
2278         unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2279         unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2280 #if 0
2281         unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2282         unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2283         unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2284         BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2285         BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2286         int32 timeout = IVALS(inbuf,smb_timeout);
2287 #endif
2288         unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2289         unsigned int tran_call = SVAL(inbuf, smb_setup0);
2290         char *params = NULL, *data = NULL;
2291         int num_params, num_params_sofar, num_data, num_data_sofar;
2292         START_PROFILE(SMBtrans2);
2293
2294         if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2295                 /* Queue this open message as we are the process of an
2296                  * oplock break.  */
2297
2298                 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2299                 DEBUGADD(2,( "in oplock break state.\n"));
2300
2301                 push_oplock_pending_smb_message(inbuf, length);
2302                 END_PROFILE(SMBtrans2);
2303                 return -1;
2304         }
2305         
2306         if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2307             && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2308                 END_PROFILE(SMBtrans2);
2309                 return(ERROR(ERRSRV,ERRaccess));
2310         }
2311
2312         outsize = set_message(outbuf,0,0,True);
2313
2314         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2315            is so as a sanity check */
2316         if (suwcnt != 1) {
2317                 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2318                 END_PROFILE(SMBtrans2);
2319                 return(ERROR(ERRSRV,ERRerror));
2320         }
2321     
2322         /* Allocate the space for the maximum needed parameters and data */
2323         if (total_params > 0)
2324                 params = (char *)malloc(total_params);
2325         if (total_data > 0)
2326                 data = (char *)malloc(total_data);
2327   
2328         if ((total_params && !params)  || (total_data && !data)) {
2329                 DEBUG(2,("Out of memory in reply_trans2\n"));
2330                 if(params)
2331                   free(params);
2332                 if(data)
2333                   free(data); 
2334                 END_PROFILE(SMBtrans2);
2335                 return(ERROR(ERRDOS,ERRnomem));
2336         }
2337
2338         /* Copy the param and data bytes sent with this request into
2339            the params buffer */
2340         num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2341         num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2342
2343         if (num_params > total_params || num_data > total_data)
2344                 exit_server("invalid params in reply_trans2");
2345
2346         if(params)
2347                 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2348         if(data)
2349                 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2350
2351         if(num_data_sofar < total_data || num_params_sofar < total_params)  {
2352                 /* We need to send an interim response then receive the rest
2353                    of the parameter/data bytes */
2354                 outsize = set_message(outbuf,0,0,True);
2355                 send_smb(smbd_server_fd(),outbuf);
2356
2357                 while (num_data_sofar < total_data || 
2358                        num_params_sofar < total_params) {
2359                         BOOL ret;
2360
2361                         ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2362                         
2363                         if ((ret && 
2364                              (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2365                                 outsize = set_message(outbuf,0,0,True);
2366                                 if(ret)
2367                                         DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2368                                 else
2369                                         DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2370                                                  (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2371                                 if(params)
2372                                         free(params);
2373                                 if(data)
2374                                         free(data);
2375                                 END_PROFILE(SMBtrans2);
2376                                 return(ERROR(ERRSRV,ERRerror));
2377                         }
2378       
2379                         /* Revise total_params and total_data in case
2380                            they have changed downwards */
2381                         total_params = SVAL(inbuf, smb_tpscnt);
2382                         total_data = SVAL(inbuf, smb_tdscnt);
2383                         num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2384                         num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2385                         if (num_params_sofar > total_params || num_data_sofar > total_data)
2386                                 exit_server("data overflow in trans2");
2387                         
2388                         memcpy( &params[ SVAL(inbuf, smb_spsdisp)], 
2389                                 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2390                         memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2391                                 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2392                 }
2393         }
2394         
2395         if (Protocol >= PROTOCOL_NT1) {
2396                 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2397         }
2398
2399         /* Now we must call the relevant TRANS2 function */
2400         switch(tran_call)  {
2401         case TRANSACT2_OPEN:
2402                 START_PROFILE_NESTED(Trans2_open);
2403                 outsize = call_trans2open(conn, 
2404                                           inbuf, outbuf, bufsize, 
2405                                           &params, &data);
2406                 END_PROFILE_NESTED(Trans2_open);
2407                 break;
2408
2409         case TRANSACT2_FINDFIRST:
2410                 START_PROFILE_NESTED(Trans2_findfirst);
2411                 outsize = call_trans2findfirst(conn, inbuf, outbuf, 
2412                                                bufsize, &params, &data);
2413                 END_PROFILE_NESTED(Trans2_findfirst);
2414                 break;
2415
2416         case TRANSACT2_FINDNEXT:
2417                 START_PROFILE_NESTED(Trans2_findnext);
2418                 outsize = call_trans2findnext(conn, inbuf, outbuf, 
2419                                               length, bufsize, 
2420                                               &params, &data);
2421                 END_PROFILE_NESTED(Trans2_findnext);
2422                 break;
2423
2424         case TRANSACT2_QFSINFO:
2425                 START_PROFILE_NESTED(Trans2_qfsinfo);
2426             outsize = call_trans2qfsinfo(conn, inbuf, outbuf, 
2427                                          length, bufsize, &params, 
2428                                          &data);
2429                 END_PROFILE_NESTED(Trans2_qfsinfo);
2430             break;
2431
2432         case TRANSACT2_SETFSINFO:
2433                 START_PROFILE_NESTED(Trans2_setfsinfo);
2434                 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, 
2435                                                length, bufsize, 
2436                                                &params, &data);
2437                 END_PROFILE_NESTED(Trans2_setfsinfo);
2438                 break;
2439
2440         case TRANSACT2_QPATHINFO:
2441         case TRANSACT2_QFILEINFO:
2442                 START_PROFILE_NESTED(Trans2_qpathinfo);
2443                 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, 
2444                                                    length, bufsize, 
2445                                                    &params, &data, total_data);
2446                 END_PROFILE_NESTED(Trans2_qpathinfo);
2447                 break;
2448         case TRANSACT2_SETPATHINFO:
2449         case TRANSACT2_SETFILEINFO:
2450                 START_PROFILE_NESTED(Trans2_setpathinfo);
2451                 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, 
2452                                                      length, bufsize, 
2453                                                      &params, &data, 
2454                                                      total_data);
2455                 END_PROFILE_NESTED(Trans2_setpathinfo);
2456                 break;
2457
2458         case TRANSACT2_FINDNOTIFYFIRST:
2459                 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2460                 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, 
2461                                                      length, bufsize, 
2462                                                      &params, &data);
2463                 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2464                 break;
2465
2466         case TRANSACT2_FINDNOTIFYNEXT:
2467                 START_PROFILE_NESTED(Trans2_findnotifynext);
2468                 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, 
2469                                                     length, bufsize, 
2470                                                     &params, &data);
2471                 END_PROFILE_NESTED(Trans2_findnotifynext);
2472                 break;
2473         case TRANSACT2_MKDIR:
2474                 START_PROFILE_NESTED(Trans2_mkdir);
2475                 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, 
2476                                            bufsize, &params, &data);
2477                 END_PROFILE_NESTED(Trans2_mkdir);
2478                 break;
2479
2480         case TRANSACT2_GET_DFS_REFERRAL:
2481                 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2482                 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2483                                                     bufsize, &params, &data);
2484                 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2485                 break;
2486         default:
2487                 /* Error in request */
2488                 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2489                 if(params)
2490                         free(params);
2491                 if(data)
2492                         free(data);
2493                 END_PROFILE(SMBtrans2);
2494                 return (ERROR(ERRSRV,ERRerror));
2495         }
2496         
2497         /* As we do not know how many data packets will need to be
2498            returned here the various call_trans2xxxx calls
2499            must send their own. Thus a call_trans2xxx routine only
2500            returns a value other than -1 when it wants to send
2501            an error packet. 
2502         */
2503         
2504         if(params)
2505                 free(params);
2506         if(data)
2507                 free(data);
2508         END_PROFILE(SMBtrans2);
2509         return outsize; /* If a correct response was needed the
2510                            call_trans2xxx calls have already sent
2511                            it. If outsize != -1 then it is returning */
2512 }