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