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