Fixed memory leak when freeing ChangeNotify structures.
[kai/samba-autobuild/.git] / source3 / smbd / nttrans.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    SMB NT transaction handling
5    Copyright (C) Jeremy Allison 1994-1998
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25 extern int Protocol;
26 extern int chain_fnum;
27 extern connection_struct Connections[];
28 extern files_struct Files[];
29 extern int Client;  
30 extern int oplock_sock;
31 extern int smb_read_error;
32 extern int global_oplock_break;
33 extern BOOL case_sensitive;
34 extern BOOL case_preserve;
35 extern BOOL short_case_preserve;
36
37 static char *known_nt_pipes[] = {
38   "\\LANMAN",
39   "\\srvsvc",
40   "\\samr",
41   "\\wkssvc",
42   "\\NETLOGON",
43   "\\ntlsa",
44   "\\ntsvcs",
45   "\\lsass",
46   "\\lsarpc",
47   NULL
48 };
49
50 /****************************************************************************
51  Send the required number of replies back.
52  We assume all fields other than the data fields are
53  set correctly for the type of call.
54  HACK ! Always assumes smb_setup field is zero.
55 ****************************************************************************/
56
57 static int send_nt_replies(char *outbuf, int bufsize, char *params,
58                            int paramsize, char *pdata, int datasize)
59 {
60   extern int max_send;
61   int data_to_send = datasize;
62   int params_to_send = paramsize;
63   int useable_space;
64   char *pp = params;
65   char *pd = pdata;
66   int params_sent_thistime, data_sent_thistime, total_sent_thistime;
67   int alignment_offset = 3;
68   int data_alignment_offset = 0;
69
70   /*
71    * Initially set the wcnt area to be 18 - this is true for all
72    * transNT replies.
73    */
74
75   set_message(outbuf,18,0,True);
76
77   /* 
78    * If there genuinely are no parameters or data to send just send
79    * the empty packet.
80    */
81
82   if(params_to_send == 0 && data_to_send == 0) {
83     send_smb(Client,outbuf);
84     return 0;
85   }
86
87   /*
88    * When sending params and data ensure that both are nicely aligned.
89    * Only do this alignment when there is also data to send - else
90    * can cause NT redirector problems.
91    */
92
93   if (((params_to_send % 4) != 0) && (data_to_send != 0))
94     data_alignment_offset = 4 - (params_to_send % 4);
95
96   /* 
97    * Space is bufsize minus Netbios over TCP header minus SMB header.
98    * The alignment_offset is to align the param bytes on a four byte
99    * boundary (2 bytes for data len, one byte pad). 
100    * NT needs this to work correctly.
101    */
102
103   useable_space = bufsize - ((smb_buf(outbuf)+
104                     alignment_offset+data_alignment_offset) -
105                     outbuf);
106
107   /*
108    * useable_space can never be more than max_send minus the
109    * alignment offset.
110    */
111
112   useable_space = MIN(useable_space,
113                       max_send - (alignment_offset+data_alignment_offset));
114
115
116   while (params_to_send || data_to_send) {
117
118     /*
119      * Calculate whether we will totally or partially fill this packet.
120      */
121
122     total_sent_thistime = params_to_send + data_to_send +
123                             alignment_offset + data_alignment_offset;
124
125     /* 
126      * We can never send more than useable_space.
127      */
128
129     total_sent_thistime = MIN(total_sent_thistime, useable_space);
130
131     set_message(outbuf, 18, total_sent_thistime, True);
132
133     /*
134      * Set total params and data to be sent.
135      */
136
137     SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
138     SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
139
140     /* 
141      * Calculate how many parameters and data we can fit into
142      * this packet. Parameters get precedence.
143      */
144
145     params_sent_thistime = MIN(params_to_send,useable_space);
146     data_sent_thistime = useable_space - params_sent_thistime;
147     data_sent_thistime = MIN(data_sent_thistime,data_to_send);
148
149     SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
150
151     if(params_sent_thistime == 0) {
152       SIVAL(outbuf,smb_ntr_ParameterOffset,0);
153       SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
154     } else {
155       /*
156        * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
157        * parameter bytes, however the first 4 bytes of outbuf are
158        * the Netbios over TCP header. Thus use smb_base() to subtract
159        * them from the calculation.
160        */
161
162       SIVAL(outbuf,smb_ntr_ParameterOffset,
163             ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
164       /* 
165        * Absolute displacement of param bytes sent in this packet.
166        */
167
168       SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
169     }
170
171     /*
172      * Deal with the data portion.
173      */
174
175     SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
176
177     if(data_sent_thistime == 0) {
178       SIVAL(outbuf,smb_ntr_DataOffset,0);
179       SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
180     } else {
181       /*
182        * The offset of the data bytes is the offset of the
183        * parameter bytes plus the number of parameters being sent this time.
184        */
185
186       SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
187             smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
188       SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
189     }
190
191     /* 
192      * Copy the param bytes into the packet.
193      */
194
195     if(params_sent_thistime)
196       memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
197
198     /*
199      * Copy in the data bytes
200      */
201
202     if(data_sent_thistime)
203       memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
204              data_alignment_offset,pd,data_sent_thistime);
205     
206     DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
207           params_sent_thistime, data_sent_thistime, useable_space));
208     DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
209           params_to_send, data_to_send, paramsize, datasize));
210     
211     /* Send the packet */
212     send_smb(Client,outbuf);
213     
214     pp += params_sent_thistime;
215     pd += data_sent_thistime;
216     
217     params_to_send -= params_sent_thistime;
218     data_to_send -= data_sent_thistime;
219
220     /*
221      * Sanity check
222      */
223
224     if(params_to_send < 0 || data_to_send < 0) {
225       DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
226             params_to_send, data_to_send));
227       return -1;
228     }
229   } 
230
231   return 0;
232 }
233
234 /****************************************************************************
235  Save case statics.
236 ****************************************************************************/
237
238 static BOOL saved_case_sensitive;
239 static BOOL saved_case_preserve;
240 static BOOL saved_short_case_preserve;
241
242 /****************************************************************************
243  Save case semantics.
244 ****************************************************************************/
245
246 static void set_posix_case_semantics(uint32 file_attributes)
247 {
248   if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
249     return;
250
251   saved_case_sensitive = case_sensitive;
252   saved_case_preserve = case_preserve;
253   saved_short_case_preserve = short_case_preserve;
254
255   /* Set to POSIX. */
256   case_sensitive = True;
257   case_preserve = True;
258   short_case_preserve = True;
259 }
260
261 /****************************************************************************
262  Restore case semantics.
263 ****************************************************************************/
264
265 static void restore_case_semantics(uint32 file_attributes)
266 {
267   if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
268     return;
269
270   case_sensitive = saved_case_sensitive;
271   case_preserve = saved_case_preserve;
272   short_case_preserve = saved_short_case_preserve;
273 }
274
275 /****************************************************************************
276  Utility function to map create disposition.
277 ****************************************************************************/
278
279 static int map_create_disposition( uint32 create_disposition)
280 {
281   switch( create_disposition ) {
282   case FILE_CREATE:
283     /* create if not exist, fail if exist */
284     return 0x10;
285   case FILE_SUPERSEDE:
286   case FILE_OVERWRITE_IF:
287     /* create if not exist, trunc if exist */
288     return 0x12;
289   case FILE_OPEN:
290     /* fail if not exist, open if exists */
291     return 0x1;
292   case FILE_OPEN_IF:
293     /* create if not exist, open if exists */
294     return 0x11;
295   case FILE_OVERWRITE:
296     /* fail if not exist, truncate if exists */
297     return 0x2;
298   default:
299     DEBUG(0,("map_create_disposition: Incorrect value for create_disposition = %d\n",
300              create_disposition ));
301     return -1;
302   }
303 }
304
305 /****************************************************************************
306  Utility function to map share modes.
307 ****************************************************************************/
308
309 static int map_share_mode( uint32 desired_access, uint32 share_access, uint32 file_attributes)
310 {
311   int smb_open_mode = -1;
312
313   switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA) ) {
314   case FILE_READ_DATA:
315     smb_open_mode = 0;
316     break;
317   case FILE_WRITE_DATA:
318     smb_open_mode = 1;
319     break;
320   case FILE_READ_DATA|FILE_WRITE_DATA:
321     smb_open_mode = 2;
322     break;
323   }
324
325   if (smb_open_mode == -1) {
326     if(desired_access & DELETE_ACCESS)
327       smb_open_mode = 2;
328     else if( desired_access & FILE_EXECUTE)
329       smb_open_mode = 0;
330     else {
331       DEBUG(0,("map_share_mode: Incorrect value for desired_access = %x\n",
332              desired_access));
333       return -1;
334     }
335   }
336
337   /* Add in the requested share mode - ignore FILE_SHARE_DELETE for now. */
338   switch( share_access & (FILE_SHARE_READ|FILE_SHARE_WRITE)) {
339   case FILE_SHARE_READ:
340     smb_open_mode |= (DENY_WRITE<<4);
341     break;
342   case FILE_SHARE_WRITE:
343     smb_open_mode |= (DENY_READ<<4);
344     break;
345   case (FILE_SHARE_READ|FILE_SHARE_WRITE):
346     smb_open_mode |= (DENY_NONE<<4);
347     break;
348   case FILE_SHARE_NONE:
349     smb_open_mode |= (DENY_ALL<<4);
350     break;
351   }
352
353   /*
354    * Handle a O_SYNC request.
355    */
356   if(file_attributes & FILE_FLAG_WRITE_THROUGH)
357     smb_open_mode |= (1<<14);
358
359   return smb_open_mode;
360 }
361
362 /****************************************************************************
363  Reply to an NT create and X call on a pipe.
364 ****************************************************************************/
365
366 static int nt_open_pipe(char *fname, char *inbuf, char *outbuf, int *ppnum)
367 {
368   int cnum = SVAL(inbuf,smb_tid);
369   int pnum = -1;
370   uint16 vuid = SVAL(inbuf, smb_uid);
371   int i;
372
373   DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
374     
375   /* See if it is one we want to handle. */
376   for( i = 0; known_nt_pipes[i]; i++ )
377     if( strequal(fname,known_nt_pipes[i]))
378       break;
379     
380   if ( known_nt_pipes[i] == NULL )
381     return(ERROR(ERRSRV,ERRaccess));
382     
383   /* Strip \\ off the name. */
384   fname++;
385     
386   DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
387
388   pnum = open_rpc_pipe_hnd(fname, cnum, vuid);
389   if (pnum < 0)
390     return(ERROR(ERRSRV,ERRnofids));
391
392   *ppnum = pnum + 0x800; /* Mark file handle up into high range. */
393   return 0;
394 }
395
396 /****************************************************************************
397  Reply to an NT create and X call.
398 ****************************************************************************/
399
400 int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize)
401 {  
402   pstring fname;
403   int cnum = SVAL(inbuf,smb_tid);
404   int fnum = -1;
405   uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
406   uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
407   uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
408   uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
409   uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
410   uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)),
411                          ((uint32)sizeof(fname)-1));
412   int smb_ofun;
413   int smb_open_mode;
414   int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
415   /* Breakout the oplock request bits so we can set the
416      reply bits separately. */
417   int oplock_request = 0;
418   int unixmode;
419   int fmode=0,mtime=0,rmode=0;
420   off_t file_len = 0;
421   struct stat sbuf;
422   int smb_action = 0;
423   BOOL bad_path = False;
424   files_struct *fsp;
425   char *p = NULL;
426   
427   /* 
428    * We need to construct the open_and_X ofun value from the
429    * NT values, as that's what our code is structured to accept.
430    */    
431
432   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
433     return(ERROR(ERRDOS,ERRbadaccess));
434
435   /*
436    * Now contruct the smb_open_mode value from the desired access
437    * and the share access.
438    */
439
440   if((smb_open_mode = map_share_mode( desired_access, share_access, file_attributes)) == -1)
441     return(ERROR(ERRDOS,ERRbadaccess));
442
443   /*
444    * Get the file name.
445    */
446   StrnCpy(fname,smb_buf(inbuf),fname_len);
447   fname[fname_len] = '\0';
448
449   /* If it's an IPC, use the pipe handler. */
450   if (IS_IPC(cnum)) {
451     int ret = nt_open_pipe(fname, inbuf, outbuf, &fnum);
452     if(ret != 0)
453       return ret;
454     smb_action = FILE_WAS_OPENED;
455   } else {
456
457     /*
458      * Ordinary file or directory.
459      */
460
461     /*
462      * Check if POSIX semantics are wanted.
463      */
464
465     set_posix_case_semantics(file_attributes);
466
467     unix_convert(fname,cnum,0,&bad_path);
468     
469     fnum = find_free_file();
470     if (fnum < 0) {
471       restore_case_semantics(file_attributes);
472       return(ERROR(ERRSRV,ERRnofids));
473     }
474
475     fsp = &Files[fnum];
476     
477     if (!check_name(fname,cnum)) { 
478       if((errno == ENOENT) && bad_path) {
479         unix_ERR_class = ERRDOS;
480         unix_ERR_code = ERRbadpath;
481       }
482       fsp->reserved = False;
483
484       restore_case_semantics(file_attributes);
485
486       return(UNIXERROR(ERRDOS,ERRnoaccess));
487     } 
488   
489     unixmode = unix_mode(cnum,smb_attr | aARCH);
490     
491     oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
492     oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
493
494     /* 
495      * If it's a request for a directory open, deal with it separately.
496      */
497
498     if(flags & OPEN_DIRECTORY) {
499       oplock_request = 0;
500
501       open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action);
502
503       restore_case_semantics(file_attributes);
504
505       if(!fsp->open) {
506         fsp->reserved = False;
507         return(UNIXERROR(ERRDOS,ERRnoaccess));
508       }
509     } else {
510
511       /*
512        * Ordinary file case.
513        */
514
515       /*
516        * NB. We have a potential bug here. If we cause an oplock
517        * break to ourselves, then we could end up processing filename
518        * related SMB requests whilst we await the oplock break
519        * response. As we may have changed the filename case
520        * semantics to be POSIX-like, this could mean a filename
521        * request could fail when it should succeed. This is a
522        * rare condition, but eventually we must arrange to restore
523        * the correct case semantics before issuing an oplock break
524        * request to our client. JRA.
525        */
526
527       open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
528                        oplock_request,&rmode,&smb_action);
529
530       if (!fsp->open) { 
531         /*
532          * We cheat here. The only case we care about is a directory
533          * rename, where the NT client will attempt to open the source
534          * directory for DELETE access. Note that when the NT client
535          * does this it does *not* set the directory bit in the
536          * request packet. This is translated into a read/write open
537          * request. POSIX states that any open for write request on a directory
538          * will generate an EISDIR error, so we can catch this here and open
539          * a pseudo handle that is flagged as a directory. JRA.
540          */
541
542         if(errno == EISDIR) {
543           oplock_request = 0;
544
545           open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action);
546
547           if(!fsp->open) {
548             fsp->reserved = False;
549             restore_case_semantics(file_attributes);
550             return(UNIXERROR(ERRDOS,ERRnoaccess));
551           }
552         } else {
553           if((errno == ENOENT) && bad_path) {
554             unix_ERR_class = ERRDOS;
555             unix_ERR_code = ERRbadpath;
556           }
557
558           fsp->reserved = False;
559
560           restore_case_semantics(file_attributes);
561
562           return(UNIXERROR(ERRDOS,ERRnoaccess));
563         }
564       } 
565     }
566   
567     if(fsp->is_directory) {
568       if(sys_stat(fsp->name, &sbuf) != 0) {
569         close_directory(fnum);
570         restore_case_semantics(file_attributes);
571         return(ERROR(ERRDOS,ERRnoaccess));
572       }
573     } else {
574       if (fstat(fsp->f_u.fd_ptr->fd,&sbuf) != 0) {
575         close_file(fnum,False);
576         restore_case_semantics(file_attributes);
577         return(ERROR(ERRDOS,ERRnoaccess));
578       } 
579     }
580   
581     restore_case_semantics(file_attributes);
582
583     file_len = sbuf.st_size;
584     fmode = dos_mode(cnum,fname,&sbuf);
585     if(fmode == 0)
586       fmode = FILE_ATTRIBUTE_NORMAL;
587     mtime = sbuf.st_mtime;
588     if (!fsp->is_directory && (fmode & aDIR)) {
589       close_file(fnum,False);
590       return(ERROR(ERRDOS,ERRnoaccess));
591     } 
592   
593     /* 
594      * If the caller set the extended oplock request bit
595      * and we granted one (by whatever means) - set the
596      * correct bit for extended oplock reply.
597      */
598     
599     if (oplock_request && lp_fake_oplocks(SNUM(cnum)))
600       smb_action |= EXTENDED_OPLOCK_GRANTED;
601   
602     if(oplock_request && fsp->granted_oplock)
603       smb_action |= EXTENDED_OPLOCK_GRANTED;
604   }
605  
606   set_message(outbuf,34,0,True);
607
608   p = outbuf + smb_vwv2;
609
610   /*
611    * Currently as we don't support level II oplocks we just report
612    * exclusive & batch here.
613    */
614
615   SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
616   p++;
617   SSVAL(p,0,fnum);
618   p += 2;
619   SIVAL(p,0,smb_action);
620   p += 4;
621
622   if (IS_IPC(cnum)) {
623     /*
624      * Deal with pipe return.
625      */  
626     p += 32;
627     SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
628     p += 20;
629     /* File type. */
630     SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
631     /* Device state. */
632     SSVAL(p,2, 0x5FF); /* ? */
633   } else {
634     /*
635      * Deal with file return.
636      */  
637     /* Create time. */  
638     put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum))));
639     p += 8;
640     put_long_date(p,sbuf.st_atime); /* access time */
641     p += 8;
642     put_long_date(p,sbuf.st_mtime); /* write time */
643     p += 8;
644     put_long_date(p,sbuf.st_mtime); /* change time */
645     p += 8;
646     SIVAL(p,0,fmode); /* File Attributes. */
647     p += 12;
648 #if OFF_T_IS_64_BITS
649       SIVAL(p,0, file_len & 0xFFFFFFFF);
650       SIVAL(p,4, file_len >> 32);
651 #else /* OFF_T_IS_64_BITS */
652       SIVAL(p,0,file_len);
653 #endif /* OFF_T_IS_64_BITS */
654     p += 12;
655     SCVAL(p,0,fsp->is_directory ? 1 : 0);
656   }
657
658   chain_fnum = fnum;
659
660   DEBUG(5,("reply_ntcreate_and_X: open fnum = %d, name = %s\n",
661         fnum, fsp->name ));
662
663   return chain_reply(inbuf,outbuf,length,bufsize);
664 }
665
666 /****************************************************************************
667  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
668 ****************************************************************************/
669
670 static int call_nt_transact_create(char *inbuf, char *outbuf, int length, 
671                                    int bufsize, int cnum,
672                                    char **ppsetup, char **ppparams, char **ppdata)
673 {
674   pstring fname;
675   int fnum = -1;
676   char *params = *ppparams;
677   uint32 flags = IVAL(params,0);
678   uint32 desired_access = IVAL(params,8);
679   uint32 file_attributes = IVAL(params,20);
680   uint32 share_access = IVAL(params,24);
681   uint32 create_disposition = IVAL(params,28);
682   uint32 fname_len = MIN(((uint32)IVAL(params,44)),
683                          ((uint32)sizeof(fname)-1));
684   int smb_ofun;
685   int smb_open_mode;
686   int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
687   /* Breakout the oplock request bits so we can set the
688      reply bits separately. */
689   int oplock_request = 0;
690   int unixmode;
691   int fmode=0,mtime=0,rmode=0;
692   off_t file_len = 0;
693   struct stat sbuf;
694   int smb_action = 0;
695   BOOL bad_path = False;
696   files_struct *fsp;
697   char *p = NULL;
698
699   /* 
700    * We need to construct the open_and_X ofun value from the
701    * NT values, as that's what our code is structured to accept.
702    */    
703
704   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
705     return(ERROR(ERRDOS,ERRbadaccess));
706
707   /*
708    * Now contruct the smb_open_mode value from the desired access
709    * and the share access.
710    */
711
712   if((smb_open_mode = map_share_mode( desired_access, share_access, file_attributes)) == -1)
713     return(ERROR(ERRDOS,ERRbadaccess));
714
715   /*
716    * Get the file name.
717    */
718
719   StrnCpy(fname,params+53,fname_len);
720   fname[fname_len] = '\0';
721
722   /* If it's an IPC, use the pipe handler. */
723   if (IS_IPC(cnum)) {
724     int ret = nt_open_pipe(fname, inbuf, outbuf, &fnum);
725     if(ret != 0)
726       return ret;
727     smb_action = FILE_WAS_OPENED;
728   } else {
729     /*
730      * Check if POSIX semantics are wanted.
731      */
732
733     set_posix_case_semantics(file_attributes);
734
735     unix_convert(fname,cnum,0,&bad_path);
736     
737     fnum = find_free_file();
738     if (fnum < 0) {
739       restore_case_semantics(file_attributes);
740       return(ERROR(ERRSRV,ERRnofids));
741     }
742
743     fsp = &Files[fnum];
744
745     if (!check_name(fname,cnum)) { 
746       if((errno == ENOENT) && bad_path) {
747         unix_ERR_class = ERRDOS;
748         unix_ERR_code = ERRbadpath;
749       }
750       fsp->reserved = False;
751
752       restore_case_semantics(file_attributes);
753
754       return(UNIXERROR(ERRDOS,ERRnoaccess));
755     } 
756   
757     unixmode = unix_mode(cnum,smb_attr | aARCH);
758     
759     oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
760     oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
761
762     /*
763      * If it's a request for a directory open, deal with it separately.
764      */
765
766     if(flags & OPEN_DIRECTORY) {
767
768       oplock_request = 0;
769
770       /*
771        * We will get a create directory here if the Win32
772        * app specified a security descriptor in the 
773        * CreateDirectory() call.
774        */
775
776       open_directory(fnum, cnum, fname, smb_ofun, unixmode, &smb_action);
777
778       if(!fsp->open) {
779         fsp->reserved = False;
780         return(UNIXERROR(ERRDOS,ERRnoaccess));
781       }
782     } else {
783
784       /*
785        * Ordinary file case.
786        */
787
788       open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
789                        oplock_request,&rmode,&smb_action);
790
791       if (!fsp->open) { 
792         if((errno == ENOENT) && bad_path) {
793           unix_ERR_class = ERRDOS;
794           unix_ERR_code = ERRbadpath;
795         }
796         fsp->reserved = False;
797
798         restore_case_semantics(file_attributes);
799
800         return(UNIXERROR(ERRDOS,ERRnoaccess));
801       } 
802   
803       if (fstat(fsp->f_u.fd_ptr->fd,&sbuf) != 0) {
804         close_file(fnum,False);
805
806         restore_case_semantics(file_attributes);
807
808         return(ERROR(ERRDOS,ERRnoaccess));
809       } 
810   
811       file_len = sbuf.st_size;
812       fmode = dos_mode(cnum,fname,&sbuf);
813       if(fmode == 0)
814         fmode = FILE_ATTRIBUTE_NORMAL;
815       mtime = sbuf.st_mtime;
816
817       if (fmode & aDIR) {
818         close_file(fnum,False);
819         restore_case_semantics(file_attributes);
820         return(ERROR(ERRDOS,ERRnoaccess));
821       } 
822
823       /* 
824        * If the caller set the extended oplock request bit
825        * and we granted one (by whatever means) - set the
826        * correct bit for extended oplock reply.
827        */
828     
829       if (oplock_request && lp_fake_oplocks(SNUM(cnum)))
830         smb_action |= EXTENDED_OPLOCK_GRANTED;
831   
832       if(oplock_request && fsp->granted_oplock)
833         smb_action |= EXTENDED_OPLOCK_GRANTED;
834     }
835   }
836
837   restore_case_semantics(file_attributes);
838
839   /* Realloc the size of parameters and data we will return */
840   params = *ppparams = Realloc(*ppparams, 69);
841   if(params == NULL)
842     return(ERROR(ERRDOS,ERRnomem));
843
844   p = params;
845   SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
846   p += 2;
847   SSVAL(p,0,fnum);
848   p += 2;
849   SIVAL(p,0,smb_action);
850   p += 8;
851
852   if (IS_IPC(cnum)) {
853     /*
854      * Deal with pipe return.
855      */  
856     p += 32;
857     SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
858     p += 20;
859     /* File type. */
860     SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
861     /* Device state. */
862     SSVAL(p,2, 0x5FF); /* ? */
863   } else {
864     /*
865      * Deal with file return.
866      */
867     /* Create time. */
868     put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum))));
869     p += 8;
870     put_long_date(p,sbuf.st_atime); /* access time */
871     p += 8;
872     put_long_date(p,sbuf.st_mtime); /* write time */
873     p += 8;
874     put_long_date(p,sbuf.st_mtime); /* change time */
875     p += 8;
876     SIVAL(p,0,fmode); /* File Attributes. */
877     p += 12;
878 #if OFF_T_IS_64_BITS
879       SIVAL(p,0, file_len & 0xFFFFFFFF);
880       SIVAL(p,4, (file_len >> 32));
881 #else /* OFF_T_IS_64_BITS */
882       SIVAL(p,0,file_len);
883 #endif /* OFF_T_IS_64_BITS */
884   }
885
886   /* Send the required number of replies */
887   send_nt_replies(outbuf, bufsize, params, 69, *ppdata, 0);
888
889   return -1;
890 }
891
892 /****************************************************************************
893  Reply to a NT CANCEL request.
894 ****************************************************************************/
895
896 int reply_ntcancel(char *inbuf,char *outbuf,int length,int bufsize)
897 {
898   /*
899    * Go through and cancel any pending change notifies.
900    * TODO: When we add blocking locks we will add cancel
901    * for them here too.
902    */
903
904   int mid = SVAL(inbuf,smb_mid);
905   remove_pending_change_notify_requests_by_mid(mid);
906
907   DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
908
909   return(-1);
910 }
911
912 /****************************************************************************
913  Reply to an unsolicited SMBNTtranss - just ignore it!
914 ****************************************************************************/
915
916 int reply_nttranss(char *inbuf,char *outbuf,int length,int bufsize)
917 {
918   DEBUG(4,("Ignoring nttranss of length %d\n",length));
919   return(-1);
920 }
921
922 /****************************************************************************
923  Reply to an NT transact rename command.
924 ****************************************************************************/
925
926 static int call_nt_transact_rename(char *inbuf, char *outbuf, int length, 
927                                    int bufsize, int cnum,
928                                    char **ppsetup, char **ppparams, char **ppdata)
929 {
930   char *params = *ppparams;
931   pstring new_name;
932   int fnum = SVAL(params, 0);
933   BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
934   uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
935                          ((uint32)sizeof(new_name)-1));
936   int outsize = 0;
937
938   CHECK_FNUM(fnum, cnum);
939   StrnCpy(new_name,params+4,fname_len);
940   new_name[fname_len] = '\0';
941
942   outsize = rename_internals(inbuf, outbuf, Files[fnum].name,
943                              new_name, replace_if_exists);
944   if(outsize == 0) {
945     /*
946      * Rename was successful.
947      */
948     send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0);
949
950     DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 
951           Files[fnum].name, new_name));
952
953     outsize = -1;
954   }
955
956   return(outsize);
957 }
958    
959 /****************************************************************************
960  This is the structure to queue to implement NT change
961  notify. It consists of smb_size bytes stored from the
962  transact command (to keep the mid, tid etc around).
963  Plus the fid to examine and the time to check next.
964 *****************************************************************************/
965
966 typedef struct {
967   ubi_slNode msg_next;
968   int fnum;
969   int cnum;
970   time_t next_check_time;
971   char request_buf[smb_size];
972 } change_notify_buf;
973
974 static ubi_slList change_notify_queue = { NULL, (ubi_slNodePtr)&change_notify_queue, 0};
975
976 /****************************************************************************
977  Setup the common parts of the return packet and send it.
978 *****************************************************************************/
979
980 static void change_notify_reply_packet(char *inbuf, int error_class, uint32 error_code)
981 {
982   extern int Client;
983   char outbuf[smb_size];
984
985   construct_reply_common(inbuf, outbuf);
986
987   ERROR(error_class,error_code);
988   send_smb(Client,outbuf);
989 }
990
991 /****************************************************************************
992  Delete entries by fnum from the change notify pending queue.
993 *****************************************************************************/
994
995 void remove_pending_change_notify_requests_by_fid(int fnum)
996 {
997   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
998   change_notify_buf *prev = NULL;
999
1000   while(cnbp != NULL) {
1001     if(cnbp->fnum == fnum) {
1002       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1003       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1004       continue;
1005     }
1006
1007     prev = cnbp;
1008     cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1009   }
1010 }
1011
1012 /****************************************************************************
1013  Delete entries by mid from the change notify pending queue. Always send reply.
1014 *****************************************************************************/
1015
1016 void remove_pending_change_notify_requests_by_mid(int mid)
1017 {
1018   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1019   change_notify_buf *prev = NULL;
1020
1021   while(cnbp != NULL) {
1022     if(SVAL(cnbp->request_buf,smb_mid) == mid) {
1023       change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1024       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1025       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1026       continue;
1027     }
1028
1029     prev = cnbp;
1030     cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1031   }
1032 }
1033
1034 /****************************************************************************
1035  Process the change notify queue. Note that this is only called as root.
1036 *****************************************************************************/
1037
1038 void process_pending_change_notify_queue(time_t t)
1039 {
1040   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1041   change_notify_buf *prev = NULL;
1042
1043   if(cnbp == NULL)
1044     return;
1045
1046   if(cnbp->next_check_time >= t)
1047     return;
1048
1049   /*
1050    * It's time to check. Go through the queue and see if
1051    * the timestamps changed.
1052    */
1053
1054   while((cnbp != NULL) && (cnbp->next_check_time <= t)) {
1055     struct stat st;
1056     int fnum = cnbp->fnum;
1057     int cnum = cnbp->cnum;
1058     files_struct *fsp = &Files[fnum];
1059     uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : 
1060                   SVAL(cnbp->request_buf,smb_uid);
1061
1062     if(!become_user(&Connections[cnum],cnum,vuid)) {
1063       DEBUG(0,("process_pending_change_notify_queue: Unable to become user vuid=%d.\n",
1064             vuid ));
1065       /*
1066        * Remove the entry and return an error to the client.
1067        */
1068       change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1069       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1070       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1071       continue;
1072     }
1073
1074     if(!become_service(cnum,True)) {
1075       DEBUG(0,("process_pending_change_notify_queue: Unable to become service cnum=%d. \
1076 Error was %s.\n", cnum, strerror(errno) ));
1077       /*
1078        * Remove the entry and return an error to the client.
1079        */
1080       change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1081       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1082       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1083       unbecome_user();
1084       continue;
1085     }
1086
1087     if(sys_stat(fsp->name, &st) < 0) {
1088       DEBUG(0,("process_pending_change_notify_queue: Unable to stat directory %s. \
1089 Error was %s.\n", fsp->name, strerror(errno) ));
1090       /*
1091        * Remove the entry and return an error to the client.
1092        */
1093       change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1094       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1095       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1096       unbecome_user();
1097       continue;
1098     }
1099
1100     if(fsp->f_u.dir_ptr->modify_time != st.st_mtime ||
1101        fsp->f_u.dir_ptr->status_time != st.st_ctime) {
1102       /*
1103        * Remove the entry and return a change notify to the client.
1104        */
1105       DEBUG(5,("process_pending_change_notify_queue: directory fnum = %d, name = %s changed\n",
1106             fnum, fsp->name ));
1107       change_notify_reply_packet(cnbp->request_buf,ERRDOS,ERROR_NOTIFY_ENUM_DIR);
1108       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1109       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1110       unbecome_user();
1111       continue;
1112     }
1113
1114     unbecome_user();
1115
1116     /*
1117      * Move to the next in the list.
1118      */
1119     prev = cnbp;
1120     cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1121   }
1122 }
1123
1124 /****************************************************************************
1125  Reply to a notify change - queue the request and 
1126  don't allow a directory to be opened.
1127 ****************************************************************************/
1128
1129 static int call_nt_transact_notify_change(char *inbuf, char *outbuf, int length,
1130                                           int bufsize, int cnum,
1131                                           char **ppsetup, char **ppparams, char **ppdata)
1132 {
1133   char *setup = *ppsetup;
1134   files_struct *fsp;
1135   int fnum = -1;
1136   change_notify_buf *cnbp;
1137   struct stat st;
1138
1139   fnum = SVAL(setup,4);
1140
1141   DEBUG(3,("call_nt_transact_notify_change: fnum = %d.\n", fnum));
1142
1143   if(!VALID_FNUM(fnum))
1144     return(ERROR(ERRDOS,ERRbadfid));
1145
1146   fsp = &Files[fnum];
1147
1148   if((!fsp->open) || (!fsp->is_directory) || (cnum != fsp->cnum))
1149     return(ERROR(ERRDOS,ERRbadfid));
1150
1151   if(fsp->f_u.dir_ptr == NULL) {
1152
1153     /*
1154      * No currently stored directory info - we must
1155      * generate it here.
1156      */
1157
1158     if((fsp->f_u.dir_ptr = (dir_status_struct *)malloc(sizeof(dir_status_struct))) == NULL) {
1159       DEBUG(0,("call_nt_transact_notify_change: Malloc fail !\n" ));
1160       return -1;
1161     }
1162
1163     /*
1164      * Setup the current directory information in the
1165      * directory entry in the files_struct. We will use
1166      * this to check against when the timer expires.
1167      * NB. We only do this if there is no current directory
1168      * information in the directory struct - as when we start
1169      * monitoring file size etc. this information will start
1170      * becoming increasingly expensive to maintain, so we won't
1171      * want to re-generate it for every ChangeNofity call.
1172      */
1173
1174     if(sys_stat(fsp->name, &st) < 0) {
1175       DEBUG(0,("call_nt_transact_notify_change: Unable to stat fnum = %d, name = %s. \
1176 Error was %s\n", fnum, fsp->name, strerror(errno) ));
1177       return -1;
1178     }
1179  
1180     fsp->f_u.dir_ptr->modify_time = st.st_mtime;
1181     fsp->f_u.dir_ptr->status_time = st.st_ctime;
1182
1183   }
1184
1185   /*
1186    * Now queue an entry on the notify change stack. We timestamp
1187    * the entry we are adding so that we know when to scan next.
1188    * We only need to save smb_size bytes from this incoming packet
1189    * as we will always by returning a 'read the directory yourself'
1190    * error.
1191    */
1192
1193   if((cnbp = (change_notify_buf *)malloc(sizeof(change_notify_buf))) == NULL) {
1194     DEBUG(0,("call_nt_transact_notify_change: Malloc fail (2) !\n" ));
1195     return -1;
1196   }
1197
1198   memcpy(cnbp->request_buf, inbuf, smb_size);
1199   cnbp->fnum = fnum;
1200   cnbp->cnum = cnum;
1201   cnbp->next_check_time = time(NULL) + lp_change_notify_timeout();
1202
1203   /*
1204    * Adding to the tail enables us to check only
1205    * the head when scanning for change, as this entry
1206    * is forced to have the first timeout expiration.
1207    */
1208
1209   ubi_slAddTail(&change_notify_queue, cnbp);
1210
1211   DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \
1212 fid=%d, name = %s\n", fnum, fsp->name ));
1213
1214   return -1;
1215 }
1216
1217 /****************************************************************************
1218  Reply to query a security descriptor - currently this is not implemented (it
1219  is planned to be though).
1220 ****************************************************************************/
1221
1222 static int call_nt_transact_query_security_desc(char *inbuf, char *outbuf, int length, 
1223                                                 int bufsize, int cnum,
1224                                                 char **ppsetup, char **ppparams, char **ppdata)
1225 {
1226   DEBUG(0,("call_nt_transact_query_security_desc: Currently not implemented.\n"));
1227   return(ERROR(ERRSRV,ERRnosupport));
1228 }
1229    
1230 /****************************************************************************
1231  Reply to set a security descriptor - currently this is not implemented (it
1232  is planned to be though).
1233 ****************************************************************************/
1234
1235 static int call_nt_transact_set_security_desc(char *inbuf, char *outbuf, int length,
1236                                               int bufsize, int cnum,
1237                                               char **ppsetup, char **ppparams, char **ppdata)
1238 {
1239   DEBUG(0,("call_nt_transact_set_security_desc: Currently not implemented.\n"));
1240   return(ERROR(ERRSRV,ERRnosupport));
1241 }
1242    
1243 /****************************************************************************
1244  Reply to IOCTL - not implemented - no plans.
1245 ****************************************************************************/
1246
1247 static int call_nt_transact_ioctl(char *inbuf, char *outbuf, int length,
1248                                   int bufsize, int cnum,
1249                                   char **ppsetup, char **ppparams, char **ppdata)
1250 {
1251   DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n"));
1252   return(ERROR(ERRSRV,ERRnosupport));
1253 }
1254    
1255 /****************************************************************************
1256  Reply to a SMBNTtrans.
1257 ****************************************************************************/
1258
1259 int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
1260 {
1261   int  outsize = 0;
1262   int cnum = SVAL(inbuf,smb_tid);
1263 #if 0 /* Not used. */
1264   uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
1265   uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
1266   uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
1267 #endif /* Not used. */
1268   uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
1269   uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
1270   uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
1271   uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
1272   uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
1273   uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
1274   uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
1275   uint16 function_code = SVAL( inbuf, smb_nt_Function);
1276   char *params = NULL, *data = NULL, *setup = NULL;
1277   uint32 num_params_sofar, num_data_sofar;
1278
1279   if(global_oplock_break && (function_code == NT_TRANSACT_CREATE)) {
1280     /*
1281      * Queue this open message as we are the process of an oplock break.
1282      */
1283
1284     DEBUG(2,("reply_nttrans: queueing message NT_TRANSACT_CREATE \
1285 due to being in oplock break state.\n" ));
1286
1287     push_oplock_pending_smb_message( inbuf, length);
1288     return -1;
1289   }
1290
1291   outsize = set_message(outbuf,0,0,True);
1292
1293   /* 
1294    * All nttrans messages we handle have smb_wct == 19 + setup_count.
1295    * Ensure this is so as a sanity check.
1296    */
1297
1298   if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
1299     DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
1300           CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
1301     return(ERROR(ERRSRV,ERRerror));
1302   }
1303     
1304   /* Allocate the space for the setup, the maximum needed parameters and data */
1305
1306   if(setup_count > 0)
1307     setup = (char *)malloc(setup_count);
1308   if (total_parameter_count > 0)
1309     params = (char *)malloc(total_parameter_count);
1310   if (total_data_count > 0)
1311     data = (char *)malloc(total_data_count);
1312  
1313   if ((total_parameter_count && !params)  || (total_data_count && !data) ||
1314       (setup_count && !setup)) {
1315     DEBUG(0,("reply_nttrans : Out of memory\n"));
1316     return(ERROR(ERRDOS,ERRnomem));
1317   }
1318
1319   /* Copy the param and data bytes sent with this request into
1320      the params buffer */
1321   num_params_sofar = parameter_count;
1322   num_data_sofar = data_count;
1323
1324   if (parameter_count > total_parameter_count || data_count > total_data_count)
1325     exit_server("reply_nttrans: invalid sizes in packet.\n");
1326
1327   if(setup) {
1328     memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
1329     DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
1330     dump_data(10, setup, setup_count);
1331   }
1332   if(params) {
1333     memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
1334     DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
1335     dump_data(10, params, parameter_count);
1336   }
1337   if(data) {
1338     memcpy( data, smb_base(inbuf) + data_offset, data_count);
1339     DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
1340     dump_data(10, data, data_count);
1341   }
1342
1343   if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
1344     /* We need to send an interim response then receive the rest
1345        of the parameter/data bytes */
1346     outsize = set_message(outbuf,0,0,True);
1347     send_smb(Client,outbuf);
1348
1349     while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
1350       BOOL ret;
1351
1352       ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
1353                              SMB_SECONDARY_WAIT);
1354
1355       if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
1356         outsize = set_message(outbuf,0,0,True);
1357         if(ret)
1358           DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
1359         else
1360           DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
1361                 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
1362         if(params)
1363           free(params);
1364         if(data)
1365           free(data);
1366         if(setup)
1367           free(setup);
1368         return(ERROR(ERRSRV,ERRerror));
1369       }
1370       
1371       /* Revise total_params and total_data in case they have changed downwards */
1372       total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
1373       total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
1374       num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
1375       num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
1376       if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
1377         exit_server("reply_nttrans2: data overflow in secondary nttrans packet\n");
1378
1379       memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)], 
1380               smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
1381       memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
1382               smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
1383     }
1384   }
1385
1386   if (Protocol >= PROTOCOL_NT1) {
1387     uint16 flg2 = SVAL(outbuf,smb_flg2);
1388     SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1389   }
1390
1391   /* Now we must call the relevant NT_TRANS function */
1392   switch(function_code) {
1393     case NT_TRANSACT_CREATE:
1394       outsize = call_nt_transact_create(inbuf, outbuf, length, bufsize, cnum, 
1395                                         &setup, &params, &data);
1396       break;
1397     case NT_TRANSACT_IOCTL:
1398       outsize = call_nt_transact_ioctl(inbuf, outbuf, length, bufsize, cnum,
1399                                        &setup, &params, &data);
1400       break;
1401     case NT_TRANSACT_SET_SECURITY_DESC:
1402       outsize = call_nt_transact_set_security_desc(inbuf, outbuf, length, bufsize, cnum,
1403                                                    &setup, &params, &data);
1404       break;
1405     case NT_TRANSACT_NOTIFY_CHANGE:
1406       outsize = call_nt_transact_notify_change(inbuf, outbuf, length, bufsize, cnum,
1407                                                &setup, &params, &data);
1408       break;
1409     case NT_TRANSACT_RENAME:
1410       outsize = call_nt_transact_rename(inbuf, outbuf, length, bufsize, cnum,
1411                                         &setup, &params, &data);
1412       break;
1413     case NT_TRANSACT_QUERY_SECURITY_DESC:
1414       outsize = call_nt_transact_query_security_desc(inbuf, outbuf, length, bufsize, cnum,
1415                                                      &setup, &params, &data);
1416       break;
1417     default:
1418       /* Error in request */
1419       DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
1420       if(setup)
1421         free(setup);
1422       if(params)
1423         free(params);
1424       if(data)
1425         free(data);
1426       return (ERROR(ERRSRV,ERRerror));
1427   }
1428
1429   /* As we do not know how many data packets will need to be
1430      returned here the various call_nt_transact_xxxx calls
1431      must send their own. Thus a call_nt_transact_xxxx routine only
1432      returns a value other than -1 when it wants to send
1433      an error packet. 
1434   */
1435
1436   if(setup)
1437     free(setup);
1438   if(params)
1439     free(params);
1440   if(data)
1441     free(data);
1442   return outsize; /* If a correct response was needed the call_nt_transact_xxxx 
1443                      calls have already sent it. If outsize != -1 then it is
1444                      returning an error packet. */
1445 }