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