r24393: Convert call_nt_transact_set_user_quota to the new API
[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 void call_nt_transact_query_security_desc(connection_struct *conn,
2243                                                  struct smb_request *req,
2244                                                  uint16 **ppsetup,
2245                                                  uint32 setup_count,
2246                                                  char **ppparams,
2247                                                  uint32 parameter_count,
2248                                                  char **ppdata,
2249                                                  uint32 data_count,
2250                                                  uint32 max_data_count)
2251 {
2252         char *params = *ppparams;
2253         char *data = *ppdata;
2254         prs_struct pd;
2255         SEC_DESC *psd = NULL;
2256         size_t sd_size;
2257         uint32 security_info_wanted;
2258         TALLOC_CTX *mem_ctx;
2259         files_struct *fsp = NULL;
2260
2261         if(parameter_count < 8) {
2262                 reply_doserror(req, ERRDOS, ERRbadfunc);
2263                 return;
2264         }
2265
2266         fsp = file_fsp(SVAL(params,0));
2267         if(!fsp) {
2268                 reply_doserror(req, ERRDOS, ERRbadfid);
2269                 return;
2270         }
2271
2272         security_info_wanted = IVAL(params,4);
2273
2274         DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
2275                         (unsigned int)security_info_wanted ));
2276
2277         params = nttrans_realloc(ppparams, 4);
2278         if(params == NULL) {
2279                 reply_doserror(req, ERRDOS, ERRnomem);
2280                 return;
2281         }
2282
2283         if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {
2284                 DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
2285                 reply_doserror(req, ERRDOS, ERRnomem);
2286                 return;
2287         }
2288
2289         /*
2290          * Get the permissions to return.
2291          */
2292
2293         if (!lp_nt_acl_support(SNUM(conn))) {
2294                 sd_size = get_null_nt_acl(mem_ctx, &psd);
2295         } else {
2296                 sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, security_info_wanted, &psd);
2297         }
2298
2299         if (sd_size == 0) {
2300                 talloc_destroy(mem_ctx);
2301                 reply_unixerror(req, ERRDOS, ERRnoaccess);
2302                 return;
2303         }
2304
2305         DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
2306
2307         SIVAL(params,0,(uint32)sd_size);
2308
2309         if(max_data_count < sd_size) {
2310
2311                 send_nt_replies_new(req, NT_STATUS_BUFFER_TOO_SMALL,
2312                                     params, 4, *ppdata, 0);
2313                 talloc_destroy(mem_ctx);
2314                 return;
2315         }
2316
2317         /*
2318          * Allocate the data we will point this at.
2319          */
2320
2321         data = nttrans_realloc(ppdata, sd_size);
2322         if(data == NULL) {
2323                 talloc_destroy(mem_ctx);
2324                 reply_doserror(req, ERRDOS, ERRnomem);
2325                 return;
2326         }
2327
2328         /*
2329          * Init the parse struct we will marshall into.
2330          */
2331
2332         prs_init(&pd, 0, mem_ctx, MARSHALL);
2333
2334         /*
2335          * Setup the prs_struct to point at the memory we just
2336          * allocated.
2337          */
2338
2339         prs_give_memory( &pd, data, (uint32)sd_size, False);
2340
2341         /*
2342          * Finally, linearize into the outgoing buffer.
2343          */
2344
2345         if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
2346                 DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
2347 security descriptor.\n"));
2348                 /*
2349                  * Return access denied for want of a better error message..
2350                  */ 
2351                 talloc_destroy(mem_ctx);
2352                 reply_unixerror(req, ERRDOS, ERRnoaccess);
2353                 return;
2354         }
2355
2356         /*
2357          * Now we can delete the security descriptor.
2358          */
2359
2360         talloc_destroy(mem_ctx);
2361
2362         send_nt_replies_new(req, NT_STATUS_OK, params, 4, data,
2363                             (int)sd_size);
2364         return;
2365 }
2366
2367 /****************************************************************************
2368  Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
2369 ****************************************************************************/
2370
2371 static void call_nt_transact_set_security_desc(connection_struct *conn,
2372                                                struct smb_request *req,
2373                                                uint16 **ppsetup,
2374                                                uint32 setup_count,
2375                                                char **ppparams,
2376                                                uint32 parameter_count,
2377                                                char **ppdata,
2378                                                uint32 data_count,
2379                                                uint32 max_data_count)
2380 {
2381         char *params= *ppparams;
2382         char *data = *ppdata;
2383         files_struct *fsp = NULL;
2384         uint32 security_info_sent = 0;
2385         NTSTATUS nt_status;
2386
2387         if(parameter_count < 8) {
2388                 reply_doserror(req, ERRDOS, ERRbadfunc);
2389                 return;
2390         }
2391
2392         if((fsp = file_fsp(SVAL(params,0))) == NULL) {
2393                 reply_doserror(req, ERRDOS, ERRbadfid);
2394                 return;
2395         }
2396
2397         if(!lp_nt_acl_support(SNUM(conn))) {
2398                 goto done;
2399         }
2400
2401         security_info_sent = IVAL(params,4);
2402
2403         DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
2404                 (unsigned int)security_info_sent ));
2405
2406         if (data_count == 0) {
2407                 reply_doserror(req, ERRDOS, ERRnoaccess);
2408                 return;
2409         }
2410
2411         if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) {
2412                 reply_nterror(req, nt_status);
2413                 return;
2414         }
2415
2416   done:
2417
2418         send_nt_replies_new(req, NT_STATUS_OK, NULL, 0, NULL, 0);
2419         return;
2420 }
2421    
2422 /****************************************************************************
2423  Reply to NT IOCTL
2424 ****************************************************************************/
2425
2426 static void call_nt_transact_ioctl(connection_struct *conn,
2427                                    struct smb_request *req,
2428                                    uint16 **ppsetup, uint32 setup_count,
2429                                    char **ppparams, uint32 parameter_count,
2430                                    char **ppdata, uint32 data_count,
2431                                    uint32 max_data_count)
2432 {
2433         uint32 function;
2434         uint16 fidnum;
2435         files_struct *fsp;
2436         uint8 isFSctl;
2437         uint8 compfilter;
2438         static BOOL logged_message;
2439         char *pdata = *ppdata;
2440
2441         if (setup_count != 8) {
2442                 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
2443                 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2444                 return;
2445         }
2446
2447         function = IVAL(*ppsetup, 0);
2448         fidnum = SVAL(*ppsetup, 4);
2449         isFSctl = CVAL(*ppsetup, 6);
2450         compfilter = CVAL(*ppsetup, 7);
2451
2452         DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 
2453                  function, fidnum, isFSctl, compfilter));
2454
2455         fsp=file_fsp(fidnum);
2456         /* this check is done in each implemented function case for now
2457            because I don't want to break anything... --metze
2458         FSP_BELONGS_CONN(fsp,conn);*/
2459
2460         switch (function) {
2461         case FSCTL_SET_SPARSE:
2462                 /* pretend this succeeded - tho strictly we should
2463                    mark the file sparse (if the local fs supports it)
2464                    so we can know if we need to pre-allocate or not */
2465
2466                 DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
2467                 send_nt_replies_new(req, NT_STATUS_OK, NULL, 0, NULL, 0);
2468                 return;
2469         
2470         case FSCTL_CREATE_OR_GET_OBJECT_ID:
2471         {
2472                 unsigned char objid[16];
2473
2474                 /* This should return the object-id on this file.
2475                  * I think I'll make this be the inode+dev. JRA.
2476                  */
2477
2478                 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on FID[0x%04X]\n",fidnum));
2479
2480                 if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
2481                         return;
2482                 }
2483
2484                 data_count = 64;
2485                 pdata = nttrans_realloc(ppdata, data_count);
2486                 if (pdata == NULL) {
2487                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2488                         return;
2489                 }
2490                 push_file_id_16(pdata, &fsp->file_id);
2491                 memcpy(pdata+16,create_volume_objectid(conn,objid),16);
2492                 push_file_id_16(pdata+32, &fsp->file_id);
2493                 send_nt_replies_new(req, NT_STATUS_OK, NULL, 0,
2494                                     pdata, data_count);
2495                 return;
2496         }
2497
2498         case FSCTL_GET_REPARSE_POINT:
2499                 /* pretend this fail - my winXP does it like this
2500                  * --metze
2501                  */
2502
2503                 DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
2504                 reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT);
2505                 return;
2506
2507         case FSCTL_SET_REPARSE_POINT:
2508                 /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.
2509                  * --metze
2510                  */
2511
2512                 DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
2513                 reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT);
2514                 return;
2515                         
2516         case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
2517         {
2518                 /*
2519                  * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
2520                  * and return their volume names.  If max_data_count is 16, then it is just
2521                  * asking for the number of volumes and length of the combined names.
2522                  *
2523                  * pdata is the data allocated by our caller, but that uses
2524                  * total_data_count (which is 0 in our case) rather than max_data_count.
2525                  * Allocate the correct amount and return the pointer to let
2526                  * it be deallocated when we return.
2527                  */
2528                 SHADOW_COPY_DATA *shadow_data = NULL;
2529                 TALLOC_CTX *shadow_mem_ctx = NULL;
2530                 BOOL labels = False;
2531                 uint32 labels_data_count = 0;
2532                 uint32 i;
2533                 char *cur_pdata;
2534
2535                 if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
2536                         return;
2537                 }
2538
2539                 if (max_data_count < 16) {
2540                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
2541                                 max_data_count));
2542                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2543                         return;
2544                 }
2545
2546                 if (max_data_count > 16) {
2547                         labels = True;
2548                 }
2549
2550                 shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
2551                 if (shadow_mem_ctx == NULL) {
2552                         DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
2553                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2554                         return;
2555                 }
2556
2557                 shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);
2558                 if (shadow_data == NULL) {
2559                         DEBUG(0,("TALLOC_ZERO() failed!\n"));
2560                         talloc_destroy(shadow_mem_ctx);
2561                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2562                         return;
2563                 }
2564                 
2565                 shadow_data->mem_ctx = shadow_mem_ctx;
2566                 
2567                 /*
2568                  * Call the VFS routine to actually do the work.
2569                  */
2570                 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
2571                         talloc_destroy(shadow_data->mem_ctx);
2572                         if (errno == ENOSYS) {
2573                                 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 
2574                                         conn->connectpath));
2575                                 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2576                                 return;
2577                         } else {
2578                                 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 
2579                                         conn->connectpath));
2580                                 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
2581                                 return;
2582                         }
2583                 }
2584
2585                 labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
2586
2587                 if (!labels) {
2588                         data_count = 16;
2589                 } else {
2590                         data_count = 12+labels_data_count+4;
2591                 }
2592
2593                 if (max_data_count<data_count) {
2594                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
2595                                 max_data_count,data_count));
2596                         talloc_destroy(shadow_data->mem_ctx);
2597                         reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2598                         return;
2599                 }
2600
2601                 pdata = nttrans_realloc(ppdata, data_count);
2602                 if (pdata == NULL) {
2603                         talloc_destroy(shadow_data->mem_ctx);
2604                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2605                         return;
2606                 }               
2607
2608                 cur_pdata = pdata;
2609
2610                 /* num_volumes 4 bytes */
2611                 SIVAL(pdata,0,shadow_data->num_volumes);
2612
2613                 if (labels) {
2614                         /* num_labels 4 bytes */
2615                         SIVAL(pdata,4,shadow_data->num_volumes);
2616                 }
2617
2618                 /* needed_data_count 4 bytes */
2619                 SIVAL(pdata,8,labels_data_count);
2620
2621                 cur_pdata+=12;
2622
2623                 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
2624                         shadow_data->num_volumes,fsp->fsp_name));
2625                 if (labels && shadow_data->labels) {
2626                         for (i=0;i<shadow_data->num_volumes;i++) {
2627                                 srvstr_push(pdata, req->flags2,
2628                                             cur_pdata, shadow_data->labels[i],
2629                                             2*sizeof(SHADOW_COPY_LABEL),
2630                                             STR_UNICODE|STR_TERMINATE);
2631                                 cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
2632                                 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
2633                         }
2634                 }
2635
2636                 talloc_destroy(shadow_data->mem_ctx);
2637
2638                 send_nt_replies_new(req, NT_STATUS_OK, NULL, 0,
2639                                     pdata, data_count);
2640
2641                 return;
2642         }
2643         
2644         case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
2645         {
2646                 /* pretend this succeeded - 
2647                  * 
2648                  * we have to send back a list with all files owned by this SID
2649                  *
2650                  * but I have to check that --metze
2651                  */
2652                 DOM_SID sid;
2653                 uid_t uid;
2654                 size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
2655                 
2656                 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
2657
2658                 if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
2659                         return;
2660                 }
2661
2662                 /* unknown 4 bytes: this is not the length of the sid :-(  */
2663                 /*unknown = IVAL(pdata,0);*/
2664                 
2665                 sid_parse(pdata+4,sid_len,&sid);
2666                 DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
2667
2668                 if (!sid_to_uid(&sid, &uid)) {
2669                         DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
2670                                 sid_string_static(&sid),(unsigned long)sid_len));
2671                         uid = (-1);
2672                 }
2673                 
2674                 /* we can take a look at the find source :-)
2675                  *
2676                  * find ./ -uid $uid  -name '*'   is what we need here
2677                  *
2678                  *
2679                  * and send 4bytes len and then NULL terminated unicode strings
2680                  * for each file
2681                  *
2682                  * but I don't know how to deal with the paged results
2683                  * (maybe we can hang the result anywhere in the fsp struct)
2684                  *
2685                  * we don't send all files at once
2686                  * and at the next we should *not* start from the beginning, 
2687                  * so we have to cache the result 
2688                  *
2689                  * --metze
2690                  */
2691                 
2692                 /* this works for now... */
2693                 send_nt_replies_new(req, NT_STATUS_OK, NULL, 0, NULL, 0);
2694                 return;
2695         }       
2696         default:
2697                 if (!logged_message) {
2698                         logged_message = True; /* Only print this once... */
2699                         DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
2700                                  function));
2701                 }
2702         }
2703
2704         reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2705 }
2706
2707
2708 #ifdef HAVE_SYS_QUOTAS
2709 /****************************************************************************
2710  Reply to get user quota 
2711 ****************************************************************************/
2712
2713 static void call_nt_transact_get_user_quota(connection_struct *conn,
2714                                             struct smb_request *req,
2715                                             uint16 **ppsetup,
2716                                             uint32 setup_count,
2717                                             char **ppparams,
2718                                             uint32 parameter_count,
2719                                             char **ppdata,
2720                                             uint32 data_count,
2721                                             uint32 max_data_count)
2722 {
2723         NTSTATUS nt_status = NT_STATUS_OK;
2724         char *params = *ppparams;
2725         char *pdata = *ppdata;
2726         char *entry;
2727         int data_len=0,param_len=0;
2728         int qt_len=0;
2729         int entry_len = 0;
2730         files_struct *fsp = NULL;
2731         uint16 level = 0;
2732         size_t sid_len;
2733         DOM_SID sid;
2734         BOOL start_enum = True;
2735         SMB_NTQUOTA_STRUCT qt;
2736         SMB_NTQUOTA_LIST *tmp_list;
2737         SMB_NTQUOTA_HANDLE *qt_handle = NULL;
2738
2739         ZERO_STRUCT(qt);
2740
2741         /* access check */
2742         if (current_user.ut.uid != 0) {
2743                 DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n",
2744                         lp_servicename(SNUM(conn)),conn->user));
2745                 reply_doserror(req, ERRDOS, ERRnoaccess);
2746                 return;
2747         }
2748
2749         /*
2750          * Ensure minimum number of parameters sent.
2751          */
2752
2753         if (parameter_count < 4) {
2754                 DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
2755                 reply_doserror(req, ERRDOS, ERRinvalidparam);
2756                 return;
2757         }
2758         
2759         /* maybe we can check the quota_fnum */
2760         fsp = file_fsp(SVAL(params,0));
2761         if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2762                 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2763                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2764                 return;
2765         }
2766
2767         /* the NULL pointer checking for fsp->fake_file_handle->pd
2768          * is done by CHECK_NTQUOTA_HANDLE_OK()
2769          */
2770         qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
2771
2772         level = SVAL(params,2);
2773         
2774         /* unknown 12 bytes leading in params */ 
2775         
2776         switch (level) {
2777                 case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
2778                         /* seems that we should continue with the enum here --metze */
2779
2780                         if (qt_handle->quota_list!=NULL && 
2781                             qt_handle->tmp_list==NULL) {
2782                 
2783                                 /* free the list */
2784                                 free_ntquota_list(&(qt_handle->quota_list));
2785
2786                                 /* Realloc the size of parameters and data we will return */
2787                                 param_len = 4;
2788                                 params = nttrans_realloc(ppparams, param_len);
2789                                 if(params == NULL) {
2790                                         reply_doserror(req, ERRDOS, ERRnomem);
2791                                         return;
2792                                 }
2793
2794                                 data_len = 0;
2795                                 SIVAL(params,0,data_len);
2796
2797                                 break;
2798                         }
2799
2800                         start_enum = False;
2801
2802                 case TRANSACT_GET_USER_QUOTA_LIST_START:
2803
2804                         if (qt_handle->quota_list==NULL &&
2805                                 qt_handle->tmp_list==NULL) {
2806                                 start_enum = True;
2807                         }
2808
2809                         if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0) {
2810                                 reply_doserror(req, ERRSRV, ERRerror);
2811                                 return;
2812                         }
2813
2814                         /* Realloc the size of parameters and data we will return */
2815                         param_len = 4;
2816                         params = nttrans_realloc(ppparams, param_len);
2817                         if(params == NULL) {
2818                                 reply_doserror(req, ERRDOS, ERRnomem);
2819                                 return;
2820                         }
2821
2822                         /* we should not trust the value in max_data_count*/
2823                         max_data_count = MIN(max_data_count,2048);
2824                         
2825                         pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
2826                         if(pdata == NULL) {
2827                                 reply_doserror(req, ERRDOS, ERRnomem);
2828                                 return;
2829                         }
2830
2831                         entry = pdata;
2832
2833                         /* set params Size of returned Quota Data 4 bytes*/
2834                         /* but set it later when we know it */
2835                 
2836                         /* for each entry push the data */
2837
2838                         if (start_enum) {
2839                                 qt_handle->tmp_list = qt_handle->quota_list;
2840                         }
2841
2842                         tmp_list = qt_handle->tmp_list;
2843
2844                         for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
2845                                 tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
2846
2847                                 sid_len = sid_size(&tmp_list->quotas->sid);
2848                                 entry_len = 40 + sid_len;
2849
2850                                 /* nextoffset entry 4 bytes */
2851                                 SIVAL(entry,0,entry_len);
2852                 
2853                                 /* then the len of the SID 4 bytes */
2854                                 SIVAL(entry,4,sid_len);
2855                                 
2856                                 /* unknown data 8 bytes SMB_BIG_UINT */
2857                                 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
2858                                 
2859                                 /* the used disk space 8 bytes SMB_BIG_UINT */
2860                                 SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
2861                                 
2862                                 /* the soft quotas 8 bytes SMB_BIG_UINT */
2863                                 SBIG_UINT(entry,24,tmp_list->quotas->softlim);
2864                                 
2865                                 /* the hard quotas 8 bytes SMB_BIG_UINT */
2866                                 SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
2867                                 
2868                                 /* and now the SID */
2869                                 sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
2870                         }
2871                         
2872                         qt_handle->tmp_list = tmp_list;
2873                         
2874                         /* overwrite the offset of the last entry */
2875                         SIVAL(entry-entry_len,0,0);
2876
2877                         data_len = 4+qt_len;
2878                         /* overwrite the params quota_data_len */
2879                         SIVAL(params,0,data_len);
2880
2881                         break;
2882
2883                 case TRANSACT_GET_USER_QUOTA_FOR_SID:
2884                         
2885                         /* unknown 4 bytes IVAL(pdata,0) */     
2886                         
2887                         if (data_count < 8) {
2888                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
2889                                 reply_doserror(req, ERRDOS, ERRunknownlevel);
2890                                 return;
2891                         }
2892
2893                         sid_len = IVAL(pdata,4);
2894                         /* Ensure this is less than 1mb. */
2895                         if (sid_len > (1024*1024)) {
2896                                 reply_doserror(req, ERRDOS, ERRnomem);
2897                                 return;
2898                         }
2899
2900                         if (data_count < 8+sid_len) {
2901                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
2902                                 reply_doserror(req, ERRDOS, ERRunknownlevel);
2903                                 return;
2904                         }
2905
2906                         data_len = 4+40+sid_len;
2907
2908                         if (max_data_count < data_len) {
2909                                 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
2910                                         max_data_count, data_len));
2911                                 param_len = 4;
2912                                 SIVAL(params,0,data_len);
2913                                 data_len = 0;
2914                                 nt_status = NT_STATUS_BUFFER_TOO_SMALL;
2915                                 break;
2916                         }
2917
2918                         sid_parse(pdata+8,sid_len,&sid);
2919                 
2920                         if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2921                                 ZERO_STRUCT(qt);
2922                                 /* 
2923                                  * we have to return zero's in all fields 
2924                                  * instead of returning an error here
2925                                  * --metze
2926                                  */
2927                         }
2928
2929                         /* Realloc the size of parameters and data we will return */
2930                         param_len = 4;
2931                         params = nttrans_realloc(ppparams, param_len);
2932                         if(params == NULL) {
2933                                 reply_doserror(req, ERRDOS, ERRnomem);
2934                                 return;
2935                         }
2936
2937                         pdata = nttrans_realloc(ppdata, data_len);
2938                         if(pdata == NULL) {
2939                                 reply_doserror(req, ERRDOS, ERRnomem);
2940                                 return;
2941                         }
2942
2943                         entry = pdata;
2944
2945                         /* set params Size of returned Quota Data 4 bytes*/
2946                         SIVAL(params,0,data_len);
2947         
2948                         /* nextoffset entry 4 bytes */
2949                         SIVAL(entry,0,0);
2950         
2951                         /* then the len of the SID 4 bytes */
2952                         SIVAL(entry,4,sid_len);
2953                         
2954                         /* unknown data 8 bytes SMB_BIG_UINT */
2955                         SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
2956                         
2957                         /* the used disk space 8 bytes SMB_BIG_UINT */
2958                         SBIG_UINT(entry,16,qt.usedspace);
2959                         
2960                         /* the soft quotas 8 bytes SMB_BIG_UINT */
2961                         SBIG_UINT(entry,24,qt.softlim);
2962                         
2963                         /* the hard quotas 8 bytes SMB_BIG_UINT */
2964                         SBIG_UINT(entry,32,qt.hardlim);
2965                         
2966                         /* and now the SID */
2967                         sid_linearize(entry+40, sid_len, &sid);
2968
2969                         break;
2970
2971                 default:
2972                         DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
2973                         reply_doserror(req, ERRSRV, ERRerror);
2974                         return;
2975                         break;
2976         }
2977
2978         send_nt_replies_new(req, nt_status, params, param_len,
2979                             pdata, data_len);
2980 }
2981
2982 /****************************************************************************
2983  Reply to set user quota
2984 ****************************************************************************/
2985
2986 static void call_nt_transact_set_user_quota(connection_struct *conn,
2987                                             struct smb_request *req,
2988                                             uint16 **ppsetup,
2989                                             uint32 setup_count,
2990                                             char **ppparams,
2991                                             uint32 parameter_count,
2992                                             char **ppdata,
2993                                             uint32 data_count,
2994                                             uint32 max_data_count)
2995 {
2996         char *params = *ppparams;
2997         char *pdata = *ppdata;
2998         int data_len=0,param_len=0;
2999         SMB_NTQUOTA_STRUCT qt;
3000         size_t sid_len;
3001         DOM_SID sid;
3002         files_struct *fsp = NULL;
3003
3004         ZERO_STRUCT(qt);
3005
3006         /* access check */
3007         if (current_user.ut.uid != 0) {
3008                 DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
3009                         lp_servicename(SNUM(conn)),conn->user));
3010                 reply_doserror(req, ERRDOS, ERRnoaccess);
3011                 return;
3012         }
3013
3014         /*
3015          * Ensure minimum number of parameters sent.
3016          */
3017
3018         if (parameter_count < 2) {
3019                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
3020                 reply_doserror(req, ERRDOS, ERRinvalidparam);
3021                 return;
3022         }
3023         
3024         /* maybe we can check the quota_fnum */
3025         fsp = file_fsp(SVAL(params,0));
3026         if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
3027                 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3028                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
3029                 return;
3030         }
3031
3032         if (data_count < 40) {
3033                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
3034                 reply_doserror(req, ERRDOS, ERRunknownlevel);
3035                 return;
3036         }
3037
3038         /* offset to next quota record.
3039          * 4 bytes IVAL(pdata,0)
3040          * unused here...
3041          */
3042
3043         /* sid len */
3044         sid_len = IVAL(pdata,4);
3045
3046         if (data_count < 40+sid_len) {
3047                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
3048                 reply_doserror(req, ERRDOS, ERRunknownlevel);
3049                 return;
3050         }
3051
3052         /* unknown 8 bytes in pdata 
3053          * maybe its the change time in NTTIME
3054          */
3055
3056         /* the used space 8 bytes (SMB_BIG_UINT)*/
3057         qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16);
3058 #ifdef LARGE_SMB_OFF_T
3059         qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32);
3060 #else /* LARGE_SMB_OFF_T */
3061         if ((IVAL(pdata,20) != 0)&&
3062                 ((qt.usedspace != 0xFFFFFFFF)||
3063                 (IVAL(pdata,20)!=0xFFFFFFFF))) {
3064                 /* more than 32 bits? */
3065                 reply_doserror(req, ERRDOS, ERRunknownlevel);
3066                 return;
3067         }
3068 #endif /* LARGE_SMB_OFF_T */
3069
3070         /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
3071         qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
3072 #ifdef LARGE_SMB_OFF_T
3073         qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
3074 #else /* LARGE_SMB_OFF_T */
3075         if ((IVAL(pdata,28) != 0)&&
3076                 ((qt.softlim != 0xFFFFFFFF)||
3077                 (IVAL(pdata,28)!=0xFFFFFFFF))) {
3078                 /* more than 32 bits? */
3079                 reply_doserror(req, ERRDOS, ERRunknownlevel);
3080                 return;
3081         }
3082 #endif /* LARGE_SMB_OFF_T */
3083
3084         /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
3085         qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
3086 #ifdef LARGE_SMB_OFF_T
3087         qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
3088 #else /* LARGE_SMB_OFF_T */
3089         if ((IVAL(pdata,36) != 0)&&
3090                 ((qt.hardlim != 0xFFFFFFFF)||
3091                 (IVAL(pdata,36)!=0xFFFFFFFF))) {
3092                 /* more than 32 bits? */
3093                 reply_doserror(req, ERRDOS, ERRunknownlevel);
3094                 return;
3095         }
3096 #endif /* LARGE_SMB_OFF_T */
3097         
3098         sid_parse(pdata+40,sid_len,&sid);
3099         DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
3100
3101         /* 44 unknown bytes left... */
3102
3103         if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
3104                 reply_doserror(req, ERRSRV, ERRerror);
3105                 return;
3106         }
3107
3108         send_nt_replies_new(req, NT_STATUS_OK, params, param_len,
3109                             pdata, data_len);
3110 }
3111 #endif /* HAVE_SYS_QUOTAS */
3112
3113 static void handle_nttrans(connection_struct *conn,
3114                            struct trans_state *state,
3115                            struct smb_request *req)
3116 {
3117         if (Protocol >= PROTOCOL_NT1) {
3118                 req->flags2 |= 0x40; /* IS_LONG_NAME */
3119                 SSVAL(req->inbuf,smb_flg2,req->flags2);
3120         }
3121
3122         /* Now we must call the relevant NT_TRANS function */
3123         switch(state->call) {
3124                 case NT_TRANSACT_CREATE:
3125                 {
3126                         START_PROFILE(NT_transact_create);
3127                         call_nt_transact_create(
3128                                 conn, req,
3129                                 &state->setup, state->setup_count,
3130                                 &state->param, state->total_param,
3131                                 &state->data, state->total_data,
3132                                 state->max_data_return);
3133                         END_PROFILE(NT_transact_create);
3134                         break;
3135                 }
3136
3137                 case NT_TRANSACT_IOCTL:
3138                 {
3139                         START_PROFILE(NT_transact_ioctl);
3140                         call_nt_transact_ioctl(
3141                                 conn, req,
3142                                 &state->setup, state->setup_count,
3143                                 &state->param, state->total_param,
3144                                 &state->data, state->total_data,
3145                                 state->max_data_return);
3146                         END_PROFILE(NT_transact_ioctl);
3147                         break;
3148                 }
3149
3150                 case NT_TRANSACT_SET_SECURITY_DESC:
3151                 {
3152                         START_PROFILE(NT_transact_set_security_desc);
3153                         call_nt_transact_set_security_desc(
3154                                 conn, req,
3155                                 &state->setup, state->setup_count,
3156                                 &state->param, state->total_param,
3157                                 &state->data, state->total_data,
3158                                 state->max_data_return);
3159                         END_PROFILE(NT_transact_set_security_desc);
3160                         break;
3161                 }
3162
3163                 case NT_TRANSACT_NOTIFY_CHANGE:
3164                 {
3165                         char *inbuf, *outbuf;
3166                         int size, bufsize;
3167
3168                         START_PROFILE(NT_transact_notify_change);
3169
3170                         if (!reply_prep_legacy(req, &inbuf, &outbuf, &size,
3171                                                &bufsize)) {
3172                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
3173                                 END_PROFILE(SMBnttrans);
3174                                 return;
3175                         }
3176
3177                         reply_post_legacy(
3178                                 req,
3179                                 call_nt_transact_notify_change(
3180                                         conn, inbuf, outbuf, size, bufsize,
3181                                         &state->setup, state->setup_count,
3182                                         &state->param, state->total_param,
3183                                         &state->data, state->total_data,
3184                                         state->max_data_return,
3185                                         state->max_param_return));
3186
3187                         END_PROFILE(NT_transact_notify_change);
3188                         break;
3189                 }
3190
3191                 case NT_TRANSACT_RENAME:
3192                 {
3193                         char *inbuf, *outbuf;
3194                         int size, bufsize;
3195
3196                         START_PROFILE(NT_transact_rename);
3197
3198                         if (!reply_prep_legacy(req, &inbuf, &outbuf, &size,
3199                                                &bufsize)) {
3200                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
3201                                 END_PROFILE(SMBnttrans);
3202                                 return;
3203                         }
3204
3205                         reply_post_legacy(
3206                                 req,
3207                                 call_nt_transact_rename(
3208                                         conn, inbuf, outbuf,
3209                                         size, bufsize,
3210                                         &state->setup, state->setup_count,
3211                                         &state->param, state->total_param,
3212                                         &state->data, state->total_data,
3213                                         state->max_data_return));
3214
3215                         END_PROFILE(NT_transact_rename);
3216                         break;
3217                 }
3218
3219                 case NT_TRANSACT_QUERY_SECURITY_DESC:
3220                 {
3221                         START_PROFILE(NT_transact_query_security_desc);
3222                         call_nt_transact_query_security_desc(
3223                                 conn, req,
3224                                 &state->setup, state->setup_count,
3225                                 &state->param, state->total_param,
3226                                 &state->data, state->total_data,
3227                                 state->max_data_return);
3228                         END_PROFILE(NT_transact_query_security_desc);
3229                         break;
3230                 }
3231
3232 #ifdef HAVE_SYS_QUOTAS
3233                 case NT_TRANSACT_GET_USER_QUOTA:
3234                 {
3235                         START_PROFILE(NT_transact_get_user_quota);
3236                         call_nt_transact_get_user_quota(
3237                                 conn, req,
3238                                 &state->setup, state->setup_count,
3239                                 &state->param, state->total_param,
3240                                 &state->data, state->total_data,
3241                                 state->max_data_return);
3242                         END_PROFILE(NT_transact_get_user_quota);
3243                         break;
3244                 }
3245
3246                 case NT_TRANSACT_SET_USER_QUOTA:
3247                 {
3248                         START_PROFILE(NT_transact_set_user_quota);
3249                         call_nt_transact_set_user_quota(
3250                                 conn, req,
3251                                 &state->setup, state->setup_count,
3252                                 &state->param, state->total_param,
3253                                 &state->data, state->total_data,
3254                                 state->max_data_return);
3255                         END_PROFILE(NT_transact_set_user_quota);
3256                         break;                                  
3257                 }
3258 #endif /* HAVE_SYS_QUOTAS */
3259
3260                 default:
3261                         /* Error in request */
3262                         DEBUG(0,("handle_nttrans: Unknown request %d in "
3263                                  "nttrans call\n", state->call));
3264                         reply_doserror(req, ERRSRV, ERRerror);
3265                         return;
3266         }
3267         return;
3268 }
3269
3270 /****************************************************************************
3271  Reply to a SMBNTtrans.
3272 ****************************************************************************/
3273
3274 void reply_nttrans(connection_struct *conn, struct smb_request *req)
3275 {
3276         uint32 pscnt;
3277         uint32 psoff;
3278         uint32 dscnt;
3279         uint32 dsoff;
3280         uint16 function_code;
3281         NTSTATUS result;
3282         struct trans_state *state;
3283         int size;
3284
3285         START_PROFILE(SMBnttrans);
3286
3287         if (req->wct < 19) {
3288                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3289                 END_PROFILE(SMBnttrans);
3290                 return;
3291         }
3292
3293         size = smb_len(req->inbuf) + 4;
3294         pscnt = IVAL(req->inbuf,smb_nt_ParameterCount);
3295         psoff = IVAL(req->inbuf,smb_nt_ParameterOffset);
3296         dscnt = IVAL(req->inbuf,smb_nt_DataCount);
3297         dsoff = IVAL(req->inbuf,smb_nt_DataOffset);
3298         function_code = SVAL(req->inbuf, smb_nt_Function);
3299
3300         if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
3301                 reply_doserror(req, ERRSRV, ERRaccess);
3302                 END_PROFILE(SMBnttrans);
3303                 return;
3304         }
3305
3306         result = allow_new_trans(conn->pending_trans, req->mid);
3307         if (!NT_STATUS_IS_OK(result)) {
3308                 DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
3309                 reply_nterror(req, result);
3310                 END_PROFILE(SMBnttrans);
3311                 return;
3312         }
3313
3314         if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
3315                 reply_doserror(req, ERRSRV, ERRaccess);
3316                 END_PROFILE(SMBnttrans);
3317                 return;
3318         }
3319
3320         state->cmd = SMBnttrans;
3321
3322         state->mid = req->mid;
3323         state->vuid = req->vuid;
3324         state->total_data = IVAL(req->inbuf, smb_nt_TotalDataCount);
3325         state->data = NULL;
3326         state->total_param = IVAL(req->inbuf, smb_nt_TotalParameterCount);
3327         state->param = NULL;
3328         state->max_data_return = IVAL(req->inbuf,smb_nt_MaxDataCount);
3329         state->max_param_return = IVAL(req->inbuf,smb_nt_MaxParameterCount);
3330
3331         /* setup count is in *words* */
3332         state->setup_count = 2*CVAL(req->inbuf,smb_nt_SetupCount);
3333         state->setup = NULL;
3334         state->call = function_code;
3335
3336         /* 
3337          * All nttrans messages we handle have smb_wct == 19 +
3338          * state->setup_count.  Ensure this is so as a sanity check.
3339          */
3340
3341         if(req->wct != 19 + (state->setup_count/2)) {
3342                 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
3343                          req->wct, 19 + (state->setup_count/2)));
3344                 goto bad_param;
3345         }
3346
3347         /* Don't allow more than 128mb for each value. */
3348         if ((state->total_data > (1024*1024*128)) ||
3349             (state->total_param > (1024*1024*128))) {
3350                 reply_doserror(req, ERRDOS, ERRnomem);
3351                 END_PROFILE(SMBnttrans);
3352                 return;
3353         }
3354
3355         if ((dscnt > state->total_data) || (pscnt > state->total_param))
3356                 goto bad_param;
3357
3358         if (state->total_data)  {
3359                 /* Can't use talloc here, the core routines do realloc on the
3360                  * params and data. */
3361                 if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
3362                         DEBUG(0,("reply_nttrans: data malloc fail for %u "
3363                                  "bytes !\n", (unsigned int)state->total_data));
3364                         TALLOC_FREE(state);
3365                         reply_doserror(req, ERRDOS, ERRnomem);
3366                         END_PROFILE(SMBnttrans);
3367                         return;
3368                 } 
3369                 if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
3370                         goto bad_param;
3371                 if ((smb_base(req->inbuf)+dsoff+dscnt
3372                      > (char *)req->inbuf + size) ||
3373                     (smb_base(req->inbuf)+dsoff+dscnt < smb_base(req->inbuf)))
3374                         goto bad_param;
3375
3376                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
3377         }
3378
3379         if (state->total_param) {
3380                 /* Can't use talloc here, the core routines do realloc on the
3381                  * params and data. */
3382                 if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
3383                         DEBUG(0,("reply_nttrans: param malloc fail for %u "
3384                                  "bytes !\n", (unsigned int)state->total_param));
3385                         SAFE_FREE(state->data);
3386                         TALLOC_FREE(state);
3387                         reply_doserror(req, ERRDOS, ERRnomem);
3388                         END_PROFILE(SMBnttrans);
3389                         return;
3390                 } 
3391                 if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
3392                         goto bad_param;
3393                 if ((smb_base(req->inbuf)+psoff+pscnt
3394                      > (char *)req->inbuf + size) ||
3395                     (smb_base(req->inbuf)+psoff+pscnt < smb_base(req->inbuf)))
3396                         goto bad_param;
3397
3398                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
3399         }
3400
3401         state->received_data  = dscnt;
3402         state->received_param = pscnt;
3403
3404         if(state->setup_count > 0) {
3405                 DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
3406                           state->setup_count));
3407                 state->setup = (uint16 *)TALLOC(state, state->setup_count);
3408                 if (state->setup == NULL) {
3409                         DEBUG(0,("reply_nttrans : Out of memory\n"));
3410                         SAFE_FREE(state->data);
3411                         SAFE_FREE(state->param);
3412                         TALLOC_FREE(state);
3413                         reply_doserror(req, ERRDOS, ERRnomem);
3414                         END_PROFILE(SMBnttrans);
3415                         return;
3416                 }
3417
3418                 if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
3419                     (smb_nt_SetupStart + state->setup_count < state->setup_count)) {
3420                         goto bad_param;
3421                 }
3422                 if (smb_nt_SetupStart + state->setup_count > size) {
3423                         goto bad_param;
3424                 }
3425
3426                 memcpy( state->setup, &req->inbuf[smb_nt_SetupStart],
3427                         state->setup_count);
3428                 dump_data(10, (uint8 *)state->setup, state->setup_count);
3429         }
3430
3431         if ((state->received_data == state->total_data) &&
3432             (state->received_param == state->total_param)) {
3433                 handle_nttrans(conn, state, req);
3434                 SAFE_FREE(state->param);
3435                 SAFE_FREE(state->data);
3436                 TALLOC_FREE(state);
3437                 END_PROFILE(SMBnttrans);
3438                 return;
3439         }
3440
3441         DLIST_ADD(conn->pending_trans, state);
3442
3443         /* We need to send an interim response then receive the rest
3444            of the parameter/data bytes */
3445         reply_outbuf(req, 0, 0);
3446         show_msg((char *)req->outbuf);
3447         END_PROFILE(SMBnttrans);
3448         return;
3449
3450   bad_param:
3451
3452         DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
3453         SAFE_FREE(state->data);
3454         SAFE_FREE(state->param);
3455         TALLOC_FREE(state);
3456         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3457         END_PROFILE(SMBnttrans);
3458         return;
3459 }
3460         
3461 /****************************************************************************
3462  Reply to a SMBnttranss
3463  ****************************************************************************/
3464
3465 void reply_nttranss(connection_struct *conn, struct smb_request *req)
3466 {
3467         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
3468         struct trans_state *state;
3469
3470         int size;
3471
3472         START_PROFILE(SMBnttranss);
3473
3474         show_msg((char *)req->inbuf);
3475
3476         if (req->wct < 18) {
3477                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3478                 END_PROFILE(SMBnttranss);
3479                 return;
3480         }
3481
3482         for (state = conn->pending_trans; state != NULL;
3483              state = state->next) {
3484                 if (state->mid == req->mid) {
3485                         break;
3486                 }
3487         }
3488
3489         if ((state == NULL) || (state->cmd != SMBnttrans)) {
3490                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3491                 END_PROFILE(SMBnttranss);
3492                 return;
3493         }
3494
3495         /* Revise state->total_param and state->total_data in case they have
3496            changed downwards */
3497         if (IVAL(req->inbuf, smb_nts_TotalParameterCount)
3498             < state->total_param) {
3499                 state->total_param = IVAL(req->inbuf,
3500                                           smb_nts_TotalParameterCount);
3501         }
3502         if (IVAL(req->inbuf, smb_nts_TotalDataCount) < state->total_data) {