locking.c: Added lock type to is_locked() and do_lock()
[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   /* If it's a request for a directory open, fail it. */
428   if(flags & OPEN_DIRECTORY)
429     return(ERROR(ERRDOS,ERRnoaccess));
430
431   /* 
432    * We need to construct the open_and_X ofun value from the
433    * NT values, as that's what our code is structured to accept.
434    */    
435
436   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
437     return(ERROR(ERRDOS,ERRbadaccess));
438
439   /*
440    * Now contruct the smb_open_mode value from the desired access
441    * and the share access.
442    */
443
444   if((smb_open_mode = map_share_mode( desired_access, share_access, file_attributes)) == -1)
445     return(ERROR(ERRDOS,ERRbadaccess));
446
447   /*
448    * Get the file name.
449    */
450   StrnCpy(fname,smb_buf(inbuf),fname_len);
451   fname[fname_len] = '\0';
452
453   /* If it's an IPC, use the pipe handler. */
454   if (IS_IPC(cnum)) {
455     int ret = nt_open_pipe(fname, inbuf, outbuf, &fnum);
456     if(ret != 0)
457       return ret;
458     smb_action = FILE_WAS_OPENED;
459   } else {
460
461     /*
462      * Ordinary file.
463      */
464
465     /*
466      * Check if POSIX semantics are wanted.
467      */
468
469     set_posix_case_semantics(file_attributes);
470
471     unix_convert(fname,cnum,0,&bad_path);
472     
473     fnum = find_free_file();
474     if (fnum < 0) {
475       restore_case_semantics(file_attributes);
476       return(ERROR(ERRSRV,ERRnofids));
477     }
478
479     fsp = &Files[fnum];
480     
481     if (!check_name(fname,cnum)) { 
482       if((errno == ENOENT) && bad_path) {
483         unix_ERR_class = ERRDOS;
484         unix_ERR_code = ERRbadpath;
485       }
486       fsp->reserved = False;
487
488       restore_case_semantics(file_attributes);
489
490       return(UNIXERROR(ERRDOS,ERRnoaccess));
491     } 
492   
493     unixmode = unix_mode(cnum,smb_attr | aARCH);
494     
495     oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
496     oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
497
498     /*
499      * NB. We have a potential bug here. If we cause an oplock
500      * break to ourselves, then we could end up processing filename
501      * related SMB requests whilst we await the oplock break
502      * response. As we may have changed the filename case
503      * semantics to be POSIX-like, this could mean a filename
504      * request could fail when it should succeed. This is a
505      * rare condition, but eventually we must arrange to restore
506      * the correct case semantics before issuing an oplock break
507      * request to our client. JRA.
508      */
509
510     open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
511                      oplock_request,&rmode,&smb_action);
512
513     restore_case_semantics(file_attributes);
514
515     if (!fsp->open) { 
516       /*
517        * We cheat here. The only case we care about is a directory
518        * rename, where the NT client will attempt to open the source
519        * directory for DELETE access. Note that when the NT client
520        * does this it does *not* set the directory bit in the
521        * request packet. This is translated into a read/write open
522        * request. POSIX states that any open for write request on a directory
523        * will generate an EISDIR error, so we can catch this here and open
524        * a pseudo handle that is flagged as a directory. JRA.
525        */
526
527       if(errno == EISDIR) {
528         oplock_request = 0;
529         open_directory(fnum, cnum, fname, &smb_action);
530
531         if(!fsp->open) {
532           fsp->reserved = False;
533           return(UNIXERROR(ERRDOS,ERRnoaccess));
534         }
535       } else {
536         if((errno == ENOENT) && bad_path) {
537           unix_ERR_class = ERRDOS;
538           unix_ERR_code = ERRbadpath;
539         }
540
541         fsp->reserved = False;
542         return(UNIXERROR(ERRDOS,ERRnoaccess));
543       }
544     } 
545   
546     if(fsp->is_directory) {
547       if(stat(fsp->name, &sbuf) != 0) {
548         close_directory(fnum);
549         return(ERROR(ERRDOS,ERRnoaccess));
550       }
551     } else {
552       if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
553         close_file(fnum,False);
554         return(ERROR(ERRDOS,ERRnoaccess));
555       } 
556     }
557   
558     file_len = sbuf.st_size;
559     fmode = dos_mode(cnum,fname,&sbuf);
560     if(fmode == 0)
561       fmode = FILE_ATTRIBUTE_NORMAL;
562     mtime = sbuf.st_mtime;
563     if (!fsp->is_directory && (fmode & aDIR)) {
564       close_file(fnum,False);
565       return(ERROR(ERRDOS,ERRnoaccess));
566     } 
567   
568     /* 
569      * If the caller set the extended oplock request bit
570      * and we granted one (by whatever means) - set the
571      * correct bit for extended oplock reply.
572      */
573     
574     if (oplock_request && lp_fake_oplocks(SNUM(cnum)))
575       smb_action |= EXTENDED_OPLOCK_GRANTED;
576   
577     if(oplock_request && fsp->granted_oplock)
578       smb_action |= EXTENDED_OPLOCK_GRANTED;
579   }
580  
581   set_message(outbuf,34,0,True);
582
583   p = outbuf + smb_vwv2;
584
585   /*
586    * Currently as we don't support level II oplocks we just report
587    * exclusive & batch here.
588    */
589
590   SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
591   p++;
592   SSVAL(p,0,fnum);
593   p += 2;
594   SIVAL(p,0,smb_action);
595   p += 4;
596
597   if (IS_IPC(cnum)) {
598     /*
599      * Deal with pipe return.
600      */  
601     p += 32;
602     SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
603     p += 20;
604     /* File type. */
605     SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
606     /* Device state. */
607     SSVAL(p,2, 0x5FF); /* ? */
608   } else {
609     /*
610      * Deal with file return.
611      */  
612     /* Create time. */  
613     put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum))));
614     p += 8;
615     put_long_date(p,sbuf.st_atime); /* access time */
616     p += 8;
617     put_long_date(p,sbuf.st_mtime); /* write time */
618     p += 8;
619     put_long_date(p,sbuf.st_mtime); /* change time */
620     p += 8;
621     SIVAL(p,0,fmode); /* File Attributes. */
622     p += 12;
623 #if OFF_T_IS_64_BITS
624       SIVAL(p,0, file_len & 0xFFFFFFFF);
625       SIVAL(p,4, file_len >> 32);
626 #else /* OFF_T_IS_64_BITS */
627       SIVAL(p,0,file_len);
628 #endif /* OFF_T_IS_64_BITS */
629     p += 12;
630     SCVAL(p,0,fsp->is_directory ? 1 : 0);
631   }
632
633   chain_fnum = fnum;
634
635   return chain_reply(inbuf,outbuf,length,bufsize);
636 }
637
638 /****************************************************************************
639  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
640 ****************************************************************************/
641
642 static int call_nt_transact_create(char *inbuf, char *outbuf, int length, 
643                                    int bufsize, int cnum,
644                                    char **ppsetup, char **ppparams, char **ppdata)
645 {
646   pstring fname;
647   int fnum = -1;
648   char *params = *ppparams;
649   uint32 flags = IVAL(params,0);
650   uint32 desired_access = IVAL(params,8);
651   uint32 file_attributes = IVAL(params,20);
652   uint32 share_access = IVAL(params,24);
653   uint32 create_disposition = IVAL(params,28);
654   uint32 fname_len = MIN(((uint32)IVAL(params,44)),
655                          ((uint32)sizeof(fname)-1));
656   int smb_ofun;
657   int smb_open_mode;
658   int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
659   /* Breakout the oplock request bits so we can set the
660      reply bits separately. */
661   int oplock_request = 0;
662   int unixmode;
663   int fmode=0,mtime=0,rmode=0;
664   off_t file_len = 0;
665   struct stat sbuf;
666   int smb_action = 0;
667   BOOL bad_path = False;
668   files_struct *fsp;
669   char *p = NULL;
670
671   /* If it's a request for a directory open, fail it. */
672   if(flags & OPEN_DIRECTORY)
673     return(ERROR(ERRDOS,ERRnoaccess));
674
675   /* 
676    * We need to construct the open_and_X ofun value from the
677    * NT values, as that's what our code is structured to accept.
678    */    
679
680   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
681     return(ERROR(ERRDOS,ERRbadaccess));
682
683   /*
684    * Now contruct the smb_open_mode value from the desired access
685    * and the share access.
686    */
687
688   if((smb_open_mode = map_share_mode( desired_access, share_access, file_attributes)) == -1)
689     return(ERROR(ERRDOS,ERRbadaccess));
690
691   /*
692    * Get the file name.
693    */
694
695   StrnCpy(fname,params+53,fname_len);
696   fname[fname_len] = '\0';
697
698   /* If it's an IPC, use the pipe handler. */
699   if (IS_IPC(cnum)) {
700     int ret = nt_open_pipe(fname, inbuf, outbuf, &fnum);
701     if(ret != 0)
702       return ret;
703     smb_action = FILE_WAS_OPENED;
704   } else {
705     /*
706      * Check if POSIX semantics are wanted.
707      */
708
709     set_posix_case_semantics(file_attributes);
710
711     unix_convert(fname,cnum,0,&bad_path);
712     
713     fnum = find_free_file();
714     if (fnum < 0) {
715       restore_case_semantics(file_attributes);
716       return(ERROR(ERRSRV,ERRnofids));
717     }
718
719     if (!check_name(fname,cnum)) { 
720       if((errno == ENOENT) && bad_path) {
721         unix_ERR_class = ERRDOS;
722         unix_ERR_code = ERRbadpath;
723       }
724       Files[fnum].reserved = False;
725
726       restore_case_semantics(file_attributes);
727
728       return(UNIXERROR(ERRDOS,ERRnoaccess));
729     } 
730   
731     unixmode = unix_mode(cnum,smb_attr | aARCH);
732     
733     oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
734     oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
735
736     open_file_shared(fnum,cnum,fname,smb_open_mode,smb_ofun,unixmode,
737                      oplock_request,&rmode,&smb_action);
738
739     fsp = &Files[fnum];
740     
741     if (!fsp->open) { 
742       if((errno == ENOENT) && bad_path) {
743         unix_ERR_class = ERRDOS;
744         unix_ERR_code = ERRbadpath;
745       }
746       Files[fnum].reserved = False;
747
748       restore_case_semantics(file_attributes);
749
750       return(UNIXERROR(ERRDOS,ERRnoaccess));
751     } 
752   
753     if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
754       close_file(fnum,False);
755
756       restore_case_semantics(file_attributes);
757
758       return(ERROR(ERRDOS,ERRnoaccess));
759     } 
760   
761     restore_case_semantics(file_attributes);
762
763     file_len = sbuf.st_size;
764     fmode = dos_mode(cnum,fname,&sbuf);
765     if(fmode == 0)
766       fmode = FILE_ATTRIBUTE_NORMAL;
767     mtime = sbuf.st_mtime;
768     if (fmode & aDIR) {
769       close_file(fnum,False);
770       return(ERROR(ERRDOS,ERRnoaccess));
771     } 
772   
773     /* 
774      * If the caller set the extended oplock request bit
775      * and we granted one (by whatever means) - set the
776      * correct bit for extended oplock reply.
777      */
778     
779     if (oplock_request && lp_fake_oplocks(SNUM(cnum)))
780       smb_action |= EXTENDED_OPLOCK_GRANTED;
781   
782     if(oplock_request && fsp->granted_oplock)
783       smb_action |= EXTENDED_OPLOCK_GRANTED;
784   }
785
786   /* Realloc the size of parameters and data we will return */
787   params = *ppparams = Realloc(*ppparams, 69);
788   if(params == NULL)
789     return(ERROR(ERRDOS,ERRnomem));
790
791   p = params;
792   SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
793   p += 2;
794   SSVAL(p,0,fnum);
795   p += 2;
796   SIVAL(p,0,smb_action);
797   p += 8;
798
799   if (IS_IPC(cnum)) {
800     /*
801      * Deal with pipe return.
802      */  
803     p += 32;
804     SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
805     p += 20;
806     /* File type. */
807     SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
808     /* Device state. */
809     SSVAL(p,2, 0x5FF); /* ? */
810   } else {
811     /*
812      * Deal with file return.
813      */
814     /* Create time. */
815     put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(cnum))));
816     p += 8;
817     put_long_date(p,sbuf.st_atime); /* access time */
818     p += 8;
819     put_long_date(p,sbuf.st_mtime); /* write time */
820     p += 8;
821     put_long_date(p,sbuf.st_mtime); /* change time */
822     p += 8;
823     SIVAL(p,0,fmode); /* File Attributes. */
824     p += 12;
825 #if OFF_T_IS_64_BITS
826       SIVAL(p,0, file_len & 0xFFFFFFFF);
827       SIVAL(p,4, (file_len >> 32));
828 #else /* OFF_T_IS_64_BITS */
829       SIVAL(p,0,file_len);
830 #endif /* OFF_T_IS_64_BITS */
831   }
832
833   /* Send the required number of replies */
834   send_nt_replies(outbuf, bufsize, params, 69, *ppdata, 0);
835
836   return -1;
837 }
838
839 /****************************************************************************
840  Reply to a NT CANCEL request - just ignore it.
841 ****************************************************************************/
842
843 int reply_ntcancel(char *inbuf,char *outbuf,int length,int bufsize)
844 {
845   DEBUG(4,("Ignoring ntcancel of length %d\n",length));
846   return(-1);
847 }
848
849 /****************************************************************************
850  Reply to an unsolicited SMBNTtranss - just ignore it!
851 ****************************************************************************/
852
853 int reply_nttranss(char *inbuf,char *outbuf,int length,int bufsize)
854 {
855   DEBUG(4,("Ignoring nttranss of length %d\n",length));
856   return(-1);
857 }
858
859 /****************************************************************************
860  Reply to an NT transact rename command.
861 ****************************************************************************/
862
863 static int call_nt_transact_rename(char *inbuf, char *outbuf, int length, 
864                                    int bufsize, int cnum,
865                                    char **ppsetup, char **ppparams, char **ppdata)
866 {
867   char *params = *ppparams;
868   pstring new_name;
869   int fnum = SVAL(params, 0);
870   BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
871   uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
872                          ((uint32)sizeof(new_name)-1));
873   int outsize = 0;
874
875   CHECK_FNUM(fnum, cnum);
876   StrnCpy(new_name,params+4,fname_len);
877   new_name[fname_len] = '\0';
878
879   outsize = rename_internals(inbuf, outbuf, Files[fnum].name,
880                              new_name, replace_if_exists);
881   if(outsize == 0) {
882     /*
883      * Rename was successful.
884      */
885     send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0);
886     outsize = -1;
887   }
888
889   return(outsize);
890 }
891    
892 /****************************************************************************
893  Reply to a notify change - we should never get this (for now) as we
894  don't allow a directory to be opened.
895 ****************************************************************************/
896
897 static int call_nt_transact_notify_change(char *inbuf, char *outbuf, int length,
898                                           int bufsize, int cnum,
899                                           char **ppsetup, char **ppparams, char **ppdata)
900 {
901   DEBUG(0,("call_nt_transact_notify_change: Should not be called !\n"));
902   return(ERROR(ERRSRV,ERRnosupport));
903 }
904    
905 /****************************************************************************
906  Reply to query a security descriptor - currently this is not implemented (it
907  is planned to be though).
908 ****************************************************************************/
909
910 static int call_nt_transact_query_security_desc(char *inbuf, char *outbuf, int length, 
911                                                 int bufsize, int cnum,
912                                                 char **ppsetup, char **ppparams, char **ppdata)
913 {
914   DEBUG(0,("call_nt_transact_query_security_desc: Currently not implemented.\n"));
915   return(ERROR(ERRSRV,ERRnosupport));
916 }
917    
918 /****************************************************************************
919  Reply to set a security descriptor - currently this is not implemented (it
920  is planned to be though).
921 ****************************************************************************/
922
923 static int call_nt_transact_set_security_desc(char *inbuf, char *outbuf, int length,
924                                               int bufsize, int cnum,
925                                               char **ppsetup, char **ppparams, char **ppdata)
926 {
927   DEBUG(0,("call_nt_transact_set_security_desc: Currently not implemented.\n"));
928   return(ERROR(ERRSRV,ERRnosupport));
929 }
930    
931 /****************************************************************************
932  Reply to IOCTL - not implemented - no plans.
933 ****************************************************************************/
934
935 static int call_nt_transact_ioctl(char *inbuf, char *outbuf, int length,
936                                   int bufsize, int cnum,
937                                   char **ppsetup, char **ppparams, char **ppdata)
938 {
939   DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n"));
940   return(ERROR(ERRSRV,ERRnosupport));
941 }
942    
943 /****************************************************************************
944  Reply to a SMBNTtrans.
945 ****************************************************************************/
946
947 int reply_nttrans(char *inbuf,char *outbuf,int length,int bufsize)
948 {
949   int outsize = 0;
950   int cnum = SVAL(inbuf,smb_tid);
951 #if 0 /* Not used. */
952   uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
953   uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
954   uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
955 #endif /* Not used. */
956   uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
957   uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
958   uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
959   uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
960   uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
961   uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
962   uint16 setup_count = CVAL(inbuf,smb_nt_SetupCount);
963   uint16 function_code = SVAL( inbuf, smb_nt_Function);
964   char *params = NULL, *data = NULL, *setup = NULL;
965   uint32 num_params_sofar, num_data_sofar;
966
967   if(global_oplock_break && (function_code == NT_TRANSACT_CREATE)) {
968     /*
969      * Queue this open message as we are the process of an oplock break.
970      */
971
972     DEBUG(2,("%s: reply_nttrans: queueing message NT_TRANSACT_CREATE \
973 due to being in oplock break state.\n", timestring() ));
974
975     push_smb_message( inbuf, length);
976     return -1;
977   }
978
979   outsize = set_message(outbuf,0,0,True);
980
981   /* 
982    * All nttrans messages we handle have smb_wct == 19 + setup_count.
983    * Ensure this is so as a sanity check.
984    */
985
986   if(CVAL(inbuf, smb_wct) != 19 + setup_count) {
987     DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
988           CVAL(inbuf, smb_wct), 19 + setup_count));
989     return(ERROR(ERRSRV,ERRerror));
990   }
991     
992   /* Allocate the space for the setup, the maximum needed parameters and data */
993
994   if(setup_count > 0)
995     setup = (char *)malloc(setup_count);
996   if (total_parameter_count > 0)
997     params = (char *)malloc(total_parameter_count);
998   if (total_data_count > 0)
999     data = (char *)malloc(total_data_count);
1000  
1001   if ((total_parameter_count && !params)  || (total_data_count && !data) ||
1002       (setup_count && !setup)) {
1003     DEBUG(0,("reply_nttrans : Out of memory\n"));
1004     return(ERROR(ERRDOS,ERRnomem));
1005   }
1006
1007   /* Copy the param and data bytes sent with this request into
1008      the params buffer */
1009   num_params_sofar = parameter_count;
1010   num_data_sofar = data_count;
1011
1012   if (parameter_count > total_parameter_count || data_count > total_data_count)
1013     exit_server("reply_nttrans: invalid sizes in packet.\n");
1014
1015   if(setup)
1016     memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
1017   if(params)
1018     memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
1019   if(data)
1020     memcpy( data, smb_base(inbuf) + data_offset, data_count);
1021
1022   if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
1023     /* We need to send an interim response then receive the rest
1024        of the parameter/data bytes */
1025     outsize = set_message(outbuf,0,0,True);
1026     send_smb(Client,outbuf);
1027
1028     while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
1029       BOOL ret;
1030
1031       ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
1032                              SMB_SECONDARY_WAIT);
1033
1034       if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
1035         outsize = set_message(outbuf,0,0,True);
1036         if(ret)
1037           DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
1038         else
1039           DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
1040                 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
1041         if(params)
1042           free(params);
1043         if(data)
1044           free(data);
1045         if(setup)
1046           free(setup);
1047         return(ERROR(ERRSRV,ERRerror));
1048       }
1049       
1050       /* Revise total_params and total_data in case they have changed downwards */
1051       total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
1052       total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
1053       num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
1054       num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
1055       if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
1056         exit_server("reply_nttrans2: data overflow in secondary nttrans packet\n");
1057
1058       memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)], 
1059               smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
1060       memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
1061               smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
1062     }
1063   }
1064
1065   if (Protocol >= PROTOCOL_NT1) {
1066     uint16 flg2 = SVAL(outbuf,smb_flg2);
1067     SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1068   }
1069
1070   /* Now we must call the relevant NT_TRANS function */
1071   switch(function_code) {
1072     case NT_TRANSACT_CREATE:
1073       outsize = call_nt_transact_create(inbuf, outbuf, length, bufsize, cnum, 
1074                                         &setup, &params, &data);
1075       break;
1076     case NT_TRANSACT_IOCTL:
1077       outsize = call_nt_transact_ioctl(inbuf, outbuf, length, bufsize, cnum,
1078                                        &setup, &params, &data);
1079       break;
1080     case NT_TRANSACT_SET_SECURITY_DESC:
1081       outsize = call_nt_transact_set_security_desc(inbuf, outbuf, length, bufsize, cnum,
1082                                                    &setup, &params, &data);
1083       break;
1084     case NT_TRANSACT_NOTIFY_CHANGE:
1085       outsize = call_nt_transact_notify_change(inbuf, outbuf, length, bufsize, cnum,
1086                                                &setup, &params, &data);
1087       break;
1088     case NT_TRANSACT_RENAME:
1089       outsize = call_nt_transact_rename(inbuf, outbuf, length, bufsize, cnum,
1090                                         &setup, &params, &data);
1091       break;
1092     case NT_TRANSACT_QUERY_SECURITY_DESC:
1093       outsize = call_nt_transact_query_security_desc(inbuf, outbuf, length, bufsize, cnum,
1094                                                      &setup, &params, &data);
1095       break;
1096     default:
1097       /* Error in request */
1098       DEBUG(0,("reply_nttrans: %s Unknown request %d in nttrans call\n",timestring(),
1099                  function_code));
1100       if(setup)
1101         free(setup);
1102       if(params)
1103         free(params);
1104       if(data)
1105         free(data);
1106       return (ERROR(ERRSRV,ERRerror));
1107   }
1108
1109   /* As we do not know how many data packets will need to be
1110      returned here the various call_nt_transact_xxxx calls
1111      must send their own. Thus a call_nt_transact_xxxx routine only
1112      returns a value other than -1 when it wants to send
1113      an error packet. 
1114   */
1115
1116   if(setup)
1117     free(setup);
1118   if(params)
1119     free(params);
1120   if(data)
1121     free(data);
1122   return outsize; /* If a correct response was needed the call_nt_transact_xxxx 
1123                      calls have already sent it. If outsize != -1 then it is
1124                      returning an error packet. */
1125 }