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