Implementing more NT SMB functionality.
[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  Save case statics.
52 ****************************************************************************/
53
54 static BOOL saved_case_sensitive;
55 static BOOL saved_case_preserve;
56 static BOOL saved_short_case_preserve;
57
58 /****************************************************************************
59  Save case semantics.
60 ****************************************************************************/
61
62 static void set_posix_case_semantics(uint32 file_attributes)
63 {
64   if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
65     return;
66
67   saved_case_sensitive = case_sensitive;
68   saved_case_preserve = case_preserve;
69   saved_short_case_preserve = short_case_preserve;
70
71   /* Set to POSIX. */
72   case_sensitive = True;
73   case_preserve = True;
74   short_case_preserve = True;
75 }
76
77 /****************************************************************************
78  Restore case semantics.
79 ****************************************************************************/
80
81 static void restore_case_semantics(uint32 file_attributes)
82 {
83   if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
84     return;
85
86   case_sensitive = saved_case_sensitive;
87   case_preserve = saved_case_preserve;
88   short_case_preserve = saved_short_case_preserve;
89 }
90
91 /****************************************************************************
92  Utility function to map create disposition.
93 ****************************************************************************/
94
95 static int map_create_disposition( uint32 create_disposition)
96 {
97   switch( create_disposition ) {
98   case CREATE_NEW:
99     /* create if not exist, fail if exist */
100     return 0x10;
101   case CREATE_ALWAYS:
102     /* create if not exist, trunc if exist */
103     return 0x12;
104   case OPEN_EXISTING:
105     /* fail if not exist, open if exists */
106     return 0x1;
107   case OPEN_ALWAYS:
108     /* create if not exist, open if exists */
109     return 0x11;
110   case TRUNCATE_EXISTING:
111     /* fail if not exist, truncate if exists */
112     return 0x2;
113   default:
114     DEBUG(0,("map_create_disposition: Incorrect value for create_disposition = %d\n",
115              create_disposition ));
116     return -1;
117   }
118 }
119
120 /****************************************************************************
121  Utility function to map share modes.
122 ****************************************************************************/
123
124 static int map_share_mode( uint32 desired_access, uint32 share_access)
125 {
126   int smb_open_mode;
127
128   switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA) ) {
129   case FILE_READ_DATA:
130     smb_open_mode = 0;
131     break;
132   case FILE_WRITE_DATA:
133     smb_open_mode = 1;
134     break;
135   case FILE_READ_DATA|FILE_WRITE_DATA:
136     smb_open_mode = 2;
137     break;
138   default:
139     DEBUG(0,("map_share_mode: Incorrect value for desired_access = %x\n",
140              desired_access));
141     return -1;
142   }
143
144   /* Add in the requested share mode - ignore FILE_SHARE_DELETE for now. */
145   switch( share_access & (FILE_SHARE_READ|FILE_SHARE_WRITE)) {
146   case FILE_SHARE_READ:
147     smb_open_mode |= (DENY_WRITE<<4);
148     break;
149   case FILE_SHARE_WRITE:
150     smb_open_mode |= (DENY_READ<<4);
151     break;
152   case (FILE_SHARE_READ|FILE_SHARE_WRITE):
153     smb_open_mode |= (DENY_NONE<<4);
154     break;
155   case FILE_SHARE_NONE:
156     smb_open_mode |= (DENY_ALL<<4);
157     break;
158   }
159
160   /*
161    * Handle a O_SYNC request.
162    */
163   if(file_attributes & FILE_FLAG_WRITE_THROUGH)
164     smb_open_mode |= (1<<14);
165
166   return smb_open_mode;
167 }
168
169 /****************************************************************************
170  Reply to an NT create and X call on a pipe.
171 ****************************************************************************/
172
173 static int nt_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
174 {
175   pstring fname;
176   int cnum = SVAL(inbuf,smb_tid);
177   int pnum = -1;
178   uint16 vuid = SVAL(inbuf, smb_uid);
179   uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
180   uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
181   uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
182   uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
183   uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
184   uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)),
185                          ((uint32)sizeof(fname)-1));
186   int smb_ofun;
187   int smb_open_mode;
188   int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
189   int unixmode;
190   int fmode=0,mtime=0,rmode=0;
191   off_t file_size = 0;
192   struct stat sbuf;
193   int smb_action = 0;
194   BOOL bad_path = False;
195   files_struct *fsp;
196   char *p = NULL;
197
198   StrnCpy(fname,smb_buf(inbuf),fname_len);
199     
200   DEBUG(4,("nt_open_pipe_and_X: Opening pipe %s.\n", fname));
201     
202   /* See if it is one we want to handle. */
203   for( i = 0; known_nt_pipes[i]; i++ )
204     if( strequal(fname,known_nt_pipes[i]))
205       break;
206     
207   if ( known_nt_pipes[i] == NULL )
208     return(ERROR(ERRSRV,ERRaccess));
209     
210   /* Strip \\ off the name. */
211   p = &fname[1];
212     
213   /* Known pipes arrive with DIR attribs. Remove it so a regular file */
214   /* can be opened and add it in after the open. */
215   DEBUG(3,("nt_open_pipe_and_X: Known pipe %s opening.\n",p));
216
217   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
218     return(ERROR(ERRDOS,ERRbadaccess));
219   smb_ofun |= 0x10;     /* Add Create it not exists flag */
220     
221   pnum = open_rpc_pipe_hnd(p, cnum, vuid);
222   if (pnum < 0)
223     return(ERROR(ERRSRV,ERRnofids));
224 }
225
226 /****************************************************************************
227  Reply to an NT create and X call.
228 ****************************************************************************/
229
230 int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize)
231 {  
232   pstring fname;
233   int cnum = SVAL(inbuf,smb_tid);
234   int fnum = -1;
235   uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
236   uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
237   uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
238   uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
239   uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
240   uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)),
241                          ((uint32)sizeof(fname)-1));
242   int smb_ofun;
243   int smb_open_mode;
244   int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
245   /* Breakout the oplock request bits so we can set the
246      reply bits separately. */
247   int oplock_request = flags & (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK);
248   int unixmode;
249   int fmode=0,mtime=0,rmode=0;
250   off_t file_size = 0;
251   struct stat sbuf;
252   int smb_action = 0;
253   BOOL bad_path = False;
254   files_struct *fsp;
255   char *p = NULL;
256   
257   /* If it's an IPC, pass off the pipe handler. */
258   if (IS_IPC(cnum))
259     return nt_open_pipe_and_X(inbuf,outbuf,length,bufsize);
260
261   /* If it's a request for a directory open, fail it. */
262   if(flags & OPEN_DIRECTORY)
263     return(ERROR(ERRDOS,ERRnoaccess));
264
265   /* 
266    * We need to construct the open_and_X ofun value from the
267    * NT values, as that's what our code is structured to accept.
268    */    
269
270   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
271     return(ERROR(ERRDOS,ERRbadaccess));
272
273   /*
274    * Now contruct the smb_open_mode value from the desired access
275    * and the share access.
276    */
277
278   if((smb_open_mode = map_share_mode( desired_access, share_access)) == -1)
279     return(ERROR(ERRDOS,ERRbadaccess));
280
281   /*
282    * Check if POSIX semantics are wanted.
283    */
284
285   set_posix_case_semantics(file_attributes);
286
287   StrnCpy(fname,smb_buf(inbuf),fname_len);
288   unix_convert(fname,cnum,0,&bad_path);
289     
290   fnum = find_free_file();
291   if (fnum < 0) {
292     restore_case_semantics(file_attributes);
293     return(ERROR(ERRSRV,ERRnofids));
294   }
295
296   if (!check_name(fname,cnum)) { 
297     if((errno == ENOENT) && bad_path) {
298       unix_ERR_class = ERRDOS;
299       unix_ERR_code = ERRbadpath;
300     }
301     Files[fnum].reserved = False;
302
303     restore_case_semantics(file_attributes);
304
305     return(UNIXERROR(ERRDOS,ERRnoaccess));
306   } 
307   
308   unixmode = unix_mode(cnum,smb_attr | aARCH);
309     
310   open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
311                    oplock_request,&rmode,&smb_action);
312
313   fsp = &Files[fnum];
314     
315   if (!fsp->open) { 
316     if((errno == ENOENT) && bad_path) {
317       unix_ERR_class = ERRDOS;
318       unix_ERR_code = ERRbadpath;
319     }
320     Files[fnum].reserved = False;
321
322     restore_case_semantics(file_attributes);
323
324     return(UNIXERROR(ERRDOS,ERRnoaccess));
325   } 
326   
327   if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
328     close_file(fnum,False);
329
330     restore_case_semantics(file_attributes);
331
332     return(ERROR(ERRDOS,ERRnoaccess));
333   } 
334   
335   restore_case_semantics(file_attributes);
336
337   size = sbuf.st_size;
338   fmode = dos_mode(cnum,fname,&sbuf);
339   mtime = sbuf.st_mtime;
340   if (fmode & aDIR) {
341     close_file(fnum,False);
342     return(ERROR(ERRDOS,ERRnoaccess));
343   } 
344   
345   /* If the caller set the extended oplock request bit
346      and we granted one (by whatever means) - set the
347      correct bit for extended oplock reply.
348    */
349     
350   if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
351     smb_action |= EXTENDED_OPLOCK_GRANTED;
352   } 
353   
354   if(oplock_request && fsp->granted_oplock) {
355     smb_action |= EXTENDED_OPLOCK_GRANTED;
356   } 
357   
358   set_message(outbuf,34,0,True);
359
360   p = outbuf + smb_vwv2;
361
362   /*
363    * Currently as we don't support level II oplocks we just report
364    * exclusive & batch here.
365    */
366
367   SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 3 : 0));
368   p++;
369   SSVAL(p,0,fnum);
370   p += 2;
371   SIVAL(p,0,smb_action);
372   p += 4;
373
374   /* Create time. */  
375   put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum))));
376   p += 8;
377   put_long_date(p,sbuf.st_atime); /* access time */
378   p += 8;
379   put_long_date(p,sbuf.st_mtime); /* write time */
380   p += 8;
381   put_long_date(p,sbuf.st_mtime); /* change time */
382   p += 8;
383   SIVAL(p,0,fmode); /* File Attributes. */
384   p += 12;
385   SIVAL(p,0, size & 0xFFFFFFFF);
386   SIVAL(p,4, (size >> 32));
387
388   chain_fnum = fnum;
389     
390   return chain_reply(inbuf,outbuf,length,bufsize);
391 }
392
393 /****************************************************************************
394  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
395 ****************************************************************************/
396
397 static int call_nt_transact_create(char *inbuf, char *outbuf, int bufsize, int cnum,
398                                    char **setup, char **params, char **data)
399 {
400   pstring fname;
401   int fnum = -1;
402   char *params = *pparams;
403   uint32 flags = IVAL(params,0);
404   uint32 desired_access = IVAL(params,8);
405   uint32 file_attributes = IVAL(params,20);
406   uint32 share_access = IVAL(params,24);
407   uint32 create_disposition = IVAL(params,28);
408   uint32 fname_len = MIN(((uint32)IVAL(params,44)),
409                          ((uint32)sizeof(fname)-1));
410   int smb_ofun;
411   int smb_open_mode;
412   int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
413
414   /* If it's a request for a directory open, fail it. */
415   if(flags & OPEN_DIRECTORY)
416     return(ERROR(ERRDOS,ERRnoaccess));
417
418   /* 
419    * We need to construct the open_and_X ofun value from the
420    * NT values, as that's what our code is structured to accept.
421    */    
422
423   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
424     return(ERROR(ERRDOS,ERRbadaccess));
425
426   /*
427    * Now contruct the smb_open_mode value from the desired access
428    * and the share access.
429    */
430
431   if((smb_open_mode = map_share_mode( desired_access, share_access)) == -1)
432     return(ERROR(ERRDOS,ERRbadaccess));
433
434   /*
435    * Check if POSIX semantics are wanted.
436    */
437
438   set_posix_case_semantics(file_attributes);
439
440   StrnCpy(fname,params+53,fname_len);
441   unix_convert(fname,cnum,0,&bad_path);
442     
443   fnum = find_free_file();
444   if (fnum < 0) {
445     restore_case_semantics(file_attributes);
446     return(ERROR(ERRSRV,ERRnofids));
447   }
448
449   if (!check_name(fname,cnum)) { 
450     if((errno == ENOENT) && bad_path) {
451       unix_ERR_class = ERRDOS;
452       unix_ERR_code = ERRbadpath;
453     }
454     Files[fnum].reserved = False;
455
456     restore_case_semantics(file_attributes);
457
458     return(UNIXERROR(ERRDOS,ERRnoaccess));
459   } 
460   
461   unixmode = unix_mode(cnum,smb_attr | aARCH);
462     
463   open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
464                    oplock_request,&rmode,&smb_action);
465
466   fsp = &Files[fnum];
467     
468   if (!fsp->open) { 
469     if((errno == ENOENT) && bad_path) {
470       unix_ERR_class = ERRDOS;
471       unix_ERR_code = ERRbadpath;
472     }
473     Files[fnum].reserved = False;
474
475     restore_case_semantics(file_attributes);
476
477     return(UNIXERROR(ERRDOS,ERRnoaccess));
478   } 
479   
480   if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
481     close_file(fnum,False);
482
483     restore_case_semantics(file_attributes);
484
485     return(ERROR(ERRDOS,ERRnoaccess));
486   } 
487   
488   restore_case_semantics(file_attributes);
489
490   size = sbuf.st_size;
491   fmode = dos_mode(cnum,fname,&sbuf);
492   mtime = sbuf.st_mtime;
493   if (fmode & aDIR) {
494     close_file(fnum,False);
495     return(ERROR(ERRDOS,ERRnoaccess));
496   } 
497   
498   /* If the caller set the extended oplock request bit
499      and we granted one (by whatever means) - set the
500      correct bit for extended oplock reply.
501    */
502     
503   if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
504     smb_action |= EXTENDED_OPLOCK_GRANTED;
505   } 
506   
507   if(oplock_request && fsp->granted_oplock) {
508     smb_action |= EXTENDED_OPLOCK_GRANTED;
509   } 
510
511 }
512
513 /****************************************************************************
514  Reply to a NT CANCEL request - just ignore it.
515 ****************************************************************************/
516
517 int reply_ntcancel(char *inbuf,char *outbuf,int length,int bufsize)
518 {
519   DEBUG(4,("Ignoring ntcancel of length %d\n",length));
520   return(-1);
521 }
522
523 /****************************************************************************
524  Reply to an unsolicited SMBNTtranss - just ignore it!
525 ****************************************************************************/
526
527 int reply_nttranss(char *inbuf,char *outbuf,int length,int bufsize)
528 {
529   DEBUG(4,("Ignoring nttranss of length %d\n",length));
530   return(-1);
531 }
532
533 /****************************************************************************
534  Reply to an NT transact rename command.
535 ****************************************************************************/
536
537 static int call_nt_transact_rename(char *inbuf, char *outbuf, int bufsize, int cnum,
538                                    char **setup, char **params, char **data)
539 {
540   char *params = *pparams;
541   pstring fname;
542   int fnum = SVAL(params, 0);
543   uint16 rename_flags = SVAL(params,2);
544   uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
545   uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
546                          ((uint32)sizeof(fname)-1));
547
548   StrnCpy(fname,params+4,fname_len);
549   unix_convert(fname,cnum,0,&bad_path);
550     
551 }
552    
553 /****************************************************************************
554  Reply to a notify change - we should never get this (for now) as we
555  don't allow a directory to be opened.
556 ****************************************************************************/
557
558 static int call_nt_transact_notify_change(char *inbuf, char *outbuf, int bufsize, int cnum,
559                                           char **setup, char **params, char **data)
560 {
561   DEBUG(0,("call_nt_transact_notify_change: Should not be called !\n"));
562   return(ERROR(ERRSRV,ERRnosupport));
563 }
564    
565 /****************************************************************************
566  Reply to query a security descriptor - currently this is not implemented (it
567  is planned to be though).
568 ****************************************************************************/
569
570 static int call_nt_transact_query_security_desc(char *inbuf, char *outbuf, int bufsize, int cnum,
571                                                 char **setup, char **params, char **data)
572 {
573   DEBUG(0,("call_nt_transact_query_security_desc: Currently not implemented.\n"));
574   return(ERROR(ERRSRV,ERRnosupport));
575 }
576    
577 /****************************************************************************
578  Reply to set a security descriptor - currently this is not implemented (it
579  is planned to be though).
580 ****************************************************************************/
581
582 static int call_nt_transact_set_security_desc(char *inbuf, char *outbuf, int bufsize, int cnum,
583                                               char **setup, char **params, char **data)
584 {
585   DEBUG(0,("call_nt_transact_set_security_desc: Currently not implemented.\n"));
586   return(ERROR(ERRSRV,ERRnosupport));
587 }
588    
589 /****************************************************************************
590  Reply to IOCTL - not implemented - no plans.
591 ****************************************************************************/
592
593 static int call_nt_transact_ioctl(char *inbuf, char *outbuf, int bufsize, int cnum,
594                                   char **setup, char **params, char **data)
595 {
596   DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n"));
597   return(ERROR(ERRSRV,ERRnosupport));
598 }
599    
600 /****************************************************************************
601  Reply to a SMBNTtrans.
602 ****************************************************************************/
603
604 int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
605 {
606   int outsize = 0;
607   int cnum = SVAL(inbuf,smb_tid);
608 #if 0 /* Not used. */
609   uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
610   uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
611   uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
612 #endif /* Not used. */
613   uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
614   uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
615   uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
616   uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
617   uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
618   uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
619   uint16 setup_count = CVAL(inbuf,smb_nt_SetupCount);
620   uint16 function_code = SVAL( inbuf, smb_nt_Function);
621   char *params = NULL, *data = NULL, *setup = NULL;
622   uint32 num_params_sofar, num_data_sofar;
623
624   if(global_oplock_break && (function_code == NT_TRANSACT_CREATE)) {
625     /*
626      * Queue this open message as we are the process of an oplock break.
627      */
628
629     DEBUG(2,("%s: reply_nttrans: queueing message NT_TRANSACT_CREATE \
630 due to being in oplock break state.\n", timestring() ));
631
632     push_smb_message( inbuf, length);
633     return -1;
634   }
635
636   outsize = set_message(outbuf,0,0,True);
637
638   /* 
639    * All nttrans messages we handle have smb_wcnt == 19 + setup_count.
640    * Ensure this is so as a sanity check.
641    */
642
643   if(CVAL(inbuf, smb_wcnt) != 19 + setup_count) {
644     DEBUG(2,("Invalid smb_wcnt in trans2 call\n"));
645     return(ERROR(ERRSRV,ERRerror));
646   }
647     
648   /* Allocate the space for the setup, the maximum needed parameters and data */
649
650   if(setup_count > 0)
651     setup = (char *)malloc(setup_count);
652   if (total_parameter_count > 0)
653     params = (char *)malloc(total_parameter_count);
654   if (total_data_count > 0)
655     data = (char *)malloc(total_data_count);
656  
657   if ((total_parameter_count && !params)  || (total_data_count && !data) ||
658       (setup_count && !setup)) {
659     DEBUG(0,("reply_nttrans : Out of memory\n"));
660     return(ERROR(ERRDOS,ERRnomem));
661   }
662
663   /* Copy the param and data bytes sent with this request into
664      the params buffer */
665   num_params_sofar = parameter_count;
666   num_data_sofar = data_count;
667
668   if (parameter_count > total_parameter_count || data_count > total_data_count)
669     exit_server("reply_nttrans: invalid sizes in packet.\n");
670
671   if(setup)
672     memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
673   if(params)
674     memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
675   if(data)
676     memcpy( data, smb_base(inbuf) + data_offset, data_count);
677
678   if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
679     /* We need to send an interim response then receive the rest
680        of the parameter/data bytes */
681     outsize = set_message(outbuf,0,0,True);
682     send_smb(Client,outbuf);
683
684     while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
685       BOOL ret;
686
687       ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
688                              SMB_SECONDARY_WAIT);
689
690       if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
691         outsize = set_message(outbuf,0,0,True);
692         if(ret)
693           DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
694         else
695           DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
696                 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
697         if(params)
698           free(params);
699         if(data)
700           free(data);
701         if(setup)
702           free(setup);
703         return(ERROR(ERRSRV,ERRerror));
704       }
705       
706       /* Revise total_params and total_data in case they have changed downwards */
707       total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
708       total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
709       num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
710       num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
711       if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
712         exit_server("reply_nttrans2: data overflow in secondary nttrans packet\n");
713
714       memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)], 
715               smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
716       memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
717               smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
718     }
719   }
720
721   if (Protocol >= PROTOCOL_NT1) {
722     uint16 flg2 = SVAL(outbuf,smb_flg2);
723     SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
724   }
725
726   /* Now we must call the relevant NT_TRANS function */
727   switch(function_code) {
728     case NT_TRANSACT_CREATE:
729       outsize = call_nt_transact_create(inbuf, outbuf, bufsize, cnum, 
730                                         &setup, &params, &data);
731       break;
732     case NT_TRANSACT_IOCTL:
733       outsize = call_nt_transact_ioctl(inbuf, outbuf, bufsize, cnum,
734                                        &setup, &params, &data);
735       break;
736     case NT_TRANSACT_SET_SECURITY_DESC:
737       outsize = call_nt_transact_set_security_desc(inbuf, outbuf, length, bufsize, cnum,
738                                                    &setup, &params, &data);
739       break;
740     case NT_TRANSACT_NOTIFY_CHANGE:
741       outsize = call_nt_transact_notify_change(inbuf, outbuf, length, bufsize, cnum,
742                                                &setup, &params, &data);
743       break;
744     case NT_TRANSACT_RENAME:
745       outsize = call_nt_transact_rename(inbuf, outbuf, length, bufsize, cnum,
746                                         &setup, &params, &data);
747       break;
748     case NT_TRANSACT_QUERY_SECURITY_DESC:
749       outsize = call_nt_transact_query_security_desc(inbuf, outbuf, length, bufsize, cnum,
750                                                      &setup, &params, &data, total_data);
751       break;
752     default:
753       /* Error in request */
754       DEBUG(0,("reply_nttrans: %s Unknown request %d in nttrans call\n",timestring(),
755                  tran_call));
756       if(setup)
757         free(setup);
758       if(params)
759         free(params);
760       if(data)
761         free(data);
762       return (ERROR(ERRSRV,ERRerror));
763   }
764
765   /* As we do not know how many data packets will need to be
766      returned here the various call_nt_transact_xxxx calls
767      must send their own. Thus a call_nt_transact_xxxx routine only
768      returns a value other than -1 when it wants to send
769      an error packet. 
770   */
771
772   if(setup)
773     free(setup);
774   if(params)
775     free(params);
776   if(data)
777     free(data);
778   return outsize; /* If a correct response was needed the call_nt_transact_xxxx 
779                      calls have already sent it. If outsize != -1 then it is
780                      returning an error packet. */
781 }