s3:smbd: change blocking.c to use fsp_fnum_dbg() for fsp->fnum logging.
[Samba/gebeck_regimport.git] / source3 / smbd / nttrans.c
blobf7a27187e83ef57de5fc6533ec6ddb4c5a0dd65d
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
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.
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.
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/>.
21 #include "includes.h"
22 #include "system/filesys.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "fake_file.h"
26 #include "../libcli/security/security.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
28 #include "passdb/lookup_sid.h"
29 #include "auth.h"
30 #include "smbprofile.h"
31 #include "libsmb/libsmb.h"
33 extern const struct generic_mapping file_generic_mapping;
35 static char *nttrans_realloc(char **ptr, size_t size)
37 if (ptr==NULL) {
38 smb_panic("nttrans_realloc() called with NULL ptr");
41 *ptr = (char *)SMB_REALLOC(*ptr, size);
42 if(*ptr == NULL) {
43 return NULL;
45 memset(*ptr,'\0',size);
46 return *ptr;
49 /****************************************************************************
50 Send the required number of replies back.
51 We assume all fields other than the data fields are
52 set correctly for the type of call.
53 HACK ! Always assumes smb_setup field is zero.
54 ****************************************************************************/
56 static void send_nt_replies(connection_struct *conn,
57 struct smb_request *req, NTSTATUS nt_error,
58 char *params, int paramsize,
59 char *pdata, int datasize)
61 int data_to_send = datasize;
62 int params_to_send = paramsize;
63 int useable_space;
64 char *pp = params;
65 char *pd = pdata;
66 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
67 int alignment_offset = 1;
68 int data_alignment_offset = 0;
69 struct smbd_server_connection *sconn = req->sconn;
70 int max_send = sconn->smb1.sessions.max_send;
73 * If there genuinely are no parameters or data to send just send
74 * the empty packet.
77 if(params_to_send == 0 && data_to_send == 0) {
78 reply_outbuf(req, 18, 0);
79 if (NT_STATUS_V(nt_error)) {
80 error_packet_set((char *)req->outbuf,
81 0, 0, nt_error,
82 __LINE__,__FILE__);
84 show_msg((char *)req->outbuf);
85 if (!srv_send_smb(sconn,
86 (char *)req->outbuf,
87 true, req->seqnum+1,
88 IS_CONN_ENCRYPTED(conn),
89 &req->pcd)) {
90 exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
92 TALLOC_FREE(req->outbuf);
93 return;
97 * When sending params and data ensure that both are nicely aligned.
98 * Only do this alignment when there is also data to send - else
99 * can cause NT redirector problems.
102 if (((params_to_send % 4) != 0) && (data_to_send != 0)) {
103 data_alignment_offset = 4 - (params_to_send % 4);
107 * Space is bufsize minus Netbios over TCP header minus SMB header.
108 * The alignment_offset is to align the param bytes on a four byte
109 * boundary (2 bytes for data len, one byte pad).
110 * NT needs this to work correctly.
113 useable_space = max_send - (smb_size
114 + 2 * 18 /* wct */
115 + alignment_offset
116 + data_alignment_offset);
118 if (useable_space < 0) {
119 char *msg = talloc_asprintf(
120 talloc_tos(),
121 "send_nt_replies failed sanity useable_space = %d!!!",
122 useable_space);
123 DEBUG(0, ("%s\n", msg));
124 exit_server_cleanly(msg);
127 while (params_to_send || data_to_send) {
130 * Calculate whether we will totally or partially fill this packet.
133 total_sent_thistime = params_to_send + data_to_send;
136 * We can never send more than useable_space.
139 total_sent_thistime = MIN(total_sent_thistime, useable_space);
141 reply_outbuf(req, 18,
142 total_sent_thistime + alignment_offset
143 + data_alignment_offset);
146 * We might have had SMBnttranss in req->inbuf, fix that.
148 SCVAL(req->outbuf, smb_com, SMBnttrans);
151 * Set total params and data to be sent.
154 SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize);
155 SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize);
158 * Calculate how many parameters and data we can fit into
159 * this packet. Parameters get precedence.
162 params_sent_thistime = MIN(params_to_send,useable_space);
163 data_sent_thistime = useable_space - params_sent_thistime;
164 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
166 SIVAL(req->outbuf, smb_ntr_ParameterCount,
167 params_sent_thistime);
169 if(params_sent_thistime == 0) {
170 SIVAL(req->outbuf,smb_ntr_ParameterOffset,0);
171 SIVAL(req->outbuf,smb_ntr_ParameterDisplacement,0);
172 } else {
174 * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
175 * parameter bytes, however the first 4 bytes of outbuf are
176 * the Netbios over TCP header. Thus use smb_base() to subtract
177 * them from the calculation.
180 SIVAL(req->outbuf,smb_ntr_ParameterOffset,
181 ((smb_buf(req->outbuf)+alignment_offset)
182 - smb_base(req->outbuf)));
184 * Absolute displacement of param bytes sent in this packet.
187 SIVAL(req->outbuf, smb_ntr_ParameterDisplacement,
188 pp - params);
192 * Deal with the data portion.
195 SIVAL(req->outbuf, smb_ntr_DataCount, data_sent_thistime);
197 if(data_sent_thistime == 0) {
198 SIVAL(req->outbuf,smb_ntr_DataOffset,0);
199 SIVAL(req->outbuf,smb_ntr_DataDisplacement, 0);
200 } else {
202 * The offset of the data bytes is the offset of the
203 * parameter bytes plus the number of parameters being sent this time.
206 SIVAL(req->outbuf, smb_ntr_DataOffset,
207 ((smb_buf(req->outbuf)+alignment_offset) -
208 smb_base(req->outbuf))
209 + params_sent_thistime + data_alignment_offset);
210 SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata);
214 * Copy the param bytes into the packet.
217 if(params_sent_thistime) {
218 if (alignment_offset != 0) {
219 memset(smb_buf(req->outbuf), 0,
220 alignment_offset);
222 memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
223 params_sent_thistime);
227 * Copy in the data bytes
230 if(data_sent_thistime) {
231 if (data_alignment_offset != 0) {
232 memset((smb_buf(req->outbuf)+alignment_offset+
233 params_sent_thistime), 0,
234 data_alignment_offset);
236 memcpy(smb_buf(req->outbuf)+alignment_offset
237 +params_sent_thistime+data_alignment_offset,
238 pd,data_sent_thistime);
241 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
242 params_sent_thistime, data_sent_thistime, useable_space));
243 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
244 params_to_send, data_to_send, paramsize, datasize));
246 if (NT_STATUS_V(nt_error)) {
247 error_packet_set((char *)req->outbuf,
248 0, 0, nt_error,
249 __LINE__,__FILE__);
252 /* Send the packet */
253 show_msg((char *)req->outbuf);
254 if (!srv_send_smb(sconn,
255 (char *)req->outbuf,
256 true, req->seqnum+1,
257 IS_CONN_ENCRYPTED(conn),
258 &req->pcd)) {
259 exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
262 TALLOC_FREE(req->outbuf);
264 pp += params_sent_thistime;
265 pd += data_sent_thistime;
267 params_to_send -= params_sent_thistime;
268 data_to_send -= data_sent_thistime;
271 * Sanity check
274 if(params_to_send < 0 || data_to_send < 0) {
275 DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
276 params_to_send, data_to_send));
277 exit_server_cleanly("send_nt_replies: internal error");
282 /****************************************************************************
283 Reply to an NT create and X call on a pipe
284 ****************************************************************************/
286 static void nt_open_pipe(char *fname, connection_struct *conn,
287 struct smb_request *req, int *ppnum)
289 files_struct *fsp;
290 NTSTATUS status;
292 DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
294 /* Strip \\ off the name if present. */
295 while (fname[0] == '\\') {
296 fname++;
299 status = open_np_file(req, fname, &fsp);
300 if (!NT_STATUS_IS_OK(status)) {
301 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
302 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
303 ERRDOS, ERRbadpipe);
304 return;
306 reply_nterror(req, status);
307 return;
310 *ppnum = fsp->fnum;
311 return;
314 /****************************************************************************
315 Reply to an NT create and X call for pipes.
316 ****************************************************************************/
318 static void do_ntcreate_pipe_open(connection_struct *conn,
319 struct smb_request *req)
321 char *fname = NULL;
322 int pnum = -1;
323 char *p = NULL;
324 uint32 flags = IVAL(req->vwv+3, 1);
325 TALLOC_CTX *ctx = talloc_tos();
327 srvstr_pull_req_talloc(ctx, req, &fname, req->buf, STR_TERMINATE);
329 if (!fname) {
330 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
331 ERRDOS, ERRbadpipe);
332 return;
334 nt_open_pipe(fname, conn, req, &pnum);
336 if (req->outbuf) {
337 /* error reply */
338 return;
342 * Deal with pipe return.
345 if (flags & EXTENDED_RESPONSE_REQUIRED) {
346 /* This is very strange. We
347 * return 50 words, but only set
348 * the wcnt to 42 ? It's definitely
349 * what happens on the wire....
351 reply_outbuf(req, 50, 0);
352 SCVAL(req->outbuf,smb_wct,42);
353 } else {
354 reply_outbuf(req, 34, 0);
357 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
358 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
360 p = (char *)req->outbuf + smb_vwv2;
361 p++;
362 SSVAL(p,0,pnum);
363 p += 2;
364 SIVAL(p,0,FILE_WAS_OPENED);
365 p += 4;
366 p += 32;
367 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
368 p += 20;
369 /* File type. */
370 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
371 /* Device state. */
372 SSVAL(p,2, 0x5FF); /* ? */
373 p += 4;
375 if (flags & EXTENDED_RESPONSE_REQUIRED) {
376 p += 25;
377 SIVAL(p,0,FILE_GENERIC_ALL);
379 * For pipes W2K3 seems to return
380 * 0x12019B next.
381 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
383 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
386 DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
389 struct case_semantics_state {
390 connection_struct *conn;
391 bool case_sensitive;
392 bool case_preserve;
393 bool short_case_preserve;
396 /****************************************************************************
397 Restore case semantics.
398 ****************************************************************************/
400 static int restore_case_semantics(struct case_semantics_state *state)
402 state->conn->case_sensitive = state->case_sensitive;
403 state->conn->case_preserve = state->case_preserve;
404 state->conn->short_case_preserve = state->short_case_preserve;
405 return 0;
408 /****************************************************************************
409 Save case semantics.
410 ****************************************************************************/
412 static struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx,
413 connection_struct *conn)
415 struct case_semantics_state *result;
417 if (!(result = talloc(mem_ctx, struct case_semantics_state))) {
418 return NULL;
421 result->conn = conn;
422 result->case_sensitive = conn->case_sensitive;
423 result->case_preserve = conn->case_preserve;
424 result->short_case_preserve = conn->short_case_preserve;
426 /* Set to POSIX. */
427 conn->case_sensitive = True;
428 conn->case_preserve = True;
429 conn->short_case_preserve = True;
431 talloc_set_destructor(result, restore_case_semantics);
433 return result;
436 /****************************************************************************
437 Reply to an NT create and X call.
438 ****************************************************************************/
440 void reply_ntcreate_and_X(struct smb_request *req)
442 connection_struct *conn = req->conn;
443 struct smb_filename *smb_fname = NULL;
444 char *fname = NULL;
445 uint32 flags;
446 uint32 access_mask;
447 uint32 file_attributes;
448 uint32 share_access;
449 uint32 create_disposition;
450 uint32 create_options;
451 uint16 root_dir_fid;
452 uint64_t allocation_size;
453 /* Breakout the oplock request bits so we can set the
454 reply bits separately. */
455 uint32 fattr=0;
456 off_t file_len = 0;
457 int info = 0;
458 files_struct *fsp = NULL;
459 char *p = NULL;
460 struct timespec create_timespec;
461 struct timespec c_timespec;
462 struct timespec a_timespec;
463 struct timespec m_timespec;
464 struct timespec write_time_ts;
465 NTSTATUS status;
466 int oplock_request;
467 uint8_t oplock_granted = NO_OPLOCK_RETURN;
468 struct case_semantics_state *case_state = NULL;
469 TALLOC_CTX *ctx = talloc_tos();
471 START_PROFILE(SMBntcreateX);
473 if (req->wct < 24) {
474 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
475 goto out;
478 flags = IVAL(req->vwv+3, 1);
479 access_mask = IVAL(req->vwv+7, 1);
480 file_attributes = IVAL(req->vwv+13, 1);
481 share_access = IVAL(req->vwv+15, 1);
482 create_disposition = IVAL(req->vwv+17, 1);
483 create_options = IVAL(req->vwv+19, 1);
484 root_dir_fid = (uint16)IVAL(req->vwv+5, 1);
486 allocation_size = BVAL(req->vwv+9, 1);
488 srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
489 STR_TERMINATE, &status);
491 if (!NT_STATUS_IS_OK(status)) {
492 reply_nterror(req, status);
493 goto out;
496 DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
497 "file_attributes = 0x%x, share_access = 0x%x, "
498 "create_disposition = 0x%x create_options = 0x%x "
499 "root_dir_fid = 0x%x, fname = %s\n",
500 (unsigned int)flags,
501 (unsigned int)access_mask,
502 (unsigned int)file_attributes,
503 (unsigned int)share_access,
504 (unsigned int)create_disposition,
505 (unsigned int)create_options,
506 (unsigned int)root_dir_fid,
507 fname));
510 * we need to remove ignored bits when they come directly from the client
511 * because we reuse some of them for internal stuff
513 create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
516 * If it's an IPC, use the pipe handler.
519 if (IS_IPC(conn)) {
520 if (lp_nt_pipe_support()) {
521 do_ntcreate_pipe_open(conn, req);
522 goto out;
524 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
525 goto out;
528 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
529 if (oplock_request) {
530 oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
531 ? BATCH_OPLOCK : 0;
534 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
535 case_state = set_posix_case_semantics(ctx, conn);
536 if (!case_state) {
537 reply_nterror(req, NT_STATUS_NO_MEMORY);
538 goto out;
542 status = filename_convert(ctx,
543 conn,
544 req->flags2 & FLAGS2_DFS_PATHNAMES,
545 fname,
547 NULL,
548 &smb_fname);
550 TALLOC_FREE(case_state);
552 if (!NT_STATUS_IS_OK(status)) {
553 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
554 reply_botherror(req,
555 NT_STATUS_PATH_NOT_COVERED,
556 ERRSRV, ERRbadpath);
557 goto out;
559 reply_nterror(req, status);
560 goto out;
564 * Bug #6898 - clients using Windows opens should
565 * never be able to set this attribute into the
566 * VFS.
568 file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
570 status = SMB_VFS_CREATE_FILE(
571 conn, /* conn */
572 req, /* req */
573 root_dir_fid, /* root_dir_fid */
574 smb_fname, /* fname */
575 access_mask, /* access_mask */
576 share_access, /* share_access */
577 create_disposition, /* create_disposition*/
578 create_options, /* create_options */
579 file_attributes, /* file_attributes */
580 oplock_request, /* oplock_request */
581 allocation_size, /* allocation_size */
582 0, /* private_flags */
583 NULL, /* sd */
584 NULL, /* ea_list */
585 &fsp, /* result */
586 &info); /* pinfo */
588 if (!NT_STATUS_IS_OK(status)) {
589 if (open_was_deferred(req->sconn, req->mid)) {
590 /* We have re-scheduled this call, no error. */
591 goto out;
593 reply_openerror(req, status);
594 goto out;
597 /* Ensure we're pointing at the correct stat struct. */
598 TALLOC_FREE(smb_fname);
599 smb_fname = fsp->fsp_name;
602 * If the caller set the extended oplock request bit
603 * and we granted one (by whatever means) - set the
604 * correct bit for extended oplock reply.
607 if (oplock_request &&
608 (lp_fake_oplocks(SNUM(conn))
609 || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
612 * Exclusive oplock granted
615 if (flags & REQUEST_BATCH_OPLOCK) {
616 oplock_granted = BATCH_OPLOCK_RETURN;
617 } else {
618 oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
620 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
621 oplock_granted = LEVEL_II_OPLOCK_RETURN;
622 } else {
623 oplock_granted = NO_OPLOCK_RETURN;
626 file_len = smb_fname->st.st_ex_size;
628 if (flags & EXTENDED_RESPONSE_REQUIRED) {
629 /* This is very strange. We
630 * return 50 words, but only set
631 * the wcnt to 42 ? It's definitely
632 * what happens on the wire....
634 reply_outbuf(req, 50, 0);
635 SCVAL(req->outbuf,smb_wct,42);
636 } else {
637 reply_outbuf(req, 34, 0);
640 SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
641 SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
643 p = (char *)req->outbuf + smb_vwv2;
645 SCVAL(p, 0, oplock_granted);
647 p++;
648 SSVAL(p,0,fsp->fnum);
649 p += 2;
650 if ((create_disposition == FILE_SUPERSEDE)
651 && (info == FILE_WAS_OVERWRITTEN)) {
652 SIVAL(p,0,FILE_WAS_SUPERSEDED);
653 } else {
654 SIVAL(p,0,info);
656 p += 4;
658 fattr = dos_mode(conn, smb_fname);
659 if (fattr == 0) {
660 fattr = FILE_ATTRIBUTE_NORMAL;
663 /* Deal with other possible opens having a modified
664 write time. JRA. */
665 ZERO_STRUCT(write_time_ts);
666 get_file_infos(fsp->file_id, 0, NULL, &write_time_ts);
667 if (!null_timespec(write_time_ts)) {
668 update_stat_ex_mtime(&smb_fname->st, write_time_ts);
671 /* Create time. */
672 create_timespec = get_create_timespec(conn, fsp, smb_fname);
673 a_timespec = smb_fname->st.st_ex_atime;
674 m_timespec = smb_fname->st.st_ex_mtime;
675 c_timespec = get_change_timespec(conn, fsp, smb_fname);
677 if (lp_dos_filetime_resolution(SNUM(conn))) {
678 dos_filetime_timespec(&create_timespec);
679 dos_filetime_timespec(&a_timespec);
680 dos_filetime_timespec(&m_timespec);
681 dos_filetime_timespec(&c_timespec);
684 put_long_date_timespec(conn->ts_res, p, create_timespec); /* create time. */
685 p += 8;
686 put_long_date_timespec(conn->ts_res, p, a_timespec); /* access time */
687 p += 8;
688 put_long_date_timespec(conn->ts_res, p, m_timespec); /* write time */
689 p += 8;
690 put_long_date_timespec(conn->ts_res, p, c_timespec); /* change time */
691 p += 8;
692 SIVAL(p,0,fattr); /* File Attributes. */
693 p += 4;
694 SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&smb_fname->st));
695 p += 8;
696 SOFF_T(p,0,file_len);
697 p += 8;
698 if (flags & EXTENDED_RESPONSE_REQUIRED) {
699 uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG);
700 size_t num_names = 0;
701 unsigned int num_streams = 0;
702 struct stream_struct *streams = NULL;
704 /* Do we have any EA's ? */
705 status = get_ea_names_from_file(ctx, conn, fsp,
706 smb_fname->base_name, NULL, &num_names);
707 if (NT_STATUS_IS_OK(status) && num_names) {
708 file_status &= ~NO_EAS;
710 status = vfs_streaminfo(conn, NULL, smb_fname->base_name, ctx,
711 &num_streams, &streams);
712 /* There is always one stream, ::$DATA. */
713 if (NT_STATUS_IS_OK(status) && num_streams > 1) {
714 file_status &= ~NO_SUBSTREAMS;
716 TALLOC_FREE(streams);
717 SSVAL(p,2,file_status);
719 p += 4;
720 SCVAL(p,0,fsp->is_directory ? 1 : 0);
722 if (flags & EXTENDED_RESPONSE_REQUIRED) {
723 uint32 perms = 0;
724 p += 25;
725 if (fsp->is_directory ||
726 can_write_to_file(conn, smb_fname)) {
727 perms = FILE_GENERIC_ALL;
728 } else {
729 perms = FILE_GENERIC_READ|FILE_EXECUTE;
731 SIVAL(p,0,perms);
734 DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n",
735 fsp->fnum, smb_fname_str_dbg(smb_fname)));
737 out:
738 END_PROFILE(SMBntcreateX);
739 return;
742 /****************************************************************************
743 Reply to a NT_TRANSACT_CREATE call to open a pipe.
744 ****************************************************************************/
746 static void do_nt_transact_create_pipe(connection_struct *conn,
747 struct smb_request *req,
748 uint16 **ppsetup, uint32 setup_count,
749 char **ppparams, uint32 parameter_count,
750 char **ppdata, uint32 data_count)
752 char *fname = NULL;
753 char *params = *ppparams;
754 int pnum = -1;
755 char *p = NULL;
756 NTSTATUS status;
757 size_t param_len;
758 uint32 flags;
759 TALLOC_CTX *ctx = talloc_tos();
762 * Ensure minimum number of parameters sent.
765 if(parameter_count < 54) {
766 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
767 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
768 return;
771 flags = IVAL(params,0);
773 srvstr_get_path(ctx, params, req->flags2, &fname, params+53,
774 parameter_count-53, STR_TERMINATE,
775 &status);
776 if (!NT_STATUS_IS_OK(status)) {
777 reply_nterror(req, status);
778 return;
781 nt_open_pipe(fname, conn, req, &pnum);
783 if (req->outbuf) {
784 /* Error return */
785 return;
788 /* Realloc the size of parameters and data we will return */
789 if (flags & EXTENDED_RESPONSE_REQUIRED) {
790 /* Extended response is 32 more byyes. */
791 param_len = 101;
792 } else {
793 param_len = 69;
795 params = nttrans_realloc(ppparams, param_len);
796 if(params == NULL) {
797 reply_nterror(req, NT_STATUS_NO_MEMORY);
798 return;
801 p = params;
802 SCVAL(p,0,NO_OPLOCK_RETURN);
804 p += 2;
805 SSVAL(p,0,pnum);
806 p += 2;
807 SIVAL(p,0,FILE_WAS_OPENED);
808 p += 8;
810 p += 32;
811 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
812 p += 20;
813 /* File type. */
814 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
815 /* Device state. */
816 SSVAL(p,2, 0x5FF); /* ? */
817 p += 4;
819 if (flags & EXTENDED_RESPONSE_REQUIRED) {
820 p += 25;
821 SIVAL(p,0,FILE_GENERIC_ALL);
823 * For pipes W2K3 seems to return
824 * 0x12019B next.
825 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
827 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
830 DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
832 /* Send the required number of replies */
833 send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
835 return;
838 /****************************************************************************
839 Internal fn to set security descriptors.
840 ****************************************************************************/
842 NTSTATUS set_sd(files_struct *fsp, uint8_t *data, uint32_t sd_len,
843 uint32_t security_info_sent)
845 struct security_descriptor *psd = NULL;
846 NTSTATUS status;
848 if (sd_len == 0) {
849 return NT_STATUS_INVALID_PARAMETER;
852 if (!CAN_WRITE(fsp->conn)) {
853 return NT_STATUS_ACCESS_DENIED;
856 if (!lp_nt_acl_support(SNUM(fsp->conn))) {
857 return NT_STATUS_OK;
860 status = unmarshall_sec_desc(talloc_tos(), data, sd_len, &psd);
862 if (!NT_STATUS_IS_OK(status)) {
863 return status;
866 if (psd->owner_sid == NULL) {
867 security_info_sent &= ~SECINFO_OWNER;
869 if (psd->group_sid == NULL) {
870 security_info_sent &= ~SECINFO_GROUP;
873 /* Ensure we have at least one thing set. */
874 if ((security_info_sent & (SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL)) == 0) {
875 if (security_info_sent & SECINFO_LABEL) {
876 /* Only consider SECINFO_LABEL if no other
877 bits are set. Just like W2K3 we don't
878 store this. */
879 return NT_STATUS_OK;
881 return NT_STATUS_INVALID_PARAMETER;
884 /* Ensure we have the rights to do this. */
885 if (security_info_sent & SECINFO_OWNER) {
886 if (!(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
887 return NT_STATUS_ACCESS_DENIED;
891 if (security_info_sent & SECINFO_GROUP) {
892 if (!(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
893 return NT_STATUS_ACCESS_DENIED;
897 if (security_info_sent & SECINFO_DACL) {
898 if (!(fsp->access_mask & SEC_STD_WRITE_DAC)) {
899 return NT_STATUS_ACCESS_DENIED;
901 /* Convert all the generic bits. */
902 if (psd->dacl) {
903 security_acl_map_generic(psd->dacl, &file_generic_mapping);
907 if (security_info_sent & SECINFO_SACL) {
908 if (!(fsp->access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
909 return NT_STATUS_ACCESS_DENIED;
911 /* Convert all the generic bits. */
912 if (psd->sacl) {
913 security_acl_map_generic(psd->sacl, &file_generic_mapping);
917 if (DEBUGLEVEL >= 10) {
918 DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp)));
919 NDR_PRINT_DEBUG(security_descriptor, psd);
922 status = SMB_VFS_FSET_NT_ACL(fsp, security_info_sent, psd);
924 TALLOC_FREE(psd);
926 return status;
929 /****************************************************************************
930 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
931 ****************************************************************************/
933 struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
935 struct ea_list *ea_list_head = NULL;
936 size_t offset = 0;
938 if (data_size < 4) {
939 return NULL;
942 while (offset + 4 <= data_size) {
943 size_t next_offset = IVAL(pdata,offset);
944 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
946 if (!eal) {
947 return NULL;
950 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
951 if (next_offset == 0) {
952 break;
954 offset += next_offset;
957 return ea_list_head;
960 /****************************************************************************
961 Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
962 ****************************************************************************/
964 static void call_nt_transact_create(connection_struct *conn,
965 struct smb_request *req,
966 uint16 **ppsetup, uint32 setup_count,
967 char **ppparams, uint32 parameter_count,
968 char **ppdata, uint32 data_count,
969 uint32 max_data_count)
971 struct smb_filename *smb_fname = NULL;
972 char *fname = NULL;
973 char *params = *ppparams;
974 char *data = *ppdata;
975 /* Breakout the oplock request bits so we can set the reply bits separately. */
976 uint32 fattr=0;
977 off_t file_len = 0;
978 int info = 0;
979 files_struct *fsp = NULL;
980 char *p = NULL;
981 uint32 flags;
982 uint32 access_mask;
983 uint32 file_attributes;
984 uint32 share_access;
985 uint32 create_disposition;
986 uint32 create_options;
987 uint32 sd_len;
988 struct security_descriptor *sd = NULL;
989 uint32 ea_len;
990 uint16 root_dir_fid;
991 struct timespec create_timespec;
992 struct timespec c_timespec;
993 struct timespec a_timespec;
994 struct timespec m_timespec;
995 struct timespec write_time_ts;
996 struct ea_list *ea_list = NULL;
997 NTSTATUS status;
998 size_t param_len;
999 uint64_t allocation_size;
1000 int oplock_request;
1001 uint8_t oplock_granted;
1002 struct case_semantics_state *case_state = NULL;
1003 TALLOC_CTX *ctx = talloc_tos();
1005 DEBUG(5,("call_nt_transact_create\n"));
1008 * If it's an IPC, use the pipe handler.
1011 if (IS_IPC(conn)) {
1012 if (lp_nt_pipe_support()) {
1013 do_nt_transact_create_pipe(
1014 conn, req,
1015 ppsetup, setup_count,
1016 ppparams, parameter_count,
1017 ppdata, data_count);
1018 goto out;
1020 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1021 goto out;
1025 * Ensure minimum number of parameters sent.
1028 if(parameter_count < 54) {
1029 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
1030 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1031 goto out;
1034 flags = IVAL(params,0);
1035 access_mask = IVAL(params,8);
1036 file_attributes = IVAL(params,20);
1037 share_access = IVAL(params,24);
1038 create_disposition = IVAL(params,28);
1039 create_options = IVAL(params,32);
1040 sd_len = IVAL(params,36);
1041 ea_len = IVAL(params,40);
1042 root_dir_fid = (uint16)IVAL(params,4);
1043 allocation_size = BVAL(params,12);
1046 * we need to remove ignored bits when they come directly from the client
1047 * because we reuse some of them for internal stuff
1049 create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
1051 /* Ensure the data_len is correct for the sd and ea values given. */
1052 if ((ea_len + sd_len > data_count)
1053 || (ea_len > data_count) || (sd_len > data_count)
1054 || (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
1055 DEBUG(10, ("call_nt_transact_create - ea_len = %u, sd_len = "
1056 "%u, data_count = %u\n", (unsigned int)ea_len,
1057 (unsigned int)sd_len, (unsigned int)data_count));
1058 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1059 goto out;
1062 if (sd_len) {
1063 DEBUG(10, ("call_nt_transact_create - sd_len = %d\n",
1064 sd_len));
1066 status = unmarshall_sec_desc(ctx, (uint8_t *)data, sd_len,
1067 &sd);
1068 if (!NT_STATUS_IS_OK(status)) {
1069 DEBUG(10, ("call_nt_transact_create: "
1070 "unmarshall_sec_desc failed: %s\n",
1071 nt_errstr(status)));
1072 reply_nterror(req, status);
1073 goto out;
1077 if (ea_len) {
1078 if (!lp_ea_support(SNUM(conn))) {
1079 DEBUG(10, ("call_nt_transact_create - ea_len = %u but "
1080 "EA's not supported.\n",
1081 (unsigned int)ea_len));
1082 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1083 goto out;
1086 if (ea_len < 10) {
1087 DEBUG(10,("call_nt_transact_create - ea_len = %u - "
1088 "too small (should be more than 10)\n",
1089 (unsigned int)ea_len ));
1090 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1091 goto out;
1094 /* We have already checked that ea_len <= data_count here. */
1095 ea_list = read_nttrans_ea_list(talloc_tos(), data + sd_len,
1096 ea_len);
1097 if (ea_list == NULL) {
1098 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1099 goto out;
1103 srvstr_get_path(ctx, params, req->flags2, &fname,
1104 params+53, parameter_count-53,
1105 STR_TERMINATE, &status);
1106 if (!NT_STATUS_IS_OK(status)) {
1107 reply_nterror(req, status);
1108 goto out;
1111 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1112 case_state = set_posix_case_semantics(ctx, conn);
1113 if (!case_state) {
1114 reply_nterror(req, NT_STATUS_NO_MEMORY);
1115 goto out;
1119 status = filename_convert(ctx,
1120 conn,
1121 req->flags2 & FLAGS2_DFS_PATHNAMES,
1122 fname,
1124 NULL,
1125 &smb_fname);
1127 TALLOC_FREE(case_state);
1129 if (!NT_STATUS_IS_OK(status)) {
1130 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1131 reply_botherror(req,
1132 NT_STATUS_PATH_NOT_COVERED,
1133 ERRSRV, ERRbadpath);
1134 goto out;
1136 reply_nterror(req, status);
1137 goto out;
1140 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1141 if (oplock_request) {
1142 oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
1143 ? BATCH_OPLOCK : 0;
1147 * Bug #6898 - clients using Windows opens should
1148 * never be able to set this attribute into the
1149 * VFS.
1151 file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
1153 status = SMB_VFS_CREATE_FILE(
1154 conn, /* conn */
1155 req, /* req */
1156 root_dir_fid, /* root_dir_fid */
1157 smb_fname, /* fname */
1158 access_mask, /* access_mask */
1159 share_access, /* share_access */
1160 create_disposition, /* create_disposition*/
1161 create_options, /* create_options */
1162 file_attributes, /* file_attributes */
1163 oplock_request, /* oplock_request */
1164 allocation_size, /* allocation_size */
1165 0, /* private_flags */
1166 sd, /* sd */
1167 ea_list, /* ea_list */
1168 &fsp, /* result */
1169 &info); /* pinfo */
1171 if(!NT_STATUS_IS_OK(status)) {
1172 if (open_was_deferred(req->sconn, req->mid)) {
1173 /* We have re-scheduled this call, no error. */
1174 return;
1176 reply_openerror(req, status);
1177 goto out;
1180 /* Ensure we're pointing at the correct stat struct. */
1181 TALLOC_FREE(smb_fname);
1182 smb_fname = fsp->fsp_name;
1185 * If the caller set the extended oplock request bit
1186 * and we granted one (by whatever means) - set the
1187 * correct bit for extended oplock reply.
1190 if (oplock_request &&
1191 (lp_fake_oplocks(SNUM(conn))
1192 || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
1195 * Exclusive oplock granted
1198 if (flags & REQUEST_BATCH_OPLOCK) {
1199 oplock_granted = BATCH_OPLOCK_RETURN;
1200 } else {
1201 oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
1203 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
1204 oplock_granted = LEVEL_II_OPLOCK_RETURN;
1205 } else {
1206 oplock_granted = NO_OPLOCK_RETURN;
1209 file_len = smb_fname->st.st_ex_size;
1211 /* Realloc the size of parameters and data we will return */
1212 if (flags & EXTENDED_RESPONSE_REQUIRED) {
1213 /* Extended response is 32 more byyes. */
1214 param_len = 101;
1215 } else {
1216 param_len = 69;
1218 params = nttrans_realloc(ppparams, param_len);
1219 if(params == NULL) {
1220 reply_nterror(req, NT_STATUS_NO_MEMORY);
1221 goto out;
1224 p = params;
1225 SCVAL(p, 0, oplock_granted);
1227 p += 2;
1228 SSVAL(p,0,fsp->fnum);
1229 p += 2;
1230 if ((create_disposition == FILE_SUPERSEDE)
1231 && (info == FILE_WAS_OVERWRITTEN)) {
1232 SIVAL(p,0,FILE_WAS_SUPERSEDED);
1233 } else {
1234 SIVAL(p,0,info);
1236 p += 8;
1238 fattr = dos_mode(conn, smb_fname);
1239 if (fattr == 0) {
1240 fattr = FILE_ATTRIBUTE_NORMAL;
1243 /* Deal with other possible opens having a modified
1244 write time. JRA. */
1245 ZERO_STRUCT(write_time_ts);
1246 get_file_infos(fsp->file_id, 0, NULL, &write_time_ts);
1247 if (!null_timespec(write_time_ts)) {
1248 update_stat_ex_mtime(&smb_fname->st, write_time_ts);
1251 /* Create time. */
1252 create_timespec = get_create_timespec(conn, fsp, smb_fname);
1253 a_timespec = smb_fname->st.st_ex_atime;
1254 m_timespec = smb_fname->st.st_ex_mtime;
1255 c_timespec = get_change_timespec(conn, fsp, smb_fname);
1257 if (lp_dos_filetime_resolution(SNUM(conn))) {
1258 dos_filetime_timespec(&create_timespec);
1259 dos_filetime_timespec(&a_timespec);
1260 dos_filetime_timespec(&m_timespec);
1261 dos_filetime_timespec(&c_timespec);
1264 put_long_date_timespec(conn->ts_res, p, create_timespec); /* create time. */
1265 p += 8;
1266 put_long_date_timespec(conn->ts_res, p, a_timespec); /* access time */
1267 p += 8;
1268 put_long_date_timespec(conn->ts_res, p, m_timespec); /* write time */
1269 p += 8;
1270 put_long_date_timespec(conn->ts_res, p, c_timespec); /* change time */
1271 p += 8;
1272 SIVAL(p,0,fattr); /* File Attributes. */
1273 p += 4;
1274 SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st));
1275 p += 8;
1276 SOFF_T(p,0,file_len);
1277 p += 8;
1278 if (flags & EXTENDED_RESPONSE_REQUIRED) {
1279 uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG);
1280 size_t num_names = 0;
1281 unsigned int num_streams = 0;
1282 struct stream_struct *streams = NULL;
1284 /* Do we have any EA's ? */
1285 status = get_ea_names_from_file(ctx, conn, fsp,
1286 smb_fname->base_name, NULL, &num_names);
1287 if (NT_STATUS_IS_OK(status) && num_names) {
1288 file_status &= ~NO_EAS;
1290 status = vfs_streaminfo(conn, NULL, smb_fname->base_name, ctx,
1291 &num_streams, &streams);
1292 /* There is always one stream, ::$DATA. */
1293 if (NT_STATUS_IS_OK(status) && num_streams > 1) {
1294 file_status &= ~NO_SUBSTREAMS;
1296 TALLOC_FREE(streams);
1297 SSVAL(p,2,file_status);
1299 p += 4;
1300 SCVAL(p,0,fsp->is_directory ? 1 : 0);
1302 if (flags & EXTENDED_RESPONSE_REQUIRED) {
1303 uint32 perms = 0;
1304 p += 25;
1305 if (fsp->is_directory ||
1306 can_write_to_file(conn, smb_fname)) {
1307 perms = FILE_GENERIC_ALL;
1308 } else {
1309 perms = FILE_GENERIC_READ|FILE_EXECUTE;
1311 SIVAL(p,0,perms);
1314 DEBUG(5,("call_nt_transact_create: open name = %s\n",
1315 smb_fname_str_dbg(smb_fname)));
1317 /* Send the required number of replies */
1318 send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
1319 out:
1320 return;
1323 /****************************************************************************
1324 Reply to a NT CANCEL request.
1325 conn POINTER CAN BE NULL HERE !
1326 ****************************************************************************/
1328 void reply_ntcancel(struct smb_request *req)
1331 * Go through and cancel any pending change notifies.
1334 START_PROFILE(SMBntcancel);
1335 srv_cancel_sign_response(req->sconn);
1336 remove_pending_change_notify_requests_by_mid(req->sconn, req->mid);
1337 remove_pending_lock_requests_by_mid_smb1(req->sconn, req->mid);
1339 DEBUG(3,("reply_ntcancel: cancel called on mid = %llu.\n",
1340 (unsigned long long)req->mid));
1342 END_PROFILE(SMBntcancel);
1343 return;
1346 /****************************************************************************
1347 Copy a file.
1348 ****************************************************************************/
1350 static NTSTATUS copy_internals(TALLOC_CTX *ctx,
1351 connection_struct *conn,
1352 struct smb_request *req,
1353 struct smb_filename *smb_fname_src,
1354 struct smb_filename *smb_fname_dst,
1355 uint32 attrs)
1357 files_struct *fsp1,*fsp2;
1358 uint32 fattr;
1359 int info;
1360 off_t ret=-1;
1361 NTSTATUS status = NT_STATUS_OK;
1362 char *parent;
1364 if (!CAN_WRITE(conn)) {
1365 status = NT_STATUS_MEDIA_WRITE_PROTECTED;
1366 goto out;
1369 /* Source must already exist. */
1370 if (!VALID_STAT(smb_fname_src->st)) {
1371 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1372 goto out;
1375 /* Ensure attributes match. */
1376 fattr = dos_mode(conn, smb_fname_src);
1377 if ((fattr & ~attrs) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
1378 status = NT_STATUS_NO_SUCH_FILE;
1379 goto out;
1382 /* Disallow if dst file already exists. */
1383 if (VALID_STAT(smb_fname_dst->st)) {
1384 status = NT_STATUS_OBJECT_NAME_COLLISION;
1385 goto out;
1388 /* No links from a directory. */
1389 if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
1390 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1391 goto out;
1394 DEBUG(10,("copy_internals: doing file copy %s to %s\n",
1395 smb_fname_str_dbg(smb_fname_src),
1396 smb_fname_str_dbg(smb_fname_dst)));
1398 status = SMB_VFS_CREATE_FILE(
1399 conn, /* conn */
1400 req, /* req */
1401 0, /* root_dir_fid */
1402 smb_fname_src, /* fname */
1403 FILE_READ_DATA|FILE_READ_ATTRIBUTES|
1404 FILE_READ_EA, /* access_mask */
1405 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
1406 FILE_SHARE_DELETE),
1407 FILE_OPEN, /* create_disposition*/
1408 0, /* create_options */
1409 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
1410 NO_OPLOCK, /* oplock_request */
1411 0, /* allocation_size */
1412 0, /* private_flags */
1413 NULL, /* sd */
1414 NULL, /* ea_list */
1415 &fsp1, /* result */
1416 &info); /* pinfo */
1418 if (!NT_STATUS_IS_OK(status)) {
1419 goto out;
1422 status = SMB_VFS_CREATE_FILE(
1423 conn, /* conn */
1424 req, /* req */
1425 0, /* root_dir_fid */
1426 smb_fname_dst, /* fname */
1427 FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|
1428 FILE_WRITE_EA, /* access_mask */
1429 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
1430 FILE_SHARE_DELETE),
1431 FILE_CREATE, /* create_disposition*/
1432 0, /* create_options */
1433 fattr, /* file_attributes */
1434 NO_OPLOCK, /* oplock_request */
1435 0, /* allocation_size */
1436 0, /* private_flags */
1437 NULL, /* sd */
1438 NULL, /* ea_list */
1439 &fsp2, /* result */
1440 &info); /* pinfo */
1442 if (!NT_STATUS_IS_OK(status)) {
1443 close_file(NULL, fsp1, ERROR_CLOSE);
1444 goto out;
1447 if (smb_fname_src->st.st_ex_size) {
1448 ret = vfs_transfer_file(fsp1, fsp2, smb_fname_src->st.st_ex_size);
1452 * As we are opening fsp1 read-only we only expect
1453 * an error on close on fsp2 if we are out of space.
1454 * Thus we don't look at the error return from the
1455 * close of fsp1.
1457 close_file(NULL, fsp1, NORMAL_CLOSE);
1459 /* Ensure the modtime is set correctly on the destination file. */
1460 set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime);
1462 status = close_file(NULL, fsp2, NORMAL_CLOSE);
1464 /* Grrr. We have to do this as open_file_ntcreate adds FILE_ATTRIBUTE_ARCHIVE when it
1465 creates the file. This isn't the correct thing to do in the copy
1466 case. JRA */
1467 if (!parent_dirname(talloc_tos(), smb_fname_dst->base_name, &parent,
1468 NULL)) {
1469 status = NT_STATUS_NO_MEMORY;
1470 goto out;
1472 file_set_dosmode(conn, smb_fname_dst, fattr, parent, false);
1473 TALLOC_FREE(parent);
1475 if (ret < (off_t)smb_fname_src->st.st_ex_size) {
1476 status = NT_STATUS_DISK_FULL;
1477 goto out;
1479 out:
1480 if (!NT_STATUS_IS_OK(status)) {
1481 DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
1482 nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
1483 smb_fname_str_dbg(smb_fname_dst)));
1486 return status;
1489 /****************************************************************************
1490 Reply to a NT rename request.
1491 ****************************************************************************/
1493 void reply_ntrename(struct smb_request *req)
1495 connection_struct *conn = req->conn;
1496 struct smb_filename *smb_fname_old = NULL;
1497 struct smb_filename *smb_fname_new = NULL;
1498 char *oldname = NULL;
1499 char *newname = NULL;
1500 const char *p;
1501 NTSTATUS status;
1502 bool src_has_wcard = False;
1503 bool dest_has_wcard = False;
1504 uint32 attrs;
1505 uint32_t ucf_flags_src = 0;
1506 uint32_t ucf_flags_dst = 0;
1507 uint16 rename_type;
1508 TALLOC_CTX *ctx = talloc_tos();
1509 bool stream_rename = false;
1511 START_PROFILE(SMBntrename);
1513 if (req->wct < 4) {
1514 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1515 goto out;
1518 attrs = SVAL(req->vwv+0, 0);
1519 rename_type = SVAL(req->vwv+1, 0);
1521 p = (const char *)req->buf + 1;
1522 p += srvstr_get_path_req_wcard(ctx, req, &oldname, p, STR_TERMINATE,
1523 &status, &src_has_wcard);
1524 if (!NT_STATUS_IS_OK(status)) {
1525 reply_nterror(req, status);
1526 goto out;
1529 if (ms_has_wild(oldname)) {
1530 reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
1531 goto out;
1534 p++;
1535 p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
1536 &status, &dest_has_wcard);
1537 if (!NT_STATUS_IS_OK(status)) {
1538 reply_nterror(req, status);
1539 goto out;
1542 if (!lp_posix_pathnames()) {
1543 /* The newname must begin with a ':' if the
1544 oldname contains a ':'. */
1545 if (strchr_m(oldname, ':')) {
1546 if (newname[0] != ':') {
1547 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1548 goto out;
1550 stream_rename = true;
1555 * If this is a rename operation, allow wildcards and save the
1556 * destination's last component.
1558 if (rename_type == RENAME_FLAG_RENAME) {
1559 ucf_flags_src = UCF_COND_ALLOW_WCARD_LCOMP;
1560 ucf_flags_dst = UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP;
1563 /* rename_internals() calls unix_convert(), so don't call it here. */
1564 status = filename_convert(ctx, conn,
1565 req->flags2 & FLAGS2_DFS_PATHNAMES,
1566 oldname,
1567 ucf_flags_src,
1568 NULL,
1569 &smb_fname_old);
1570 if (!NT_STATUS_IS_OK(status)) {
1571 if (NT_STATUS_EQUAL(status,
1572 NT_STATUS_PATH_NOT_COVERED)) {
1573 reply_botherror(req,
1574 NT_STATUS_PATH_NOT_COVERED,
1575 ERRSRV, ERRbadpath);
1576 goto out;
1578 reply_nterror(req, status);
1579 goto out;
1582 status = filename_convert(ctx, conn,
1583 req->flags2 & FLAGS2_DFS_PATHNAMES,
1584 newname,
1585 ucf_flags_dst,
1586 &dest_has_wcard,
1587 &smb_fname_new);
1588 if (!NT_STATUS_IS_OK(status)) {
1589 if (NT_STATUS_EQUAL(status,
1590 NT_STATUS_PATH_NOT_COVERED)) {
1591 reply_botherror(req,
1592 NT_STATUS_PATH_NOT_COVERED,
1593 ERRSRV, ERRbadpath);
1594 goto out;
1596 reply_nterror(req, status);
1597 goto out;
1600 if (stream_rename) {
1601 /* smb_fname_new must be the same as smb_fname_old. */
1602 TALLOC_FREE(smb_fname_new->base_name);
1603 smb_fname_new->base_name = talloc_strdup(smb_fname_new,
1604 smb_fname_old->base_name);
1605 if (!smb_fname_new->base_name) {
1606 reply_nterror(req, NT_STATUS_NO_MEMORY);
1607 goto out;
1611 DEBUG(3,("reply_ntrename: %s -> %s\n",
1612 smb_fname_str_dbg(smb_fname_old),
1613 smb_fname_str_dbg(smb_fname_new)));
1615 switch(rename_type) {
1616 case RENAME_FLAG_RENAME:
1617 status = rename_internals(ctx, conn, req,
1618 smb_fname_old, smb_fname_new,
1619 attrs, False, src_has_wcard,
1620 dest_has_wcard,
1621 DELETE_ACCESS);
1622 break;
1623 case RENAME_FLAG_HARD_LINK:
1624 if (src_has_wcard || dest_has_wcard) {
1625 /* No wildcards. */
1626 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1627 } else {
1628 status = hardlink_internals(ctx, conn,
1629 req,
1630 false,
1631 smb_fname_old,
1632 smb_fname_new);
1634 break;
1635 case RENAME_FLAG_COPY:
1636 if (src_has_wcard || dest_has_wcard) {
1637 /* No wildcards. */
1638 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1639 } else {
1640 status = copy_internals(ctx, conn, req,
1641 smb_fname_old,
1642 smb_fname_new,
1643 attrs);
1645 break;
1646 case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
1647 status = NT_STATUS_INVALID_PARAMETER;
1648 break;
1649 default:
1650 status = NT_STATUS_ACCESS_DENIED; /* Default error. */
1651 break;
1654 if (!NT_STATUS_IS_OK(status)) {
1655 if (open_was_deferred(req->sconn, req->mid)) {
1656 /* We have re-scheduled this call. */
1657 goto out;
1660 reply_nterror(req, status);
1661 goto out;
1664 reply_outbuf(req, 0, 0);
1665 out:
1666 END_PROFILE(SMBntrename);
1667 return;
1670 /****************************************************************************
1671 Reply to a notify change - queue the request and
1672 don't allow a directory to be opened.
1673 ****************************************************************************/
1675 static void smbd_smb1_notify_reply(struct smb_request *req,
1676 NTSTATUS error_code,
1677 uint8_t *buf, size_t len)
1679 send_nt_replies(req->conn, req, error_code, (char *)buf, len, NULL, 0);
1682 static void call_nt_transact_notify_change(connection_struct *conn,
1683 struct smb_request *req,
1684 uint16 **ppsetup,
1685 uint32 setup_count,
1686 char **ppparams,
1687 uint32 parameter_count,
1688 char **ppdata, uint32 data_count,
1689 uint32 max_data_count,
1690 uint32 max_param_count)
1692 uint16 *setup = *ppsetup;
1693 files_struct *fsp;
1694 uint32 filter;
1695 NTSTATUS status;
1696 bool recursive;
1698 if(setup_count < 6) {
1699 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1700 return;
1703 fsp = file_fsp(req, SVAL(setup,4));
1704 filter = IVAL(setup, 0);
1705 recursive = (SVAL(setup, 6) != 0) ? True : False;
1707 DEBUG(3,("call_nt_transact_notify_change\n"));
1709 if(!fsp) {
1710 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1711 return;
1715 char *filter_string;
1717 if (!(filter_string = notify_filter_string(NULL, filter))) {
1718 reply_nterror(req,NT_STATUS_NO_MEMORY);
1719 return;
1722 DEBUG(3,("call_nt_transact_notify_change: notify change "
1723 "called on %s, filter = %s, recursive = %d\n",
1724 fsp_str_dbg(fsp), filter_string, recursive));
1726 TALLOC_FREE(filter_string);
1729 if((!fsp->is_directory) || (conn != fsp->conn)) {
1730 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1731 return;
1734 if (fsp->notify == NULL) {
1736 status = change_notify_create(fsp, filter, recursive);
1738 if (!NT_STATUS_IS_OK(status)) {
1739 DEBUG(10, ("change_notify_create returned %s\n",
1740 nt_errstr(status)));
1741 reply_nterror(req, status);
1742 return;
1746 if (change_notify_fsp_has_changes(fsp)) {
1749 * We've got changes pending, respond immediately
1753 * TODO: write a torture test to check the filtering behaviour
1754 * here.
1757 change_notify_reply(req,
1758 NT_STATUS_OK,
1759 max_param_count,
1760 fsp->notify,
1761 smbd_smb1_notify_reply);
1764 * change_notify_reply() above has independently sent its
1765 * results
1767 return;
1771 * No changes pending, queue the request
1774 status = change_notify_add_request(req,
1775 max_param_count,
1776 filter,
1777 recursive, fsp,
1778 smbd_smb1_notify_reply);
1779 if (!NT_STATUS_IS_OK(status)) {
1780 reply_nterror(req, status);
1782 return;
1785 /****************************************************************************
1786 Reply to an NT transact rename command.
1787 ****************************************************************************/
1789 static void call_nt_transact_rename(connection_struct *conn,
1790 struct smb_request *req,
1791 uint16 **ppsetup, uint32 setup_count,
1792 char **ppparams, uint32 parameter_count,
1793 char **ppdata, uint32 data_count,
1794 uint32 max_data_count)
1796 char *params = *ppparams;
1797 char *new_name = NULL;
1798 files_struct *fsp = NULL;
1799 bool dest_has_wcard = False;
1800 NTSTATUS status;
1801 TALLOC_CTX *ctx = talloc_tos();
1803 if(parameter_count < 5) {
1804 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1805 return;
1808 fsp = file_fsp(req, SVAL(params, 0));
1809 if (!check_fsp(conn, req, fsp)) {
1810 return;
1812 srvstr_get_path_wcard(ctx, params, req->flags2, &new_name, params+4,
1813 parameter_count - 4,
1814 STR_TERMINATE, &status, &dest_has_wcard);
1815 if (!NT_STATUS_IS_OK(status)) {
1816 reply_nterror(req, status);
1817 return;
1821 * W2K3 ignores this request as the RAW-RENAME test
1822 * demonstrates, so we do.
1824 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
1826 DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
1827 fsp_str_dbg(fsp), new_name));
1829 return;
1832 /******************************************************************************
1833 Fake up a completely empty SD.
1834 *******************************************************************************/
1836 static NTSTATUS get_null_nt_acl(TALLOC_CTX *mem_ctx, struct security_descriptor **ppsd)
1838 size_t sd_size;
1840 *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
1841 if(!*ppsd) {
1842 DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
1843 return NT_STATUS_NO_MEMORY;
1846 return NT_STATUS_OK;
1849 /****************************************************************************
1850 Reply to query a security descriptor.
1851 Callable from SMB2 and SMB2.
1852 If it returns NT_STATUS_BUFFER_TOO_SMALL, pdata_size is initialized with
1853 the required size.
1854 ****************************************************************************/
1856 NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
1857 TALLOC_CTX *mem_ctx,
1858 files_struct *fsp,
1859 uint32_t security_info_wanted,
1860 uint32_t max_data_count,
1861 uint8_t **ppmarshalled_sd,
1862 size_t *psd_size)
1864 NTSTATUS status;
1865 struct security_descriptor *psd = NULL;
1868 * Get the permissions to return.
1871 if ((security_info_wanted & SECINFO_SACL) &&
1872 !(fsp->access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
1873 DEBUG(10, ("Access to SACL denied.\n"));
1874 return NT_STATUS_ACCESS_DENIED;
1877 if ((security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|SECINFO_GROUP)) &&
1878 !(fsp->access_mask & SEC_STD_READ_CONTROL)) {
1879 DEBUG(10, ("Access to DACL, OWNER, or GROUP denied.\n"));
1880 return NT_STATUS_ACCESS_DENIED;
1883 if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|
1884 SECINFO_GROUP|SECINFO_SACL)) {
1885 /* Don't return SECINFO_LABEL if anything else was
1886 requested. See bug #8458. */
1887 security_info_wanted &= ~SECINFO_LABEL;
1890 if (!lp_nt_acl_support(SNUM(conn))) {
1891 status = get_null_nt_acl(mem_ctx, &psd);
1892 } else if (security_info_wanted & SECINFO_LABEL) {
1893 /* Like W2K3 return a null object. */
1894 status = get_null_nt_acl(mem_ctx, &psd);
1895 } else {
1896 status = SMB_VFS_FGET_NT_ACL(
1897 fsp, security_info_wanted, &psd);
1899 if (!NT_STATUS_IS_OK(status)) {
1900 return status;
1903 if (!(security_info_wanted & SECINFO_OWNER)) {
1904 psd->owner_sid = NULL;
1906 if (!(security_info_wanted & SECINFO_GROUP)) {
1907 psd->group_sid = NULL;
1909 if (!(security_info_wanted & SECINFO_DACL)) {
1910 psd->type &= ~SEC_DESC_DACL_PRESENT;
1911 psd->dacl = NULL;
1913 if (!(security_info_wanted & SECINFO_SACL)) {
1914 psd->type &= ~SEC_DESC_SACL_PRESENT;
1915 psd->sacl = NULL;
1918 /* If the SACL/DACL is NULL, but was requested, we mark that it is
1919 * present in the reply to match Windows behavior */
1920 if (psd->sacl == NULL &&
1921 security_info_wanted & SECINFO_SACL)
1922 psd->type |= SEC_DESC_SACL_PRESENT;
1923 if (psd->dacl == NULL &&
1924 security_info_wanted & SECINFO_DACL)
1925 psd->type |= SEC_DESC_DACL_PRESENT;
1927 if (security_info_wanted & SECINFO_LABEL) {
1928 /* Like W2K3 return a null object. */
1929 psd->owner_sid = NULL;
1930 psd->group_sid = NULL;
1931 psd->dacl = NULL;
1932 psd->sacl = NULL;
1933 psd->type &= ~(SEC_DESC_DACL_PRESENT|SEC_DESC_SACL_PRESENT);
1936 *psd_size = ndr_size_security_descriptor(psd, 0);
1938 DEBUG(3,("smbd_do_query_security_desc: sd_size = %lu.\n",
1939 (unsigned long)*psd_size));
1941 if (DEBUGLEVEL >= 10) {
1942 DEBUG(10,("smbd_do_query_security_desc for file %s\n",
1943 fsp_str_dbg(fsp)));
1944 NDR_PRINT_DEBUG(security_descriptor, psd);
1947 if (max_data_count < *psd_size) {
1948 TALLOC_FREE(psd);
1949 return NT_STATUS_BUFFER_TOO_SMALL;
1952 status = marshall_sec_desc(mem_ctx, psd,
1953 ppmarshalled_sd, psd_size);
1955 if (!NT_STATUS_IS_OK(status)) {
1956 TALLOC_FREE(psd);
1957 return status;
1960 TALLOC_FREE(psd);
1961 return NT_STATUS_OK;
1964 /****************************************************************************
1965 SMB1 reply to query a security descriptor.
1966 ****************************************************************************/
1968 static void call_nt_transact_query_security_desc(connection_struct *conn,
1969 struct smb_request *req,
1970 uint16 **ppsetup,
1971 uint32 setup_count,
1972 char **ppparams,
1973 uint32 parameter_count,
1974 char **ppdata,
1975 uint32 data_count,
1976 uint32 max_data_count)
1978 char *params = *ppparams;
1979 char *data = *ppdata;
1980 size_t sd_size = 0;
1981 uint32 security_info_wanted;
1982 files_struct *fsp = NULL;
1983 NTSTATUS status;
1984 uint8_t *marshalled_sd = NULL;
1986 if(parameter_count < 8) {
1987 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1988 return;
1991 fsp = file_fsp(req, SVAL(params,0));
1992 if(!fsp) {
1993 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1994 return;
1997 security_info_wanted = IVAL(params,4);
1999 DEBUG(3,("call_nt_transact_query_security_desc: file = %s, "
2000 "info_wanted = 0x%x\n", fsp_str_dbg(fsp),
2001 (unsigned int)security_info_wanted));
2003 params = nttrans_realloc(ppparams, 4);
2004 if(params == NULL) {
2005 reply_nterror(req, NT_STATUS_NO_MEMORY);
2006 return;
2010 * Get the permissions to return.
2013 status = smbd_do_query_security_desc(conn,
2014 talloc_tos(),
2015 fsp,
2016 security_info_wanted,
2017 max_data_count,
2018 &marshalled_sd,
2019 &sd_size);
2021 if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
2022 SIVAL(params,0,(uint32_t)sd_size);
2023 send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
2024 params, 4, NULL, 0);
2025 return;
2028 if (!NT_STATUS_IS_OK(status)) {
2029 reply_nterror(req, status);
2030 return;
2033 SMB_ASSERT(sd_size > 0);
2035 SIVAL(params,0,(uint32_t)sd_size);
2037 if (max_data_count < sd_size) {
2038 send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
2039 params, 4, NULL, 0);
2040 return;
2044 * Allocate the data we will return.
2047 data = nttrans_realloc(ppdata, sd_size);
2048 if(data == NULL) {
2049 reply_nterror(req, NT_STATUS_NO_MEMORY);
2050 return;
2053 memcpy(data, marshalled_sd, sd_size);
2055 send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
2057 return;
2060 /****************************************************************************
2061 Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
2062 ****************************************************************************/
2064 static void call_nt_transact_set_security_desc(connection_struct *conn,
2065 struct smb_request *req,
2066 uint16 **ppsetup,
2067 uint32 setup_count,
2068 char **ppparams,
2069 uint32 parameter_count,
2070 char **ppdata,
2071 uint32 data_count,
2072 uint32 max_data_count)
2074 char *params= *ppparams;
2075 char *data = *ppdata;
2076 files_struct *fsp = NULL;
2077 uint32 security_info_sent = 0;
2078 NTSTATUS status;
2080 if(parameter_count < 8) {
2081 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2082 return;
2085 if((fsp = file_fsp(req, SVAL(params,0))) == NULL) {
2086 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2087 return;
2090 if (!CAN_WRITE(fsp->conn)) {
2091 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2092 return;
2095 if(!lp_nt_acl_support(SNUM(conn))) {
2096 goto done;
2099 security_info_sent = IVAL(params,4);
2101 DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n",
2102 fsp_str_dbg(fsp), (unsigned int)security_info_sent));
2104 if (data_count == 0) {
2105 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2106 return;
2109 status = set_sd(fsp, (uint8 *)data, data_count, security_info_sent);
2111 if (!NT_STATUS_IS_OK(status)) {
2112 reply_nterror(req, status);
2113 return;
2116 done:
2117 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
2118 return;
2121 /****************************************************************************
2122 Reply to NT IOCTL
2123 ****************************************************************************/
2125 static void call_nt_transact_ioctl(connection_struct *conn,
2126 struct smb_request *req,
2127 uint16 **ppsetup, uint32 setup_count,
2128 char **ppparams, uint32 parameter_count,
2129 char **ppdata, uint32 data_count,
2130 uint32 max_data_count)
2132 NTSTATUS status;
2133 uint32 function;
2134 uint16 fidnum;
2135 files_struct *fsp;
2136 uint8 isFSctl;
2137 uint8 compfilter;
2138 char *out_data = NULL;
2139 uint32 out_data_len = 0;
2140 char *pdata = *ppdata;
2141 TALLOC_CTX *ctx = talloc_tos();
2143 if (setup_count != 8) {
2144 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
2145 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2146 return;
2149 function = IVAL(*ppsetup, 0);
2150 fidnum = SVAL(*ppsetup, 4);
2151 isFSctl = CVAL(*ppsetup, 6);
2152 compfilter = CVAL(*ppsetup, 7);
2154 DEBUG(10, ("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
2155 function, fidnum, isFSctl, compfilter));
2157 fsp=file_fsp(req, fidnum);
2160 * We don't really implement IOCTLs, especially on files.
2162 if (!isFSctl) {
2163 DEBUG(10, ("isFSctl: 0x%02X indicates IOCTL, not FSCTL!\n",
2164 isFSctl));
2165 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2166 return;
2169 /* Has to be for an open file! */
2170 if (!check_fsp_open(conn, req, fsp)) {
2171 return;
2174 SMB_PERFCOUNT_SET_IOCTL(&req->pcd, function);
2177 * out_data might be allocated by the VFS module, but talloc should be
2178 * used, and should be cleaned up when the request ends.
2180 status = SMB_VFS_FSCTL(fsp,
2181 ctx,
2182 function,
2183 req->flags2,
2184 (uint8_t *)pdata,
2185 data_count,
2186 (uint8_t **)&out_data,
2187 max_data_count,
2188 &out_data_len);
2189 if (!NT_STATUS_IS_OK(status)) {
2190 reply_nterror(req, status);
2191 } else {
2192 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, out_data, out_data_len);
2197 #ifdef HAVE_SYS_QUOTAS
2198 /****************************************************************************
2199 Reply to get user quota
2200 ****************************************************************************/
2202 static void call_nt_transact_get_user_quota(connection_struct *conn,
2203 struct smb_request *req,
2204 uint16 **ppsetup,
2205 uint32 setup_count,
2206 char **ppparams,
2207 uint32 parameter_count,
2208 char **ppdata,
2209 uint32 data_count,
2210 uint32 max_data_count)
2212 NTSTATUS nt_status = NT_STATUS_OK;
2213 char *params = *ppparams;
2214 char *pdata = *ppdata;
2215 char *entry;
2216 int data_len=0,param_len=0;
2217 int qt_len=0;
2218 int entry_len = 0;
2219 files_struct *fsp = NULL;
2220 uint16 level = 0;
2221 size_t sid_len;
2222 struct dom_sid sid;
2223 bool start_enum = True;
2224 SMB_NTQUOTA_STRUCT qt;
2225 SMB_NTQUOTA_LIST *tmp_list;
2226 SMB_NTQUOTA_HANDLE *qt_handle = NULL;
2228 ZERO_STRUCT(qt);
2230 /* access check */
2231 if (get_current_uid(conn) != 0) {
2232 DEBUG(1,("get_user_quota: access_denied service [%s] user "
2233 "[%s]\n", lp_servicename(SNUM(conn)),
2234 conn->session_info->unix_info->unix_name));
2235 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2236 return;
2240 * Ensure minimum number of parameters sent.
2243 if (parameter_count < 4) {
2244 DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
2245 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2246 return;
2249 /* maybe we can check the quota_fnum */
2250 fsp = file_fsp(req, SVAL(params,0));
2251 if (!check_fsp_ntquota_handle(conn, req, fsp)) {
2252 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2253 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2254 return;
2257 /* the NULL pointer checking for fsp->fake_file_handle->pd
2258 * is done by CHECK_NTQUOTA_HANDLE_OK()
2260 qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->private_data;
2262 level = SVAL(params,2);
2264 /* unknown 12 bytes leading in params */
2266 switch (level) {
2267 case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
2268 /* seems that we should continue with the enum here --metze */
2270 if (qt_handle->quota_list!=NULL &&
2271 qt_handle->tmp_list==NULL) {
2273 /* free the list */
2274 free_ntquota_list(&(qt_handle->quota_list));
2276 /* Realloc the size of parameters and data we will return */
2277 param_len = 4;
2278 params = nttrans_realloc(ppparams, param_len);
2279 if(params == NULL) {
2280 reply_nterror(req, NT_STATUS_NO_MEMORY);
2281 return;
2284 data_len = 0;
2285 SIVAL(params,0,data_len);
2287 break;
2290 start_enum = False;
2292 case TRANSACT_GET_USER_QUOTA_LIST_START:
2294 if (qt_handle->quota_list==NULL &&
2295 qt_handle->tmp_list==NULL) {
2296 start_enum = True;
2299 if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0) {
2300 reply_nterror(req, NT_STATUS_INTERNAL_ERROR);
2301 return;
2304 /* Realloc the size of parameters and data we will return */
2305 param_len = 4;
2306 params = nttrans_realloc(ppparams, param_len);
2307 if(params == NULL) {
2308 reply_nterror(req, NT_STATUS_NO_MEMORY);
2309 return;
2312 /* we should not trust the value in max_data_count*/
2313 max_data_count = MIN(max_data_count,2048);
2315 pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
2316 if(pdata == NULL) {
2317 reply_nterror(req, NT_STATUS_NO_MEMORY);
2318 return;
2321 entry = pdata;
2323 /* set params Size of returned Quota Data 4 bytes*/
2324 /* but set it later when we know it */
2326 /* for each entry push the data */
2328 if (start_enum) {
2329 qt_handle->tmp_list = qt_handle->quota_list;
2332 tmp_list = qt_handle->tmp_list;
2334 for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
2335 tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
2337 sid_len = ndr_size_dom_sid(
2338 &tmp_list->quotas->sid, 0);
2339 entry_len = 40 + sid_len;
2341 /* nextoffset entry 4 bytes */
2342 SIVAL(entry,0,entry_len);
2344 /* then the len of the SID 4 bytes */
2345 SIVAL(entry,4,sid_len);
2347 /* unknown data 8 bytes uint64_t */
2348 SBIG_UINT(entry,8,(uint64_t)0); /* this is not 0 in windows...-metze*/
2350 /* the used disk space 8 bytes uint64_t */
2351 SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
2353 /* the soft quotas 8 bytes uint64_t */
2354 SBIG_UINT(entry,24,tmp_list->quotas->softlim);
2356 /* the hard quotas 8 bytes uint64_t */
2357 SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
2359 /* and now the SID */
2360 sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
2363 qt_handle->tmp_list = tmp_list;
2365 /* overwrite the offset of the last entry */
2366 SIVAL(entry-entry_len,0,0);
2368 data_len = 4+qt_len;
2369 /* overwrite the params quota_data_len */
2370 SIVAL(params,0,data_len);
2372 break;
2374 case TRANSACT_GET_USER_QUOTA_FOR_SID:
2376 /* unknown 4 bytes IVAL(pdata,0) */
2378 if (data_count < 8) {
2379 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
2380 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2381 return;
2384 sid_len = IVAL(pdata,4);
2385 /* Ensure this is less than 1mb. */
2386 if (sid_len > (1024*1024)) {
2387 reply_nterror(req, NT_STATUS_NO_MEMORY);
2388 return;
2391 if (data_count < 8+sid_len) {
2392 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
2393 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2394 return;
2397 data_len = 4+40+sid_len;
2399 if (max_data_count < data_len) {
2400 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
2401 max_data_count, data_len));
2402 param_len = 4;
2403 SIVAL(params,0,data_len);
2404 data_len = 0;
2405 nt_status = NT_STATUS_BUFFER_TOO_SMALL;
2406 break;
2409 if (!sid_parse(pdata+8,sid_len,&sid)) {
2410 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2411 return;
2414 if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2415 ZERO_STRUCT(qt);
2417 * we have to return zero's in all fields
2418 * instead of returning an error here
2419 * --metze
2423 /* Realloc the size of parameters and data we will return */
2424 param_len = 4;
2425 params = nttrans_realloc(ppparams, param_len);
2426 if(params == NULL) {
2427 reply_nterror(req, NT_STATUS_NO_MEMORY);
2428 return;
2431 pdata = nttrans_realloc(ppdata, data_len);
2432 if(pdata == NULL) {
2433 reply_nterror(req, NT_STATUS_NO_MEMORY);
2434 return;
2437 entry = pdata;
2439 /* set params Size of returned Quota Data 4 bytes*/
2440 SIVAL(params,0,data_len);
2442 /* nextoffset entry 4 bytes */
2443 SIVAL(entry,0,0);
2445 /* then the len of the SID 4 bytes */
2446 SIVAL(entry,4,sid_len);
2448 /* unknown data 8 bytes uint64_t */
2449 SBIG_UINT(entry,8,(uint64_t)0); /* this is not 0 in windows...-mezte*/
2451 /* the used disk space 8 bytes uint64_t */
2452 SBIG_UINT(entry,16,qt.usedspace);
2454 /* the soft quotas 8 bytes uint64_t */
2455 SBIG_UINT(entry,24,qt.softlim);
2457 /* the hard quotas 8 bytes uint64_t */
2458 SBIG_UINT(entry,32,qt.hardlim);
2460 /* and now the SID */
2461 sid_linearize(entry+40, sid_len, &sid);
2463 break;
2465 default:
2466 DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
2467 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2468 return;
2469 break;
2472 send_nt_replies(conn, req, nt_status, params, param_len,
2473 pdata, data_len);
2476 /****************************************************************************
2477 Reply to set user quota
2478 ****************************************************************************/
2480 static void call_nt_transact_set_user_quota(connection_struct *conn,
2481 struct smb_request *req,
2482 uint16 **ppsetup,
2483 uint32 setup_count,
2484 char **ppparams,
2485 uint32 parameter_count,
2486 char **ppdata,
2487 uint32 data_count,
2488 uint32 max_data_count)
2490 char *params = *ppparams;
2491 char *pdata = *ppdata;
2492 int data_len=0,param_len=0;
2493 SMB_NTQUOTA_STRUCT qt;
2494 size_t sid_len;
2495 struct dom_sid sid;
2496 files_struct *fsp = NULL;
2498 ZERO_STRUCT(qt);
2500 /* access check */
2501 if (get_current_uid(conn) != 0) {
2502 DEBUG(1,("set_user_quota: access_denied service [%s] user "
2503 "[%s]\n", lp_servicename(SNUM(conn)),
2504 conn->session_info->unix_info->unix_name));
2505 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2506 return;
2510 * Ensure minimum number of parameters sent.
2513 if (parameter_count < 2) {
2514 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
2515 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2516 return;
2519 /* maybe we can check the quota_fnum */
2520 fsp = file_fsp(req, SVAL(params,0));
2521 if (!check_fsp_ntquota_handle(conn, req, fsp)) {
2522 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2523 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2524 return;
2527 if (data_count < 40) {
2528 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
2529 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2530 return;
2533 /* offset to next quota record.
2534 * 4 bytes IVAL(pdata,0)
2535 * unused here...
2538 /* sid len */
2539 sid_len = IVAL(pdata,4);
2541 if (data_count < 40+sid_len || (40+sid_len < sid_len)) {
2542 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
2543 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2544 return;
2547 /* unknown 8 bytes in pdata
2548 * maybe its the change time in NTTIME
2551 /* the used space 8 bytes (uint64_t)*/
2552 qt.usedspace = BVAL(pdata,16);
2554 /* the soft quotas 8 bytes (uint64_t)*/
2555 qt.softlim = BVAL(pdata,24);
2557 /* the hard quotas 8 bytes (uint64_t)*/
2558 qt.hardlim = BVAL(pdata,32);
2560 if (!sid_parse(pdata+40,sid_len,&sid)) {
2561 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2562 return;
2565 DEBUGADD(8,("SID: %s\n", sid_string_dbg(&sid)));
2567 /* 44 unknown bytes left... */
2569 if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2570 reply_nterror(req, NT_STATUS_INTERNAL_ERROR);
2571 return;
2574 send_nt_replies(conn, req, NT_STATUS_OK, params, param_len,
2575 pdata, data_len);
2577 #endif /* HAVE_SYS_QUOTAS */
2579 static void handle_nttrans(connection_struct *conn,
2580 struct trans_state *state,
2581 struct smb_request *req)
2583 if (get_Protocol() >= PROTOCOL_NT1) {
2584 req->flags2 |= 0x40; /* IS_LONG_NAME */
2585 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_flg2,req->flags2);
2589 SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
2591 /* Now we must call the relevant NT_TRANS function */
2592 switch(state->call) {
2593 case NT_TRANSACT_CREATE:
2595 START_PROFILE(NT_transact_create);
2596 call_nt_transact_create(
2597 conn, req,
2598 &state->setup, state->setup_count,
2599 &state->param, state->total_param,
2600 &state->data, state->total_data,
2601 state->max_data_return);
2602 END_PROFILE(NT_transact_create);
2603 break;
2606 case NT_TRANSACT_IOCTL:
2608 START_PROFILE(NT_transact_ioctl);
2609 call_nt_transact_ioctl(
2610 conn, req,
2611 &state->setup, state->setup_count,
2612 &state->param, state->total_param,
2613 &state->data, state->total_data,
2614 state->max_data_return);
2615 END_PROFILE(NT_transact_ioctl);
2616 break;
2619 case NT_TRANSACT_SET_SECURITY_DESC:
2621 START_PROFILE(NT_transact_set_security_desc);
2622 call_nt_transact_set_security_desc(
2623 conn, req,
2624 &state->setup, state->setup_count,
2625 &state->param, state->total_param,
2626 &state->data, state->total_data,
2627 state->max_data_return);
2628 END_PROFILE(NT_transact_set_security_desc);
2629 break;
2632 case NT_TRANSACT_NOTIFY_CHANGE:
2634 START_PROFILE(NT_transact_notify_change);
2635 call_nt_transact_notify_change(
2636 conn, req,
2637 &state->setup, state->setup_count,
2638 &state->param, state->total_param,
2639 &state->data, state->total_data,
2640 state->max_data_return,
2641 state->max_param_return);
2642 END_PROFILE(NT_transact_notify_change);
2643 break;
2646 case NT_TRANSACT_RENAME:
2648 START_PROFILE(NT_transact_rename);
2649 call_nt_transact_rename(
2650 conn, req,
2651 &state->setup, state->setup_count,
2652 &state->param, state->total_param,
2653 &state->data, state->total_data,
2654 state->max_data_return);
2655 END_PROFILE(NT_transact_rename);
2656 break;
2659 case NT_TRANSACT_QUERY_SECURITY_DESC:
2661 START_PROFILE(NT_transact_query_security_desc);
2662 call_nt_transact_query_security_desc(
2663 conn, req,
2664 &state->setup, state->setup_count,
2665 &state->param, state->total_param,
2666 &state->data, state->total_data,
2667 state->max_data_return);
2668 END_PROFILE(NT_transact_query_security_desc);
2669 break;
2672 #ifdef HAVE_SYS_QUOTAS
2673 case NT_TRANSACT_GET_USER_QUOTA:
2675 START_PROFILE(NT_transact_get_user_quota);
2676 call_nt_transact_get_user_quota(
2677 conn, req,
2678 &state->setup, state->setup_count,
2679 &state->param, state->total_param,
2680 &state->data, state->total_data,
2681 state->max_data_return);
2682 END_PROFILE(NT_transact_get_user_quota);
2683 break;
2686 case NT_TRANSACT_SET_USER_QUOTA:
2688 START_PROFILE(NT_transact_set_user_quota);
2689 call_nt_transact_set_user_quota(
2690 conn, req,
2691 &state->setup, state->setup_count,
2692 &state->param, state->total_param,
2693 &state->data, state->total_data,
2694 state->max_data_return);
2695 END_PROFILE(NT_transact_set_user_quota);
2696 break;
2698 #endif /* HAVE_SYS_QUOTAS */
2700 default:
2701 /* Error in request */
2702 DEBUG(0,("handle_nttrans: Unknown request %d in "
2703 "nttrans call\n", state->call));
2704 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2705 return;
2707 return;
2710 /****************************************************************************
2711 Reply to a SMBNTtrans.
2712 ****************************************************************************/
2714 void reply_nttrans(struct smb_request *req)
2716 connection_struct *conn = req->conn;
2717 uint32_t pscnt;
2718 uint32_t psoff;
2719 uint32_t dscnt;
2720 uint32_t dsoff;
2721 uint16 function_code;
2722 NTSTATUS result;
2723 struct trans_state *state;
2725 START_PROFILE(SMBnttrans);
2727 if (req->wct < 19) {
2728 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2729 END_PROFILE(SMBnttrans);
2730 return;
2733 pscnt = IVAL(req->vwv+9, 1);
2734 psoff = IVAL(req->vwv+11, 1);
2735 dscnt = IVAL(req->vwv+13, 1);
2736 dsoff = IVAL(req->vwv+15, 1);
2737 function_code = SVAL(req->vwv+18, 0);
2739 if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
2740 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2741 END_PROFILE(SMBnttrans);
2742 return;
2745 result = allow_new_trans(conn->pending_trans, req->mid);
2746 if (!NT_STATUS_IS_OK(result)) {
2747 DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
2748 reply_nterror(req, result);
2749 END_PROFILE(SMBnttrans);
2750 return;
2753 if ((state = talloc(conn, struct trans_state)) == NULL) {
2754 reply_nterror(req, NT_STATUS_NO_MEMORY);
2755 END_PROFILE(SMBnttrans);
2756 return;
2759 state->cmd = SMBnttrans;
2761 state->mid = req->mid;
2762 state->vuid = req->vuid;
2763 state->total_data = IVAL(req->vwv+3, 1);
2764 state->data = NULL;
2765 state->total_param = IVAL(req->vwv+1, 1);
2766 state->param = NULL;
2767 state->max_data_return = IVAL(req->vwv+7, 1);
2768 state->max_param_return = IVAL(req->vwv+5, 1);
2770 /* setup count is in *words* */
2771 state->setup_count = 2*CVAL(req->vwv+17, 1);
2772 state->setup = NULL;
2773 state->call = function_code;
2775 DEBUG(10, ("num_setup=%u, "
2776 "param_total=%u, this_param=%u, max_param=%u, "
2777 "data_total=%u, this_data=%u, max_data=%u, "
2778 "param_offset=%u, data_offset=%u\n",
2779 (unsigned)state->setup_count,
2780 (unsigned)state->total_param, (unsigned)pscnt,
2781 (unsigned)state->max_param_return,
2782 (unsigned)state->total_data, (unsigned)dscnt,
2783 (unsigned)state->max_data_return,
2784 (unsigned)psoff, (unsigned)dsoff));
2787 * All nttrans messages we handle have smb_wct == 19 +
2788 * state->setup_count. Ensure this is so as a sanity check.
2791 if(req->wct != 19 + (state->setup_count/2)) {
2792 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
2793 req->wct, 19 + (state->setup_count/2)));
2794 goto bad_param;
2797 /* Don't allow more than 128mb for each value. */
2798 if ((state->total_data > (1024*1024*128)) ||
2799 (state->total_param > (1024*1024*128))) {
2800 reply_nterror(req, NT_STATUS_NO_MEMORY);
2801 END_PROFILE(SMBnttrans);
2802 return;
2805 if ((dscnt > state->total_data) || (pscnt > state->total_param))
2806 goto bad_param;
2808 if (state->total_data) {
2810 if (trans_oob(state->total_data, 0, dscnt)
2811 || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
2812 goto bad_param;
2815 /* Can't use talloc here, the core routines do realloc on the
2816 * params and data. */
2817 if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
2818 DEBUG(0,("reply_nttrans: data malloc fail for %u "
2819 "bytes !\n", (unsigned int)state->total_data));
2820 TALLOC_FREE(state);
2821 reply_nterror(req, NT_STATUS_NO_MEMORY);
2822 END_PROFILE(SMBnttrans);
2823 return;
2826 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
2829 if (state->total_param) {
2831 if (trans_oob(state->total_param, 0, pscnt)
2832 || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
2833 goto bad_param;
2836 /* Can't use talloc here, the core routines do realloc on the
2837 * params and data. */
2838 if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
2839 DEBUG(0,("reply_nttrans: param malloc fail for %u "
2840 "bytes !\n", (unsigned int)state->total_param));
2841 SAFE_FREE(state->data);
2842 TALLOC_FREE(state);
2843 reply_nterror(req, NT_STATUS_NO_MEMORY);
2844 END_PROFILE(SMBnttrans);
2845 return;
2848 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
2851 state->received_data = dscnt;
2852 state->received_param = pscnt;
2854 if(state->setup_count > 0) {
2855 DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
2856 state->setup_count));
2859 * No overflow possible here, state->setup_count is an
2860 * unsigned int, being filled by a single byte from
2861 * CVAL(req->vwv+13, 0) above. The cast in the comparison
2862 * below is not necessary, it's here to clarify things. The
2863 * validity of req->vwv and req->wct has been checked in
2864 * init_smb_request already.
2866 if ((state->setup_count/2) + 19 > (unsigned int)req->wct) {
2867 goto bad_param;
2870 state->setup = (uint16 *)TALLOC(state, state->setup_count);
2871 if (state->setup == NULL) {
2872 DEBUG(0,("reply_nttrans : Out of memory\n"));
2873 SAFE_FREE(state->data);
2874 SAFE_FREE(state->param);
2875 TALLOC_FREE(state);
2876 reply_nterror(req, NT_STATUS_NO_MEMORY);
2877 END_PROFILE(SMBnttrans);
2878 return;
2881 memcpy(state->setup, req->vwv+19, state->setup_count);
2882 dump_data(10, (uint8 *)state->setup, state->setup_count);
2885 if ((state->received_data == state->total_data) &&
2886 (state->received_param == state->total_param)) {
2887 handle_nttrans(conn, state, req);
2888 SAFE_FREE(state->param);
2889 SAFE_FREE(state->data);
2890 TALLOC_FREE(state);
2891 END_PROFILE(SMBnttrans);
2892 return;
2895 DLIST_ADD(conn->pending_trans, state);
2897 /* We need to send an interim response then receive the rest
2898 of the parameter/data bytes */
2899 reply_outbuf(req, 0, 0);
2900 show_msg((char *)req->outbuf);
2901 END_PROFILE(SMBnttrans);
2902 return;
2904 bad_param:
2906 DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
2907 SAFE_FREE(state->data);
2908 SAFE_FREE(state->param);
2909 TALLOC_FREE(state);
2910 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2911 END_PROFILE(SMBnttrans);
2912 return;
2915 /****************************************************************************
2916 Reply to a SMBnttranss
2917 ****************************************************************************/
2919 void reply_nttranss(struct smb_request *req)
2921 connection_struct *conn = req->conn;
2922 uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
2923 struct trans_state *state;
2925 START_PROFILE(SMBnttranss);
2927 show_msg((const char *)req->inbuf);
2929 if (req->wct < 18) {
2930 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2931 END_PROFILE(SMBnttranss);
2932 return;
2935 for (state = conn->pending_trans; state != NULL;
2936 state = state->next) {
2937 if (state->mid == req->mid) {
2938 break;
2942 if ((state == NULL) || (state->cmd != SMBnttrans)) {
2943 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2944 END_PROFILE(SMBnttranss);
2945 return;
2948 /* Revise state->total_param and state->total_data in case they have
2949 changed downwards */
2950 if (IVAL(req->vwv+1, 1) < state->total_param) {
2951 state->total_param = IVAL(req->vwv+1, 1);
2953 if (IVAL(req->vwv+3, 1) < state->total_data) {
2954 state->total_data = IVAL(req->vwv+3, 1);
2957 pcnt = IVAL(req->vwv+5, 1);
2958 poff = IVAL(req->vwv+7, 1);
2959 pdisp = IVAL(req->vwv+9, 1);
2961 dcnt = IVAL(req->vwv+11, 1);
2962 doff = IVAL(req->vwv+13, 1);
2963 ddisp = IVAL(req->vwv+15, 1);
2965 state->received_param += pcnt;
2966 state->received_data += dcnt;
2968 if ((state->received_data > state->total_data) ||
2969 (state->received_param > state->total_param))
2970 goto bad_param;
2972 if (pcnt) {
2973 if (trans_oob(state->total_param, pdisp, pcnt)
2974 || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
2975 goto bad_param;
2977 memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,pcnt);
2980 if (dcnt) {
2981 if (trans_oob(state->total_data, ddisp, dcnt)
2982 || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
2983 goto bad_param;
2985 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
2988 if ((state->received_param < state->total_param) ||
2989 (state->received_data < state->total_data)) {
2990 END_PROFILE(SMBnttranss);
2991 return;
2994 handle_nttrans(conn, state, req);
2996 DLIST_REMOVE(conn->pending_trans, state);
2997 SAFE_FREE(state->data);
2998 SAFE_FREE(state->param);
2999 TALLOC_FREE(state);
3000 END_PROFILE(SMBnttranss);
3001 return;
3003 bad_param:
3005 DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
3006 DLIST_REMOVE(conn->pending_trans, state);
3007 SAFE_FREE(state->data);
3008 SAFE_FREE(state->param);
3009 TALLOC_FREE(state);
3010 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3011 END_PROFILE(SMBnttranss);
3012 return;