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