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