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