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