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