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