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