fixed nttrans.c
[tprouty/samba.git] / source / smbd / nttrans.c
1 #define OLD_NTDOMAIN 1
2 /*
3    Unix SMB/Netbios implementation.
4    Version 1.9.
5    SMB NT transaction handling
6    Copyright (C) Jeremy Allison 1994-1998
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 extern int DEBUGLEVEL;
26 extern int Protocol;
27 extern int smb_read_error;
28 extern int global_oplock_break;
29 extern BOOL case_sensitive;
30 extern BOOL case_preserve;
31 extern BOOL short_case_preserve;
32
33 static void remove_pending_change_notify_requests_by_mid(int mid);
34
35 static char *known_nt_pipes[] = {
36   "\\LANMAN",
37   "\\srvsvc",
38   "\\samr",
39   "\\wkssvc",
40   "\\NETLOGON",
41   "\\ntlsa",
42   "\\ntsvcs",
43   "\\lsass",
44   "\\lsarpc",
45   "\\winreg",
46   "\\spoolss",
47 #ifdef WITH_MSDFS
48   "\\netdfs",
49 #endif
50   NULL
51 };
52
53 /****************************************************************************
54  Send the required number of replies back.
55  We assume all fields other than the data fields are
56  set correctly for the type of call.
57  HACK ! Always assumes smb_setup field is zero.
58 ****************************************************************************/
59
60 static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_error, char *params,
61                            int paramsize, char *pdata, int datasize)
62 {
63   extern int max_send;
64   int data_to_send = datasize;
65   int params_to_send = paramsize;
66   int useable_space;
67   char *pp = params;
68   char *pd = pdata;
69   int params_sent_thistime, data_sent_thistime, total_sent_thistime;
70   int alignment_offset = 3;
71   int data_alignment_offset = 0;
72
73   /*
74    * Initially set the wcnt area to be 18 - this is true for all
75    * transNT replies.
76    */
77
78   set_message(outbuf,18,0,True);
79
80   if(nt_error != 0) {
81     /* NT Error. */
82     SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
83
84     ERROR(0,nt_error);
85   }
86
87   /* 
88    * If there genuinely are no parameters or data to send just send
89    * the empty packet.
90    */
91
92   if(params_to_send == 0 && data_to_send == 0) {
93     send_smb(smbd_server_fd(),outbuf);
94     return 0;
95   }
96
97   /*
98    * When sending params and data ensure that both are nicely aligned.
99    * Only do this alignment when there is also data to send - else
100    * can cause NT redirector problems.
101    */
102
103   if (((params_to_send % 4) != 0) && (data_to_send != 0))
104     data_alignment_offset = 4 - (params_to_send % 4);
105
106   /* 
107    * Space is bufsize minus Netbios over TCP header minus SMB header.
108    * The alignment_offset is to align the param bytes on a four byte
109    * boundary (2 bytes for data len, one byte pad). 
110    * NT needs this to work correctly.
111    */
112
113   useable_space = bufsize - ((smb_buf(outbuf)+
114                     alignment_offset+data_alignment_offset) -
115                     outbuf);
116
117   /*
118    * useable_space can never be more than max_send minus the
119    * alignment offset.
120    */
121
122   useable_space = MIN(useable_space,
123                       max_send - (alignment_offset+data_alignment_offset));
124
125
126   while (params_to_send || data_to_send) {
127
128     /*
129      * Calculate whether we will totally or partially fill this packet.
130      */
131
132     total_sent_thistime = params_to_send + data_to_send +
133                             alignment_offset + data_alignment_offset;
134
135     /* 
136      * We can never send more than useable_space.
137      */
138
139     total_sent_thistime = MIN(total_sent_thistime, useable_space);
140
141     set_message(outbuf, 18, total_sent_thistime, True);
142
143     /*
144      * Set total params and data to be sent.
145      */
146
147     SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
148     SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
149
150     /* 
151      * Calculate how many parameters and data we can fit into
152      * this packet. Parameters get precedence.
153      */
154
155     params_sent_thistime = MIN(params_to_send,useable_space);
156     data_sent_thistime = useable_space - params_sent_thistime;
157     data_sent_thistime = MIN(data_sent_thistime,data_to_send);
158
159     SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
160
161     if(params_sent_thistime == 0) {
162       SIVAL(outbuf,smb_ntr_ParameterOffset,0);
163       SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
164     } else {
165       /*
166        * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
167        * parameter bytes, however the first 4 bytes of outbuf are
168        * the Netbios over TCP header. Thus use smb_base() to subtract
169        * them from the calculation.
170        */
171
172       SIVAL(outbuf,smb_ntr_ParameterOffset,
173             ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
174       /* 
175        * Absolute displacement of param bytes sent in this packet.
176        */
177
178       SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
179     }
180
181     /*
182      * Deal with the data portion.
183      */
184
185     SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
186
187     if(data_sent_thistime == 0) {
188       SIVAL(outbuf,smb_ntr_DataOffset,0);
189       SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
190     } else {
191       /*
192        * The offset of the data bytes is the offset of the
193        * parameter bytes plus the number of parameters being sent this time.
194        */
195
196       SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
197             smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
198       SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
199     }
200
201     /* 
202      * Copy the param bytes into the packet.
203      */
204
205     if(params_sent_thistime)
206       memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
207
208     /*
209      * Copy in the data bytes
210      */
211
212     if(data_sent_thistime)
213       memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
214              data_alignment_offset,pd,data_sent_thistime);
215     
216     DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
217           params_sent_thistime, data_sent_thistime, useable_space));
218     DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
219           params_to_send, data_to_send, paramsize, datasize));
220     
221     /* Send the packet */
222     send_smb(smbd_server_fd(),outbuf);
223     
224     pp += params_sent_thistime;
225     pd += data_sent_thistime;
226     
227     params_to_send -= params_sent_thistime;
228     data_to_send -= data_sent_thistime;
229
230     /*
231      * Sanity check
232      */
233
234     if(params_to_send < 0 || data_to_send < 0) {
235       DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
236             params_to_send, data_to_send));
237       return -1;
238     }
239   } 
240
241   return 0;
242 }
243
244 /****************************************************************************
245  (Hopefully) temporary call to fix bugs in NT5.0beta2. This OS sends unicode
246  strings in NT calls AND DOESN'T SET THE UNICODE BIT !!!!!!!
247 ****************************************************************************/
248
249 static void get_filename( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
250 {
251   /*
252    * We need various heuristics here to detect a unicode string... JRA.
253    */
254
255   DEBUG(10,("get_filename: data_offset = %d, data_len = %d, fname_len = %d\n",
256            data_offset, data_len, fname_len ));
257
258   if(data_len - fname_len > 1) {
259     /*
260      * NT 5.0 Beta 2 has kindly sent us a UNICODE string
261      * without bothering to set the unicode bit. How kind.
262      *
263      * Firstly - ensure that the data offset is aligned
264      * on a 2 byte boundary - add one if not.
265      */
266     fname_len = fname_len/2;
267     if(data_offset & 1)
268       data_offset++;
269     pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
270   } else {
271     StrnCpy(fname,inbuf+data_offset,fname_len);
272     fname[fname_len] = '\0';
273   }
274 }
275
276 /****************************************************************************
277  Fix bugs in Win2000 final release. In trans calls this OS sends unicode
278  strings AND DOESN'T SET THE UNICODE BIT !!!!!!!
279 ****************************************************************************/
280
281 static void get_filename_transact( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
282 {
283   /*
284    * We need various heuristics here to detect a unicode string... JRA.
285    */
286
287   DEBUG(10,("get_filename_transact: data_offset = %d, data_len = %d, fname_len = %d\n",
288            data_offset, data_len, fname_len ));
289
290   /*
291    * Win2K sends a unicode filename plus one extra alingment byte.
292    * WinNT4.x send an ascii string with multiple garbage bytes on
293    * the end here.
294    */
295
296   if((data_len - fname_len == 1) || (inbuf[data_offset] == '\0')) {
297     /*
298      * Ensure that the data offset is aligned
299      * on a 2 byte boundary - add one if not.
300      */
301     fname_len = fname_len/2;
302     if(data_offset & 1)
303       data_offset++;
304     pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
305   } else {
306     StrnCpy(fname,inbuf+data_offset,fname_len);
307     fname[fname_len] = '\0';
308   }
309 }
310
311 /****************************************************************************
312  Save case statics.
313 ****************************************************************************/
314
315 static BOOL saved_case_sensitive;
316 static BOOL saved_case_preserve;
317 static BOOL saved_short_case_preserve;
318
319 /****************************************************************************
320  Save case semantics.
321 ****************************************************************************/
322
323 static void set_posix_case_semantics(uint32 file_attributes)
324 {
325   if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
326     return;
327
328   saved_case_sensitive = case_sensitive;
329   saved_case_preserve = case_preserve;
330   saved_short_case_preserve = short_case_preserve;
331
332   /* Set to POSIX. */
333   case_sensitive = True;
334   case_preserve = True;
335   short_case_preserve = True;
336 }
337
338 /****************************************************************************
339  Restore case semantics.
340 ****************************************************************************/
341
342 static void restore_case_semantics(uint32 file_attributes)
343 {
344   if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
345     return;
346
347   case_sensitive = saved_case_sensitive;
348   case_preserve = saved_case_preserve;
349   short_case_preserve = saved_short_case_preserve;
350 }
351
352 /****************************************************************************
353  Utility function to map create disposition.
354 ****************************************************************************/
355
356 static int map_create_disposition( uint32 create_disposition)
357 {
358   int ret;
359
360   switch( create_disposition ) {
361   case FILE_CREATE:
362     /* create if not exist, fail if exist */
363     ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL);
364     break;
365   case FILE_SUPERSEDE:
366   case FILE_OVERWRITE_IF:
367     /* create if not exist, trunc if exist */
368     ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE);
369     break;
370   case FILE_OPEN:
371     /* fail if not exist, open if exists */
372     ret = (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN);
373     break;
374   case FILE_OPEN_IF:
375     /* create if not exist, open if exists */
376     ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_OPEN);
377     break;
378   case FILE_OVERWRITE:
379     /* fail if not exist, truncate if exists */
380     ret = (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE);
381     break;
382   default:
383     DEBUG(0,("map_create_disposition: Incorrect value for create_disposition = %d\n",
384              create_disposition ));
385     return -1;
386   }
387
388   DEBUG(10,("map_create_disposition: Mapped create_disposition %lx to %x\n",
389         (unsigned long)create_disposition, ret ));
390
391   return ret;
392 }
393
394 /****************************************************************************
395  Utility function to map share modes.
396 ****************************************************************************/
397
398 static int map_share_mode( BOOL *pstat_open_only, char *fname,
399                                                         uint32 desired_access, uint32 share_access, uint32 file_attributes)
400 {
401   int smb_open_mode = -1;
402
403   *pstat_open_only = False;
404
405   switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA) ) {
406   case FILE_READ_DATA:
407     smb_open_mode = DOS_OPEN_RDONLY;
408     break;
409   case FILE_WRITE_DATA:
410   case FILE_APPEND_DATA:
411   case FILE_WRITE_DATA|FILE_APPEND_DATA:
412     smb_open_mode = DOS_OPEN_WRONLY;
413     break;
414   case FILE_READ_DATA|FILE_WRITE_DATA:
415   case FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA:
416   case FILE_READ_DATA|FILE_APPEND_DATA:
417     smb_open_mode = DOS_OPEN_RDWR;
418     break;
419   }
420
421   /*
422    * NB. For DELETE_ACCESS we should really check the
423    * directory permissions, as that is what controls
424    * delete, and for WRITE_DAC_ACCESS we should really
425    * check the ownership, as that is what controls the
426    * chmod. Note that this is *NOT* a security hole (this
427    * note is for you, Andrew) as we are not *allowing*
428    * the access at this point, the actual unlink or
429    * chown or chmod call would do this. We are just helping
430    * clients out by telling them if they have a hope
431    * of any of this succeeding. POSIX acls may still
432    * deny the real call. JRA.
433    */
434
435   if (smb_open_mode == -1) {
436         if(desired_access == WRITE_DAC_ACCESS || desired_access == READ_CONTROL_ACCESS)
437                 *pstat_open_only = True;
438
439     if(desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
440                               FILE_EXECUTE|FILE_READ_ATTRIBUTES|
441                               FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
442                               FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS))
443       smb_open_mode = DOS_OPEN_RDONLY;
444     else {
445       DEBUG(0,("map_share_mode: Incorrect value %lx for desired_access to file %s\n",
446              (unsigned long)desired_access, fname));
447       return -1;
448     }
449   }
450
451   /*
452    * Set the special bit that means allow share delete.
453    * This is held outside the normal share mode bits at 1<<15.
454    * JRA.
455    */
456
457   if(share_access & FILE_SHARE_DELETE)
458     smb_open_mode |= ALLOW_SHARE_DELETE;
459
460   /* Add in the requested share mode. */
461   switch( share_access & (FILE_SHARE_READ|FILE_SHARE_WRITE)) {
462   case FILE_SHARE_READ:
463     smb_open_mode |= SET_DENY_MODE(DENY_WRITE);
464     break;
465   case FILE_SHARE_WRITE:
466     smb_open_mode |= SET_DENY_MODE(DENY_READ);
467     break;
468   case (FILE_SHARE_READ|FILE_SHARE_WRITE):
469     smb_open_mode |= SET_DENY_MODE(DENY_NONE);
470     break;
471   case FILE_SHARE_NONE:
472     smb_open_mode |= SET_DENY_MODE(DENY_ALL);
473     break;
474   }
475
476   /*
477    * Handle an O_SYNC request.
478    */
479
480   if(file_attributes & FILE_FLAG_WRITE_THROUGH)
481     smb_open_mode |= FILE_SYNC_OPENMODE;
482
483   DEBUG(10,("map_share_mode: Mapped desired access %lx, share access %lx, file attributes %lx \
484 to open_mode %x\n", (unsigned long)desired_access, (unsigned long)share_access,
485                     (unsigned long)file_attributes, smb_open_mode ));
486  
487   return smb_open_mode;
488 }
489
490 /*
491  * This is a *disgusting* hack.
492  * This is *so* bad that even I'm embarrassed (and I
493  * have no shame). Here's the deal :
494  * Until we get the correct SPOOLSS code into smbd
495  * then when we're running with NT SMB support then
496  * NT makes this call with a level of zero, and then
497  * immediately follows it with an open request to
498  * the \\SRVSVC pipe. If we allow that open to
499  * succeed then NT barfs when it cannot open the
500  * \\SPOOLSS pipe immediately after and continually
501  * whines saying "Printer name is invalid" forever
502  * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
503  * to fail, then NT downgrades to using the downlevel code
504  * and everything works as well as before. I hate
505  * myself for adding this code.... JRA.
506  *
507  * The HACK_FAIL_TIME define allows only a 2
508  * second window for this to occur, just in
509  * case...
510  */
511
512 static BOOL fail_next_srvsvc = False;
513 static time_t fail_time;
514 #define HACK_FAIL_TIME 2 /* In seconds. */
515
516 void fail_next_srvsvc_open(void)
517 {
518   /* Check client is WinNT proper; Win2K doesn't like Jeremy's hack - matty */
519   if (get_remote_arch() != RA_WINNT)
520     return;
521
522   fail_next_srvsvc = True;
523   fail_time = time(NULL);
524   DEBUG(10,("fail_next_srvsvc_open: setting up timeout close of \\srvsvc pipe for print fix.\n"));
525 }
526
527 /*
528  * HACK alert.... see above - JRA.
529  */
530
531 BOOL should_fail_next_srvsvc_open(const char *pipename)
532 {
533
534   DEBUG(10,("should_fail_next_srvsvc_open: fail = %d, pipe = %s\n",
535     (int)fail_next_srvsvc, pipename));
536
537   if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
538     fail_next_srvsvc = False;
539     fail_time = (time_t)0;
540     DEBUG(10,("should_fail_next_srvsvc_open: End of timeout close of \\srvsvc pipe for print fix.\n"));
541   }
542
543   if(fail_next_srvsvc && strequal(pipename, "srvsvc")) {
544     fail_next_srvsvc = False;
545     DEBUG(10,("should_fail_next_srvsvc_open: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
546     return True;
547   }
548   return False;
549 }
550
551
552 /****************************************************************************
553  Reply to an NT create and X call on a pipe.
554 ****************************************************************************/
555 static int nt_open_pipe(char *fname, connection_struct *conn,
556                         char *inbuf, char *outbuf, int *ppnum)
557 {
558         pipes_struct *p = NULL;
559
560         uint16 vuid = SVAL(inbuf, smb_uid);
561         int i;
562
563         DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
564     
565         /* See if it is one we want to handle. */
566         for( i = 0; known_nt_pipes[i]; i++ )
567                 if( strequal(fname,known_nt_pipes[i]))
568                         break;
569     
570         if ( known_nt_pipes[i] == NULL )
571                 return(ERROR(ERRSRV,ERRaccess));
572     
573         /* Strip \\ off the name. */
574         fname++;
575     
576         if(should_fail_next_srvsvc_open(fname))
577                 return (ERROR(ERRSRV,ERRaccess));
578
579         DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
580
581         p = open_rpc_pipe_p(fname, conn, vuid);
582         if (!p)
583                 return(ERROR(ERRSRV,ERRnofids));
584
585         *ppnum = p->pnum;
586
587         return 0;
588 }
589
590 /****************************************************************************
591  Reply to an NT create and X call for pipes.
592 ****************************************************************************/
593
594 static int do_ntcreate_pipe_open(connection_struct *conn,
595                          char *inbuf,char *outbuf,int length,int bufsize)
596 {
597         pstring fname;
598         int ret;
599         int pnum = -1;
600         char *p = NULL;
601         uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)),
602                                ((uint32)sizeof(fname)-1));
603
604         get_filename(fname, inbuf, smb_buf(inbuf)-inbuf, 
605                   smb_buflen(inbuf),fname_len);
606         if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0)
607                 return ret;
608
609         /*
610          * Deal with pipe return.
611          */  
612
613         set_message(outbuf,34,0,True);
614
615         p = outbuf + smb_vwv2;
616         p++;
617         SSVAL(p,0,pnum);
618         p += 2;
619         SIVAL(p,0,FILE_WAS_OPENED);
620         p += 4;
621         p += 32;
622         SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
623         p += 20;
624         /* File type. */
625         SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
626         /* Device state. */
627         SSVAL(p,2, 0x5FF); /* ? */
628
629         DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
630
631         return chain_reply(inbuf,outbuf,length,bufsize);
632 }
633
634 /****************************************************************************
635  Reply to an NT create and X call.
636 ****************************************************************************/
637
638 int reply_ntcreate_and_X(connection_struct *conn,
639                          char *inbuf,char *outbuf,int length,int bufsize)
640 {  
641         pstring fname;
642         uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
643         uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
644         uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
645         uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
646         uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
647         uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
648         uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)),
649                                ((uint32)sizeof(fname)-1));
650         uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
651         int smb_ofun;
652         int smb_open_mode;
653         int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
654         /* Breakout the oplock request bits so we can set the
655            reply bits separately. */
656         int oplock_request = 0;
657         mode_t unixmode;
658         int fmode=0,rmode=0;
659         SMB_OFF_T file_len = 0;
660         SMB_STRUCT_STAT sbuf;
661         int smb_action = 0;
662         BOOL bad_path = False;
663         files_struct *fsp=NULL;
664         char *p = NULL;
665         BOOL stat_open_only = False;
666
667         /* If it's an IPC, use the pipe handler. */
668
669         if (IS_IPC(conn)) {
670                 if (lp_nt_pipe_support())
671                         return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);
672                 else
673                         return(ERROR(ERRDOS,ERRbadaccess));
674         }
675                         
676
677         /* 
678          * We need to construct the open_and_X ofun value from the
679          * NT values, as that's what our code is structured to accept.
680          */    
681         
682         if((smb_ofun = map_create_disposition( create_disposition )) == -1)
683                 return(ERROR(ERRDOS,ERRbadaccess));
684
685         /*
686          * Get the file name.
687          */
688
689     if(root_dir_fid != 0) {
690       /*
691        * This filename is relative to a directory fid.
692        */
693       files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
694       size_t dir_name_len;
695
696       if(!dir_fsp)
697         return(ERROR(ERRDOS,ERRbadfid));
698
699       if(!dir_fsp->is_directory) {
700         /* 
701          * Check to see if this is a mac fork of some kind.
702          */
703
704         get_filename(&fname[0], inbuf, smb_buf(inbuf)-inbuf, 
705                    smb_buflen(inbuf),fname_len);
706
707         if( fname[0] == ':') {
708           SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
709           return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
710         }
711         return(ERROR(ERRDOS,ERRbadfid));
712       }
713
714       /*
715        * Copy in the base directory name.
716        */
717
718       pstrcpy( fname, dir_fsp->fsp_name );
719       dir_name_len = strlen(fname);
720
721       /*
722        * Ensure it ends in a '\'.
723        */
724
725       if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
726         pstrcat(fname, "\\");
727         dir_name_len++;
728       }
729
730       /*
731        * This next calculation can refuse a correct filename if we're dealing
732        * with the Win2k unicode bug, but that would be rare. JRA.
733        */
734
735       if(fname_len + dir_name_len >= sizeof(pstring))
736         return(ERROR(ERRSRV,ERRfilespecs));
737
738       get_filename(&fname[dir_name_len], inbuf, smb_buf(inbuf)-inbuf, 
739                    smb_buflen(inbuf),fname_len);
740
741     } else {
742       
743       get_filename(fname, inbuf, smb_buf(inbuf)-inbuf, 
744                    smb_buflen(inbuf),fname_len);
745     }
746         
747         /*
748          * Now contruct the smb_open_mode value from the filename, 
749      * desired access and the share access.
750          */
751         RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
752
753         if((smb_open_mode = map_share_mode(&stat_open_only, fname, desired_access, 
754                                            share_access, 
755                                            file_attributes)) == -1)
756                 return(ERROR(ERRDOS,ERRbadaccess));
757
758         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
759         oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
760
761         /*
762          * Ordinary file or directory.
763          */
764                 
765         /*
766          * Check if POSIX semantics are wanted.
767          */
768                 
769         set_posix_case_semantics(file_attributes);
770                 
771         unix_convert(fname,conn,0,&bad_path,NULL);
772                 
773         unixmode = unix_mode(conn,smb_attr | aARCH, fname);
774     
775         /* 
776          * If it's a request for a directory open, deal with it separately.
777          */
778
779         if(create_options & FILE_DIRECTORY_FILE) {
780                 oplock_request = 0;
781                 
782                 fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
783                         
784                 restore_case_semantics(file_attributes);
785
786                 if(!fsp) {
787                         return(UNIXERROR(ERRDOS,ERRnoaccess));
788                 }
789         } else {
790                 /*
791                  * Ordinary file case.
792                  */
793
794                 /* NB. We have a potential bug here. If we
795                  * cause an oplock break to ourselves, then we
796                  * could end up processing filename related
797                  * SMB requests whilst we await the oplock
798                  * break response. As we may have changed the
799                  * filename case semantics to be POSIX-like,
800                  * this could mean a filename request could
801                  * fail when it should succeed. This is a rare
802                  * condition, but eventually we must arrange
803                  * to restore the correct case semantics
804                  * before issuing an oplock break request to
805                  * our client. JRA.  */
806
807                 fsp = open_file_shared(conn,fname,smb_open_mode,
808                                  smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
809
810                 if (!fsp) { 
811                         /* We cheat here. There are two cases we
812                          * care about. One is a directory rename,
813                          * where the NT client will attempt to
814                          * open the source directory for
815                          * DELETE access. Note that when the
816                          * NT client does this it does *not*
817                          * set the directory bit in the
818                          * request packet. This is translated
819                          * into a read/write open
820                          * request. POSIX states that any open
821                          * for write request on a directory
822                          * will generate an EISDIR error, so
823                          * we can catch this here and open a
824                          * pseudo handle that is flagged as a
825                          * directory. The second is an open
826                          * for a permissions read only, which
827                          * we handle in the open_file_stat case. JRA.
828                          */
829
830                         if(errno == EISDIR) {
831
832                                 /*
833                                  * Fail the open if it was explicitly a non-directory file.
834                                  */
835
836                                 if (create_options & FILE_NON_DIRECTORY_FILE) {
837                                         restore_case_semantics(file_attributes);
838                                         SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
839                                         return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
840                                 }
841         
842                                 oplock_request = 0;
843                                 fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
844                                 
845                                 if(!fsp) {
846                                         restore_case_semantics(file_attributes);
847                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
848                                 }
849 #ifdef EROFS
850                         } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
851 #else /* !EROFS */
852                         } else if (errno == EACCES && stat_open_only) {
853 #endif
854                                 /*
855                                  * We couldn't open normally and all we want
856                                  * are the permissions. Try and do a stat open.
857                                  */
858
859                                 oplock_request = 0;
860
861                                 fsp = open_file_stat(conn,fname,smb_open_mode,&sbuf,&smb_action);
862
863                                 if(!fsp) {
864                                         restore_case_semantics(file_attributes);
865                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
866                                 }
867
868                         } else {
869
870                                 if((errno == ENOENT) && bad_path) {
871                                         unix_ERR_class = ERRDOS;
872                                         unix_ERR_code = ERRbadpath;
873                                 }
874                                 
875                                 restore_case_semantics(file_attributes);
876                                 
877                                 return(UNIXERROR(ERRDOS,ERRnoaccess));
878                         }
879                 } 
880         }
881                 
882         if(fsp->is_directory) {
883                 if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &sbuf) != 0) {
884                         close_file(fsp,True);
885                         restore_case_semantics(file_attributes);
886                         return(ERROR(ERRDOS,ERRnoaccess));
887                 }
888         } else {
889                 if (conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
890                         close_file(fsp,False);
891                         restore_case_semantics(file_attributes);
892                         return(ERROR(ERRDOS,ERRnoaccess));
893                 } 
894         }
895                 
896         restore_case_semantics(file_attributes);
897                 
898         file_len = sbuf.st_size;
899         fmode = dos_mode(conn,fname,&sbuf);
900         if(fmode == 0)
901                 fmode = FILE_ATTRIBUTE_NORMAL;
902         if (!fsp->is_directory && (fmode & aDIR)) {
903                 close_file(fsp,False);
904                 return(ERROR(ERRDOS,ERRnoaccess));
905         } 
906         
907         /* 
908          * If the caller set the extended oplock request bit
909          * and we granted one (by whatever means) - set the
910          * correct bit for extended oplock reply.
911          */
912         
913         if (oplock_request && lp_fake_oplocks(SNUM(conn)))
914                 smb_action |= EXTENDED_OPLOCK_GRANTED;
915         
916         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
917                 smb_action |= EXTENDED_OPLOCK_GRANTED;
918
919         set_message(outbuf,34,0,True);
920         
921         p = outbuf + smb_vwv2;
922         
923         /*
924          * Currently as we don't support level II oplocks we just report
925          * exclusive & batch here.
926          */
927
928     if (smb_action & EXTENDED_OPLOCK_GRANTED)   
929                 SCVAL(p,0, BATCH_OPLOCK_RETURN);
930         else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
931         SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
932         else
933                 SCVAL(p,0,NO_OPLOCK_RETURN);
934         
935         p++;
936         SSVAL(p,0,fsp->fnum);
937         p += 2;
938         SIVAL(p,0,smb_action);
939         p += 4;
940         
941         /* Create time. */  
942         put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
943         p += 8;
944         put_long_date(p,sbuf.st_atime); /* access time */
945         p += 8;
946         put_long_date(p,sbuf.st_mtime); /* write time */
947         p += 8;
948         put_long_date(p,sbuf.st_mtime); /* change time */
949         p += 8;
950         SIVAL(p,0,fmode); /* File Attributes. */
951         p += 4;
952         SOFF_T(p, 0, file_len);
953         p += 8;
954         SOFF_T(p,0,file_len);
955         p += 12;
956         SCVAL(p,0,fsp->is_directory ? 1 : 0);
957         
958         DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
959
960         return chain_reply(inbuf,outbuf,length,bufsize);
961 }
962
963 /****************************************************************************
964  Reply to a NT_TRANSACT_CREATE call to open a pipe.
965 ****************************************************************************/
966
967 static int do_nt_transact_create_pipe( connection_struct *conn,
968                                         char *inbuf, char *outbuf, int length, 
969                                         int bufsize, char **ppsetup, char **ppparams, 
970                                         char **ppdata)
971 {
972         pstring fname;
973         uint32 fname_len;
974         int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
975         char *params = *ppparams;
976         int ret;
977         int pnum = -1;
978         char *p = NULL;
979
980         /*
981          * Ensure minimum number of parameters sent.
982          */
983
984         if(total_parameter_count < 54) {
985                 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
986                 return(ERROR(ERRDOS,ERRbadaccess));
987         }
988
989         fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
990
991         get_filename_transact(&fname[0], params, 53,
992                         total_parameter_count - 53 - fname_len, fname_len);
993
994     if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0)
995       return ret;
996
997         /* Realloc the size of parameters and data we will return */
998         params = *ppparams = Realloc(*ppparams, 69);
999         if(params == NULL)
1000                 return(ERROR(ERRDOS,ERRnomem));
1001
1002         memset((char *)params,'\0',69);
1003
1004         p = params;
1005         SCVAL(p,0,NO_OPLOCK_RETURN);
1006
1007         p += 2;
1008         SSVAL(p,0,pnum);
1009         p += 2;
1010         SIVAL(p,0,FILE_WAS_OPENED);
1011         p += 8;
1012
1013         p += 32;
1014         SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
1015         p += 20;
1016         /* File type. */
1017         SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
1018         /* Device state. */
1019         SSVAL(p,2, 0x5FF); /* ? */
1020
1021         DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
1022
1023         /* Send the required number of replies */
1024         send_nt_replies(inbuf, outbuf, bufsize, 0, params, 69, *ppdata, 0);
1025
1026         return -1;
1027 }
1028
1029 /****************************************************************************
1030  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
1031 ****************************************************************************/
1032
1033 static int call_nt_transact_create(connection_struct *conn,
1034                                         char *inbuf, char *outbuf, int length, 
1035                                         int bufsize, char **ppsetup, char **ppparams, 
1036                                         char **ppdata)
1037 {
1038   pstring fname;
1039   char *params = *ppparams;
1040   int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
1041   /* Breakout the oplock request bits so we can set the
1042      reply bits separately. */
1043   int oplock_request = 0;
1044   mode_t unixmode;
1045   int fmode=0,rmode=0;
1046   SMB_OFF_T file_len = 0;
1047   SMB_STRUCT_STAT sbuf;
1048   int smb_action = 0;
1049   BOOL bad_path = False;
1050   files_struct *fsp = NULL;
1051   char *p = NULL;
1052   BOOL stat_open_only = False;
1053   uint32 flags;
1054   uint32 desired_access;
1055   uint32 file_attributes;
1056   uint32 share_access;
1057   uint32 create_disposition;
1058   uint32 create_options;
1059   uint32 fname_len;
1060   uint16 root_dir_fid;
1061   int smb_ofun;
1062   int smb_open_mode;
1063   int smb_attr;
1064
1065   DEBUG(5,("call_nt_transact_create\n"));
1066
1067   /*
1068    * If it's an IPC, use the pipe handler.
1069    */
1070
1071   if (IS_IPC(conn)) {
1072                 if (lp_nt_pipe_support())
1073                         return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, 
1074                                         bufsize, ppsetup, ppparams, ppdata);
1075                 else
1076                         return(ERROR(ERRDOS,ERRbadaccess));
1077   }
1078
1079   /*
1080    * Ensure minimum number of parameters sent.
1081    */
1082
1083   if(total_parameter_count < 54) {
1084     DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
1085     return(ERROR(ERRDOS,ERRbadaccess));
1086   }
1087
1088   flags = IVAL(params,0);
1089   desired_access = IVAL(params,8);
1090   file_attributes = IVAL(params,20);
1091   share_access = IVAL(params,24);
1092   create_disposition = IVAL(params,28);
1093   create_options = IVAL(params,32);
1094   fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
1095   root_dir_fid = (uint16)IVAL(params,4);
1096   smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
1097
1098   /* 
1099    * We need to construct the open_and_X ofun value from the
1100    * NT values, as that's what our code is structured to accept.
1101    */    
1102
1103   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
1104     return(ERROR(ERRDOS,ERRbadmem));
1105
1106   /*
1107    * Get the file name.
1108    */
1109
1110   if(root_dir_fid != 0) {
1111     /*
1112      * This filename is relative to a directory fid.
1113      */
1114
1115     files_struct *dir_fsp = file_fsp(params,4);
1116     size_t dir_name_len;
1117
1118     if(!dir_fsp)
1119         return(ERROR(ERRDOS,ERRbadfid));
1120
1121     if(!dir_fsp->is_directory) {
1122       /*
1123        * Check to see if this is a mac fork of some kind.
1124        */
1125
1126       get_filename_transact(&fname[0], params, 53,
1127                             total_parameter_count - 53 - fname_len, fname_len);
1128
1129       if( fname[0] == ':') {
1130           SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1131           return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
1132       }
1133
1134       return(ERROR(ERRDOS,ERRbadfid));
1135     }
1136
1137     /*
1138      * Copy in the base directory name.
1139      */
1140
1141     pstrcpy( fname, dir_fsp->fsp_name );
1142     dir_name_len = strlen(fname);
1143
1144     /*
1145      * Ensure it ends in a '\'.
1146      */
1147
1148     if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
1149       pstrcat(fname, "\\");
1150       dir_name_len++;
1151     }
1152
1153     /*
1154      * This next calculation can refuse a correct filename if we're dealing
1155      * with the Win2k unicode bug, but that would be rare. JRA.
1156      */
1157
1158     if(fname_len + dir_name_len >= sizeof(pstring))
1159       return(ERROR(ERRSRV,ERRfilespecs));
1160
1161     get_filename_transact(&fname[dir_name_len], params, 53,
1162                  total_parameter_count - 53 - fname_len, fname_len);
1163
1164   } else {
1165     get_filename_transact(&fname[0], params, 53,
1166                  total_parameter_count - 53 - fname_len, fname_len);
1167   }
1168
1169   /*
1170    * Now contruct the smb_open_mode value from the desired access
1171    * and the share access.
1172    */
1173
1174   if((smb_open_mode = map_share_mode( &stat_open_only, fname, desired_access,
1175                                       share_access, file_attributes)) == -1)
1176     return(ERROR(ERRDOS,ERRbadaccess));
1177
1178   oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1179   oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1180
1181   /*
1182    * Check if POSIX semantics are wanted.
1183    */
1184
1185   set_posix_case_semantics(file_attributes);
1186     
1187   RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1188
1189   unix_convert(fname,conn,0,&bad_path,NULL);
1190     
1191   unixmode = unix_mode(conn,smb_attr | aARCH, fname);
1192    
1193   /*
1194    * If it's a request for a directory open, deal with it separately.
1195    */
1196
1197   if(create_options & FILE_DIRECTORY_FILE) {
1198
1199     oplock_request = 0;
1200
1201     /*
1202      * We will get a create directory here if the Win32
1203      * app specified a security descriptor in the 
1204      * CreateDirectory() call.
1205      */
1206
1207     fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
1208
1209     if(!fsp) {
1210       restore_case_semantics(file_attributes);
1211       return(UNIXERROR(ERRDOS,ERRnoaccess));
1212     }
1213
1214     if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False),
1215              &sbuf) != 0) {
1216       close_file(fsp,True);
1217       restore_case_semantics(file_attributes);
1218       return(ERROR(ERRDOS,ERRnoaccess));
1219     }
1220
1221   } else {
1222
1223     /*
1224      * Ordinary file case.
1225      */
1226
1227     fsp = open_file_shared(conn,fname,smb_open_mode,smb_ofun,unixmode,
1228                      oplock_request,&rmode,&smb_action);
1229
1230     if (!fsp) { 
1231
1232                 if(errno == EISDIR) {
1233
1234                         /*
1235                          * Fail the open if it was explicitly a non-directory file.
1236                          */
1237
1238                         if (create_options & FILE_NON_DIRECTORY_FILE) {
1239                                 restore_case_semantics(file_attributes);
1240                                 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1241                                 return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
1242                         }
1243         
1244                         oplock_request = 0;
1245                         fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
1246                                 
1247                         if(!fsp) {
1248                                 restore_case_semantics(file_attributes);
1249                                 return(UNIXERROR(ERRDOS,ERRnoaccess));
1250                         }
1251 #ifdef EROFS
1252                 } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
1253 #else /* !EROFS */
1254                 } else if (errno == EACCES && stat_open_only) {
1255 #endif
1256
1257                         /*
1258                          * We couldn't open normally and all we want
1259                          * are the permissions. Try and do a stat open.
1260                          */
1261
1262                         oplock_request = 0;
1263
1264                         fsp = open_file_stat(conn,fname,smb_open_mode,&sbuf,&smb_action);
1265
1266                         if(!fsp) {
1267                                 restore_case_semantics(file_attributes);
1268                                 return(UNIXERROR(ERRDOS,ERRnoaccess));
1269                         }
1270                 } else {
1271
1272                         if((errno == ENOENT) && bad_path) {
1273                                 unix_ERR_class = ERRDOS;
1274                                 unix_ERR_code = ERRbadpath;
1275                         }
1276
1277                         restore_case_semantics(file_attributes);
1278
1279                         return(UNIXERROR(ERRDOS,ERRnoaccess));
1280                 }
1281       } 
1282   
1283       if(fsp->is_directory) {
1284           if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf) != 0) {
1285               close_file(fsp,True);
1286               restore_case_semantics(file_attributes);
1287               return(ERROR(ERRDOS,ERRnoaccess));
1288           }
1289       } else {
1290           if (!fsp->stat_open && conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
1291               close_file(fsp,False);
1292               restore_case_semantics(file_attributes);
1293               return(ERROR(ERRDOS,ERRnoaccess));
1294           } 
1295       }
1296  
1297       file_len = sbuf.st_size;
1298       fmode = dos_mode(conn,fname,&sbuf);
1299       if(fmode == 0)
1300         fmode = FILE_ATTRIBUTE_NORMAL;
1301
1302       if (fmode & aDIR) {
1303         close_file(fsp,False);
1304         restore_case_semantics(file_attributes);
1305         return(ERROR(ERRDOS,ERRnoaccess));
1306       } 
1307
1308       /* 
1309        * If the caller set the extended oplock request bit
1310        * and we granted one (by whatever means) - set the
1311        * correct bit for extended oplock reply.
1312        */
1313     
1314       if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1315         smb_action |= EXTENDED_OPLOCK_GRANTED;
1316   
1317       if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1318         smb_action |= EXTENDED_OPLOCK_GRANTED;
1319   }
1320
1321   restore_case_semantics(file_attributes);
1322
1323   /* Realloc the size of parameters and data we will return */
1324   params = *ppparams = Realloc(*ppparams, 69);
1325   if(params == NULL)
1326     return(ERROR(ERRDOS,ERRnomem));
1327
1328   memset((char *)params,'\0',69);
1329
1330   p = params;
1331   if (smb_action & EXTENDED_OPLOCK_GRANTED)     
1332         SCVAL(p,0, BATCH_OPLOCK_RETURN);
1333   else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
1334     SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
1335   else
1336         SCVAL(p,0,NO_OPLOCK_RETURN);
1337         
1338   p += 2;
1339   SSVAL(p,0,fsp->fnum);
1340   p += 2;
1341   SIVAL(p,0,smb_action);
1342   p += 8;
1343
1344   /* Create time. */
1345   put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1346   p += 8;
1347   put_long_date(p,sbuf.st_atime); /* access time */
1348   p += 8;
1349   put_long_date(p,sbuf.st_mtime); /* write time */
1350   p += 8;
1351   put_long_date(p,sbuf.st_mtime); /* change time */
1352   p += 8;
1353   SIVAL(p,0,fmode); /* File Attributes. */
1354   p += 4;
1355   SOFF_T(p,0,file_len);
1356   p += 8;
1357   SOFF_T(p,0,file_len);
1358
1359   DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
1360
1361   /* Send the required number of replies */
1362   send_nt_replies(inbuf, outbuf, bufsize, 0, params, 69, *ppdata, 0);
1363
1364   return -1;
1365 }
1366
1367 /****************************************************************************
1368  Reply to a NT CANCEL request.
1369 ****************************************************************************/
1370 int reply_ntcancel(connection_struct *conn,
1371                    char *inbuf,char *outbuf,int length,int bufsize)
1372 {
1373         /*
1374          * Go through and cancel any pending change notifies.
1375          */
1376         
1377         int mid = SVAL(inbuf,smb_mid);
1378         remove_pending_change_notify_requests_by_mid(mid);
1379         remove_pending_lock_requests_by_mid(mid);
1380         
1381         DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
1382
1383         return(-1);
1384 }
1385
1386 /****************************************************************************
1387  Reply to an unsolicited SMBNTtranss - just ignore it!
1388 ****************************************************************************/
1389 int reply_nttranss(connection_struct *conn,
1390                    char *inbuf,char *outbuf,int length,int bufsize)
1391 {
1392         DEBUG(4,("Ignoring nttranss of length %d\n",length));
1393         return(-1);
1394 }
1395
1396 /****************************************************************************
1397  Reply to an NT transact rename command.
1398 ****************************************************************************/
1399
1400 static int call_nt_transact_rename(connection_struct *conn,
1401                                    char *inbuf, char *outbuf, int length, 
1402                                    int bufsize,
1403                                    char **ppsetup, char **ppparams, char **ppdata)
1404 {
1405   char *params = *ppparams;
1406   pstring new_name;
1407   files_struct *fsp = file_fsp(params, 0);
1408   BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
1409   uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
1410                          ((uint32)sizeof(new_name)-1));
1411   int outsize = 0;
1412
1413   CHECK_FSP(fsp, conn);
1414   StrnCpy(new_name,params+4,fname_len);
1415   new_name[fname_len] = '\0';
1416
1417   outsize = rename_internals(conn, inbuf, outbuf, fsp->fsp_name,
1418                              new_name, replace_if_exists);
1419   if(outsize == 0) {
1420     /*
1421      * Rename was successful.
1422      */
1423     send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
1424
1425     DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 
1426           fsp->fsp_name, new_name));
1427
1428     outsize = -1;
1429   }
1430
1431   return(outsize);
1432 }
1433    
1434 /****************************************************************************
1435  This is the structure to keep the information needed to
1436  determine if a directory has changed.
1437 *****************************************************************************/
1438
1439 typedef struct {
1440   time_t modify_time; /* Info from the directory we're monitoring. */ 
1441   time_t status_time; /* Info from the directory we're monitoring. */
1442   time_t total_time; /* Total time of all directory entries - don't care if it wraps. */
1443   unsigned int num_entries; /* Zero or the number of files in the directory. */
1444 } change_hash_data;
1445
1446 /****************************************************************************
1447  This is the structure to queue to implement NT change
1448  notify. It consists of smb_size bytes stored from the
1449  transact command (to keep the mid, tid etc around).
1450  Plus the fid to examine and the time to check next.
1451 *****************************************************************************/
1452
1453 typedef struct {
1454   ubi_slNode msg_next;
1455   files_struct *fsp;
1456   connection_struct *conn;
1457   uint32 flags;
1458   time_t next_check_time;
1459   change_hash_data change_data;
1460   char request_buf[smb_size];
1461 } change_notify_buf;
1462
1463 static ubi_slList change_notify_queue = { NULL, (ubi_slNodePtr)&change_notify_queue, 0};
1464
1465 /****************************************************************************
1466  Setup the common parts of the return packet and send it.
1467 *****************************************************************************/
1468
1469 static void change_notify_reply_packet(char *inbuf, int error_class, uint32 error_code)
1470 {
1471   char outbuf[smb_size+38];
1472
1473   memset(outbuf, '\0', sizeof(outbuf));
1474   construct_reply_common(inbuf, outbuf);
1475
1476   /*
1477    * If we're returning a 'too much in the directory changed' we need to
1478    * set this is an NT error status flags. If we don't then the (probably
1479    * untested) code in the NT redirector has a bug in that it doesn't re-issue
1480    * the change notify.... Ah - I *love* it when I get so deeply into this I
1481    * can even determine how MS failed to test stuff and why.... :-). JRA.
1482    */
1483
1484   if(error_class == 0) /* NT Error. */
1485     SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
1486
1487   ERROR(error_class,error_code);
1488
1489   /*
1490    * Seems NT needs a transact command with an error code
1491    * in it. This is a longer packet than a simple error.
1492    */
1493   set_message(outbuf,18,0,False);
1494
1495   send_smb(smbd_server_fd(),outbuf);
1496 }
1497
1498 /****************************************************************************
1499  Create the hash we will use to determine if the contents changed.
1500 *****************************************************************************/
1501
1502 static BOOL create_directory_notify_hash( change_notify_buf *cnbp, change_hash_data *change_data)
1503 {
1504   SMB_STRUCT_STAT st;
1505   files_struct *fsp = cnbp->fsp;
1506
1507   memset((char *)change_data, '\0', sizeof(change_data));
1508
1509   /* 
1510    * Store the current timestamp on the directory we are monitoring.
1511    */
1512
1513   if(dos_stat(fsp->fsp_name, &st) < 0) {
1514     DEBUG(0,("create_directory_notify_hash: Unable to stat name = %s. \
1515 Error was %s\n", fsp->fsp_name, strerror(errno) ));
1516     return False;
1517   }
1518  
1519   change_data->modify_time = st.st_mtime;
1520   change_data->status_time = st.st_ctime;
1521
1522   /*
1523    * If we are to watch for changes that are only stored
1524    * in inodes of files, not in the directory inode, we must
1525    * scan the directory and produce a unique identifier with
1526    * which we can determine if anything changed. We use the
1527    * modify and change times from all the files in the
1528    * directory, added together (ignoring wrapping if it's
1529    * larger than the max time_t value).
1530    */
1531
1532   if(cnbp->flags & (FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE)) {
1533     pstring full_name;
1534     char *p;
1535     char *fname;
1536     size_t remaining_len;
1537     size_t fullname_len;
1538     void *dp = OpenDir(cnbp->conn, fsp->fsp_name, True);
1539
1540     if(dp == NULL) {
1541       DEBUG(0,("create_directory_notify_hash: Unable to open directory = %s. \
1542 Error was %s\n", fsp->fsp_name, strerror(errno) ));
1543       return False;
1544     }
1545
1546     change_data->num_entries = 0;
1547
1548     pstrcpy(full_name, fsp->fsp_name);
1549     pstrcat(full_name, "/");
1550
1551     fullname_len = strlen(full_name);
1552     remaining_len = sizeof(full_name) - fullname_len - 1;
1553     p = &full_name[fullname_len];
1554
1555     while ((fname = ReadDirName(dp))) {
1556       if(strequal(fname, ".") || strequal(fname, ".."))
1557         continue;
1558
1559       change_data->num_entries++;
1560       safe_strcpy( p, fname, remaining_len);
1561
1562       memset(&st, '\0', sizeof(st));
1563
1564       /*
1565        * Do the stat - but ignore errors.
1566        */
1567
1568       if(dos_stat(full_name, &st) < 0) {
1569         DEBUG(5,("create_directory_notify_hash: Unable to stat content file = %s. \
1570 Error was %s\n", fsp->fsp_name, strerror(errno) ));
1571       }
1572       change_data->total_time += (st.st_mtime + st.st_ctime);
1573     }
1574
1575     CloseDir(dp);
1576   }
1577
1578   return True;
1579 }
1580
1581 /****************************************************************************
1582  Delete entries by fnum from the change notify pending queue.
1583 *****************************************************************************/
1584
1585 void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
1586 {
1587   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1588   change_notify_buf *prev = NULL;
1589
1590   while(cnbp != NULL) {
1591     if(cnbp->fsp->fnum == fsp->fnum) {
1592       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1593       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1594       continue;
1595     }
1596
1597     prev = cnbp;
1598     cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1599   }
1600 }
1601
1602 /****************************************************************************
1603  Delete entries by mid from the change notify pending queue. Always send reply.
1604 *****************************************************************************/
1605
1606 static void remove_pending_change_notify_requests_by_mid(int mid)
1607 {
1608   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1609   change_notify_buf *prev = NULL;
1610
1611   while(cnbp != NULL) {
1612     if(SVAL(cnbp->request_buf,smb_mid) == mid) {
1613       change_notify_reply_packet(cnbp->request_buf,0,0xC0000000 |NT_STATUS_CANCELLED);
1614       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1615       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1616       continue;
1617     }
1618
1619     prev = cnbp;
1620     cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1621   }
1622 }
1623
1624 /****************************************************************************
1625  Delete entries by filename and cnum from the change notify pending queue.
1626  Always send reply.
1627 *****************************************************************************/
1628
1629 void remove_pending_change_notify_requests_by_filename(files_struct *fsp)
1630 {
1631   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1632   change_notify_buf *prev = NULL;
1633
1634   while(cnbp != NULL) {
1635     /*
1636      * We know it refers to the same directory if the connection number and
1637      * the filename are identical.
1638      */
1639     if((cnbp->fsp->conn == fsp->conn) && strequal(cnbp->fsp->fsp_name,fsp->fsp_name)) {
1640       change_notify_reply_packet(cnbp->request_buf,0,0xC0000000 |NT_STATUS_CANCELLED);
1641       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1642       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1643       continue;
1644     }
1645
1646     prev = cnbp;
1647     cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1648   }
1649 }
1650
1651 /****************************************************************************
1652  Process the change notify queue. Note that this is only called as root.
1653  Returns True if there are still outstanding change notify requests on the
1654  queue.
1655 *****************************************************************************/
1656
1657 BOOL process_pending_change_notify_queue(time_t t)
1658 {
1659   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1660   change_notify_buf *prev = NULL;
1661
1662   if(cnbp == NULL)
1663     return False;
1664
1665   if(cnbp->next_check_time >= t)
1666     return True;
1667
1668   /*
1669    * It's time to check. Go through the queue and see if
1670    * the timestamps changed.
1671    */
1672
1673   while((cnbp != NULL) && (cnbp->next_check_time <= t)) {
1674     change_hash_data change_data;
1675     connection_struct *conn = cnbp->conn;
1676     uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : 
1677                   SVAL(cnbp->request_buf,smb_uid);
1678
1679     ZERO_STRUCT(change_data);
1680
1681     /*
1682      * Ensure we don't have any old chain_fsp values
1683      * sitting around....
1684      */
1685     chain_size = 0;
1686     file_chain_reset();
1687
1688     if(!become_user(conn,vuid)) {
1689       DEBUG(0,("process_pending_change_notify_queue: Unable to become user vuid=%d.\n",
1690             vuid ));
1691       /*
1692        * Remove the entry and return an error to the client.
1693        */
1694       change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1695       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1696       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1697       continue;
1698     }
1699
1700     if(!become_service(conn,True)) {
1701             DEBUG(0,("process_pending_change_notify_queue: Unable to become service Error was %s.\n", strerror(errno) ));
1702       /*
1703        * Remove the entry and return an error to the client.
1704        */
1705       change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1706       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1707       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1708       unbecome_user();
1709       continue;
1710     }
1711
1712     if(!create_directory_notify_hash( cnbp, &change_data)) {
1713       DEBUG(0,("process_pending_change_notify_queue: Unable to create change data for \
1714 directory %s\n", cnbp->fsp->fsp_name ));
1715       /*
1716        * Remove the entry and return an error to the client.
1717        */
1718       change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1719       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1720       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1721       unbecome_user();
1722       continue;
1723     }
1724
1725     if(memcmp( (char *)&cnbp->change_data, (char *)&change_data, sizeof(change_data))) {
1726       /*
1727        * Remove the entry and return a change notify to the client.
1728        */
1729       DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed.\n",
1730             cnbp->fsp->fsp_name ));
1731       change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_NOTIFY_ENUM_DIR);
1732       free((char *)ubi_slRemNext( &change_notify_queue, prev));
1733       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1734       unbecome_user();
1735       continue;
1736     }
1737
1738     unbecome_user();
1739
1740     /*
1741      * Move to the next in the list.
1742      */
1743     prev = cnbp;
1744     cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1745   }
1746
1747   return (cnbp != NULL);
1748 }
1749
1750 /****************************************************************************
1751  Return true if there are pending change notifies.
1752 ****************************************************************************/
1753
1754 BOOL change_notifies_pending(void)
1755 {
1756   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1757   return (cnbp != NULL);
1758 }
1759
1760 /****************************************************************************
1761  Reply to a notify change - queue the request and 
1762  don't allow a directory to be opened.
1763 ****************************************************************************/
1764
1765 static int call_nt_transact_notify_change(connection_struct *conn,
1766                                           char *inbuf, char *outbuf, int length,
1767                                           int bufsize, 
1768                                           char **ppsetup, 
1769                                           char **ppparams, char **ppdata)
1770 {
1771   char *setup = *ppsetup;
1772   files_struct *fsp;
1773   change_notify_buf *cnbp;
1774
1775   fsp = file_fsp(setup,4);
1776
1777   DEBUG(3,("call_nt_transact_notify_change\n"));
1778
1779   if(!fsp)
1780     return(ERROR(ERRDOS,ERRbadfid));
1781
1782   if((!fsp->is_directory) || (conn != fsp->conn))
1783     return(ERROR(ERRDOS,ERRbadfid));
1784
1785   /*
1786    * Now queue an entry on the notify change stack. We timestamp
1787    * the entry we are adding so that we know when to scan next.
1788    * We only need to save smb_size bytes from this incoming packet
1789    * as we will always by returning a 'read the directory yourself'
1790    * error.
1791    */
1792
1793   if((cnbp = (change_notify_buf *)malloc(sizeof(change_notify_buf))) == NULL) {
1794     DEBUG(0,("call_nt_transact_notify_change: malloc fail !\n" ));
1795     return -1;
1796   }
1797
1798   memset((char *)cnbp, '\0', sizeof(change_notify_buf));
1799
1800   memcpy(cnbp->request_buf, inbuf, smb_size);
1801   cnbp->fsp = fsp;
1802   cnbp->conn = conn;
1803   cnbp->next_check_time = time(NULL) + lp_change_notify_timeout();
1804   cnbp->flags = IVAL(setup, 0);
1805
1806   if(!create_directory_notify_hash( cnbp, &cnbp->change_data )) {
1807     free((char *)cnbp);
1808     return(UNIXERROR(ERRDOS,ERRbadfid));
1809   }
1810
1811   /*
1812    * Adding to the tail enables us to check only
1813    * the head when scanning for change, as this entry
1814    * is forced to have the first timeout expiration.
1815    */
1816
1817   ubi_slAddTail(&change_notify_queue, cnbp);
1818
1819   DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \
1820 name = %s\n", fsp->fsp_name ));
1821
1822   return -1;
1823 }
1824
1825 /****************************************************************************
1826  Reply to query a security descriptor from an fsp. If it succeeds it allocates
1827  the space for the return elements and returns True.
1828 ****************************************************************************/
1829
1830 static size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
1831 {
1832   SMB_STRUCT_STAT sbuf;
1833   mode_t mode;
1834
1835     if(fsp->is_directory || fsp->fd == -1) {
1836       if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
1837         return 0;
1838       }
1839     } else {
1840       if(fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
1841         return 0;
1842       }
1843     }
1844
1845     if(fsp->is_directory) {
1846       /*
1847        * For directory ACLs we also add in the inherited permissions
1848        * ACE entries. These are the permissions a file would get when
1849        * being created in the directory.
1850        */
1851       mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name);
1852     }
1853     else
1854     {
1855             mode = sbuf.st_mode;
1856     }
1857   return convertperms_unix_to_sd(&sbuf, fsp->is_directory, mode, ppdesc);
1858 }
1859
1860 /****************************************************************************
1861  Reply to query a security descriptor - currently this is not implemented (it
1862  is planned to be though). Right now it just returns the same thing NT would
1863  when queried on a FAT filesystem. JRA.
1864 ****************************************************************************/
1865
1866 static int call_nt_transact_query_security_desc(connection_struct *conn,
1867                                                 char *inbuf, char *outbuf, 
1868                                                 int length, int bufsize, 
1869                                                 char **ppsetup, char **ppparams, char **ppdata)
1870 {
1871   uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
1872   char *params = *ppparams;
1873   char *data = *ppdata;
1874   prs_struct pd;
1875   SEC_DESC *psd = NULL;
1876   size_t sec_desc_size;
1877
1878   files_struct *fsp = file_fsp(params,0);
1879
1880   if(!fsp)
1881     return(ERROR(ERRDOS,ERRbadfid));
1882
1883   DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
1884
1885   params = *ppparams = Realloc(*ppparams, 4);
1886   if(params == NULL)
1887     return(ERROR(ERRDOS,ERRnomem));
1888
1889   /*
1890    * Get the permissions to return.
1891    */
1892
1893   if((sec_desc_size = get_nt_acl(fsp, &psd)) == 0)
1894     return(UNIXERROR(ERRDOS,ERRnoaccess));
1895
1896   DEBUG(3,("call_nt_transact_query_security_desc: sec_desc_size = %d.\n",(int)sec_desc_size));
1897
1898   SIVAL(params,0,(uint32)sec_desc_size);
1899
1900   if(max_data_count < sec_desc_size) {
1901
1902     free_sec_desc(psd);
1903     safe_free(psd);
1904
1905     send_nt_replies(inbuf, outbuf, bufsize, 0xC0000000|NT_STATUS_BUFFER_TOO_SMALL,
1906                     params, 4, *ppdata, 0);
1907     return -1;
1908   }
1909
1910   /*
1911    * Allocate the data we will point this at.
1912    */
1913
1914   data = *ppdata = Realloc(*ppdata, sec_desc_size);
1915   if(data == NULL) {
1916     free_sec_desc(psd);
1917     safe_free(psd);
1918     return(ERROR(ERRDOS,ERRnomem));
1919   }
1920
1921   memset(data, '\0', sec_desc_size);
1922
1923   /*
1924    * Init the parse struct we will marshall into.
1925    */
1926
1927   prs_init(&pd, sec_desc_size, 4, MARSHALL);
1928
1929   /*
1930    * Finally, linearize into the outgoing buffer.
1931    */
1932
1933   if(!sec_io_desc( "sd data", psd, &pd, 1))
1934   {
1935     free_sec_desc(psd);
1936     safe_free(psd);
1937     prs_mem_free(&pd);
1938     DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
1939 security descriptor.\n"));
1940     /*
1941      * Return access denied for want of a better error message..
1942      */ 
1943     return(UNIXERROR(ERRDOS,ERRnoaccess));
1944   }
1945
1946   /*
1947    * copy the data out of the marshalled structure
1948    */
1949
1950   prs_give_memory( &pd, data, (uint32)sec_desc_size, False);
1951
1952   /*
1953    * Now we can delete the security descriptor.
1954    */
1955
1956   prs_mem_free(&pd);
1957   free_sec_desc(psd);
1958   safe_free(psd);
1959
1960   send_nt_replies(inbuf, outbuf, bufsize, 0, params, 4, data, (int)sec_desc_size);
1961   return -1;
1962 }
1963
1964 /****************************************************************************
1965  Reply to set a security descriptor. Map to UNIX perms.
1966 ****************************************************************************/
1967
1968 static int call_nt_transact_set_security_desc(connection_struct *conn,
1969                                                                         char *inbuf, char *outbuf, int length,
1970                                                                         int bufsize, char **ppsetup, 
1971                                                                         char **ppparams, char **ppdata)
1972 {
1973   uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
1974   char *params= *ppparams;
1975   char *data = *ppdata;
1976   prs_struct pd;
1977   SEC_DESC psd;
1978   uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
1979   uid_t user = (uid_t)-1;
1980   gid_t grp = (gid_t)-1;
1981   mode_t perms = 0;
1982   SMB_STRUCT_STAT sbuf;
1983   files_struct *fsp = NULL;
1984   uint32 security_info_sent = 0;
1985   BOOL got_dacl = False;
1986
1987   if(!lp_nt_acl_support())
1988     return(UNIXERROR(ERRDOS,ERRnoaccess));
1989
1990   if(total_parameter_count < 8)
1991     return(ERROR(ERRDOS,ERRbadfunc));
1992
1993   if((fsp = file_fsp(params,0)) == NULL)
1994     return(ERROR(ERRDOS,ERRbadfid));
1995
1996   security_info_sent = IVAL(params,4);
1997
1998   DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
1999        (unsigned int)security_info_sent ));
2000
2001   /*
2002    * Init the parse struct we will unmarshall from.
2003    */
2004
2005   prs_init(&pd, 0, 4, UNMARSHALL);
2006
2007   /*
2008    * Setup the prs_struct to point at the memory we just
2009    * allocated.
2010    */
2011         
2012   prs_give_memory( &pd, data, total_data_count, False);
2013
2014   /*
2015    * Finally, unmarshall from the data buffer.
2016    */
2017
2018   if(!sec_io_desc( "sd data", &psd, &pd, 1))
2019   {
2020     free_sec_desc(&psd);
2021     prs_mem_free(&pd);
2022     DEBUG(0,("call_nt_transact_set_security_desc: Error in unmarshalling \
2023 security descriptor.\n"));
2024     /*
2025      * Return access denied for want of a better error message..
2026      */ 
2027     return(UNIXERROR(ERRDOS,ERRnoaccess));
2028   }
2029
2030   /*
2031    * finished with the marshalling structure, already
2032    */
2033
2034   prs_mem_free(&pd);
2035
2036   /*
2037    * Get the current state of the file.
2038    */
2039
2040   if(fsp->is_directory) {
2041     if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
2042       free_sec_desc(&psd);
2043       return(UNIXERROR(ERRDOS,ERRnoaccess));
2044     }
2045   } else {
2046
2047     int ret;
2048
2049     if(fsp->fd == -1)
2050       ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
2051     else
2052       ret = conn->vfs_ops.fstat(fsp->fd,&sbuf);
2053
2054     if(ret != 0) {
2055       free_sec_desc(&psd);
2056       return(UNIXERROR(ERRDOS,ERRnoaccess));
2057     }
2058   }
2059
2060   /*
2061    * Unpack the user/group/world id's and permissions.
2062    */
2063
2064   if(!convertperms_sd_to_unix( &sbuf, &user, &grp, &perms, security_info_sent, &psd, fsp->is_directory)) {
2065     free_sec_desc(&psd);
2066     return(UNIXERROR(ERRDOS,ERRnoaccess));
2067   }
2068
2069   if (psd.dacl != NULL)
2070     got_dacl = True;
2071
2072   free_sec_desc(&psd);
2073
2074   /*
2075    * Do we need to chown ?
2076    */
2077
2078   if((user != (uid_t)-1 || grp != (uid_t)-1) && (sbuf.st_uid != user || sbuf.st_gid != grp)) {
2079
2080     DEBUG(3,("call_nt_transact_set_security_desc: chown %s. uid = %u, gid = %u.\n",
2081           fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
2082
2083     if(dos_chown( fsp->fsp_name, user, grp) == -1) {
2084       DEBUG(3,("call_nt_transact_set_security_desc: chown %s, %u, %u failed. Error = %s.\n",
2085             fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
2086       return(UNIXERROR(ERRDOS,ERRnoaccess));
2087     }
2088
2089     /*
2090      * Recheck the current state of the file, which may have changed.
2091      * (suid/sgid bits, for instance)
2092      */
2093
2094     if(fsp->is_directory) {
2095       if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
2096         return(UNIXERROR(ERRDOS,ERRnoaccess));
2097       }
2098     } else {
2099
2100       int ret;
2101     
2102       if(fsp->fd == -1)
2103         ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
2104       else
2105         ret = conn->vfs_ops.fstat(fsp->fd,&sbuf);
2106   
2107       if(ret != 0)
2108         return(UNIXERROR(ERRDOS,ERRnoaccess));
2109     }
2110   }
2111
2112   /*
2113    * Only change security if we got a DACL.
2114    */
2115
2116   if((security_info_sent & DACL_SECURITY_INFORMATION) && got_dacl) {
2117
2118     /*
2119      * Check to see if we need to change anything.
2120      * Enforce limits on modified bits *only*. Don't enforce masks
2121          * on bits not changed by the user.
2122      */
2123
2124     if(fsp->is_directory) {
2125
2126       perms &= (lp_dir_security_mask(SNUM(conn)) | sbuf.st_mode);
2127       perms |= (lp_force_dir_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
2128
2129     } else {
2130
2131       perms &= (lp_security_mask(SNUM(conn)) | sbuf.st_mode); 
2132       perms |= (lp_force_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
2133
2134     }
2135
2136     /*
2137      * Preserve special bits.
2138      */
2139
2140     perms |= (sbuf.st_mode & ~0777);
2141
2142     /*
2143      * Do we need to chmod ?
2144      */
2145
2146     if(sbuf.st_mode != perms) {
2147
2148       DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n",
2149             fsp->fsp_name, (unsigned int)perms ));
2150
2151       if(conn->vfs_ops.chmod(dos_to_unix(fsp->fsp_name, False), perms) == -1) {
2152         DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n",
2153               fsp->fsp_name, (unsigned int)perms, strerror(errno) ));
2154         return(UNIXERROR(ERRDOS,ERRnoaccess));
2155       }
2156     }
2157   }
2158
2159   send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
2160   return -1;
2161 }
2162    
2163 /****************************************************************************
2164  Reply to IOCTL - not implemented - no plans.
2165 ****************************************************************************/
2166 static int call_nt_transact_ioctl(connection_struct *conn,
2167                                   char *inbuf, char *outbuf, int length,
2168                                   int bufsize, 
2169                                   char **ppsetup, char **ppparams, char **ppdata)
2170 {
2171   static BOOL logged_message = False;
2172
2173   if(!logged_message) {
2174     DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n"));
2175     logged_message = True; /* Only print this once... */
2176   }
2177   return(ERROR(ERRSRV,ERRnosupport));
2178 }
2179    
2180 /****************************************************************************
2181  Reply to a SMBNTtrans.
2182 ****************************************************************************/
2183 int reply_nttrans(connection_struct *conn,
2184                   char *inbuf,char *outbuf,int length,int bufsize)
2185 {
2186   int  outsize = 0;
2187 #if 0 /* Not used. */
2188   uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
2189   uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
2190   uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
2191 #endif /* Not used. */
2192   uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
2193   uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
2194   uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
2195   uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
2196   uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
2197   uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
2198   uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
2199   uint16 function_code = SVAL( inbuf, smb_nt_Function);
2200   char *params = NULL, *data = NULL, *setup = NULL;
2201   uint32 num_params_sofar, num_data_sofar;
2202
2203   if(global_oplock_break && (function_code == NT_TRANSACT_CREATE)) {
2204     /*
2205      * Queue this open message as we are the process of an oplock break.
2206      */
2207
2208     DEBUG(2,("reply_nttrans: queueing message NT_TRANSACT_CREATE \
2209 due to being in oplock break state.\n" ));
2210
2211     push_oplock_pending_smb_message( inbuf, length);
2212     return -1;
2213   }
2214
2215   if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE))
2216     return (ERROR(ERRSRV,ERRaccess));
2217
2218   outsize = set_message(outbuf,0,0,True);
2219
2220   /* 
2221    * All nttrans messages we handle have smb_wct == 19 + setup_count.
2222    * Ensure this is so as a sanity check.
2223    */
2224
2225   if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
2226     DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
2227           CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
2228     return(ERROR(ERRSRV,ERRerror));
2229   }
2230     
2231   /* Allocate the space for the setup, the maximum needed parameters and data */
2232
2233   if(setup_count > 0)
2234     setup = (char *)malloc(setup_count);
2235   if (total_parameter_count > 0)
2236     params = (char *)malloc(total_parameter_count);
2237   if (total_data_count > 0)
2238     data = (char *)malloc(total_data_count);
2239  
2240   if ((total_parameter_count && !params)  || (total_data_count && !data) ||
2241       (setup_count && !setup)) {
2242     DEBUG(0,("reply_nttrans : Out of memory\n"));
2243     return(ERROR(ERRDOS,ERRnomem));
2244   }
2245
2246   /* Copy the param and data bytes sent with this request into
2247      the params buffer */
2248   num_params_sofar = parameter_count;
2249   num_data_sofar = data_count;
2250
2251   if (parameter_count > total_parameter_count || data_count > total_data_count)
2252     exit_server("reply_nttrans: invalid sizes in packet.\n");
2253
2254   if(setup) {
2255     memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
2256     DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
2257     dump_data(10, setup, setup_count);
2258   }
2259   if(params) {
2260     memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
2261     DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
2262     dump_data(10, params, parameter_count);
2263   }
2264   if(data) {
2265     memcpy( data, smb_base(inbuf) + data_offset, data_count);
2266     DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
2267     dump_data(10, data, data_count);
2268   }
2269
2270   if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
2271     /* We need to send an interim response then receive the rest
2272        of the parameter/data bytes */
2273     outsize = set_message(outbuf,0,0,True);
2274     send_smb(smbd_server_fd(),outbuf);
2275
2276     while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
2277       BOOL ret;
2278
2279       ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2280
2281       if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
2282         outsize = set_message(outbuf,0,0,True);
2283         if(ret) {
2284                 DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
2285         } else {
2286                 DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
2287                          (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2288         }
2289         if(params)
2290           free(params);
2291         if(data)
2292           free(data);
2293         if(setup)
2294           free(setup);
2295         return(ERROR(ERRSRV,ERRerror));
2296       }
2297       
2298       /* Revise total_params and total_data in case they have changed downwards */
2299       total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
2300       total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
2301       num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
2302       num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
2303       if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
2304         exit_server("reply_nttrans2: data overflow in secondary nttrans packet\n");
2305
2306       memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)], 
2307               smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
2308       memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
2309               smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
2310     }
2311   }
2312
2313   if (Protocol >= PROTOCOL_NT1) {
2314     uint16 flg2 = SVAL(outbuf,smb_flg2);
2315     SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2316   }
2317
2318   /* Now we must call the relevant NT_TRANS function */
2319   switch(function_code) {
2320     case NT_TRANSACT_CREATE:
2321       outsize = call_nt_transact_create(conn, inbuf, outbuf, length, bufsize, 
2322                                         &setup, &params, &data);
2323       break;
2324     case NT_TRANSACT_IOCTL:
2325       outsize = call_nt_transact_ioctl(conn, 
2326                                        inbuf, outbuf, length, bufsize, 
2327                                        &setup, &params, &data);
2328       break;
2329     case NT_TRANSACT_SET_SECURITY_DESC:
2330       outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, 
2331                                                    length, bufsize, 
2332                                                    &setup, &params, &data);
2333       break;
2334     case NT_TRANSACT_NOTIFY_CHANGE:
2335       outsize = call_nt_transact_notify_change(conn, inbuf, outbuf, 
2336                                                length, bufsize, 
2337                                                &setup, &params, &data);
2338       break;
2339     case NT_TRANSACT_RENAME:
2340       outsize = call_nt_transact_rename(conn, inbuf, outbuf, length, 
2341                                         bufsize, 
2342                                         &setup, &params, &data);
2343       break;
2344
2345     case NT_TRANSACT_QUERY_SECURITY_DESC:
2346       outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, 
2347                                                      length, bufsize, 
2348                                                      &setup, &params, &data);
2349       break;
2350   default:
2351           /* Error in request */
2352           DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
2353           if(setup)
2354                   free(setup);
2355           if(params)
2356                   free(params);
2357           if(data)
2358                   free(data);
2359           return (ERROR(ERRSRV,ERRerror));
2360   }
2361
2362   /* As we do not know how many data packets will need to be
2363      returned here the various call_nt_transact_xxxx calls
2364      must send their own. Thus a call_nt_transact_xxxx routine only
2365      returns a value other than -1 when it wants to send
2366      an error packet. 
2367   */
2368
2369   if(setup)
2370     free(setup);
2371   if(params)
2372     free(params);
2373   if(data)
2374     free(data);
2375   return outsize; /* If a correct response was needed the call_nt_transact_xxxx 
2376                      calls have already sent it. If outsize != -1 then it is
2377                      returning an error packet. */
2378 }
2379 #undef OLD_NTDOMAIN