r5636: Re-add the allocation size - parameterized by share as
[tprouty/samba.git] / source / smbd / nttrans.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB NT transaction handling
4    Copyright (C) Jeremy Allison                 1994-1998
5    Copyright (C) Stefan (metze) Metzmacher      2003
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 enum protocol_types Protocol;
25 extern int smb_read_error;
26 extern int global_oplock_break;
27 extern struct current_user current_user;
28
29 static const char *known_nt_pipes[] = {
30         "\\LANMAN",
31         "\\srvsvc",
32         "\\samr",
33         "\\wkssvc",
34         "\\NETLOGON",
35         "\\ntlsa",
36         "\\ntsvcs",
37         "\\lsass",
38         "\\lsarpc",
39         "\\winreg",
40         "\\spoolss",
41         "\\netdfs",
42         "\\rpcecho",
43         NULL
44 };
45
46 /* Map generic permissions to file object specific permissions */
47  
48 struct generic_mapping file_generic_mapping = {
49         FILE_GENERIC_READ,
50         FILE_GENERIC_WRITE,
51         FILE_GENERIC_EXECUTE,
52         FILE_GENERIC_ALL
53 };
54
55 static char *nttrans_realloc(char **ptr, size_t size)
56 {
57         char *tptr = NULL;
58         if (ptr==NULL)
59                 smb_panic("nttrans_realloc() called with NULL ptr\n");
60                 
61         tptr = SMB_REALLOC(*ptr, size);
62         if(tptr == NULL) {
63                 *ptr = NULL;
64                 return NULL;
65         }
66         memset(tptr,'\0',size);
67
68         *ptr = tptr;
69
70         return tptr;
71 }
72
73
74 /****************************************************************************
75  Send the required number of replies back.
76  We assume all fields other than the data fields are
77  set correctly for the type of call.
78  HACK ! Always assumes smb_setup field is zero.
79 ****************************************************************************/
80
81 static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_error, char *params,
82                            int paramsize, char *pdata, int datasize)
83 {
84         extern int max_send;
85         int data_to_send = datasize;
86         int params_to_send = paramsize;
87         int useable_space;
88         char *pp = params;
89         char *pd = pdata;
90         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
91         int alignment_offset = 3;
92         int data_alignment_offset = 0;
93
94         /*
95          * Initially set the wcnt area to be 18 - this is true for all
96          * transNT replies.
97          */
98
99         set_message(outbuf,18,0,True);
100
101         if (NT_STATUS_V(nt_error))
102                 ERROR_NT(nt_error);
103
104         /* 
105          * If there genuinely are no parameters or data to send just send
106          * the empty packet.
107          */
108
109         if(params_to_send == 0 && data_to_send == 0) {
110                 if (!send_smb(smbd_server_fd(),outbuf))
111                         exit_server("send_nt_replies: send_smb failed.");
112                 return 0;
113         }
114
115         /*
116          * When sending params and data ensure that both are nicely aligned.
117          * Only do this alignment when there is also data to send - else
118          * can cause NT redirector problems.
119          */
120
121         if (((params_to_send % 4) != 0) && (data_to_send != 0))
122                 data_alignment_offset = 4 - (params_to_send % 4);
123
124         /* 
125          * Space is bufsize minus Netbios over TCP header minus SMB header.
126          * The alignment_offset is to align the param bytes on a four byte
127          * boundary (2 bytes for data len, one byte pad). 
128          * NT needs this to work correctly.
129          */
130
131         useable_space = bufsize - ((smb_buf(outbuf)+
132                                 alignment_offset+data_alignment_offset) -
133                                 outbuf);
134
135         /*
136          * useable_space can never be more than max_send minus the
137          * alignment offset.
138          */
139
140         useable_space = MIN(useable_space,
141                                 max_send - (alignment_offset+data_alignment_offset));
142
143
144         while (params_to_send || data_to_send) {
145
146                 /*
147                  * Calculate whether we will totally or partially fill this packet.
148                  */
149
150                 total_sent_thistime = params_to_send + data_to_send +
151                                         alignment_offset + data_alignment_offset;
152
153                 /* 
154                  * We can never send more than useable_space.
155                  */
156
157                 total_sent_thistime = MIN(total_sent_thistime, useable_space);
158
159                 set_message(outbuf, 18, total_sent_thistime, True);
160
161                 /*
162                  * Set total params and data to be sent.
163                  */
164
165                 SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
166                 SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
167
168                 /* 
169                  * Calculate how many parameters and data we can fit into
170                  * this packet. Parameters get precedence.
171                  */
172
173                 params_sent_thistime = MIN(params_to_send,useable_space);
174                 data_sent_thistime = useable_space - params_sent_thistime;
175                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
176
177                 SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
178
179                 if(params_sent_thistime == 0) {
180                         SIVAL(outbuf,smb_ntr_ParameterOffset,0);
181                         SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
182                 } else {
183                         /*
184                          * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
185                          * parameter bytes, however the first 4 bytes of outbuf are
186                          * the Netbios over TCP header. Thus use smb_base() to subtract
187                          * them from the calculation.
188                          */
189
190                         SIVAL(outbuf,smb_ntr_ParameterOffset,
191                                 ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
192                         /* 
193                          * Absolute displacement of param bytes sent in this packet.
194                          */
195
196                         SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
197                 }
198
199                 /*
200                  * Deal with the data portion.
201                  */
202
203                 SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
204
205                 if(data_sent_thistime == 0) {
206                         SIVAL(outbuf,smb_ntr_DataOffset,0);
207                         SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
208                 } else {
209                         /*
210                          * The offset of the data bytes is the offset of the
211                          * parameter bytes plus the number of parameters being sent this time.
212                          */
213
214                         SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
215                                 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
216                                 SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
217                 }
218
219                 /* 
220                  * Copy the param bytes into the packet.
221                  */
222
223                 if(params_sent_thistime)
224                         memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
225
226                 /*
227                  * Copy in the data bytes
228                  */
229
230                 if(data_sent_thistime)
231                         memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
232                                 data_alignment_offset,pd,data_sent_thistime);
233     
234                 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
235                         params_sent_thistime, data_sent_thistime, useable_space));
236                 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
237                         params_to_send, data_to_send, paramsize, datasize));
238     
239                 /* Send the packet */
240                 if (!send_smb(smbd_server_fd(),outbuf))
241                         exit_server("send_nt_replies: send_smb failed.");
242     
243                 pp += params_sent_thistime;
244                 pd += data_sent_thistime;
245     
246                 params_to_send -= params_sent_thistime;
247                 data_to_send -= data_sent_thistime;
248
249                 /*
250                  * Sanity check
251                  */
252
253                 if(params_to_send < 0 || data_to_send < 0) {
254                         DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
255                                 params_to_send, data_to_send));
256                         return -1;
257                 }
258         } 
259
260         return 0;
261 }
262
263 /****************************************************************************
264  Save case statics.
265 ****************************************************************************/
266
267 static BOOL saved_case_sensitive;
268 static BOOL saved_case_preserve;
269 static BOOL saved_short_case_preserve;
270
271 /****************************************************************************
272  Save case semantics.
273 ****************************************************************************/
274
275 static void set_posix_case_semantics(connection_struct *conn, uint32 file_attributes)
276 {
277         if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
278                 return;
279
280         saved_case_sensitive = conn->case_sensitive;
281         saved_case_preserve = conn->case_preserve;
282         saved_short_case_preserve = conn->short_case_preserve;
283
284         /* Set to POSIX. */
285         conn->case_sensitive = True;
286         conn->case_preserve = True;
287         conn->short_case_preserve = True;
288 }
289
290 /****************************************************************************
291  Restore case semantics.
292 ****************************************************************************/
293
294 static void restore_case_semantics(connection_struct *conn, uint32 file_attributes)
295 {
296         if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
297                 return;
298
299         conn->case_sensitive = saved_case_sensitive;
300         conn->case_preserve = saved_case_preserve;
301         conn->short_case_preserve = saved_short_case_preserve;
302 }
303
304 /****************************************************************************
305  Utility function to map create disposition.
306 ****************************************************************************/
307
308 static int map_create_disposition( uint32 create_disposition)
309 {
310         int ret;
311
312         switch( create_disposition ) {
313                 case FILE_CREATE:
314                         /* create if not exist, fail if exist */
315                         ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL);
316                         break;
317                 case FILE_SUPERSEDE:
318                 case FILE_OVERWRITE_IF:
319                         /* create if not exist, trunc if exist */
320                         ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE);
321                         break;
322                 case FILE_OPEN:
323                         /* fail if not exist, open if exists */
324                         ret = (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN);
325                         break;
326                 case FILE_OPEN_IF:
327                         /* create if not exist, open if exists */
328                         ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_OPEN);
329                         break;
330                 case FILE_OVERWRITE:
331                         /* fail if not exist, truncate if exists */
332                         ret = (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE);
333                         break;
334                 default:
335                         DEBUG(0,("map_create_disposition: Incorrect value for create_disposition = %d\n",
336                                 create_disposition ));
337                         return -1;
338         }
339
340         DEBUG(10,("map_create_disposition: Mapped create_disposition 0x%lx to 0x%x\n",
341                         (unsigned long)create_disposition, ret ));
342
343         return ret;
344 }
345
346 /****************************************************************************
347  Utility function to map share modes.
348 ****************************************************************************/
349
350 static int map_share_mode( char *fname, uint32 create_options,
351                         uint32 *desired_access, uint32 share_access, uint32 file_attributes)
352 {
353         int smb_open_mode = -1;
354         uint32 original_desired_access = *desired_access;
355
356         /*
357          * Convert GENERIC bits to specific bits.
358          */
359
360         se_map_generic(desired_access, &file_generic_mapping);
361
362         switch( *desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA) ) {
363                 case FILE_READ_DATA:
364                         smb_open_mode = DOS_OPEN_RDONLY;
365                         break;
366                 case FILE_WRITE_DATA:
367                 case FILE_APPEND_DATA:
368                 case FILE_WRITE_DATA|FILE_APPEND_DATA:
369                         smb_open_mode = DOS_OPEN_WRONLY;
370                         break;
371                 case FILE_READ_DATA|FILE_WRITE_DATA:
372                 case FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA:
373                 case FILE_READ_DATA|FILE_APPEND_DATA:
374                         smb_open_mode = DOS_OPEN_RDWR;
375                         break;
376         }
377
378         /*
379          * NB. For DELETE_ACCESS we should really check the
380          * directory permissions, as that is what controls
381          * delete, and for WRITE_DAC_ACCESS we should really
382          * check the ownership, as that is what controls the
383          * chmod. Note that this is *NOT* a security hole (this
384          * note is for you, Andrew) as we are not *allowing*
385          * the access at this point, the actual unlink or
386          * chown or chmod call would do this. We are just helping
387          * clients out by telling them if they have a hope
388          * of any of this succeeding. POSIX acls may still
389          * deny the real call. JRA.
390          */
391
392         if (smb_open_mode == -1) {
393
394                 if(*desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS|
395                                         FILE_EXECUTE|FILE_READ_ATTRIBUTES|
396                                         FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
397                                         FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS)) {
398                         smb_open_mode = DOS_OPEN_RDONLY;
399                 } else if(*desired_access == 0) {
400
401                         /* 
402                          * JRA - NT seems to sometimes send desired_access as zero. play it safe
403                          * and map to a stat open.
404                          */
405
406                         smb_open_mode = DOS_OPEN_RDONLY;
407
408                 } else {
409                         DEBUG(0,("map_share_mode: Incorrect value 0x%lx for desired_access to file %s\n",
410                                 (unsigned long)*desired_access, fname));
411                         return -1;
412                 }
413         }
414
415         /*
416          * Set the special bit that means allow share delete.
417          * This is held outside the normal share mode bits at 1<<15.
418          * JRA.
419          */
420
421         if(share_access & FILE_SHARE_DELETE) {
422                 smb_open_mode |= ALLOW_SHARE_DELETE;
423                 DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = 0x%x\n", smb_open_mode));
424         }
425
426         if(*desired_access & DELETE_ACCESS) {
427                 DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
428         }
429
430         /*
431          * We need to store the intent to open for Delete. This
432          * is what determines if a delete on close flag can be set.
433          * This is the wrong way (and place) to store this, but for 2.2 this
434          * is the only practical way. JRA.
435          */
436
437         if (create_options & FILE_DELETE_ON_CLOSE) {
438                 /*
439                  * W2K3 bug compatibility mode... To set delete on close
440                  * the redirector must have *specifically* set DELETE_ACCESS
441                  * in the desired_access field. Just asking for GENERIC_ALL won't do. JRA.
442                  */
443
444                 if (!(original_desired_access & DELETE_ACCESS)) {
445                         DEBUG(5,("map_share_mode: FILE_DELETE_ON_CLOSE requested without \
446 DELETE_ACCESS for file %s. (desired_access = 0x%lx)\n",
447                                 fname, (unsigned long)*desired_access));
448                         return -1;
449                 }
450                 /* Implicit delete access is *NOT* requested... */
451                 smb_open_mode |= DELETE_ON_CLOSE_FLAG;
452                 DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = 0x%x\n", smb_open_mode));
453         }
454
455         /* Add in the requested share mode. */
456         switch( share_access & (FILE_SHARE_READ|FILE_SHARE_WRITE)) {
457                 case FILE_SHARE_READ:
458                         smb_open_mode |= SET_DENY_MODE(DENY_WRITE);
459                         break;
460                 case FILE_SHARE_WRITE:
461                         smb_open_mode |= SET_DENY_MODE(DENY_READ);
462                         break;
463                 case (FILE_SHARE_READ|FILE_SHARE_WRITE):
464                         smb_open_mode |= SET_DENY_MODE(DENY_NONE);
465                         break;
466                 case FILE_SHARE_NONE:
467                         smb_open_mode |= SET_DENY_MODE(DENY_ALL);
468                         break;
469         }
470
471         /*
472          * Handle an O_SYNC request.
473          */
474
475         if(file_attributes & FILE_FLAG_WRITE_THROUGH)
476                 smb_open_mode |= FILE_SYNC_OPENMODE;
477
478         DEBUG(10,("map_share_mode: Mapped desired access 0x%lx, share access 0x%lx, file attributes 0x%lx \
479 to open_mode 0x%x\n", (unsigned long)*desired_access, (unsigned long)share_access,
480                 (unsigned long)file_attributes, smb_open_mode ));
481  
482         return smb_open_mode;
483 }
484
485 /****************************************************************************
486  Reply to an NT create and X call on a pipe.
487 ****************************************************************************/
488
489 static int nt_open_pipe(char *fname, connection_struct *conn,
490                         char *inbuf, char *outbuf, int *ppnum)
491 {
492         smb_np_struct *p = NULL;
493
494         uint16 vuid = SVAL(inbuf, smb_uid);
495         int i;
496
497         DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
498     
499         /* See if it is one we want to handle. */
500
501         if (lp_disable_spoolss() && strequal(fname, "\\spoolss"))
502                 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
503
504         for( i = 0; known_nt_pipes[i]; i++ )
505                 if( strequal(fname,known_nt_pipes[i]))
506                         break;
507     
508         if ( known_nt_pipes[i] == NULL )
509                 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
510     
511         /* Strip \\ off the name. */
512         fname++;
513     
514         DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
515
516         p = open_rpc_pipe_p(fname, conn, vuid);
517         if (!p)
518                 return(ERROR_DOS(ERRSRV,ERRnofids));
519
520         *ppnum = p->pnum;
521
522         return 0;
523 }
524
525 /****************************************************************************
526  Reply to an NT create and X call for pipes.
527 ****************************************************************************/
528
529 static int do_ntcreate_pipe_open(connection_struct *conn,
530                          char *inbuf,char *outbuf,int length,int bufsize)
531 {
532         pstring fname;
533         int ret;
534         int pnum = -1;
535         char *p = NULL;
536
537         srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
538
539         if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0)
540                 return ret;
541
542         /*
543          * Deal with pipe return.
544          */  
545
546         set_message(outbuf,34,0,True);
547
548         p = outbuf + smb_vwv2;
549         p++;
550         SSVAL(p,0,pnum);
551         p += 2;
552         SIVAL(p,0,FILE_WAS_OPENED);
553         p += 4;
554         p += 32;
555         SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
556         p += 20;
557         /* File type. */
558         SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
559         /* Device state. */
560         SSVAL(p,2, 0x5FF); /* ? */
561
562         DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
563
564         return chain_reply(inbuf,outbuf,length,bufsize);
565 }
566
567 /****************************************************************************
568  Reply to an NT create and X call.
569 ****************************************************************************/
570
571 int reply_ntcreate_and_X(connection_struct *conn,
572                          char *inbuf,char *outbuf,int length,int bufsize)
573 {  
574         int result;
575         pstring fname;
576         enum FAKE_FILE_TYPE fake_file_type = FAKE_FILE_TYPE_NONE;
577         uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
578         uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
579         uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
580         uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
581         uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
582         uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
583         uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
584         SMB_BIG_UINT allocation_size = 0;
585         int smb_ofun;
586         int smb_open_mode;
587         /* Breakout the oplock request bits so we can set the
588            reply bits separately. */
589         int oplock_request = 0;
590         int fmode=0,rmode=0;
591         SMB_OFF_T file_len = 0;
592         SMB_STRUCT_STAT sbuf;
593         int smb_action = 0;
594         BOOL bad_path = False;
595         files_struct *fsp=NULL;
596         char *p = NULL;
597         time_t c_time;
598         BOOL extended_oplock_granted = False;
599         NTSTATUS status;
600
601         START_PROFILE(SMBntcreateX);
602
603         DEBUG(10,("reply_ntcreateX: flags = 0x%x, desired_access = 0x%x \
604 file_attributes = 0x%x, share_access = 0x%x, create_disposition = 0x%x \
605 create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attributes,
606                         share_access, create_disposition,
607                         create_options, root_dir_fid ));
608
609         /* If it's an IPC, use the pipe handler. */
610
611         if (IS_IPC(conn)) {
612                 if (lp_nt_pipe_support()) {
613                         END_PROFILE(SMBntcreateX);
614                         return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);
615                 } else {
616                         END_PROFILE(SMBntcreateX);
617                         return(ERROR_DOS(ERRDOS,ERRnoaccess));
618                 }
619         }
620                         
621         if (create_options & FILE_OPEN_BY_FILE_ID) {
622                 END_PROFILE(SMBntcreateX);
623                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
624         }
625
626         /* 
627          * We need to construct the open_and_X ofun value from the
628          * NT values, as that's what our code is structured to accept.
629          */    
630         
631         if((smb_ofun = map_create_disposition( create_disposition )) == -1) {
632                 END_PROFILE(SMBntcreateX);
633                 return(ERROR_DOS(ERRDOS,ERRnoaccess));
634         }
635
636         /*
637          * Get the file name.
638          */
639
640         if(root_dir_fid != 0) {
641                 /*
642                  * This filename is relative to a directory fid.
643                  */
644                 pstring rel_fname;
645                 files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
646                 size_t dir_name_len;
647
648                 if(!dir_fsp) {
649                         END_PROFILE(SMBntcreateX);
650                         return(ERROR_DOS(ERRDOS,ERRbadfid));
651                 }
652
653                 if(!dir_fsp->is_directory) {
654
655                         srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status,False);
656                         if (!NT_STATUS_IS_OK(status)) {
657                                 END_PROFILE(SMBntcreateX);
658                                 return ERROR_NT(status);
659                         }
660
661                         /* 
662                          * Check to see if this is a mac fork of some kind.
663                          */
664
665                         if( strchr_m(fname, ':')) {
666                                 END_PROFILE(SMBntcreateX);
667                                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
668                         }
669
670                         /*
671                           we need to handle the case when we get a
672                           relative open relative to a file and the
673                           pathname is blank - this is a reopen!
674                           (hint from demyn plantenberg)
675                         */
676
677                         END_PROFILE(SMBntcreateX);
678                         return(ERROR_DOS(ERRDOS,ERRbadfid));
679                 }
680
681                 /*
682                  * Copy in the base directory name.
683                  */
684
685                 pstrcpy( fname, dir_fsp->fsp_name );
686                 dir_name_len = strlen(fname);
687
688                 /*
689                  * Ensure it ends in a '\'.
690                  */
691
692                 if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
693                         pstrcat(fname, "/");
694                         dir_name_len++;
695                 }
696
697                 srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status,False);
698                 if (!NT_STATUS_IS_OK(status)) {
699                         END_PROFILE(SMBntcreateX);
700                         return ERROR_NT(status);
701                 }
702                 pstrcat(fname, rel_fname);
703         } else {
704                 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status,False);
705                 if (!NT_STATUS_IS_OK(status)) {
706                         END_PROFILE(SMBntcreateX);
707                         return ERROR_NT(status);
708                 }
709
710                 /* 
711                  * Check to see if this is a mac fork of some kind.
712                  */
713
714                 if( strchr_m(fname, ':')) {
715                         
716 #ifdef HAVE_SYS_QUOTAS
717                         if ((fake_file_type=is_fake_file(fname))!=FAKE_FILE_TYPE_NONE) {
718                                 /*
719                                  * here we go! support for changing the disk quotas --metze
720                                  *
721                                  * we need to fake up to open this MAGIC QUOTA file 
722                                  * and return a valid FID
723                                  *
724                                  * w2k close this file directly after openening
725                                  * xp also tries a QUERY_FILE_INFO on the file and then close it
726                                  */
727                         } else {
728 #endif
729                                 END_PROFILE(SMBntcreateX);
730                                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
731 #ifdef HAVE_SYS_QUOTAS
732                         }
733 #endif
734                 }
735         }
736         
737         /*
738          * Now contruct the smb_open_mode value from the filename, 
739          * desired access and the share access.
740          */
741         RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
742
743         if((smb_open_mode = map_share_mode(fname, create_options, &desired_access, 
744                                            share_access, 
745                                            file_attributes)) == -1) {
746                 END_PROFILE(SMBntcreateX);
747                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
748         }
749
750         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
751         if (oplock_request) {
752                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
753         }
754
755         /*
756          * Ordinary file or directory.
757          */
758                 
759         /*
760          * Check if POSIX semantics are wanted.
761          */
762                 
763         set_posix_case_semantics(conn, file_attributes);
764                 
765         unix_convert(fname,conn,0,&bad_path,&sbuf);
766
767         /* FAKE_FILE is a special case */
768         if (fake_file_type == FAKE_FILE_TYPE_NONE) {
769                 /* Normal file. */
770                 if (bad_path) {
771                         restore_case_semantics(conn, file_attributes);
772                         END_PROFILE(SMBntcreateX);
773                         return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
774                 }
775                 /* All file access must go through check_name() */
776                 if (!check_name(fname,conn)) {
777                         restore_case_semantics(conn, file_attributes);
778                         END_PROFILE(SMBntcreateX);
779                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
780                 }
781         }
782
783 #if 0
784         /* This is the correct thing to do (check every time) but can_delete is
785            expensive (it may have to read the parent directory permissions). So
786            for now we're not doing it unless we have a strong hint the client
787            is really going to delete this file. */
788         if (desired_access & DELETE_ACCESS) {
789 #else
790         /* Setting FILE_SHARE_DELETE is the hint. */
791         if ((share_access & FILE_SHARE_DELETE) && (desired_access & DELETE_ACCESS)) {
792 #endif
793                 status = can_delete(conn, fname, file_attributes, bad_path, True);
794                 /* We're only going to fail here if it's access denied, as that's the
795                    only error we care about for "can we delete this ?" questions. */
796                 if (!NT_STATUS_IS_OK(status) && (NT_STATUS_EQUAL(status,NT_STATUS_ACCESS_DENIED) ||
797                                                  NT_STATUS_EQUAL(status,NT_STATUS_CANNOT_DELETE))) {
798                         restore_case_semantics(conn, file_attributes);
799                         END_PROFILE(SMBntcreateX);
800                         return ERROR_NT(status);
801                 }
802         }
803
804         /* 
805          * If it's a request for a directory open, deal with it separately.
806          */
807
808         if(create_options & FILE_DIRECTORY_FILE) {
809                 oplock_request = 0;
810                 
811                 /* Can't open a temp directory. IFS kit test. */
812                 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
813                         END_PROFILE(SMBntcreateX);
814                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
815                 }
816
817                 fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
818                         
819                 restore_case_semantics(conn, file_attributes);
820
821                 if(!fsp) {
822                         END_PROFILE(SMBntcreateX);
823                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
824                 }
825         } else {
826                 /*
827                  * Ordinary file case.
828                  */
829
830                 /* NB. We have a potential bug here. If we
831                  * cause an oplock break to ourselves, then we
832                  * could end up processing filename related
833                  * SMB requests whilst we await the oplock
834                  * break response. As we may have changed the
835                  * filename case semantics to be POSIX-like,
836                  * this could mean a filename request could
837                  * fail when it should succeed. This is a rare
838                  * condition, but eventually we must arrange
839                  * to restore the correct case semantics
840                  * before issuing an oplock break request to
841                  * our client. JRA.  */
842
843                 if (fake_file_type==FAKE_FILE_TYPE_NONE) {
844                         fsp = open_file_shared1(conn,fname,&sbuf,
845                                         desired_access,
846                                         smb_open_mode,
847                                         smb_ofun,file_attributes,oplock_request,
848                                         &rmode,&smb_action);
849                 } else {
850                         /* to open a fake_file --metze */
851                         fsp = open_fake_file_shared1(fake_file_type,conn,fname,&sbuf,
852                                         desired_access,
853                                         smb_open_mode,
854                                         smb_ofun,file_attributes, oplock_request,
855                                         &rmode,&smb_action);
856                 }
857                 
858                 if (!fsp) { 
859                         /* We cheat here. There are two cases we
860                          * care about. One is a directory rename,
861                          * where the NT client will attempt to
862                          * open the source directory for
863                          * DELETE access. Note that when the
864                          * NT client does this it does *not*
865                          * set the directory bit in the
866                          * request packet. This is translated
867                          * into a read/write open
868                          * request. POSIX states that any open
869                          * for write request on a directory
870                          * will generate an EISDIR error, so
871                          * we can catch this here and open a
872                          * pseudo handle that is flagged as a
873                          * directory. The second is an open
874                          * for a permissions read only, which
875                          * we handle in the open_file_stat case. JRA.
876                          */
877
878                         if(errno == EISDIR) {
879
880                                 /*
881                                  * Fail the open if it was explicitly a non-directory file.
882                                  */
883
884                                 if (create_options & FILE_NON_DIRECTORY_FILE) {
885                                         restore_case_semantics(conn, file_attributes);
886                                         SSVAL(outbuf, smb_flg2, 
887                                               SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
888                                         END_PROFILE(SMBntcreateX);
889                                         return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
890                                 }
891         
892                                 oplock_request = 0;
893                                 fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
894                                 
895                                 if(!fsp) {
896                                         restore_case_semantics(conn, file_attributes);
897                                         END_PROFILE(SMBntcreateX);
898                                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
899                                 }
900                         } else {
901
902                                 restore_case_semantics(conn, file_attributes);
903                                 END_PROFILE(SMBntcreateX);
904                                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
905                                         /* We have re-scheduled this call. */
906                                         clear_cached_errors();
907                                         return -1;
908                                 }
909                                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
910                         }
911                 } 
912         }
913                 
914         restore_case_semantics(conn, file_attributes);
915                 
916         file_len = sbuf.st_size;
917         fmode = dos_mode(conn,fname,&sbuf);
918         if(fmode == 0)
919                 fmode = FILE_ATTRIBUTE_NORMAL;
920         if (!fsp->is_directory && (fmode & aDIR)) {
921                 close_file(fsp,False);
922                 END_PROFILE(SMBntcreateX);
923                 return ERROR_DOS(ERRDOS,ERRnoaccess);
924         } 
925         
926         /* Save the requested allocation size. */
927         allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
928 #ifdef LARGE_SMB_OFF_T
929         allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
930 #endif
931         if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
932                 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
933                 if (fsp->is_directory) {
934                         close_file(fsp,False);
935                         END_PROFILE(SMBntcreateX);
936                         /* Can't set allocation size on a directory. */
937                         return ERROR_NT(NT_STATUS_ACCESS_DENIED);
938                 }
939                 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
940                         close_file(fsp,False);
941                         END_PROFILE(SMBntcreateX);
942                         return ERROR_NT(NT_STATUS_DISK_FULL);
943                 }
944         } else {
945                 fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
946         }
947
948         /* 
949          * If the caller set the extended oplock request bit
950          * and we granted one (by whatever means) - set the
951          * correct bit for extended oplock reply.
952          */
953         
954         if (oplock_request && lp_fake_oplocks(SNUM(conn)))
955                 extended_oplock_granted = True;
956         
957         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
958                 extended_oplock_granted = True;
959
960 #if 0
961         /* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */
962         set_message(outbuf,42,0,True);
963 #else
964         set_message(outbuf,34,0,True);
965 #endif
966         
967         p = outbuf + smb_vwv2;
968         
969         /*
970          * Currently as we don't support level II oplocks we just report
971          * exclusive & batch here.
972          */
973
974         if (extended_oplock_granted) {
975                 if (flags & REQUEST_BATCH_OPLOCK) {
976                         SCVAL(p,0, BATCH_OPLOCK_RETURN);
977                 } else {
978                         SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
979                 }
980         } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
981                 SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
982         } else {
983                 SCVAL(p,0,NO_OPLOCK_RETURN);
984         }
985         
986         p++;
987         SSVAL(p,0,fsp->fnum);
988         p += 2;
989         if ((create_disposition == FILE_SUPERSEDE) && (smb_action == FILE_WAS_OVERWRITTEN))
990                 SIVAL(p,0,FILE_WAS_SUPERSEDED);
991         else
992                 SIVAL(p,0,smb_action);
993         p += 4;
994         
995         /* Create time. */  
996         c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
997
998         if (lp_dos_filetime_resolution(SNUM(conn))) {
999                 c_time &= ~1;
1000                 sbuf.st_atime &= ~1;
1001                 sbuf.st_mtime &= ~1;
1002                 sbuf.st_mtime &= ~1;
1003         }
1004
1005         put_long_date(p,c_time);
1006         p += 8;
1007         put_long_date(p,sbuf.st_atime); /* access time */
1008         p += 8;
1009         put_long_date(p,sbuf.st_mtime); /* write time */
1010         p += 8;
1011         put_long_date(p,sbuf.st_mtime); /* change time */
1012         p += 8;
1013         SIVAL(p,0,fmode); /* File Attributes. */
1014         p += 4;
1015         SOFF_T(p, 0, get_allocation_size(fsp,&sbuf));
1016         p += 8;
1017         SOFF_T(p,0,file_len);
1018         p += 8;
1019         if (flags & EXTENDED_RESPONSE_REQUIRED)
1020                 SSVAL(p,2,0x7);
1021         p += 4;
1022         SCVAL(p,0,fsp->is_directory ? 1 : 0);
1023
1024         DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
1025
1026         result = chain_reply(inbuf,outbuf,length,bufsize);
1027         END_PROFILE(SMBntcreateX);
1028         return result;
1029 }
1030
1031 /****************************************************************************
1032  Reply to a NT_TRANSACT_CREATE call to open a pipe.
1033 ****************************************************************************/
1034
1035 static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1036                                   char **ppsetup, uint32 setup_count,
1037                                   char **ppparams, uint32 parameter_count,
1038                                   char **ppdata, uint32 data_count)
1039 {
1040         pstring fname;
1041         char *params = *ppparams;
1042         int ret;
1043         int pnum = -1;
1044         char *p = NULL;
1045         NTSTATUS status;
1046
1047         /*
1048          * Ensure minimum number of parameters sent.
1049          */
1050
1051         if(parameter_count < 54) {
1052                 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
1053                 return ERROR_DOS(ERRDOS,ERRnoaccess);
1054         }
1055
1056         srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
1057         if (!NT_STATUS_IS_OK(status)) {
1058                 return ERROR_NT(status);
1059         }
1060
1061         if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0)
1062                 return ret;
1063         
1064         /* Realloc the size of parameters and data we will return */
1065         params = nttrans_realloc(ppparams, 69);
1066         if(params == NULL)
1067                 return ERROR_DOS(ERRDOS,ERRnomem);
1068         
1069         p = params;
1070         SCVAL(p,0,NO_OPLOCK_RETURN);
1071         
1072         p += 2;
1073         SSVAL(p,0,pnum);
1074         p += 2;
1075         SIVAL(p,0,FILE_WAS_OPENED);
1076         p += 8;
1077         
1078         p += 32;
1079         SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
1080         p += 20;
1081         /* File type. */
1082         SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
1083         /* Device state. */
1084         SSVAL(p,2, 0x5FF); /* ? */
1085         
1086         DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
1087         
1088         /* Send the required number of replies */
1089         send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
1090         
1091         return -1;
1092 }
1093
1094 /****************************************************************************
1095  Internal fn to set security descriptors.
1096 ****************************************************************************/
1097
1098 static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent)
1099 {
1100         prs_struct pd;
1101         SEC_DESC *psd = NULL;
1102         TALLOC_CTX *mem_ctx;
1103         BOOL ret;
1104         
1105         if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {
1106                 return NT_STATUS_OK;
1107         }
1108
1109         /*
1110          * Init the parse struct we will unmarshall from.
1111          */
1112
1113         if ((mem_ctx = talloc_init("set_sd")) == NULL) {
1114                 DEBUG(0,("set_sd: talloc_init failed.\n"));
1115                 return NT_STATUS_NO_MEMORY;
1116         }
1117
1118         prs_init(&pd, 0, mem_ctx, UNMARSHALL);
1119
1120         /*
1121          * Setup the prs_struct to point at the memory we just
1122          * allocated.
1123          */
1124         
1125         prs_give_memory( &pd, data, sd_len, False);
1126
1127         /*
1128          * Finally, unmarshall from the data buffer.
1129          */
1130
1131         if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
1132                 DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));
1133                 /*
1134                  * Return access denied for want of a better error message..
1135                  */ 
1136                 talloc_destroy(mem_ctx);
1137                 return NT_STATUS_NO_MEMORY;
1138         }
1139         
1140         if (psd->off_owner_sid==0)
1141                 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
1142         if (psd->off_grp_sid==0)
1143                 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
1144         if (psd->off_sacl==0)
1145                 security_info_sent &= ~SACL_SECURITY_INFORMATION;
1146         if (psd->off_dacl==0)
1147                 security_info_sent &= ~DACL_SECURITY_INFORMATION;
1148         
1149         ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fd, security_info_sent, psd);
1150         
1151         if (!ret) {
1152                 talloc_destroy(mem_ctx);
1153                 return NT_STATUS_ACCESS_DENIED;
1154         }
1155         
1156         talloc_destroy(mem_ctx);
1157         
1158         return NT_STATUS_OK;
1159 }
1160
1161 /****************************************************************************
1162  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
1163 ****************************************************************************/
1164
1165 static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1166                                   char **ppsetup, uint32 setup_count,
1167                                   char **ppparams, uint32 parameter_count,
1168                                   char **ppdata, uint32 data_count, uint32 max_data_count)
1169 {
1170         pstring fname;
1171         char *params = *ppparams;
1172         char *data = *ppdata;
1173         /* Breakout the oplock request bits so we can set the reply bits separately. */
1174         int oplock_request = 0;
1175         int fmode=0,rmode=0;
1176         SMB_OFF_T file_len = 0;
1177         SMB_STRUCT_STAT sbuf;
1178         int smb_action = 0;
1179         BOOL bad_path = False;
1180         files_struct *fsp = NULL;
1181         char *p = NULL;
1182         BOOL extended_oplock_granted = False;
1183         uint32 flags;
1184         uint32 desired_access;
1185         uint32 file_attributes;
1186         uint32 share_access;
1187         uint32 create_disposition;
1188         uint32 create_options;
1189         uint32 sd_len;
1190         uint16 root_dir_fid;
1191         SMB_BIG_UINT allocation_size = 0;
1192         int smb_ofun;
1193         int smb_open_mode;
1194         time_t c_time;
1195         NTSTATUS status;
1196
1197         DEBUG(5,("call_nt_transact_create\n"));
1198
1199         /*
1200          * If it's an IPC, use the pipe handler.
1201          */
1202
1203         if (IS_IPC(conn)) {
1204                 if (lp_nt_pipe_support())
1205                         return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, 
1206                                         bufsize,
1207                                         ppsetup, setup_count,
1208                                         ppparams, parameter_count,
1209                                         ppdata, data_count);
1210                 else
1211                         return ERROR_DOS(ERRDOS,ERRnoaccess);
1212         }
1213
1214         /*
1215          * Ensure minimum number of parameters sent.
1216          */
1217
1218         if(parameter_count < 54) {
1219                 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
1220                 return ERROR_DOS(ERRDOS,ERRnoaccess);
1221         }
1222
1223         flags = IVAL(params,0);
1224         desired_access = IVAL(params,8);
1225         file_attributes = IVAL(params,20);
1226         share_access = IVAL(params,24);
1227         create_disposition = IVAL(params,28);
1228         create_options = IVAL(params,32);
1229         sd_len = IVAL(params,36);
1230         root_dir_fid = (uint16)IVAL(params,4);
1231
1232         if (create_options & FILE_OPEN_BY_FILE_ID) {
1233                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
1234         }
1235
1236         /* 
1237          * We need to construct the open_and_X ofun value from the
1238          * NT values, as that's what our code is structured to accept.
1239          */    
1240
1241         if((smb_ofun = map_create_disposition( create_disposition )) == -1)
1242                 return ERROR_DOS(ERRDOS,ERRbadmem);
1243
1244         /*
1245          * Get the file name.
1246          */
1247
1248         if(root_dir_fid != 0) {
1249                 /*
1250                  * This filename is relative to a directory fid.
1251                  */
1252                 files_struct *dir_fsp = file_fsp(params,4);
1253                 size_t dir_name_len;
1254
1255                 if(!dir_fsp)
1256                         return ERROR_DOS(ERRDOS,ERRbadfid);
1257
1258                 if(!dir_fsp->is_directory) {
1259                         srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
1260                         if (!NT_STATUS_IS_OK(status)) {
1261                                 return ERROR_NT(status);
1262                         }
1263
1264                         /*
1265                          * Check to see if this is a mac fork of some kind.
1266                          */
1267
1268                         if( strchr_m(fname, ':'))
1269                                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1270
1271                         return ERROR_DOS(ERRDOS,ERRbadfid);
1272                 }
1273
1274                 /*
1275                  * Copy in the base directory name.
1276                  */
1277
1278                 pstrcpy( fname, dir_fsp->fsp_name );
1279                 dir_name_len = strlen(fname);
1280
1281                 /*
1282                  * Ensure it ends in a '\'.
1283                  */
1284
1285                 if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
1286                         pstrcat(fname, "/");
1287                         dir_name_len++;
1288                 }
1289
1290                 {
1291                         pstring tmpname;
1292                         srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status, False);
1293                         if (!NT_STATUS_IS_OK(status)) {
1294                                 return ERROR_NT(status);
1295                         }
1296                         pstrcat(fname, tmpname);
1297                 }
1298         } else {
1299                 srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
1300                 if (!NT_STATUS_IS_OK(status)) {
1301                         return ERROR_NT(status);
1302                 }
1303
1304                 /*
1305                  * Check to see if this is a mac fork of some kind.
1306                  */
1307
1308                 if( strchr_m(fname, ':'))
1309                         return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1310         }
1311
1312         /*
1313          * Now contruct the smb_open_mode value from the desired access
1314          * and the share access.
1315          */
1316
1317         if((smb_open_mode = map_share_mode( fname, create_options, &desired_access,
1318                                                 share_access, file_attributes)) == -1)
1319                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1320
1321         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1322         oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1323
1324         /*
1325          * Check if POSIX semantics are wanted.
1326          */
1327
1328         set_posix_case_semantics(conn, file_attributes);
1329     
1330         RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1331
1332         unix_convert(fname,conn,0,&bad_path,&sbuf);
1333         if (bad_path) {
1334                 restore_case_semantics(conn, file_attributes);
1335                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1336         }
1337         /* All file access must go through check_name() */
1338         if (!check_name(fname,conn)) {
1339                 restore_case_semantics(conn, file_attributes);
1340                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1341         }
1342     
1343 #if 0
1344         /* This is the correct thing to do (check every time) but can_delete is
1345            expensive (it may have to read the parent directory permissions). So
1346            for now we're not doing it unless we have a strong hint the client
1347            is really going to delete this file. */
1348         if (desired_access & DELETE_ACCESS) {
1349 #else
1350         /* Setting FILE_SHARE_DELETE is the hint. */
1351         if ((share_access & FILE_SHARE_DELETE) && (desired_access & DELETE_ACCESS)) {
1352 #endif
1353                 status = can_delete(conn, fname, file_attributes, bad_path, True);
1354                 /* We're only going to fail here if it's access denied, as that's the
1355                    only error we care about for "can we delete this ?" questions. */
1356                 if (!NT_STATUS_IS_OK(status) && (NT_STATUS_EQUAL(status,NT_STATUS_ACCESS_DENIED) ||
1357                                                  NT_STATUS_EQUAL(status,NT_STATUS_CANNOT_DELETE))) {
1358                         restore_case_semantics(conn, file_attributes);
1359                         END_PROFILE(SMBntcreateX);
1360                         return ERROR_NT(status);
1361                 }
1362         }
1363
1364         /*
1365          * If it's a request for a directory open, deal with it separately.
1366          */
1367
1368         if(create_options & FILE_DIRECTORY_FILE) {
1369
1370                 /* Can't open a temp directory. IFS kit test. */
1371                 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
1372                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1373                 }
1374
1375                 oplock_request = 0;
1376
1377                 /*
1378                  * We will get a create directory here if the Win32
1379                  * app specified a security descriptor in the 
1380                  * CreateDirectory() call.
1381                  */
1382
1383                 fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
1384
1385                 if(!fsp) {
1386                         restore_case_semantics(conn, file_attributes);
1387                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
1388                 }
1389
1390         } else {
1391
1392                 /*
1393                  * Ordinary file case.
1394                  */
1395
1396                 fsp = open_file_shared1(conn,fname,&sbuf,desired_access,
1397                                                 smb_open_mode,smb_ofun,file_attributes,
1398                                                 oplock_request,&rmode,&smb_action);
1399
1400                 if (!fsp) { 
1401
1402                         if(errno == EISDIR) {
1403
1404                                 /*
1405                                  * Fail the open if it was explicitly a non-directory file.
1406                                  */
1407
1408                                 if (create_options & FILE_NON_DIRECTORY_FILE) {
1409                                         restore_case_semantics(conn, file_attributes);
1410                                         SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
1411                                         return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
1412                                 }
1413         
1414                                 oplock_request = 0;
1415                                 fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
1416                                 
1417                                 if(!fsp) {
1418                                         restore_case_semantics(conn, file_attributes);
1419                                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
1420                                 }
1421                         } else {
1422                                 restore_case_semantics(conn, file_attributes);
1423                                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1424                                         /* We have re-scheduled this call. */
1425                                         clear_cached_errors();
1426                                         return -1;
1427                                 }
1428                                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
1429                         }
1430                 } 
1431   
1432                 file_len = sbuf.st_size;
1433                 fmode = dos_mode(conn,fname,&sbuf);
1434                 if(fmode == 0)
1435                         fmode = FILE_ATTRIBUTE_NORMAL;
1436
1437                 if (fmode & aDIR) {
1438                         close_file(fsp,False);
1439                         restore_case_semantics(conn, file_attributes);
1440                         return ERROR_DOS(ERRDOS,ERRnoaccess);
1441                 } 
1442
1443                 /* 
1444                  * If the caller set the extended oplock request bit
1445                  * and we granted one (by whatever means) - set the
1446                  * correct bit for extended oplock reply.
1447                  */
1448     
1449                 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1450                         extended_oplock_granted = True;
1451   
1452                 if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1453                         extended_oplock_granted = True;
1454         }
1455
1456         /*
1457          * Now try and apply the desired SD.
1458          */
1459
1460         if (lp_nt_acl_support(SNUM(conn)) && sd_len &&
1461                         !NT_STATUS_IS_OK(status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION))) {
1462                 close_file(fsp,False);
1463                 restore_case_semantics(conn, file_attributes);
1464                 return ERROR_NT(status);
1465         }
1466         
1467         restore_case_semantics(conn, file_attributes);
1468
1469         /* Save the requested allocation size. */
1470         allocation_size = (SMB_BIG_UINT)IVAL(params,12);
1471 #ifdef LARGE_SMB_OFF_T
1472         allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
1473 #endif
1474         if (allocation_size && (allocation_size > file_len)) {
1475                 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
1476                 if (fsp->is_directory) {
1477                         close_file(fsp,False);
1478                         END_PROFILE(SMBntcreateX);
1479                         /* Can't set allocation size on a directory. */
1480                         return ERROR_NT(NT_STATUS_ACCESS_DENIED);
1481                 }
1482                 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
1483                         close_file(fsp,False);
1484                         return ERROR_NT(NT_STATUS_DISK_FULL);
1485                 }
1486         } else {
1487                 fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
1488         }
1489
1490         /* Realloc the size of parameters and data we will return */
1491         params = nttrans_realloc(ppparams, 69);
1492         if(params == NULL)
1493                 return ERROR_DOS(ERRDOS,ERRnomem);
1494
1495         p = params;
1496         if (extended_oplock_granted)
1497                 SCVAL(p,0, BATCH_OPLOCK_RETURN);
1498         else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
1499                 SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
1500         else
1501                 SCVAL(p,0,NO_OPLOCK_RETURN);
1502         
1503         p += 2;
1504         SSVAL(p,0,fsp->fnum);
1505         p += 2;
1506         if ((create_disposition == FILE_SUPERSEDE) && (smb_action == FILE_WAS_OVERWRITTEN))
1507                 SIVAL(p,0,FILE_WAS_SUPERSEDED);
1508         else
1509                 SIVAL(p,0,smb_action);
1510         p += 8;
1511
1512         /* Create time. */
1513         c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1514
1515         if (lp_dos_filetime_resolution(SNUM(conn))) {
1516                 c_time &= ~1;
1517                 sbuf.st_atime &= ~1;
1518                 sbuf.st_mtime &= ~1;
1519                 sbuf.st_mtime &= ~1;
1520         }
1521
1522         put_long_date(p,c_time);
1523         p += 8;
1524         put_long_date(p,sbuf.st_atime); /* access time */
1525         p += 8;
1526         put_long_date(p,sbuf.st_mtime); /* write time */
1527         p += 8;
1528         put_long_date(p,sbuf.st_mtime); /* change time */
1529         p += 8;
1530         SIVAL(p,0,fmode); /* File Attributes. */
1531         p += 4;
1532         SOFF_T(p, 0, get_allocation_size(fsp,&sbuf));
1533         p += 8;
1534         SOFF_T(p,0,file_len);
1535         p += 8;
1536         if (flags & EXTENDED_RESPONSE_REQUIRED)
1537                 SSVAL(p,2,0x7);
1538         p += 4;
1539         SCVAL(p,0,fsp->is_directory ? 1 : 0);
1540
1541         DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
1542
1543         /* Send the required number of replies */
1544         send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
1545
1546         return -1;
1547 }
1548
1549 /****************************************************************************
1550  Reply to a NT CANCEL request.
1551 ****************************************************************************/
1552
1553 int reply_ntcancel(connection_struct *conn,
1554                    char *inbuf,char *outbuf,int length,int bufsize)
1555 {
1556         /*
1557          * Go through and cancel any pending change notifies.
1558          */
1559         
1560         int mid = SVAL(inbuf,smb_mid);
1561         START_PROFILE(SMBntcancel);
1562         remove_pending_change_notify_requests_by_mid(mid);
1563         remove_pending_lock_requests_by_mid(mid);
1564         srv_cancel_sign_response(mid);
1565         
1566         DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
1567
1568         END_PROFILE(SMBntcancel);
1569         return(-1);
1570 }
1571
1572 /****************************************************************************
1573  Copy a file.
1574 ****************************************************************************/
1575
1576 static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint16 attrs)
1577 {
1578         BOOL bad_path_oldname = False;
1579         BOOL bad_path_newname = False;
1580         SMB_STRUCT_STAT sbuf1, sbuf2;
1581         pstring last_component_oldname;
1582         pstring last_component_newname;
1583         files_struct *fsp1,*fsp2;
1584         uint16 fmode;
1585         int access_mode;
1586         int smb_action;
1587         SMB_OFF_T ret=-1;
1588         int close_ret;
1589         NTSTATUS status = NT_STATUS_OK;
1590
1591         ZERO_STRUCT(sbuf1);
1592         ZERO_STRUCT(sbuf2);
1593
1594         /* No wildcards. */
1595         if (ms_has_wild(newname) || ms_has_wild(oldname)) {
1596                 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1597         }
1598
1599         if (!CAN_WRITE(conn))
1600                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1601
1602         unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
1603         if (bad_path_oldname) {
1604                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1605         }
1606
1607         /* Quick check for "." and ".." */
1608         if (last_component_oldname[0] == '.') {
1609                 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
1610                         return NT_STATUS_OBJECT_NAME_INVALID;
1611                 }
1612         }
1613
1614         /* Source must already exist. */
1615         if (!VALID_STAT(sbuf1)) {
1616                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1617         }
1618         if (!check_name(oldname,conn)) {
1619                 return NT_STATUS_ACCESS_DENIED;
1620         }
1621
1622         /* Ensure attributes match. */
1623         fmode = dos_mode(conn,oldname,&sbuf1);
1624         if ((fmode & ~attrs) & (aHIDDEN | aSYSTEM))
1625                 return NT_STATUS_NO_SUCH_FILE;
1626
1627         unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
1628         if (bad_path_newname) {
1629                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1630         }
1631
1632         /* Quick check for "." and ".." */
1633         if (last_component_newname[0] == '.') {
1634                 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
1635                         return NT_STATUS_OBJECT_NAME_INVALID;
1636                 }
1637         }
1638
1639         /* Disallow if newname already exists. */
1640         if (VALID_STAT(sbuf2)) {
1641                 return NT_STATUS_OBJECT_NAME_COLLISION;
1642         }
1643
1644         if (!check_name(newname,conn)) {
1645                 return NT_STATUS_ACCESS_DENIED;
1646         }
1647
1648         /* No links from a directory. */
1649         if (S_ISDIR(sbuf1.st_mode)) {
1650                 return NT_STATUS_FILE_IS_A_DIRECTORY;
1651         }
1652
1653         /* Ensure this is within the share. */
1654         if (!reduce_name(conn, oldname) != 0) {
1655                 return NT_STATUS_ACCESS_DENIED;
1656         }
1657
1658         DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));
1659
1660         fsp1 = open_file_shared1(conn,oldname,&sbuf1,FILE_READ_DATA,SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
1661                         (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),FILE_ATTRIBUTE_NORMAL,0,
1662                         &access_mode,&smb_action);
1663
1664         if (!fsp1) {
1665                 status = NT_STATUS_ACCESS_DENIED;
1666                 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1667                         status = NT_STATUS_SHARING_VIOLATION;
1668                 unix_ERR_class = 0;
1669                 unix_ERR_code = 0;
1670                 unix_ERR_ntstatus = NT_STATUS_OK;
1671                 return status;
1672         }
1673
1674         fsp2 = open_file_shared1(conn,newname,&sbuf2,FILE_WRITE_DATA,SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
1675                         (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL),fmode,INTERNAL_OPEN_ONLY,
1676                         &access_mode,&smb_action);
1677
1678         if (!fsp2) {
1679                 status = NT_STATUS_ACCESS_DENIED;
1680                 if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
1681                         status = NT_STATUS_SHARING_VIOLATION;
1682                 unix_ERR_class = 0;
1683                 unix_ERR_code = 0;
1684                 unix_ERR_ntstatus = NT_STATUS_OK;
1685                 close_file(fsp1,False);
1686                 return status;
1687         }
1688
1689         if (sbuf1.st_size)
1690                 ret = vfs_transfer_file(fsp1, fsp2, sbuf1.st_size);
1691
1692         /*
1693          * As we are opening fsp1 read-only we only expect
1694          * an error on close on fsp2 if we are out of space.
1695          * Thus we don't look at the error return from the
1696          * close of fsp1.
1697          */
1698         close_file(fsp1,False);
1699
1700         /* Ensure the modtime is set correctly on the destination file. */
1701         fsp2->pending_modtime = sbuf1.st_mtime;
1702
1703         close_ret = close_file(fsp2,False);
1704
1705         /* Grrr. We have to do this as open_file_shared1 adds aARCH when it
1706            creates the file. This isn't the correct thing to do in the copy case. JRA */
1707         file_set_dosmode(conn, newname, fmode, &sbuf2, True);
1708
1709         if (ret < (SMB_OFF_T)sbuf1.st_size) {
1710                 return NT_STATUS_DISK_FULL;
1711         }
1712
1713         if (close_ret != 0) {
1714                 status = map_nt_error_from_unix(close_ret);
1715                 DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
1716                         nt_errstr(status), oldname, newname));
1717         }
1718         return status;
1719 }
1720
1721 /****************************************************************************
1722  Reply to a NT rename request.
1723 ****************************************************************************/
1724
1725 int reply_ntrename(connection_struct *conn,
1726                    char *inbuf,char *outbuf,int length,int bufsize)
1727 {
1728         int outsize = 0;
1729         pstring oldname;
1730         pstring newname;
1731         char *p;
1732         NTSTATUS status;
1733         uint16 attrs = SVAL(inbuf,smb_vwv0);
1734         uint16 rename_type = SVAL(inbuf,smb_vwv1);
1735
1736         START_PROFILE(SMBntrename);
1737
1738         p = smb_buf(inbuf) + 1;
1739         p += srvstr_get_path(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, True);
1740         if (!NT_STATUS_IS_OK(status)) {
1741                 END_PROFILE(SMBntrename);
1742                 return ERROR_NT(status);
1743         }
1744
1745         if( strchr_m(oldname, ':')) {
1746                 /* Can't rename a stream. */
1747                 END_PROFILE(SMBntrename);
1748                 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
1749         }
1750
1751         if (ms_has_wild(oldname)) {
1752                 END_PROFILE(SMBntrename);
1753                 return ERROR_NT(NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
1754         }
1755
1756         p++;
1757         p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, False);
1758         if (!NT_STATUS_IS_OK(status)) {
1759                 END_PROFILE(SMBntrename);
1760                 return ERROR_NT(status);
1761         }
1762         
1763         RESOLVE_DFSPATH(oldname, conn, inbuf, outbuf);
1764         RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
1765         
1766         DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
1767         
1768         switch(rename_type) {
1769                 case RENAME_FLAG_RENAME:
1770                         status = rename_internals(conn, oldname, newname, attrs, False);
1771                         break;
1772                 case RENAME_FLAG_HARD_LINK:
1773                         status = hardlink_internals(conn, oldname, newname);
1774                         break;
1775                 case RENAME_FLAG_COPY:
1776                         status = copy_internals(conn, oldname, newname, attrs);
1777                         break;
1778                 case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
1779                         status = NT_STATUS_INVALID_PARAMETER;
1780                         break;
1781                 default:
1782                         status = NT_STATUS_ACCESS_DENIED; /* Default error. */
1783                         break;
1784         }
1785
1786         if (!NT_STATUS_IS_OK(status)) {
1787                 END_PROFILE(SMBntrename);
1788                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
1789                         /* We have re-scheduled this call. */
1790                         clear_cached_errors();
1791                         return -1;
1792                 }
1793                 return ERROR_NT(status);
1794         }
1795
1796         /*
1797          * Win2k needs a changenotify request response before it will
1798          * update after a rename..
1799          */     
1800         process_pending_change_notify_queue((time_t)0);
1801         outsize = set_message(outbuf,0,0,True);
1802   
1803         END_PROFILE(SMBntrename);
1804         return(outsize);
1805 }
1806
1807 /****************************************************************************
1808  Reply to an unsolicited SMBNTtranss - just ignore it!
1809 ****************************************************************************/
1810
1811 int reply_nttranss(connection_struct *conn,
1812                    char *inbuf,char *outbuf,int length,int bufsize)
1813 {
1814         START_PROFILE(SMBnttranss);
1815         DEBUG(4,("Ignoring nttranss of length %d\n",length));
1816         END_PROFILE(SMBnttranss);
1817         return(-1);
1818 }
1819
1820 /****************************************************************************
1821  Reply to a notify change - queue the request and 
1822  don't allow a directory to be opened.
1823 ****************************************************************************/
1824
1825 static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
1826                                   char **ppsetup, uint32 setup_count,
1827                                   char **ppparams, uint32 parameter_count,
1828                                   char **ppdata, uint32 data_count, uint32 max_data_count)
1829 {
1830         char *setup = *ppsetup;
1831         files_struct *fsp;
1832         uint32 flags;
1833
1834         if(setup_count < 6)
1835                 return ERROR_DOS(ERRDOS,ERRbadfunc);
1836
1837         fsp = file_fsp(setup,4);
1838         flags = IVAL(setup, 0);
1839
1840         DEBUG(3,("call_nt_transact_notify_change\n"));
1841
1842         if(!fsp)
1843                 return ERROR_DOS(ERRDOS,ERRbadfid);
1844
1845         if((!fsp->is_directory) || (conn != fsp->conn))
1846                 return ERROR_DOS(ERRDOS,ERRbadfid);
1847
1848         if (!change_notify_set(inbuf, fsp, conn, flags))
1849                 return(UNIXERROR(ERRDOS,ERRbadfid));
1850
1851         DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \
1852 name = %s\n", fsp->fsp_name ));
1853
1854         return -1;
1855 }
1856
1857 /****************************************************************************
1858  Reply to an NT transact rename command.
1859 ****************************************************************************/
1860
1861 static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1862                                   char **ppsetup, uint32 setup_count,
1863                                   char **ppparams, uint32 parameter_count,
1864                                   char **ppdata, uint32 data_count, uint32 max_data_count)
1865 {
1866         char *params = *ppparams;
1867         pstring new_name;
1868         files_struct *fsp = NULL;
1869         BOOL replace_if_exists = False;
1870         NTSTATUS status;
1871
1872         if(parameter_count < 4)
1873                 return ERROR_DOS(ERRDOS,ERRbadfunc);
1874
1875         fsp = file_fsp(params, 0);
1876         replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
1877         CHECK_FSP(fsp, conn);
1878         srvstr_get_path(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status, True);
1879         if (!NT_STATUS_IS_OK(status)) {
1880                 return ERROR_NT(status);
1881         }
1882
1883         status = rename_internals(conn, fsp->fsp_name,
1884                                   new_name, 0, replace_if_exists);
1885         if (!NT_STATUS_IS_OK(status))
1886                 return ERROR_NT(status);
1887
1888         /*
1889          * Rename was successful.
1890          */
1891         send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
1892         
1893         DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 
1894                  fsp->fsp_name, new_name));
1895         
1896         /*
1897          * Win2k needs a changenotify request response before it will
1898          * update after a rename..
1899          */
1900         
1901         process_pending_change_notify_queue((time_t)0);
1902
1903         return -1;
1904 }
1905
1906 /******************************************************************************
1907  Fake up a completely empty SD.
1908 *******************************************************************************/
1909
1910 static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
1911 {
1912         extern DOM_SID global_sid_World;
1913         size_t sd_size;
1914
1915         *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
1916         if(!*ppsd) {
1917                 DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
1918                 sd_size = 0;
1919         }
1920
1921         return sd_size;
1922 }
1923
1924 /****************************************************************************
1925  Reply to query a security descriptor.
1926 ****************************************************************************/
1927
1928 static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
1929                                   char **ppsetup, uint32 setup_count,
1930                                   char **ppparams, uint32 parameter_count,
1931                                   char **ppdata, uint32 data_count, uint32 max_data_count)
1932 {
1933         char *params = *ppparams;
1934         char *data = *ppdata;
1935         prs_struct pd;
1936         SEC_DESC *psd = NULL;
1937         size_t sd_size;
1938         uint32 security_info_wanted;
1939         TALLOC_CTX *mem_ctx;
1940         files_struct *fsp = NULL;
1941
1942         if(parameter_count < 8)
1943                 return ERROR_DOS(ERRDOS,ERRbadfunc);
1944
1945         fsp = file_fsp(params,0);
1946         if(!fsp)
1947                 return ERROR_DOS(ERRDOS,ERRbadfid);
1948
1949         security_info_wanted = IVAL(params,4);
1950
1951         DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
1952
1953         params = nttrans_realloc(ppparams, 4);
1954         if(params == NULL)
1955                 return ERROR_DOS(ERRDOS,ERRnomem);
1956
1957         if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {
1958                 DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
1959                 return ERROR_DOS(ERRDOS,ERRnomem);
1960         }
1961
1962         /*
1963          * Get the permissions to return.
1964          */
1965
1966         if (!lp_nt_acl_support(SNUM(conn)))
1967                 sd_size = get_null_nt_acl(mem_ctx, &psd);
1968         else
1969                 sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, security_info_wanted, &psd);
1970
1971         if (sd_size == 0) {
1972                 talloc_destroy(mem_ctx);
1973                 return(UNIXERROR(ERRDOS,ERRnoaccess));
1974         }
1975
1976         DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %d.\n",(int)sd_size));
1977
1978         SIVAL(params,0,(uint32)sd_size);
1979
1980         if(max_data_count < sd_size) {
1981
1982                 send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
1983                         params, 4, *ppdata, 0);
1984                 talloc_destroy(mem_ctx);
1985                 return -1;
1986         }
1987
1988         /*
1989          * Allocate the data we will point this at.
1990          */
1991
1992         data = nttrans_realloc(ppdata, sd_size);
1993         if(data == NULL) {
1994                 talloc_destroy(mem_ctx);
1995                 return ERROR_DOS(ERRDOS,ERRnomem);
1996         }
1997
1998         /*
1999          * Init the parse struct we will marshall into.
2000          */
2001
2002         prs_init(&pd, 0, mem_ctx, MARSHALL);
2003
2004         /*
2005          * Setup the prs_struct to point at the memory we just
2006          * allocated.
2007          */
2008
2009         prs_give_memory( &pd, data, (uint32)sd_size, False);
2010
2011         /*
2012          * Finally, linearize into the outgoing buffer.
2013          */
2014
2015         if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
2016                 DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
2017 security descriptor.\n"));
2018                 /*
2019                  * Return access denied for want of a better error message..
2020                  */ 
2021                 talloc_destroy(mem_ctx);
2022                 return(UNIXERROR(ERRDOS,ERRnoaccess));
2023         }
2024
2025         /*
2026          * Now we can delete the security descriptor.
2027          */
2028
2029         talloc_destroy(mem_ctx);
2030
2031         send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size);
2032         return -1;
2033 }
2034
2035 /****************************************************************************
2036  Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
2037 ****************************************************************************/
2038
2039 static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2040                                   char **ppsetup, uint32 setup_count,
2041                                   char **ppparams, uint32 parameter_count,
2042                                   char **ppdata, uint32 data_count, uint32 max_data_count)
2043 {
2044         char *params= *ppparams;
2045         char *data = *ppdata;
2046         files_struct *fsp = NULL;
2047         uint32 security_info_sent = 0;
2048         NTSTATUS nt_status;
2049
2050         if(parameter_count < 8)
2051                 return ERROR_DOS(ERRDOS,ERRbadfunc);
2052
2053         if((fsp = file_fsp(params,0)) == NULL)
2054                 return ERROR_DOS(ERRDOS,ERRbadfid);
2055
2056         if(!lp_nt_acl_support(SNUM(conn)))
2057                 goto done;
2058
2059         security_info_sent = IVAL(params,4);
2060
2061         DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
2062                 (unsigned int)security_info_sent ));
2063
2064         if (data_count == 0)
2065                 return ERROR_DOS(ERRDOS, ERRnoaccess);
2066
2067         if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent)))
2068                 return ERROR_NT(nt_status);
2069
2070   done:
2071
2072         send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
2073         return -1;
2074 }
2075    
2076 /****************************************************************************
2077  Reply to NT IOCTL
2078 ****************************************************************************/
2079
2080 static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2081                                   char **ppsetup, uint32 setup_count,
2082                                   char **ppparams, uint32 parameter_count,
2083                                   char **ppdata, uint32 data_count, uint32 max_data_count)
2084 {
2085         uint32 function;
2086         uint16 fidnum;
2087         files_struct *fsp;
2088         uint8 isFSctl;
2089         uint8 compfilter;
2090         static BOOL logged_message;
2091         char *pdata = *ppdata;
2092
2093         if (setup_count != 8) {
2094                 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
2095                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
2096         }
2097
2098         function = IVAL(*ppsetup, 0);
2099         fidnum = SVAL(*ppsetup, 4);
2100         isFSctl = CVAL(*ppsetup, 6);
2101         compfilter = CVAL(*ppsetup, 7);
2102
2103         DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 
2104                  function, fidnum, isFSctl, compfilter));
2105
2106         fsp=file_fsp(*ppsetup, 4);
2107         /* this check is done in each implemented function case for now
2108            because I don't want to break anything... --metze
2109         FSP_BELONGS_CONN(fsp,conn);*/
2110
2111         switch (function) {
2112         case FSCTL_SET_SPARSE:
2113                 /* pretend this succeeded - tho strictly we should
2114                    mark the file sparse (if the local fs supports it)
2115                    so we can know if we need to pre-allocate or not */
2116
2117                 DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
2118                 send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
2119                 return -1;
2120         
2121         case FSCTL_0x000900C0:
2122                 /* pretend this succeeded - don't know what this really is
2123                    but works ok like this --metze
2124                  */
2125
2126                 DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum));
2127                 send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
2128                 return -1;
2129
2130         case FSCTL_GET_REPARSE_POINT:
2131                 /* pretend this fail - my winXP does it like this
2132                  * --metze
2133                  */
2134
2135                 DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
2136                 send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
2137                 return -1;
2138
2139         case FSCTL_SET_REPARSE_POINT:
2140                 /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.
2141                  * --metze
2142                  */
2143
2144                 DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
2145                 send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
2146                 return -1;
2147                         
2148         case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
2149         {
2150                 /*
2151                  * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
2152                  * and return their volume names.  If max_data_count is 16, then it is just
2153                  * asking for the number of volumes and length of the combined names.
2154                  *
2155                  * pdata is the data allocated by our caller, but that uses
2156                  * total_data_count (which is 0 in our case) rather than max_data_count.
2157                  * Allocate the correct amount and return the pointer to let
2158                  * it be deallocated when we return.
2159                  */
2160                 SHADOW_COPY_DATA *shadow_data = NULL;
2161                 TALLOC_CTX *shadow_mem_ctx = NULL;
2162                 BOOL labels = False;
2163                 uint32 labels_data_count = 0;
2164                 uint32 i;
2165                 char *cur_pdata;
2166
2167                 FSP_BELONGS_CONN(fsp,conn);
2168
2169                 if (max_data_count < 16) {
2170                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
2171                                 max_data_count));
2172                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2173                 }
2174
2175                 if (max_data_count > 16) {
2176                         labels = True;
2177                 }
2178
2179                 shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
2180                 if (shadow_mem_ctx == NULL) {
2181                         DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
2182                         return ERROR_NT(NT_STATUS_NO_MEMORY);
2183                 }
2184
2185                 shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);
2186                 if (shadow_data == NULL) {
2187                         DEBUG(0,("talloc_zero() failed!\n"));
2188                         talloc_destroy(shadow_mem_ctx);
2189                         return ERROR_NT(NT_STATUS_NO_MEMORY);
2190                 }
2191                 
2192                 shadow_data->mem_ctx = shadow_mem_ctx;
2193                 
2194                 /*
2195                  * Call the VFS routine to actually do the work.
2196                  */
2197                 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
2198                         talloc_destroy(shadow_data->mem_ctx);
2199                         if (errno == ENOSYS) {
2200                                 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 
2201                                         conn->connectpath));
2202                                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
2203                         } else {
2204                                 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 
2205                                         conn->connectpath));
2206                                 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);                        
2207                         }
2208                 }
2209
2210                 labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
2211
2212                 if (!labels) {
2213                         data_count = 16;
2214                 } else {
2215                         data_count = 12+labels_data_count+4;
2216                 }
2217
2218                 if (max_data_count<data_count) {
2219                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
2220                                 max_data_count,data_count));
2221                         talloc_destroy(shadow_data->mem_ctx);
2222                         return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
2223                 }
2224
2225                 pdata = nttrans_realloc(ppdata, data_count);
2226                 if (pdata == NULL) {
2227                         talloc_destroy(shadow_data->mem_ctx);
2228                         return ERROR_NT(NT_STATUS_NO_MEMORY);
2229                 }               
2230
2231                 cur_pdata = pdata;
2232
2233                 /* num_volumes 4 bytes */
2234                 SIVAL(pdata,0,shadow_data->num_volumes);
2235
2236                 if (labels) {
2237                         /* num_labels 4 bytes */
2238                         SIVAL(pdata,4,shadow_data->num_volumes);
2239                 }
2240
2241                 /* needed_data_count 4 bytes */
2242                 SIVAL(pdata,8,labels_data_count);
2243
2244                 cur_pdata+=12;
2245
2246                 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
2247                         shadow_data->num_volumes,fsp->fsp_name));
2248                 if (labels && shadow_data->labels) {
2249                         for (i=0;i<shadow_data->num_volumes;i++) {
2250                                 srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);
2251                                 cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
2252                                 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
2253                         }
2254                 }
2255
2256                 talloc_destroy(shadow_data->mem_ctx);
2257
2258                 send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, pdata, data_count);
2259
2260                 return -1;
2261         }
2262         
2263         case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
2264         {
2265                 /* pretend this succeeded - 
2266                  * 
2267                  * we have to send back a list with all files owned by this SID
2268                  *
2269                  * but I have to check that --metze
2270                  */
2271                 DOM_SID sid;
2272                 uid_t uid;
2273                 size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
2274                 
2275                 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
2276
2277                 FSP_BELONGS_CONN(fsp,conn);
2278
2279                 /* unknown 4 bytes: this is not the length of the sid :-(  */
2280                 /*unknown = IVAL(pdata,0);*/
2281                 
2282                 sid_parse(pdata+4,sid_len,&sid);
2283                 DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
2284
2285                 if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) {
2286                         DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
2287                                 sid_string_static(&sid),(unsigned long)sid_len));
2288                         uid = (-1);
2289                 }
2290                 
2291                 /* we can take a look at the find source :-)
2292                  *
2293                  * find ./ -uid $uid  -name '*'   is what we need here
2294                  *
2295                  *
2296                  * and send 4bytes len and then NULL terminated unicode strings
2297                  * for each file
2298                  *
2299                  * but I don't know how to deal with the paged results
2300                  * (maybe we can hang the result anywhere in the fsp struct)
2301                  *
2302                  * we don't send all files at once
2303                  * and at the next we should *not* start from the beginning, 
2304                  * so we have to cache the result 
2305                  *
2306                  * --metze
2307                  */
2308                 
2309                 /* this works for now... */
2310                 send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
2311                 return -1;      
2312         }       
2313         default:
2314                 if (!logged_message) {
2315                         logged_message = True; /* Only print this once... */
2316                         DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
2317                                  function));
2318                 }
2319         }
2320
2321         return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
2322 }
2323
2324
2325 #ifdef HAVE_SYS_QUOTAS
2326 /****************************************************************************
2327  Reply to get user quota 
2328 ****************************************************************************/
2329
2330 static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2331                                   char **ppsetup, uint32 setup_count,
2332                                   char **ppparams, uint32 parameter_count,
2333                                   char **ppdata, uint32 data_count, uint32 max_data_count)
2334 {
2335         NTSTATUS nt_status = NT_STATUS_OK;
2336         char *params = *ppparams;
2337         char *pdata = *ppdata;
2338         char *entry;
2339         int data_len=0,param_len=0;
2340         int qt_len=0;
2341         int entry_len = 0;
2342         files_struct *fsp = NULL;
2343         uint16 level = 0;
2344         size_t sid_len;
2345         DOM_SID sid;
2346         BOOL start_enum = True;
2347         SMB_NTQUOTA_STRUCT qt;
2348         SMB_NTQUOTA_LIST *tmp_list;
2349         SMB_NTQUOTA_HANDLE *qt_handle = NULL;
2350         extern struct current_user current_user;
2351
2352         ZERO_STRUCT(qt);
2353
2354         /* access check */
2355         if (current_user.uid != 0) {
2356                 DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n",
2357                         lp_servicename(SNUM(conn)),conn->user));
2358                 return ERROR_DOS(ERRDOS,ERRnoaccess);
2359         }
2360
2361         /*
2362          * Ensure minimum number of parameters sent.
2363          */
2364
2365         if (parameter_count < 4) {
2366                 DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
2367                 return ERROR_DOS(ERRDOS,ERRinvalidparam);
2368         }
2369         
2370         /* maybe we can check the quota_fnum */
2371         fsp = file_fsp(params,0);
2372         if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2373                 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2374                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2375         }
2376
2377         /* the NULL pointer cheking for fsp->fake_file_handle->pd
2378          * is done by CHECK_NTQUOTA_HANDLE_OK()
2379          */
2380         qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
2381
2382         level = SVAL(params,2);
2383         
2384         /* unknown 12 bytes leading in params */ 
2385         
2386         switch (level) {
2387                 case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
2388                         /* seems that we should continue with the enum here --metze */
2389
2390                         if (qt_handle->quota_list!=NULL && 
2391                             qt_handle->tmp_list==NULL) {
2392                 
2393                                 /* free the list */
2394                                 free_ntquota_list(&(qt_handle->quota_list));
2395
2396                                 /* Realloc the size of parameters and data we will return */
2397                                 param_len = 4;
2398                                 params = nttrans_realloc(ppparams, param_len);
2399                                 if(params == NULL)
2400                                         return ERROR_DOS(ERRDOS,ERRnomem);
2401
2402                                 data_len = 0;
2403                                 SIVAL(params,0,data_len);
2404
2405                                 break;
2406                         }
2407
2408                         start_enum = False;
2409
2410                 case TRANSACT_GET_USER_QUOTA_LIST_START:
2411
2412                         if (qt_handle->quota_list==NULL &&
2413                                 qt_handle->tmp_list==NULL) {
2414                                 start_enum = True;
2415                         }
2416
2417                         if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0)
2418                                 return ERROR_DOS(ERRSRV,ERRerror);
2419
2420                         /* Realloc the size of parameters and data we will return */
2421                         param_len = 4;
2422                         params = nttrans_realloc(ppparams, param_len);
2423                         if(params == NULL)
2424                                 return ERROR_DOS(ERRDOS,ERRnomem);
2425
2426                         /* we should not trust the value in max_data_count*/
2427                         max_data_count = MIN(max_data_count,2048);
2428                         
2429                         pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
2430                         if(pdata == NULL)
2431                                 return ERROR_DOS(ERRDOS,ERRnomem);
2432
2433                         entry = pdata;
2434
2435
2436                         /* set params Size of returned Quota Data 4 bytes*/
2437                         /* but set it later when we know it */
2438                 
2439                         /* for each entry push the data */
2440
2441                         if (start_enum) {
2442                                 qt_handle->tmp_list = qt_handle->quota_list;
2443                         }
2444
2445                         tmp_list = qt_handle->tmp_list;
2446
2447                         for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
2448                                 tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
2449
2450                                 sid_len = sid_size(&tmp_list->quotas->sid);
2451                                 entry_len = 40 + sid_len;
2452
2453                                 /* nextoffset entry 4 bytes */
2454                                 SIVAL(entry,0,entry_len);
2455                 
2456                                 /* then the len of the SID 4 bytes */
2457                                 SIVAL(entry,4,sid_len);
2458                                 
2459                                 /* unknown data 8 bytes SMB_BIG_UINT */
2460                                 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
2461                                 
2462                                 /* the used disk space 8 bytes SMB_BIG_UINT */
2463                                 SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
2464                                 
2465                                 /* the soft quotas 8 bytes SMB_BIG_UINT */
2466                                 SBIG_UINT(entry,24,tmp_list->quotas->softlim);
2467                                 
2468                                 /* the hard quotas 8 bytes SMB_BIG_UINT */
2469                                 SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
2470                                 
2471                                 /* and now the SID */
2472                                 sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
2473                         }
2474                         
2475                         qt_handle->tmp_list = tmp_list;
2476                         
2477                         /* overwrite the offset of the last entry */
2478                         SIVAL(entry-entry_len,0,0);
2479
2480                         data_len = 4+qt_len;
2481                         /* overwrite the params quota_data_len */
2482                         SIVAL(params,0,data_len);
2483
2484                         break;
2485
2486                 case TRANSACT_GET_USER_QUOTA_FOR_SID:
2487                         
2488                         /* unknown 4 bytes IVAL(pdata,0) */     
2489                         
2490                         if (data_count < 8) {
2491                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
2492                                 return ERROR_DOS(ERRDOS,ERRunknownlevel);                               
2493                         }
2494
2495                         sid_len = IVAL(pdata,4);
2496                         /* Ensure this is less than 1mb. */
2497                         if (sid_len > (1024*1024)) {
2498                                 return ERROR_DOS(ERRDOS,ERRnomem);
2499                         }
2500
2501                         if (data_count < 8+sid_len) {
2502                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
2503                                 return ERROR_DOS(ERRDOS,ERRunknownlevel);                               
2504                         }
2505
2506                         data_len = 4+40+sid_len;
2507
2508                         if (max_data_count < data_len) {
2509                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
2510                                         max_data_count, data_len));
2511                                 param_len = 4;
2512                                 SIVAL(params,0,data_len);
2513                                 data_len = 0;
2514                                 nt_status = NT_STATUS_BUFFER_TOO_SMALL;
2515                                 break;
2516                         }
2517
2518                         sid_parse(pdata+8,sid_len,&sid);
2519                 
2520
2521                         if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2522                                 ZERO_STRUCT(qt);
2523                                 /* 
2524                                  * we have to return zero's in all fields 
2525                                  * instead of returning an error here
2526                                  * --metze
2527                                  */
2528                         }
2529
2530                         /* Realloc the size of parameters and data we will return */
2531                         param_len = 4;
2532                         params = nttrans_realloc(ppparams, param_len);
2533                         if(params == NULL)
2534                                 return ERROR_DOS(ERRDOS,ERRnomem);
2535
2536                         pdata = nttrans_realloc(ppdata, data_len);
2537                         if(pdata == NULL)
2538                                 return ERROR_DOS(ERRDOS,ERRnomem);
2539
2540                         entry = pdata;
2541
2542                         /* set params Size of returned Quota Data 4 bytes*/
2543                         SIVAL(params,0,data_len);
2544         
2545                         /* nextoffset entry 4 bytes */
2546                         SIVAL(entry,0,0);
2547         
2548                         /* then the len of the SID 4 bytes */
2549                         SIVAL(entry,4,sid_len);
2550                         
2551                         /* unknown data 8 bytes SMB_BIG_UINT */
2552                         SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
2553                         
2554                         /* the used disk space 8 bytes SMB_BIG_UINT */
2555                         SBIG_UINT(entry,16,qt.usedspace);
2556                         
2557                         /* the soft quotas 8 bytes SMB_BIG_UINT */
2558                         SBIG_UINT(entry,24,qt.softlim);
2559                         
2560                         /* the hard quotas 8 bytes SMB_BIG_UINT */
2561                         SBIG_UINT(entry,32,qt.hardlim);
2562                         
2563                         /* and now the SID */
2564                         sid_linearize(entry+40, sid_len, &sid);
2565
2566                         break;
2567
2568                 default:
2569                         DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
2570                         return ERROR_DOS(ERRSRV,ERRerror);
2571                         break;
2572         }
2573
2574         send_nt_replies(inbuf, outbuf, bufsize, nt_status, params, param_len, pdata, data_len);
2575
2576         return -1;
2577 }
2578
2579 /****************************************************************************
2580  Reply to set user quota
2581 ****************************************************************************/
2582
2583 static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
2584                                   char **ppsetup, uint32 setup_count,
2585                                   char **ppparams, uint32 parameter_count,
2586                                   char **ppdata, uint32 data_count, uint32 max_data_count)
2587 {
2588         char *params = *ppparams;
2589         char *pdata = *ppdata;
2590         int data_len=0,param_len=0;
2591         SMB_NTQUOTA_STRUCT qt;
2592         size_t sid_len;
2593         DOM_SID sid;
2594         files_struct *fsp = NULL;
2595
2596         ZERO_STRUCT(qt);
2597
2598         /* access check */
2599         if (current_user.uid != 0) {
2600                 DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
2601                         lp_servicename(SNUM(conn)),conn->user));
2602                 return ERROR_DOS(ERRDOS,ERRnoaccess);
2603         }
2604
2605         /*
2606          * Ensure minimum number of parameters sent.
2607          */
2608
2609         if (parameter_count < 2) {
2610                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
2611                 return ERROR_DOS(ERRDOS,ERRinvalidparam);
2612         }
2613         
2614         /* maybe we can check the quota_fnum */
2615         fsp = file_fsp(params,0);
2616         if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2617                 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2618                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2619         }
2620
2621         if (data_count < 40) {
2622                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
2623                 return ERROR_DOS(ERRDOS,ERRunknownlevel);               
2624         }
2625
2626         /* offset to next quota record.
2627          * 4 bytes IVAL(pdata,0)
2628          * unused here...
2629          */
2630
2631         /* sid len */
2632         sid_len = IVAL(pdata,4);
2633
2634         if (data_count < 40+sid_len) {
2635                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
2636                 return ERROR_DOS(ERRDOS,ERRunknownlevel);               
2637         }
2638
2639         /* unknown 8 bytes in pdata 
2640          * maybe its the change time in NTTIME
2641          */
2642
2643         /* the used space 8 bytes (SMB_BIG_UINT)*/
2644         qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16);
2645 #ifdef LARGE_SMB_OFF_T
2646         qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32);
2647 #else /* LARGE_SMB_OFF_T */
2648         if ((IVAL(pdata,20) != 0)&&
2649                 ((qt.usedspace != 0xFFFFFFFF)||
2650                 (IVAL(pdata,20)!=0xFFFFFFFF))) {
2651                 /* more than 32 bits? */
2652                 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2653         }
2654 #endif /* LARGE_SMB_OFF_T */
2655
2656         /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2657         qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2658 #ifdef LARGE_SMB_OFF_T
2659         qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2660 #else /* LARGE_SMB_OFF_T */
2661         if ((IVAL(pdata,28) != 0)&&
2662                 ((qt.softlim != 0xFFFFFFFF)||
2663                 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2664                 /* more than 32 bits? */
2665                 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2666         }
2667 #endif /* LARGE_SMB_OFF_T */
2668
2669         /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2670         qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2671 #ifdef LARGE_SMB_OFF_T
2672         qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2673 #else /* LARGE_SMB_OFF_T */
2674         if ((IVAL(pdata,36) != 0)&&
2675                 ((qt.hardlim != 0xFFFFFFFF)||
2676                 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2677                 /* more than 32 bits? */
2678                 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2679         }
2680 #endif /* LARGE_SMB_OFF_T */
2681         
2682         sid_parse(pdata+40,sid_len,&sid);
2683         DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
2684
2685         /* 44 unknown bytes left... */
2686
2687         if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2688                 return ERROR_DOS(ERRSRV,ERRerror);      
2689         }
2690
2691         send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, param_len, pdata, data_len);
2692
2693         return -1;
2694 }
2695 #endif /* HAVE_SYS_QUOTAS */
2696
2697 /****************************************************************************
2698  Reply to a SMBNTtrans.
2699 ****************************************************************************/
2700
2701 int reply_nttrans(connection_struct *conn,
2702                         char *inbuf,char *outbuf,int length,int bufsize)
2703 {
2704         int  outsize = 0;
2705         uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
2706 #if 0 /* Not used. */
2707         uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
2708         uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
2709 #endif /* Not used. */
2710         uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
2711         uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
2712         uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
2713         uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
2714         uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
2715         uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
2716         uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
2717         uint16 function_code = SVAL( inbuf, smb_nt_Function);
2718         char *params = NULL, *data = NULL, *setup = NULL;
2719         uint32 num_params_sofar, num_data_sofar;
2720         START_PROFILE(SMBnttrans);
2721
2722         if(global_oplock_break &&
2723                         ((function_code == NT_TRANSACT_CREATE) ||
2724                          (function_code == NT_TRANSACT_RENAME))) {
2725                 /*
2726                  * Queue this open message as we are the process of an oplock break.
2727                  */
2728
2729                 DEBUG(2,("reply_nttrans: queueing message code 0x%x \
2730 due to being in oplock break state.\n", (unsigned int)function_code ));
2731
2732                 push_oplock_pending_smb_message( inbuf, length);
2733                 END_PROFILE(SMBnttrans);
2734                 return -1;
2735         }
2736
2737         if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
2738                 END_PROFILE(SMBnttrans);
2739                 return ERROR_DOS(ERRSRV,ERRaccess);
2740         }
2741
2742         outsize = set_message(outbuf,0,0,True);
2743
2744         /* 
2745          * All nttrans messages we handle have smb_wct == 19 + setup_count.
2746          * Ensure this is so as a sanity check.
2747          */
2748
2749         if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
2750                 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
2751                         CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
2752                 goto bad_param;
2753         }
2754
2755         /* Don't allow more than 128mb for each value. */
2756         if ((total_parameter_count > (1024*1024*128)) || (total_data_count > (1024*1024*128))) {
2757                 END_PROFILE(SMBnttrans);
2758                 return ERROR_DOS(ERRDOS,ERRnomem);
2759         }
2760
2761         /* Allocate the space for the setup, the maximum needed parameters and data */
2762
2763         if(setup_count > 0)
2764                 setup = (char *)SMB_MALLOC(setup_count);
2765         if (total_parameter_count > 0)
2766                 params = (char *)SMB_MALLOC(total_parameter_count);
2767         if (total_data_count > 0)
2768                 data = (char *)SMB_MALLOC(total_data_count);
2769  
2770         if ((total_parameter_count && !params)  || (total_data_count && !data) ||
2771                                 (setup_count && !setup)) {
2772                 SAFE_FREE(setup);
2773                 SAFE_FREE(params);
2774                 SAFE_FREE(data);
2775                 DEBUG(0,("reply_nttrans : Out of memory\n"));
2776                 END_PROFILE(SMBnttrans);
2777                 return ERROR_DOS(ERRDOS,ERRnomem);
2778         }
2779
2780         /* Copy the param and data bytes sent with this request into the params buffer */
2781         num_params_sofar = parameter_count;
2782         num_data_sofar = data_count;
2783
2784         if (parameter_count > total_parameter_count || data_count > total_data_count)
2785                 goto bad_param;
2786
2787         if(setup) {
2788                 DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
2789                 if ((smb_nt_SetupStart + setup_count < smb_nt_SetupStart) ||
2790                                 (smb_nt_SetupStart + setup_count < setup_count))
2791                         goto bad_param;
2792                 if (smb_nt_SetupStart + setup_count > length)
2793                         goto bad_param;
2794
2795                 memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
2796                 dump_data(10, setup, setup_count);
2797         }
2798         if(params) {
2799                 DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
2800                 if ((parameter_offset + parameter_count < parameter_offset) ||
2801                                 (parameter_offset + parameter_count < parameter_count))
2802                         goto bad_param;
2803                 if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)||
2804                                 (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf)))
2805                         goto bad_param;
2806
2807                 memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
2808                 dump_data(10, params, parameter_count);
2809         }
2810         if(data) {
2811                 DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
2812                 if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count))
2813                         goto bad_param;
2814                 if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) ||
2815                                 (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf)))
2816                         goto bad_param;
2817
2818                 memcpy( data, smb_base(inbuf) + data_offset, data_count);
2819                 dump_data(10, data, data_count);
2820         }
2821
2822         srv_signing_trans_start(SVAL(inbuf,smb_mid));
2823
2824         if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
2825                 /* We need to send an interim response then receive the rest
2826                         of the parameter/data bytes */
2827                 outsize = set_message(outbuf,0,0,True);
2828                 srv_signing_trans_stop();
2829                 if (!send_smb(smbd_server_fd(),outbuf))
2830                         exit_server("reply_nttrans: send_smb failed.");
2831
2832                 while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
2833                         BOOL ret;
2834                         uint32 parameter_displacement;
2835                         uint32 data_displacement;
2836
2837                         ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2838
2839                         /*
2840                          * The sequence number for the trans reply is always
2841                          * based on the last secondary received.
2842                          */
2843
2844                         srv_signing_trans_start(SVAL(inbuf,smb_mid));
2845
2846                         if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
2847                                 outsize = set_message(outbuf,0,0,True);
2848                                 if(ret) {
2849                                         DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
2850                                 } else {
2851                                         DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
2852                                                 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2853                                 }
2854                                 goto bad_param;
2855                         }
2856       
2857                         /* Revise total_params and total_data in case they have changed downwards */
2858                         if (IVAL(inbuf, smb_nts_TotalParameterCount) < total_parameter_count)
2859                                 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
2860                         if (IVAL(inbuf, smb_nts_TotalDataCount) < total_data_count)
2861                                 total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
2862
2863                         parameter_count = IVAL(inbuf,smb_nts_ParameterCount);
2864                         parameter_offset = IVAL(inbuf, smb_nts_ParameterOffset);
2865                         parameter_displacement = IVAL(inbuf, smb_nts_ParameterDisplacement);
2866                         num_params_sofar += parameter_count;
2867
2868                         data_count = IVAL(inbuf, smb_nts_DataCount);
2869                         data_displacement = IVAL(inbuf, smb_nts_DataDisplacement);
2870                         data_offset = IVAL(inbuf, smb_nts_DataOffset);
2871                         num_data_sofar += data_count;
2872
2873                         if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count) {
2874                                 DEBUG(0,("reply_nttrans2: data overflow in secondary nttrans packet"));
2875                                 goto bad_param;
2876                         }
2877
2878                         if (parameter_count) {
2879                                 if (parameter_displacement + parameter_count > total_parameter_count)
2880                                         goto bad_param;
2881                                 if ((parameter_displacement + parameter_count < parameter_displacement) ||
2882                                                 (parameter_displacement + parameter_count < parameter_count))
2883                                         goto bad_param;
2884                                 if (parameter_displacement > total_parameter_count)
2885                                         goto bad_param;
2886                                 if ((smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize) ||
2887                                                 (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf)))
2888                                         goto bad_param;
2889                                 if (parameter_displacement + params < params)
2890                                         goto bad_param;
2891
2892                                 memcpy( &params[parameter_displacement], smb_base(inbuf) + parameter_offset, parameter_count);
2893                         }
2894
2895                         if (data_count) {
2896                                 if (data_displacement + data_count > total_data_count)
2897                                         goto bad_param;
2898                                 if ((data_displacement + data_count < data_displacement) ||
2899                                                 (data_displacement + data_count < data_count))
2900                                         goto bad_param;
2901                                 if (data_displacement > total_data_count)
2902                                         goto bad_param;
2903                                 if ((smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize) ||
2904                                                 (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf)))
2905                                         goto bad_param;
2906                                 if (data_displacement + data < data)
2907                                         goto bad_param;
2908
2909                                 memcpy( &data[data_displacement], smb_base(inbuf)+ data_offset, data_count);
2910                         }
2911                 }
2912         }
2913
2914         if (Protocol >= PROTOCOL_NT1)
2915                 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
2916
2917         /* Now we must call the relevant NT_TRANS function */
2918         switch(function_code) {
2919                 case NT_TRANSACT_CREATE:
2920                         START_PROFILE_NESTED(NT_transact_create);
2921                         outsize = call_nt_transact_create(conn, inbuf, outbuf,
2922                                                         length, bufsize, 
2923                                                         &setup, setup_count,
2924                                                         &params, total_parameter_count, 
2925                                                         &data, total_data_count, max_data_count);
2926                         END_PROFILE_NESTED(NT_transact_create);
2927                         break;
2928                 case NT_TRANSACT_IOCTL:
2929                         START_PROFILE_NESTED(NT_transact_ioctl);
2930                         outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
2931                                                          length, bufsize, 
2932                                                          &setup, setup_count,
2933                                                          &params, total_parameter_count, 
2934                                                          &data, total_data_count, max_data_count);
2935                         END_PROFILE_NESTED(NT_transact_ioctl);
2936                         break;
2937                 case NT_TRANSACT_SET_SECURITY_DESC:
2938                         START_PROFILE_NESTED(NT_transact_set_security_desc);
2939                         outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, 
2940                                                          length, bufsize, 
2941                                                          &setup, setup_count,
2942                                                          &params, total_parameter_count, 
2943                                                          &data, total_data_count, max_data_count);
2944                         END_PROFILE_NESTED(NT_transact_set_security_desc);
2945                         break;
2946                 case NT_TRANSACT_NOTIFY_CHANGE:
2947                         START_PROFILE_NESTED(NT_transact_notify_change);
2948                         outsize = call_nt_transact_notify_change(conn, inbuf, outbuf, 
2949                                                          length, bufsize, 
2950                                                          &setup, setup_count,
2951                                                          &params, total_parameter_count, 
2952                                                          &data, total_data_count, max_data_count);
2953                         END_PROFILE_NESTED(NT_transact_notify_change);
2954                         break;
2955                 case NT_TRANSACT_RENAME:
2956                         START_PROFILE_NESTED(NT_transact_rename);
2957                         outsize = call_nt_transact_rename(conn, inbuf, outbuf,
2958                                                          length, bufsize, 
2959                                                          &setup, setup_count,
2960                                                          &params, total_parameter_count, 
2961                                                          &data, total_data_count, max_data_count);
2962                         END_PROFILE_NESTED(NT_transact_rename);
2963                         break;
2964
2965                 case NT_TRANSACT_QUERY_SECURITY_DESC:
2966                         START_PROFILE_NESTED(NT_transact_query_security_desc);
2967                         outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, 
2968                                                          length, bufsize, 
2969                                                          &setup, setup_count,
2970                                                          &params, total_parameter_count, 
2971                                                          &data, total_data_count, max_data_count);
2972                         END_PROFILE_NESTED(NT_transact_query_security_desc);
2973                         break;
2974 #ifdef HAVE_SYS_QUOTAS
2975                 case NT_TRANSACT_GET_USER_QUOTA:
2976                         START_PROFILE_NESTED(NT_transact_get_user_quota);
2977                         outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, 
2978                                                          length, bufsize, 
2979                                                          &setup, setup_count,
2980                                                          &params, total_parameter_count, 
2981                                                          &data, total_data_count, max_data_count);
2982                         END_PROFILE_NESTED(NT_transact_get_user_quota);
2983                         break;
2984                 case NT_TRANSACT_SET_USER_QUOTA:
2985                         START_PROFILE_NESTED(NT_transact_set_user_quota);
2986                         outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, 
2987                                                          length, bufsize, 
2988                                                          &setup, setup_count,
2989                                                          &params, total_parameter_count, 
2990                                                          &data, total_data_count, max_data_count);
2991                         END_PROFILE_NESTED(NT_transact_set_user_quota);
2992                         break;                                  
2993 #endif /* HAVE_SYS_QUOTAS */
2994                 default:
2995                         /* Error in request */
2996                         DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
2997                         SAFE_FREE(setup);
2998                         SAFE_FREE(params);
2999                         SAFE_FREE(data);
3000                         END_PROFILE(SMBnttrans);
3001                         srv_signing_trans_stop();
3002                         return ERROR_DOS(ERRSRV,ERRerror);
3003         }
3004
3005         /* As we do not know how many data packets will need to be
3006                 returned here the various call_nt_transact_xxxx calls
3007                 must send their own. Thus a call_nt_transact_xxxx routine only
3008                 returns a value other than -1 when it wants to send
3009                 an error packet. 
3010         */
3011
3012         srv_signing_trans_stop();
3013
3014         SAFE_FREE(setup);
3015         SAFE_FREE(params);
3016         SAFE_FREE(data);
3017         END_PROFILE(SMBnttrans);
3018         return outsize; /* If a correct response was needed the call_nt_transact_xxxx 
3019                                 calls have already sent it. If outsize != -1 then it is
3020                                 returning an error packet. */
3021
3022  bad_param:
3023
3024         srv_signing_trans_stop();
3025         SAFE_FREE(params);
3026         SAFE_FREE(data);
3027         SAFE_FREE(setup);
3028         END_PROFILE(SMBnttrans);
3029         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3030 }