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