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