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/>.
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"
30 #include "smbprofile.h"
31 #include "libsmb/libsmb.h"
32 #include "lib/util_ea.h"
33 #include "librpc/gen_ndr/ndr_quota.h"
34 #include "librpc/gen_ndr/ndr_security.h"
36 extern const struct generic_mapping file_generic_mapping
;
38 static char *nttrans_realloc(char **ptr
, size_t size
)
41 smb_panic("nttrans_realloc() called with NULL ptr");
44 *ptr
= (char *)SMB_REALLOC(*ptr
, size
);
48 memset(*ptr
,'\0',size
);
52 /****************************************************************************
53 Send the required number of replies back.
54 We assume all fields other than the data fields are
55 set correctly for the type of call.
56 HACK ! Always assumes smb_setup field is zero.
57 ****************************************************************************/
59 static void send_nt_replies(connection_struct
*conn
,
60 struct smb_request
*req
, NTSTATUS nt_error
,
61 char *params
, int paramsize
,
62 char *pdata
, int datasize
)
64 int data_to_send
= datasize
;
65 int params_to_send
= paramsize
;
69 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
70 int alignment_offset
= 1;
71 int data_alignment_offset
= 0;
72 struct smbXsrv_connection
*xconn
= req
->xconn
;
73 int max_send
= xconn
->smb1
.sessions
.max_send
;
76 * If there genuinely are no parameters or data to send just send
80 if(params_to_send
== 0 && data_to_send
== 0) {
81 reply_outbuf(req
, 18, 0);
82 if (NT_STATUS_V(nt_error
)) {
83 error_packet_set((char *)req
->outbuf
,
87 show_msg((char *)req
->outbuf
);
88 if (!srv_send_smb(xconn
,
91 IS_CONN_ENCRYPTED(conn
),
93 exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
95 TALLOC_FREE(req
->outbuf
);
100 * When sending params and data ensure that both are nicely aligned.
101 * Only do this alignment when there is also data to send - else
102 * can cause NT redirector problems.
105 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0)) {
106 data_alignment_offset
= 4 - (params_to_send
% 4);
110 * Space is bufsize minus Netbios over TCP header minus SMB header.
111 * The alignment_offset is to align the param bytes on a four byte
112 * boundary (2 bytes for data len, one byte pad).
113 * NT needs this to work correctly.
116 useable_space
= max_send
- (smb_size
119 + data_alignment_offset
);
121 if (useable_space
< 0) {
122 char *msg
= talloc_asprintf(
124 "send_nt_replies failed sanity useable_space = %d!!!",
126 DEBUG(0, ("%s\n", msg
));
127 exit_server_cleanly(msg
);
130 while (params_to_send
|| data_to_send
) {
133 * Calculate whether we will totally or partially fill this packet.
136 total_sent_thistime
= params_to_send
+ data_to_send
;
139 * We can never send more than useable_space.
142 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
);
144 reply_outbuf(req
, 18,
145 total_sent_thistime
+ alignment_offset
146 + data_alignment_offset
);
149 * Set total params and data to be sent.
152 SIVAL(req
->outbuf
,smb_ntr_TotalParameterCount
,paramsize
);
153 SIVAL(req
->outbuf
,smb_ntr_TotalDataCount
,datasize
);
156 * Calculate how many parameters and data we can fit into
157 * this packet. Parameters get precedence.
160 params_sent_thistime
= MIN(params_to_send
,useable_space
);
161 data_sent_thistime
= useable_space
- params_sent_thistime
;
162 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
164 SIVAL(req
->outbuf
, smb_ntr_ParameterCount
,
165 params_sent_thistime
);
167 if(params_sent_thistime
== 0) {
168 SIVAL(req
->outbuf
,smb_ntr_ParameterOffset
,0);
169 SIVAL(req
->outbuf
,smb_ntr_ParameterDisplacement
,0);
172 * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
173 * parameter bytes, however the first 4 bytes of outbuf are
174 * the Netbios over TCP header. Thus use smb_base() to subtract
175 * them from the calculation.
178 SIVAL(req
->outbuf
,smb_ntr_ParameterOffset
,
179 ((smb_buf(req
->outbuf
)+alignment_offset
)
180 - smb_base(req
->outbuf
)));
182 * Absolute displacement of param bytes sent in this packet.
185 SIVAL(req
->outbuf
, smb_ntr_ParameterDisplacement
,
190 * Deal with the data portion.
193 SIVAL(req
->outbuf
, smb_ntr_DataCount
, data_sent_thistime
);
195 if(data_sent_thistime
== 0) {
196 SIVAL(req
->outbuf
,smb_ntr_DataOffset
,0);
197 SIVAL(req
->outbuf
,smb_ntr_DataDisplacement
, 0);
200 * The offset of the data bytes is the offset of the
201 * parameter bytes plus the number of parameters being sent this time.
204 SIVAL(req
->outbuf
, smb_ntr_DataOffset
,
205 ((smb_buf(req
->outbuf
)+alignment_offset
) -
206 smb_base(req
->outbuf
))
207 + params_sent_thistime
+ data_alignment_offset
);
208 SIVAL(req
->outbuf
,smb_ntr_DataDisplacement
, pd
- pdata
);
212 * Copy the param bytes into the packet.
215 if(params_sent_thistime
) {
216 if (alignment_offset
!= 0) {
217 memset(smb_buf(req
->outbuf
), 0,
220 memcpy((smb_buf(req
->outbuf
)+alignment_offset
), pp
,
221 params_sent_thistime
);
225 * Copy in the data bytes
228 if(data_sent_thistime
) {
229 if (data_alignment_offset
!= 0) {
230 memset((smb_buf(req
->outbuf
)+alignment_offset
+
231 params_sent_thistime
), 0,
232 data_alignment_offset
);
234 memcpy(smb_buf(req
->outbuf
)+alignment_offset
235 +params_sent_thistime
+data_alignment_offset
,
236 pd
,data_sent_thistime
);
239 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
240 params_sent_thistime
, data_sent_thistime
, useable_space
));
241 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
242 params_to_send
, data_to_send
, paramsize
, datasize
));
244 if (NT_STATUS_V(nt_error
)) {
245 error_packet_set((char *)req
->outbuf
,
250 /* Send the packet */
251 show_msg((char *)req
->outbuf
);
252 if (!srv_send_smb(xconn
,
255 IS_CONN_ENCRYPTED(conn
),
257 exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
260 TALLOC_FREE(req
->outbuf
);
262 pp
+= params_sent_thistime
;
263 pd
+= data_sent_thistime
;
265 params_to_send
-= params_sent_thistime
;
266 data_to_send
-= data_sent_thistime
;
272 if(params_to_send
< 0 || data_to_send
< 0) {
273 DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
274 params_to_send
, data_to_send
));
275 exit_server_cleanly("send_nt_replies: internal error");
280 /****************************************************************************
281 Reply to an NT create and X call on a pipe
282 ****************************************************************************/
284 static void nt_open_pipe(char *fname
, connection_struct
*conn
,
285 struct smb_request
*req
, uint16_t *ppnum
)
290 DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname
));
292 /* Strip \\ off the name if present. */
293 while (fname
[0] == '\\') {
297 status
= open_np_file(req
, fname
, &fsp
);
298 if (!NT_STATUS_IS_OK(status
)) {
299 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
300 reply_botherror(req
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
304 reply_nterror(req
, status
);
312 /****************************************************************************
313 Reply to an NT create and X call for pipes.
314 ****************************************************************************/
316 static void do_ntcreate_pipe_open(connection_struct
*conn
,
317 struct smb_request
*req
)
320 uint16_t pnum
= FNUM_FIELD_INVALID
;
322 uint32_t flags
= IVAL(req
->vwv
+3, 1);
323 TALLOC_CTX
*ctx
= talloc_tos();
325 srvstr_pull_req_talloc(ctx
, req
, &fname
, req
->buf
, STR_TERMINATE
);
328 reply_botherror(req
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
332 nt_open_pipe(fname
, conn
, req
, &pnum
);
340 * Deal with pipe return.
343 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
344 /* This is very strange. We
345 * return 50 words, but only set
346 * the wcnt to 42 ? It's definitely
347 * what happens on the wire....
349 reply_outbuf(req
, 50, 0);
350 SCVAL(req
->outbuf
,smb_wct
,42);
352 reply_outbuf(req
, 34, 0);
355 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
356 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
358 p
= (char *)req
->outbuf
+ smb_vwv2
;
362 SIVAL(p
,0,FILE_WAS_OPENED
);
365 SIVAL(p
,0,FILE_ATTRIBUTE_NORMAL
); /* File Attributes. */
368 SSVAL(p
,0,FILE_TYPE_MESSAGE_MODE_PIPE
);
370 SSVAL(p
,2, 0x5FF); /* ? */
373 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
375 SIVAL(p
,0,FILE_GENERIC_ALL
);
377 * For pipes W2K3 seems to return
379 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
381 SIVAL(p
,4,(FILE_GENERIC_READ
|FILE_GENERIC_WRITE
)&~FILE_APPEND_DATA
);
384 DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname
));
387 struct case_semantics_state
{
388 connection_struct
*conn
;
391 bool short_case_preserve
;
394 /****************************************************************************
395 Restore case semantics.
396 ****************************************************************************/
398 static int restore_case_semantics(struct case_semantics_state
*state
)
400 state
->conn
->case_sensitive
= state
->case_sensitive
;
401 state
->conn
->case_preserve
= state
->case_preserve
;
402 state
->conn
->short_case_preserve
= state
->short_case_preserve
;
406 /****************************************************************************
408 ****************************************************************************/
410 static struct case_semantics_state
*set_posix_case_semantics(TALLOC_CTX
*mem_ctx
,
411 connection_struct
*conn
)
413 struct case_semantics_state
*result
;
415 if (!(result
= talloc(mem_ctx
, struct case_semantics_state
))) {
420 result
->case_sensitive
= conn
->case_sensitive
;
421 result
->case_preserve
= conn
->case_preserve
;
422 result
->short_case_preserve
= conn
->short_case_preserve
;
425 conn
->case_sensitive
= True
;
426 conn
->case_preserve
= True
;
427 conn
->short_case_preserve
= True
;
429 talloc_set_destructor(result
, restore_case_semantics
);
435 * Calculate the full path name given a relative fid.
437 static NTSTATUS
get_relative_fid_filename(connection_struct
*conn
,
438 struct smb_request
*req
,
439 uint16_t root_dir_fid
,
443 struct files_struct
*dir_fsp
= NULL
;
444 char *new_path
= NULL
;
446 if (root_dir_fid
== 0 || path
== NULL
) {
447 return NT_STATUS_INTERNAL_ERROR
;
450 dir_fsp
= file_fsp(req
, root_dir_fid
);
451 if (dir_fsp
== NULL
) {
452 return NT_STATUS_INVALID_HANDLE
;
455 if (is_ntfs_stream_smb_fname(dir_fsp
->fsp_name
)) {
456 return NT_STATUS_INVALID_HANDLE
;
459 if (!dir_fsp
->fsp_flags
.is_directory
) {
461 * Check to see if this is a mac fork of some kind.
463 if (conn
->fs_capabilities
& FILE_NAMED_STREAMS
) {
466 stream
= strchr_m(path
, ':');
467 if (stream
!= NULL
) {
468 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
473 * We need to handle the case when we get a relative open
474 * relative to a file and the pathname is blank - this is a
475 * reopen! (hint from demyn plantenberg)
477 return NT_STATUS_INVALID_HANDLE
;
480 if (ISDOT(dir_fsp
->fsp_name
->base_name
)) {
482 * We're at the toplevel dir, the final file name
483 * must not contain ./, as this is filtered out
484 * normally by srvstr_get_path and unix_convert
485 * explicitly rejects paths containing ./.
487 new_path
= talloc_strdup(talloc_tos(), path
);
490 * Copy in the base directory name.
493 new_path
= talloc_asprintf(talloc_tos(),
495 dir_fsp
->fsp_name
->base_name
,
498 if (new_path
== NULL
) {
499 return NT_STATUS_NO_MEMORY
;
502 *path_out
= new_path
;
506 /****************************************************************************
507 Reply to an NT create and X call.
508 ****************************************************************************/
510 void reply_ntcreate_and_X(struct smb_request
*req
)
512 connection_struct
*conn
= req
->conn
;
513 struct smb_filename
*smb_fname
= NULL
;
516 uint32_t access_mask
;
517 uint32_t file_attributes
;
518 uint32_t share_access
;
519 uint32_t create_disposition
;
520 uint32_t create_options
;
521 uint16_t root_dir_fid
;
522 uint64_t allocation_size
;
523 /* Breakout the oplock request bits so we can set the
524 reply bits separately. */
528 files_struct
*fsp
= NULL
;
530 struct timespec create_timespec
;
531 struct timespec c_timespec
;
532 struct timespec a_timespec
;
533 struct timespec m_timespec
;
536 uint8_t oplock_granted
= NO_OPLOCK_RETURN
;
537 struct case_semantics_state
*case_state
= NULL
;
539 TALLOC_CTX
*ctx
= talloc_tos();
541 START_PROFILE(SMBntcreateX
);
544 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
548 flags
= IVAL(req
->vwv
+3, 1);
549 access_mask
= IVAL(req
->vwv
+7, 1);
550 file_attributes
= IVAL(req
->vwv
+13, 1);
551 share_access
= IVAL(req
->vwv
+15, 1);
552 create_disposition
= IVAL(req
->vwv
+17, 1);
553 create_options
= IVAL(req
->vwv
+19, 1);
554 root_dir_fid
= (uint16_t)IVAL(req
->vwv
+5, 1);
556 allocation_size
= BVAL(req
->vwv
+9, 1);
558 srvstr_get_path_req(ctx
, req
, &fname
, (const char *)req
->buf
,
559 STR_TERMINATE
, &status
);
561 if (!NT_STATUS_IS_OK(status
)) {
562 reply_nterror(req
, status
);
566 DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
567 "file_attributes = 0x%x, share_access = 0x%x, "
568 "create_disposition = 0x%x create_options = 0x%x "
569 "root_dir_fid = 0x%x, fname = %s\n",
571 (unsigned int)access_mask
,
572 (unsigned int)file_attributes
,
573 (unsigned int)share_access
,
574 (unsigned int)create_disposition
,
575 (unsigned int)create_options
,
576 (unsigned int)root_dir_fid
,
580 * we need to remove ignored bits when they come directly from the client
581 * because we reuse some of them for internal stuff
583 create_options
&= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK
;
586 * If it's an IPC, use the pipe handler.
590 if (lp_nt_pipe_support()) {
591 do_ntcreate_pipe_open(conn
, req
);
594 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
598 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
599 if (oplock_request
) {
600 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
)
604 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
605 case_state
= set_posix_case_semantics(ctx
, conn
);
607 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
612 if (root_dir_fid
!= 0) {
613 char *new_fname
= NULL
;
615 status
= get_relative_fid_filename(conn
,
620 if (!NT_STATUS_IS_OK(status
)) {
621 reply_nterror(req
, status
);
627 ucf_flags
= filename_create_ucf_flags(req
, create_disposition
);
628 status
= filename_convert(ctx
,
635 TALLOC_FREE(case_state
);
637 if (!NT_STATUS_IS_OK(status
)) {
638 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
640 NT_STATUS_PATH_NOT_COVERED
,
644 reply_nterror(req
, status
);
649 * Bug #6898 - clients using Windows opens should
650 * never be able to set this attribute into the
653 file_attributes
&= ~FILE_FLAG_POSIX_SEMANTICS
;
655 status
= SMB_VFS_CREATE_FILE(
658 smb_fname
, /* fname */
659 access_mask
, /* access_mask */
660 share_access
, /* share_access */
661 create_disposition
, /* create_disposition*/
662 create_options
, /* create_options */
663 file_attributes
, /* file_attributes */
664 oplock_request
, /* oplock_request */
666 allocation_size
, /* allocation_size */
667 0, /* private_flags */
672 NULL
, NULL
); /* create context */
674 if (!NT_STATUS_IS_OK(status
)) {
675 if (open_was_deferred(req
->xconn
, req
->mid
)) {
676 /* We have re-scheduled this call, no error. */
679 if (NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
680 bool ok
= defer_smb1_sharing_violation(req
);
685 reply_openerror(req
, status
);
689 /* Ensure we're pointing at the correct stat struct. */
690 TALLOC_FREE(smb_fname
);
691 smb_fname
= fsp
->fsp_name
;
694 * If the caller set the extended oplock request bit
695 * and we granted one (by whatever means) - set the
696 * correct bit for extended oplock reply.
699 if (oplock_request
&&
700 (lp_fake_oplocks(SNUM(conn
))
701 || EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
))) {
704 * Exclusive oplock granted
707 if (flags
& REQUEST_BATCH_OPLOCK
) {
708 oplock_granted
= BATCH_OPLOCK_RETURN
;
710 oplock_granted
= EXCLUSIVE_OPLOCK_RETURN
;
712 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
713 oplock_granted
= LEVEL_II_OPLOCK_RETURN
;
715 oplock_granted
= NO_OPLOCK_RETURN
;
718 file_len
= smb_fname
->st
.st_ex_size
;
720 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
721 /* This is very strange. We
722 * return 50 words, but only set
723 * the wcnt to 42 ? It's definitely
724 * what happens on the wire....
726 reply_outbuf(req
, 50, 0);
727 SCVAL(req
->outbuf
,smb_wct
,42);
729 reply_outbuf(req
, 34, 0);
732 SSVAL(req
->outbuf
, smb_vwv0
, 0xff); /* andx chain ends */
733 SSVAL(req
->outbuf
, smb_vwv1
, 0); /* no andx offset */
735 p
= (char *)req
->outbuf
+ smb_vwv2
;
737 SCVAL(p
, 0, oplock_granted
);
740 SSVAL(p
,0,fsp
->fnum
);
742 if ((create_disposition
== FILE_SUPERSEDE
)
743 && (info
== FILE_WAS_OVERWRITTEN
)) {
744 SIVAL(p
,0,FILE_WAS_SUPERSEDED
);
750 fattr
= fdos_mode(fsp
);
752 fattr
= FILE_ATTRIBUTE_NORMAL
;
756 create_timespec
= get_create_timespec(conn
, fsp
, smb_fname
);
757 a_timespec
= smb_fname
->st
.st_ex_atime
;
758 m_timespec
= smb_fname
->st
.st_ex_mtime
;
759 c_timespec
= get_change_timespec(conn
, fsp
, smb_fname
);
761 if (lp_dos_filetime_resolution(SNUM(conn
))) {
762 dos_filetime_timespec(&create_timespec
);
763 dos_filetime_timespec(&a_timespec
);
764 dos_filetime_timespec(&m_timespec
);
765 dos_filetime_timespec(&c_timespec
);
768 put_long_date_full_timespec(conn
->ts_res
, p
, &create_timespec
); /* create time. */
770 put_long_date_full_timespec(conn
->ts_res
, p
, &a_timespec
); /* access time */
772 put_long_date_full_timespec(conn
->ts_res
, p
, &m_timespec
); /* write time */
774 put_long_date_full_timespec(conn
->ts_res
, p
, &c_timespec
); /* change time */
776 SIVAL(p
,0,fattr
); /* File Attributes. */
778 SOFF_T(p
, 0, SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,&smb_fname
->st
));
780 SOFF_T(p
,0,file_len
);
782 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
783 uint16_t file_status
= (NO_EAS
|NO_SUBSTREAMS
|NO_REPARSETAG
);
784 unsigned int num_streams
= 0;
785 struct stream_struct
*streams
= NULL
;
787 if (lp_ea_support(SNUM(conn
))) {
788 size_t num_names
= 0;
789 /* Do we have any EA's ? */
790 status
= get_ea_names_from_fsp(
791 ctx
, smb_fname
->fsp
, NULL
, &num_names
);
792 if (NT_STATUS_IS_OK(status
) && num_names
) {
793 file_status
&= ~NO_EAS
;
797 status
= vfs_fstreaminfo(smb_fname
->fsp
, ctx
,
798 &num_streams
, &streams
);
799 /* There is always one stream, ::$DATA. */
800 if (NT_STATUS_IS_OK(status
) && num_streams
> 1) {
801 file_status
&= ~NO_SUBSTREAMS
;
803 TALLOC_FREE(streams
);
804 SSVAL(p
,2,file_status
);
807 SCVAL(p
,0,fsp
->fsp_flags
.is_directory
? 1 : 0);
809 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
812 if (fsp
->fsp_flags
.is_directory
||
813 fsp
->fsp_flags
.can_write
||
814 can_write_to_fsp(fsp
))
816 perms
= FILE_GENERIC_ALL
;
818 perms
= FILE_GENERIC_READ
|FILE_EXECUTE
;
823 DEBUG(5,("reply_ntcreate_and_X: %s, open name = %s\n",
824 fsp_fnum_dbg(fsp
), smb_fname_str_dbg(smb_fname
)));
827 END_PROFILE(SMBntcreateX
);
831 /****************************************************************************
832 Reply to a NT_TRANSACT_CREATE call to open a pipe.
833 ****************************************************************************/
835 static void do_nt_transact_create_pipe(connection_struct
*conn
,
836 struct smb_request
*req
,
837 uint16_t **ppsetup
, uint32_t setup_count
,
838 char **ppparams
, uint32_t parameter_count
,
839 char **ppdata
, uint32_t data_count
)
842 char *params
= *ppparams
;
843 uint16_t pnum
= FNUM_FIELD_INVALID
;
848 TALLOC_CTX
*ctx
= talloc_tos();
851 * Ensure minimum number of parameters sent.
854 if(parameter_count
< 54) {
855 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count
));
856 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
860 flags
= IVAL(params
,0);
862 if (req
->posix_pathnames
) {
863 srvstr_get_path_posix(ctx
,
881 if (!NT_STATUS_IS_OK(status
)) {
882 reply_nterror(req
, status
);
886 nt_open_pipe(fname
, conn
, req
, &pnum
);
893 /* Realloc the size of parameters and data we will return */
894 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
895 /* Extended response is 32 more byyes. */
900 params
= nttrans_realloc(ppparams
, param_len
);
902 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
907 SCVAL(p
,0,NO_OPLOCK_RETURN
);
912 SIVAL(p
,0,FILE_WAS_OPENED
);
916 SIVAL(p
,0,FILE_ATTRIBUTE_NORMAL
); /* File Attributes. */
919 SSVAL(p
,0,FILE_TYPE_MESSAGE_MODE_PIPE
);
921 SSVAL(p
,2, 0x5FF); /* ? */
924 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
926 SIVAL(p
,0,FILE_GENERIC_ALL
);
928 * For pipes W2K3 seems to return
930 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
932 SIVAL(p
,4,(FILE_GENERIC_READ
|FILE_GENERIC_WRITE
)&~FILE_APPEND_DATA
);
935 DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname
));
937 /* Send the required number of replies */
938 send_nt_replies(conn
, req
, NT_STATUS_OK
, params
, param_len
, *ppdata
, 0);
943 /*********************************************************************
944 Windows seems to do canonicalization of inheritance bits. Do the
946 *********************************************************************/
948 static void canonicalize_inheritance_bits(struct files_struct
*fsp
,
949 struct security_descriptor
*psd
)
951 bool set_auto_inherited
= false;
954 * We need to filter out the
955 * SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ
956 * bits. If both are set we store SEC_DESC_DACL_AUTO_INHERITED
957 * as this alters whether SEC_ACE_FLAG_INHERITED_ACE is set
958 * when an ACE is inherited. Otherwise we zero these bits out.
961 * http://social.msdn.microsoft.com/Forums/eu/os_fileservices/thread/11f77b68-731e-407d-b1b3-064750716531
966 if (!lp_acl_flag_inherited_canonicalization(SNUM(fsp
->conn
))) {
967 psd
->type
&= ~SEC_DESC_DACL_AUTO_INHERIT_REQ
;
971 if ((psd
->type
& (SEC_DESC_DACL_AUTO_INHERITED
|SEC_DESC_DACL_AUTO_INHERIT_REQ
))
972 == (SEC_DESC_DACL_AUTO_INHERITED
|SEC_DESC_DACL_AUTO_INHERIT_REQ
)) {
973 set_auto_inherited
= true;
976 psd
->type
&= ~(SEC_DESC_DACL_AUTO_INHERITED
|SEC_DESC_DACL_AUTO_INHERIT_REQ
);
977 if (set_auto_inherited
) {
978 psd
->type
|= SEC_DESC_DACL_AUTO_INHERITED
;
982 /****************************************************************************
983 Internal fn to set security descriptors.
984 ****************************************************************************/
986 NTSTATUS
set_sd(files_struct
*fsp
, struct security_descriptor
*psd
,
987 uint32_t security_info_sent
)
989 files_struct
*sd_fsp
= fsp
;
992 if (!CAN_WRITE(fsp
->conn
)) {
993 return NT_STATUS_ACCESS_DENIED
;
996 if (!lp_nt_acl_support(SNUM(fsp
->conn
))) {
1000 status
= refuse_symlink_fsp(fsp
);
1001 if (!NT_STATUS_IS_OK(status
)) {
1002 DBG_DEBUG("ACL set on symlink %s denied.\n",
1007 if (psd
->owner_sid
== NULL
) {
1008 security_info_sent
&= ~SECINFO_OWNER
;
1010 if (psd
->group_sid
== NULL
) {
1011 security_info_sent
&= ~SECINFO_GROUP
;
1014 /* Ensure we have at least one thing set. */
1015 if ((security_info_sent
& (SECINFO_OWNER
|SECINFO_GROUP
|SECINFO_DACL
|SECINFO_SACL
)) == 0) {
1016 /* Just like W2K3 */
1017 return NT_STATUS_OK
;
1020 /* Ensure we have the rights to do this. */
1021 if (security_info_sent
& SECINFO_OWNER
) {
1022 if (!(fsp
->access_mask
& SEC_STD_WRITE_OWNER
)) {
1023 return NT_STATUS_ACCESS_DENIED
;
1027 if (security_info_sent
& SECINFO_GROUP
) {
1028 if (!(fsp
->access_mask
& SEC_STD_WRITE_OWNER
)) {
1029 return NT_STATUS_ACCESS_DENIED
;
1033 if (security_info_sent
& SECINFO_DACL
) {
1034 if (!(fsp
->access_mask
& SEC_STD_WRITE_DAC
)) {
1035 return NT_STATUS_ACCESS_DENIED
;
1037 /* Convert all the generic bits. */
1039 security_acl_map_generic(psd
->dacl
, &file_generic_mapping
);
1043 if (security_info_sent
& SECINFO_SACL
) {
1044 if (!(fsp
->access_mask
& SEC_FLAG_SYSTEM_SECURITY
)) {
1045 return NT_STATUS_ACCESS_DENIED
;
1048 * Setting a SACL also requires WRITE_DAC.
1049 * See the smbtorture3 SMB2-SACL test.
1051 if (!(fsp
->access_mask
& SEC_STD_WRITE_DAC
)) {
1052 return NT_STATUS_ACCESS_DENIED
;
1054 /* Convert all the generic bits. */
1056 security_acl_map_generic(psd
->sacl
, &file_generic_mapping
);
1060 canonicalize_inheritance_bits(fsp
, psd
);
1062 if (DEBUGLEVEL
>= 10) {
1063 DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp
)));
1064 NDR_PRINT_DEBUG(security_descriptor
, psd
);
1067 if (fsp
->base_fsp
!= NULL
) {
1069 * This is a stream handle. Use
1070 * the underlying pathref handle.
1072 sd_fsp
= fsp
->base_fsp
;
1074 status
= SMB_VFS_FSET_NT_ACL(sd_fsp
, security_info_sent
, psd
);
1081 /****************************************************************************
1082 Internal fn to set security descriptors from a data blob.
1083 ****************************************************************************/
1085 NTSTATUS
set_sd_blob(files_struct
*fsp
, uint8_t *data
, uint32_t sd_len
,
1086 uint32_t security_info_sent
)
1088 struct security_descriptor
*psd
= NULL
;
1092 return NT_STATUS_INVALID_PARAMETER
;
1095 status
= unmarshall_sec_desc(talloc_tos(), data
, sd_len
, &psd
);
1097 if (!NT_STATUS_IS_OK(status
)) {
1101 return set_sd(fsp
, psd
, security_info_sent
);
1104 /****************************************************************************
1105 Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
1106 ****************************************************************************/
1108 static void call_nt_transact_create(connection_struct
*conn
,
1109 struct smb_request
*req
,
1110 uint16_t **ppsetup
, uint32_t setup_count
,
1111 char **ppparams
, uint32_t parameter_count
,
1112 char **ppdata
, uint32_t data_count
,
1113 uint32_t max_data_count
)
1115 struct smb_filename
*smb_fname
= NULL
;
1117 char *params
= *ppparams
;
1118 char *data
= *ppdata
;
1119 /* Breakout the oplock request bits so we can set the reply bits separately. */
1123 files_struct
*fsp
= NULL
;
1126 uint32_t access_mask
;
1127 uint32_t file_attributes
;
1128 uint32_t share_access
;
1129 uint32_t create_disposition
;
1130 uint32_t create_options
;
1132 struct security_descriptor
*sd
= NULL
;
1134 uint16_t root_dir_fid
;
1135 struct timespec create_timespec
;
1136 struct timespec c_timespec
;
1137 struct timespec a_timespec
;
1138 struct timespec m_timespec
;
1139 struct ea_list
*ea_list
= NULL
;
1142 uint64_t allocation_size
;
1144 uint8_t oplock_granted
;
1145 struct case_semantics_state
*case_state
= NULL
;
1147 TALLOC_CTX
*ctx
= talloc_tos();
1149 DEBUG(5,("call_nt_transact_create\n"));
1152 * If it's an IPC, use the pipe handler.
1156 if (lp_nt_pipe_support()) {
1157 do_nt_transact_create_pipe(
1159 ppsetup
, setup_count
,
1160 ppparams
, parameter_count
,
1161 ppdata
, data_count
);
1164 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1169 * Ensure minimum number of parameters sent.
1172 if(parameter_count
< 54) {
1173 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count
));
1174 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1178 flags
= IVAL(params
,0);
1179 access_mask
= IVAL(params
,8);
1180 file_attributes
= IVAL(params
,20);
1181 share_access
= IVAL(params
,24);
1182 create_disposition
= IVAL(params
,28);
1183 create_options
= IVAL(params
,32);
1184 sd_len
= IVAL(params
,36);
1185 ea_len
= IVAL(params
,40);
1186 root_dir_fid
= (uint16_t)IVAL(params
,4);
1187 allocation_size
= BVAL(params
,12);
1190 * we need to remove ignored bits when they come directly from the client
1191 * because we reuse some of them for internal stuff
1193 create_options
&= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK
;
1195 if (req
->posix_pathnames
) {
1196 srvstr_get_path_posix(ctx
,
1205 srvstr_get_path(ctx
,
1214 if (!NT_STATUS_IS_OK(status
)) {
1215 reply_nterror(req
, status
);
1219 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
1220 case_state
= set_posix_case_semantics(ctx
, conn
);
1222 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1227 if (root_dir_fid
!= 0) {
1228 char *new_fname
= NULL
;
1230 status
= get_relative_fid_filename(conn
,
1235 if (!NT_STATUS_IS_OK(status
)) {
1236 reply_nterror(req
, status
);
1242 ucf_flags
= filename_create_ucf_flags(req
, create_disposition
);
1243 status
= filename_convert(ctx
,
1250 TALLOC_FREE(case_state
);
1252 if (!NT_STATUS_IS_OK(status
)) {
1253 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1254 reply_botherror(req
,
1255 NT_STATUS_PATH_NOT_COVERED
,
1256 ERRSRV
, ERRbadpath
);
1259 reply_nterror(req
, status
);
1263 /* Ensure the data_len is correct for the sd and ea values given. */
1264 if ((ea_len
+ sd_len
> data_count
)
1265 || (ea_len
> data_count
) || (sd_len
> data_count
)
1266 || (ea_len
+ sd_len
< ea_len
) || (ea_len
+ sd_len
< sd_len
)) {
1267 DEBUG(10, ("call_nt_transact_create - ea_len = %u, sd_len = "
1268 "%u, data_count = %u\n", (unsigned int)ea_len
,
1269 (unsigned int)sd_len
, (unsigned int)data_count
));
1270 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1275 DEBUG(10, ("call_nt_transact_create - sd_len = %d\n",
1278 status
= unmarshall_sec_desc(ctx
, (uint8_t *)data
, sd_len
,
1280 if (!NT_STATUS_IS_OK(status
)) {
1281 DEBUG(10, ("call_nt_transact_create: "
1282 "unmarshall_sec_desc failed: %s\n",
1283 nt_errstr(status
)));
1284 reply_nterror(req
, status
);
1290 if (!lp_ea_support(SNUM(conn
))) {
1291 DEBUG(10, ("call_nt_transact_create - ea_len = %u but "
1292 "EA's not supported.\n",
1293 (unsigned int)ea_len
));
1294 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
1299 DEBUG(10,("call_nt_transact_create - ea_len = %u - "
1300 "too small (should be more than 10)\n",
1301 (unsigned int)ea_len
));
1302 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1306 /* We have already checked that ea_len <= data_count here. */
1307 ea_list
= read_nttrans_ea_list(talloc_tos(), data
+ sd_len
,
1309 if (ea_list
== NULL
) {
1310 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1314 if (!req
->posix_pathnames
&&
1315 ea_list_has_invalid_name(ea_list
)) {
1316 /* Realloc the size of parameters and data we will return */
1317 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
1318 /* Extended response is 32 more byyes. */
1323 params
= nttrans_realloc(ppparams
, param_len
);
1324 if(params
== NULL
) {
1325 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1329 memset(params
, '\0', param_len
);
1330 send_nt_replies(conn
, req
, STATUS_INVALID_EA_NAME
,
1331 params
, param_len
, NULL
, 0);
1336 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
1337 if (oplock_request
) {
1338 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
)
1343 * Bug #6898 - clients using Windows opens should
1344 * never be able to set this attribute into the
1347 file_attributes
&= ~FILE_FLAG_POSIX_SEMANTICS
;
1349 status
= SMB_VFS_CREATE_FILE(
1352 smb_fname
, /* fname */
1353 access_mask
, /* access_mask */
1354 share_access
, /* share_access */
1355 create_disposition
, /* create_disposition*/
1356 create_options
, /* create_options */
1357 file_attributes
, /* file_attributes */
1358 oplock_request
, /* oplock_request */
1360 allocation_size
, /* allocation_size */
1361 0, /* private_flags */
1363 ea_list
, /* ea_list */
1366 NULL
, NULL
); /* create context */
1368 if(!NT_STATUS_IS_OK(status
)) {
1369 if (open_was_deferred(req
->xconn
, req
->mid
)) {
1370 /* We have re-scheduled this call, no error. */
1373 if (NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
1374 bool ok
= defer_smb1_sharing_violation(req
);
1379 reply_openerror(req
, status
);
1383 /* Ensure we're pointing at the correct stat struct. */
1384 TALLOC_FREE(smb_fname
);
1385 smb_fname
= fsp
->fsp_name
;
1388 * If the caller set the extended oplock request bit
1389 * and we granted one (by whatever means) - set the
1390 * correct bit for extended oplock reply.
1393 if (oplock_request
&&
1394 (lp_fake_oplocks(SNUM(conn
))
1395 || EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
))) {
1398 * Exclusive oplock granted
1401 if (flags
& REQUEST_BATCH_OPLOCK
) {
1402 oplock_granted
= BATCH_OPLOCK_RETURN
;
1404 oplock_granted
= EXCLUSIVE_OPLOCK_RETURN
;
1406 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
1407 oplock_granted
= LEVEL_II_OPLOCK_RETURN
;
1409 oplock_granted
= NO_OPLOCK_RETURN
;
1412 file_len
= smb_fname
->st
.st_ex_size
;
1414 /* Realloc the size of parameters and data we will return */
1415 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
1416 /* Extended response is 32 more byyes. */
1421 params
= nttrans_realloc(ppparams
, param_len
);
1422 if(params
== NULL
) {
1423 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1428 SCVAL(p
, 0, oplock_granted
);
1431 SSVAL(p
,0,fsp
->fnum
);
1433 if ((create_disposition
== FILE_SUPERSEDE
)
1434 && (info
== FILE_WAS_OVERWRITTEN
)) {
1435 SIVAL(p
,0,FILE_WAS_SUPERSEDED
);
1441 fattr
= fdos_mode(fsp
);
1443 fattr
= FILE_ATTRIBUTE_NORMAL
;
1447 create_timespec
= get_create_timespec(conn
, fsp
, smb_fname
);
1448 a_timespec
= smb_fname
->st
.st_ex_atime
;
1449 m_timespec
= smb_fname
->st
.st_ex_mtime
;
1450 c_timespec
= get_change_timespec(conn
, fsp
, smb_fname
);
1452 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1453 dos_filetime_timespec(&create_timespec
);
1454 dos_filetime_timespec(&a_timespec
);
1455 dos_filetime_timespec(&m_timespec
);
1456 dos_filetime_timespec(&c_timespec
);
1459 put_long_date_full_timespec(conn
->ts_res
, p
, &create_timespec
); /* create time. */
1461 put_long_date_full_timespec(conn
->ts_res
, p
, &a_timespec
); /* access time */
1463 put_long_date_full_timespec(conn
->ts_res
, p
, &m_timespec
); /* write time */
1465 put_long_date_full_timespec(conn
->ts_res
, p
, &c_timespec
); /* change time */
1467 SIVAL(p
,0,fattr
); /* File Attributes. */
1469 SOFF_T(p
, 0, SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, &smb_fname
->st
));
1471 SOFF_T(p
,0,file_len
);
1473 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
1474 uint16_t file_status
= (NO_EAS
|NO_SUBSTREAMS
|NO_REPARSETAG
);
1475 unsigned int num_streams
= 0;
1476 struct stream_struct
*streams
= NULL
;
1478 if (lp_ea_support(SNUM(conn
))) {
1479 size_t num_names
= 0;
1480 /* Do we have any EA's ? */
1481 status
= get_ea_names_from_fsp(
1482 ctx
, smb_fname
->fsp
, NULL
, &num_names
);
1483 if (NT_STATUS_IS_OK(status
) && num_names
) {
1484 file_status
&= ~NO_EAS
;
1488 status
= vfs_fstreaminfo(smb_fname
->fsp
, ctx
,
1489 &num_streams
, &streams
);
1490 /* There is always one stream, ::$DATA. */
1491 if (NT_STATUS_IS_OK(status
) && num_streams
> 1) {
1492 file_status
&= ~NO_SUBSTREAMS
;
1494 TALLOC_FREE(streams
);
1495 SSVAL(p
,2,file_status
);
1498 SCVAL(p
,0,fsp
->fsp_flags
.is_directory
? 1 : 0);
1500 if (flags
& EXTENDED_RESPONSE_REQUIRED
) {
1503 if (fsp
->fsp_flags
.is_directory
||
1504 fsp
->fsp_flags
.can_write
||
1505 can_write_to_fsp(fsp
))
1507 perms
= FILE_GENERIC_ALL
;
1509 perms
= FILE_GENERIC_READ
|FILE_EXECUTE
;
1514 DEBUG(5,("call_nt_transact_create: open name = %s\n",
1515 smb_fname_str_dbg(smb_fname
)));
1517 /* Send the required number of replies */
1518 send_nt_replies(conn
, req
, NT_STATUS_OK
, params
, param_len
, *ppdata
, 0);
1523 /****************************************************************************
1524 Reply to a NT CANCEL request.
1525 conn POINTER CAN BE NULL HERE !
1526 ****************************************************************************/
1528 void reply_ntcancel(struct smb_request
*req
)
1530 struct smbXsrv_connection
*xconn
= req
->xconn
;
1531 struct smbd_server_connection
*sconn
= req
->sconn
;
1535 * Go through and cancel any pending change notifies.
1538 START_PROFILE(SMBntcancel
);
1539 srv_cancel_sign_response(xconn
);
1540 found
= remove_pending_change_notify_requests_by_mid(sconn
, req
->mid
);
1542 smbd_smb1_brl_finish_by_mid(sconn
, req
->mid
);
1545 DEBUG(3,("reply_ntcancel: cancel called on mid = %llu.\n",
1546 (unsigned long long)req
->mid
));
1548 END_PROFILE(SMBntcancel
);
1552 /****************************************************************************
1554 ****************************************************************************/
1556 NTSTATUS
copy_internals(TALLOC_CTX
*ctx
,
1557 connection_struct
*conn
,
1558 struct smb_request
*req
,
1559 struct smb_filename
*smb_fname_src
,
1560 struct smb_filename
*smb_fname_dst
,
1563 files_struct
*fsp1
,*fsp2
;
1567 NTSTATUS status
= NT_STATUS_OK
;
1568 struct smb_filename
*parent
= NULL
;
1569 struct smb_filename
*pathref
= NULL
;
1571 if (!CAN_WRITE(conn
)) {
1572 status
= NT_STATUS_MEDIA_WRITE_PROTECTED
;
1576 /* Source must already exist. */
1577 if (!VALID_STAT(smb_fname_src
->st
)) {
1578 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1582 /* Ensure attributes match. */
1583 fattr
= fdos_mode(smb_fname_src
->fsp
);
1584 if ((fattr
& ~attrs
) & (FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_SYSTEM
)) {
1585 status
= NT_STATUS_NO_SUCH_FILE
;
1589 /* Disallow if dst file already exists. */
1590 if (VALID_STAT(smb_fname_dst
->st
)) {
1591 status
= NT_STATUS_OBJECT_NAME_COLLISION
;
1595 /* No links from a directory. */
1596 if (S_ISDIR(smb_fname_src
->st
.st_ex_mode
)) {
1597 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
1601 DEBUG(10,("copy_internals: doing file copy %s to %s\n",
1602 smb_fname_str_dbg(smb_fname_src
),
1603 smb_fname_str_dbg(smb_fname_dst
)));
1605 status
= SMB_VFS_CREATE_FILE(
1608 smb_fname_src
, /* fname */
1609 FILE_READ_DATA
|FILE_READ_ATTRIBUTES
|
1610 FILE_READ_EA
, /* access_mask */
1611 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
1613 FILE_OPEN
, /* create_disposition*/
1614 0, /* create_options */
1615 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
1616 NO_OPLOCK
, /* oplock_request */
1618 0, /* allocation_size */
1619 0, /* private_flags */
1624 NULL
, NULL
); /* create context */
1626 if (!NT_STATUS_IS_OK(status
)) {
1630 status
= SMB_VFS_CREATE_FILE(
1633 smb_fname_dst
, /* fname */
1634 FILE_WRITE_DATA
|FILE_WRITE_ATTRIBUTES
|
1635 FILE_WRITE_EA
, /* access_mask */
1636 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
1638 FILE_CREATE
, /* create_disposition*/
1639 0, /* create_options */
1640 fattr
, /* file_attributes */
1641 NO_OPLOCK
, /* oplock_request */
1643 0, /* allocation_size */
1644 0, /* private_flags */
1649 NULL
, NULL
); /* create context */
1651 if (!NT_STATUS_IS_OK(status
)) {
1652 close_file(NULL
, fsp1
, ERROR_CLOSE
);
1656 if (smb_fname_src
->st
.st_ex_size
) {
1657 ret
= vfs_transfer_file(fsp1
, fsp2
, smb_fname_src
->st
.st_ex_size
);
1661 * As we are opening fsp1 read-only we only expect
1662 * an error on close on fsp2 if we are out of space.
1663 * Thus we don't look at the error return from the
1666 close_file(NULL
, fsp1
, NORMAL_CLOSE
);
1668 /* Ensure the modtime is set correctly on the destination file. */
1669 set_close_write_time(fsp2
, smb_fname_src
->st
.st_ex_mtime
);
1671 status
= close_file(NULL
, fsp2
, NORMAL_CLOSE
);
1673 /* Grrr. We have to do this as open_file_ntcreate adds FILE_ATTRIBUTE_ARCHIVE when it
1674 creates the file. This isn't the correct thing to do in the copy
1677 status
= SMB_VFS_PARENT_PATHNAME(conn
,
1682 if (!NT_STATUS_IS_OK(status
)) {
1685 if (smb_fname_dst
->fsp
== NULL
) {
1686 status
= synthetic_pathref(parent
,
1688 smb_fname_dst
->base_name
,
1689 smb_fname_dst
->stream_name
,
1691 smb_fname_dst
->twrp
,
1692 smb_fname_dst
->flags
,
1695 /* should we handle NT_STATUS_OBJECT_NAME_NOT_FOUND specially here ???? */
1696 if (!NT_STATUS_IS_OK(status
)) {
1697 TALLOC_FREE(parent
);
1700 file_set_dosmode(conn
, pathref
, fattr
, parent
, false);
1701 smb_fname_dst
->st
.st_ex_mode
= pathref
->st
.st_ex_mode
;
1703 file_set_dosmode(conn
, smb_fname_dst
, fattr
, parent
, false);
1705 TALLOC_FREE(parent
);
1707 if (ret
< (off_t
)smb_fname_src
->st
.st_ex_size
) {
1708 status
= NT_STATUS_DISK_FULL
;
1712 if (!NT_STATUS_IS_OK(status
)) {
1713 DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
1714 nt_errstr(status
), smb_fname_str_dbg(smb_fname_src
),
1715 smb_fname_str_dbg(smb_fname_dst
)));
1721 /****************************************************************************
1722 Reply to a NT rename request.
1723 ****************************************************************************/
1725 void reply_ntrename(struct smb_request
*req
)
1727 connection_struct
*conn
= req
->conn
;
1728 struct smb_filename
*smb_fname_old
= NULL
;
1729 struct smb_filename
*smb_fname_new
= NULL
;
1730 char *oldname
= NULL
;
1731 char *newname
= NULL
;
1732 const char *dst_original_lcomp
= NULL
;
1736 uint32_t ucf_flags_src
= ucf_flags_from_smb_request(req
);
1737 uint32_t ucf_flags_dst
= ucf_flags_from_smb_request(req
);
1738 uint16_t rename_type
;
1739 TALLOC_CTX
*ctx
= talloc_tos();
1740 bool stream_rename
= false;
1742 START_PROFILE(SMBntrename
);
1745 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1749 attrs
= SVAL(req
->vwv
+0, 0);
1750 rename_type
= SVAL(req
->vwv
+1, 0);
1752 p
= (const char *)req
->buf
+ 1;
1753 p
+= srvstr_get_path_req(ctx
, req
, &oldname
, p
, STR_TERMINATE
,
1755 if (!NT_STATUS_IS_OK(status
)) {
1756 reply_nterror(req
, status
);
1760 if (!req
->posix_pathnames
&& ms_has_wild(oldname
)) {
1761 reply_nterror(req
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
1766 p
+= srvstr_get_path_req(ctx
, req
, &newname
, p
, STR_TERMINATE
,
1768 if (!NT_STATUS_IS_OK(status
)) {
1769 reply_nterror(req
, status
);
1773 if (!req
->posix_pathnames
&& ms_has_wild(newname
)) {
1774 reply_nterror(req
, NT_STATUS_OBJECT_PATH_SYNTAX_BAD
);
1778 if (!req
->posix_pathnames
) {
1779 /* The newname must begin with a ':' if the
1780 oldname contains a ':'. */
1781 if (strchr_m(oldname
, ':')) {
1782 if (newname
[0] != ':') {
1783 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1786 stream_rename
= true;
1790 /* rename_internals() calls unix_convert(), so don't call it here. */
1791 status
= filename_convert(ctx
, conn
,
1796 if (!NT_STATUS_IS_OK(status
)) {
1797 if (NT_STATUS_EQUAL(status
,
1798 NT_STATUS_PATH_NOT_COVERED
)) {
1799 reply_botherror(req
,
1800 NT_STATUS_PATH_NOT_COVERED
,
1801 ERRSRV
, ERRbadpath
);
1804 reply_nterror(req
, status
);
1808 /* Get the last component of the destination for rename_internals(). */
1809 dst_original_lcomp
= get_original_lcomp(ctx
,
1813 if (dst_original_lcomp
== NULL
) {
1814 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1818 status
= filename_convert(ctx
, conn
,
1823 if (!NT_STATUS_IS_OK(status
)) {
1824 if (NT_STATUS_EQUAL(status
,
1825 NT_STATUS_PATH_NOT_COVERED
)) {
1826 reply_botherror(req
,
1827 NT_STATUS_PATH_NOT_COVERED
,
1828 ERRSRV
, ERRbadpath
);
1831 reply_nterror(req
, status
);
1835 if (stream_rename
) {
1836 /* smb_fname_new must be the same as smb_fname_old. */
1837 TALLOC_FREE(smb_fname_new
->base_name
);
1838 smb_fname_new
->base_name
= talloc_strdup(smb_fname_new
,
1839 smb_fname_old
->base_name
);
1840 if (!smb_fname_new
->base_name
) {
1841 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1846 DEBUG(3,("reply_ntrename: %s -> %s\n",
1847 smb_fname_str_dbg(smb_fname_old
),
1848 smb_fname_str_dbg(smb_fname_new
)));
1850 switch(rename_type
) {
1851 case RENAME_FLAG_RENAME
:
1852 status
= rename_internals(ctx
,
1862 case RENAME_FLAG_HARD_LINK
:
1863 status
= hardlink_internals(ctx
,
1870 case RENAME_FLAG_COPY
:
1871 status
= copy_internals(ctx
,
1878 case RENAME_FLAG_MOVE_CLUSTER_INFORMATION
:
1879 status
= NT_STATUS_INVALID_PARAMETER
;
1882 status
= NT_STATUS_ACCESS_DENIED
; /* Default error. */
1886 if (!NT_STATUS_IS_OK(status
)) {
1887 if (open_was_deferred(req
->xconn
, req
->mid
)) {
1888 /* We have re-scheduled this call. */
1891 if (NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
1892 bool ok
= defer_smb1_sharing_violation(req
);
1898 reply_nterror(req
, status
);
1902 reply_outbuf(req
, 0, 0);
1904 END_PROFILE(SMBntrename
);
1908 /****************************************************************************
1909 Reply to a notify change - queue the request and
1910 don't allow a directory to be opened.
1911 ****************************************************************************/
1913 static void smbd_smb1_notify_reply(struct smb_request
*req
,
1914 NTSTATUS error_code
,
1915 uint8_t *buf
, size_t len
)
1917 send_nt_replies(req
->conn
, req
, error_code
, (char *)buf
, len
, NULL
, 0);
1920 static void call_nt_transact_notify_change(connection_struct
*conn
,
1921 struct smb_request
*req
,
1923 uint32_t setup_count
,
1925 uint32_t parameter_count
,
1926 char **ppdata
, uint32_t data_count
,
1927 uint32_t max_data_count
,
1928 uint32_t max_param_count
)
1930 uint16_t *setup
= *ppsetup
;
1936 if(setup_count
< 6) {
1937 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1941 fsp
= file_fsp(req
, SVAL(setup
,4));
1942 filter
= IVAL(setup
, 0);
1943 recursive
= (SVAL(setup
, 6) != 0) ? True
: False
;
1945 DEBUG(3,("call_nt_transact_notify_change\n"));
1948 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
1953 char *filter_string
;
1955 if (!(filter_string
= notify_filter_string(NULL
, filter
))) {
1956 reply_nterror(req
,NT_STATUS_NO_MEMORY
);
1960 DEBUG(3,("call_nt_transact_notify_change: notify change "
1961 "called on %s, filter = %s, recursive = %d\n",
1962 fsp_str_dbg(fsp
), filter_string
, recursive
));
1964 TALLOC_FREE(filter_string
);
1967 if((!fsp
->fsp_flags
.is_directory
) || (conn
!= fsp
->conn
)) {
1968 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1972 if (fsp
->notify
== NULL
) {
1974 status
= change_notify_create(fsp
,
1978 if (!NT_STATUS_IS_OK(status
)) {
1979 DEBUG(10, ("change_notify_create returned %s\n",
1980 nt_errstr(status
)));
1981 reply_nterror(req
, status
);
1986 if (change_notify_fsp_has_changes(fsp
)) {
1989 * We've got changes pending, respond immediately
1993 * TODO: write a torture test to check the filtering behaviour
1997 change_notify_reply(req
,
2001 smbd_smb1_notify_reply
);
2004 * change_notify_reply() above has independently sent its
2011 * No changes pending, queue the request
2014 status
= change_notify_add_request(req
,
2018 smbd_smb1_notify_reply
);
2019 if (!NT_STATUS_IS_OK(status
)) {
2020 reply_nterror(req
, status
);
2025 /****************************************************************************
2026 Reply to an NT transact rename command.
2027 ****************************************************************************/
2029 static void call_nt_transact_rename(connection_struct
*conn
,
2030 struct smb_request
*req
,
2031 uint16_t **ppsetup
, uint32_t setup_count
,
2032 char **ppparams
, uint32_t parameter_count
,
2033 char **ppdata
, uint32_t data_count
,
2034 uint32_t max_data_count
)
2036 char *params
= *ppparams
;
2037 char *new_name
= NULL
;
2038 files_struct
*fsp
= NULL
;
2040 TALLOC_CTX
*ctx
= talloc_tos();
2042 if(parameter_count
< 5) {
2043 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2047 fsp
= file_fsp(req
, SVAL(params
, 0));
2048 if (!check_fsp(conn
, req
, fsp
)) {
2051 if (req
->posix_pathnames
) {
2052 srvstr_get_path_posix(ctx
,
2057 parameter_count
- 4,
2061 srvstr_get_path(ctx
,
2066 parameter_count
- 4,
2071 if (!NT_STATUS_IS_OK(status
)) {
2072 reply_nterror(req
, status
);
2077 * W2K3 ignores this request as the RAW-RENAME test
2078 * demonstrates, so we do.
2080 send_nt_replies(conn
, req
, NT_STATUS_OK
, NULL
, 0, NULL
, 0);
2082 DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
2083 fsp_str_dbg(fsp
), new_name
));
2088 /******************************************************************************
2089 Fake up a completely empty SD.
2090 *******************************************************************************/
2092 static NTSTATUS
get_null_nt_acl(TALLOC_CTX
*mem_ctx
, struct security_descriptor
**ppsd
)
2096 *ppsd
= make_standard_sec_desc( mem_ctx
, &global_sid_World
, &global_sid_World
, NULL
, &sd_size
);
2098 DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
2099 return NT_STATUS_NO_MEMORY
;
2102 return NT_STATUS_OK
;
2105 /****************************************************************************
2106 Reply to query a security descriptor.
2107 Callable from SMB1 and SMB2.
2108 If it returns NT_STATUS_BUFFER_TOO_SMALL, pdata_size is initialized with
2110 ****************************************************************************/
2112 NTSTATUS
smbd_do_query_security_desc(connection_struct
*conn
,
2113 TALLOC_CTX
*mem_ctx
,
2115 uint32_t security_info_wanted
,
2116 uint32_t max_data_count
,
2117 uint8_t **ppmarshalled_sd
,
2121 struct security_descriptor
*psd
= NULL
;
2122 TALLOC_CTX
*frame
= talloc_stackframe();
2123 bool need_to_read_sd
= false;
2126 * Get the permissions to return.
2129 if ((security_info_wanted
& SECINFO_SACL
) &&
2130 !(fsp
->access_mask
& SEC_FLAG_SYSTEM_SECURITY
)) {
2131 DEBUG(10, ("Access to SACL denied.\n"));
2133 return NT_STATUS_ACCESS_DENIED
;
2136 if ((security_info_wanted
& (SECINFO_DACL
|SECINFO_OWNER
|SECINFO_GROUP
)) &&
2137 !(fsp
->access_mask
& SEC_STD_READ_CONTROL
)) {
2138 DEBUG(10, ("Access to DACL, OWNER, or GROUP denied.\n"));
2140 return NT_STATUS_ACCESS_DENIED
;
2143 status
= refuse_symlink_fsp(fsp
);
2144 if (!NT_STATUS_IS_OK(status
)) {
2145 DBG_DEBUG("ACL get on symlink %s denied.\n",
2151 if (security_info_wanted
& (SECINFO_DACL
|SECINFO_OWNER
|
2152 SECINFO_GROUP
|SECINFO_SACL
)) {
2153 /* Don't return SECINFO_LABEL if anything else was
2154 requested. See bug #8458. */
2155 security_info_wanted
&= ~SECINFO_LABEL
;
2158 * Only query the file system SD if the caller asks
2159 * for any bits. This allows a caller to open without
2160 * READ_CONTROL but still issue a query sd. See
2163 need_to_read_sd
= true;
2166 if (lp_nt_acl_support(SNUM(conn
)) &&
2167 ((security_info_wanted
& SECINFO_LABEL
) == 0) &&
2170 files_struct
*sd_fsp
= fsp
;
2171 if (fsp
->base_fsp
!= NULL
) {
2173 * This is a stream handle. Use
2174 * the underlying pathref handle.
2176 sd_fsp
= fsp
->base_fsp
;
2178 status
= SMB_VFS_FGET_NT_ACL(
2179 sd_fsp
, security_info_wanted
, frame
, &psd
);
2181 status
= get_null_nt_acl(frame
, &psd
);
2184 if (!NT_STATUS_IS_OK(status
)) {
2189 if (!(security_info_wanted
& SECINFO_OWNER
)) {
2190 psd
->owner_sid
= NULL
;
2192 if (!(security_info_wanted
& SECINFO_GROUP
)) {
2193 psd
->group_sid
= NULL
;
2195 if (!(security_info_wanted
& SECINFO_DACL
)) {
2196 psd
->type
&= ~SEC_DESC_DACL_PRESENT
;
2199 if (!(security_info_wanted
& SECINFO_SACL
)) {
2200 psd
->type
&= ~SEC_DESC_SACL_PRESENT
;
2204 /* If the SACL/DACL is NULL, but was requested, we mark that it is
2205 * present in the reply to match Windows behavior */
2206 if (psd
->sacl
== NULL
&&
2207 security_info_wanted
& SECINFO_SACL
)
2208 psd
->type
|= SEC_DESC_SACL_PRESENT
;
2209 if (psd
->dacl
== NULL
&&
2210 security_info_wanted
& SECINFO_DACL
)
2211 psd
->type
|= SEC_DESC_DACL_PRESENT
;
2213 if (security_info_wanted
& SECINFO_LABEL
) {
2214 /* Like W2K3 return a null object. */
2215 psd
->owner_sid
= NULL
;
2216 psd
->group_sid
= NULL
;
2219 psd
->type
&= ~(SEC_DESC_DACL_PRESENT
|SEC_DESC_SACL_PRESENT
);
2222 *psd_size
= ndr_size_security_descriptor(psd
, 0);
2224 DEBUG(3,("smbd_do_query_security_desc: sd_size = %lu.\n",
2225 (unsigned long)*psd_size
));
2227 if (DEBUGLEVEL
>= 10) {
2228 DEBUG(10,("smbd_do_query_security_desc for file %s\n",
2230 NDR_PRINT_DEBUG(security_descriptor
, psd
);
2233 if (max_data_count
< *psd_size
) {
2235 return NT_STATUS_BUFFER_TOO_SMALL
;
2238 status
= marshall_sec_desc(mem_ctx
, psd
,
2239 ppmarshalled_sd
, psd_size
);
2241 if (!NT_STATUS_IS_OK(status
)) {
2247 return NT_STATUS_OK
;
2250 /****************************************************************************
2251 SMB1 reply to query a security descriptor.
2252 ****************************************************************************/
2254 static void call_nt_transact_query_security_desc(connection_struct
*conn
,
2255 struct smb_request
*req
,
2257 uint32_t setup_count
,
2259 uint32_t parameter_count
,
2261 uint32_t data_count
,
2262 uint32_t max_data_count
)
2264 char *params
= *ppparams
;
2265 char *data
= *ppdata
;
2267 uint32_t security_info_wanted
;
2268 files_struct
*fsp
= NULL
;
2270 uint8_t *marshalled_sd
= NULL
;
2272 if(parameter_count
< 8) {
2273 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2277 fsp
= file_fsp(req
, SVAL(params
,0));
2279 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
2283 security_info_wanted
= IVAL(params
,4);
2285 DEBUG(3,("call_nt_transact_query_security_desc: file = %s, "
2286 "info_wanted = 0x%x\n", fsp_str_dbg(fsp
),
2287 (unsigned int)security_info_wanted
));
2289 params
= nttrans_realloc(ppparams
, 4);
2290 if(params
== NULL
) {
2291 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2296 * Get the permissions to return.
2299 status
= smbd_do_query_security_desc(conn
,
2302 security_info_wanted
&
2303 SMB_SUPPORTED_SECINFO_FLAGS
,
2308 if (NT_STATUS_EQUAL(status
, NT_STATUS_BUFFER_TOO_SMALL
)) {
2309 SIVAL(params
,0,(uint32_t)sd_size
);
2310 send_nt_replies(conn
, req
, NT_STATUS_BUFFER_TOO_SMALL
,
2311 params
, 4, NULL
, 0);
2315 if (!NT_STATUS_IS_OK(status
)) {
2316 reply_nterror(req
, status
);
2320 SMB_ASSERT(sd_size
> 0);
2322 SIVAL(params
,0,(uint32_t)sd_size
);
2324 if (max_data_count
< sd_size
) {
2325 send_nt_replies(conn
, req
, NT_STATUS_BUFFER_TOO_SMALL
,
2326 params
, 4, NULL
, 0);
2331 * Allocate the data we will return.
2334 data
= nttrans_realloc(ppdata
, sd_size
);
2336 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2340 memcpy(data
, marshalled_sd
, sd_size
);
2342 send_nt_replies(conn
, req
, NT_STATUS_OK
, params
, 4, data
, (int)sd_size
);
2347 /****************************************************************************
2348 Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
2349 ****************************************************************************/
2351 static void call_nt_transact_set_security_desc(connection_struct
*conn
,
2352 struct smb_request
*req
,
2354 uint32_t setup_count
,
2356 uint32_t parameter_count
,
2358 uint32_t data_count
,
2359 uint32_t max_data_count
)
2361 char *params
= *ppparams
;
2362 char *data
= *ppdata
;
2363 files_struct
*fsp
= NULL
;
2364 uint32_t security_info_sent
= 0;
2367 if(parameter_count
< 8) {
2368 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2372 if((fsp
= file_fsp(req
, SVAL(params
,0))) == NULL
) {
2373 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
2377 if (!CAN_WRITE(fsp
->conn
)) {
2378 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
2382 if(!lp_nt_acl_support(SNUM(conn
))) {
2386 security_info_sent
= IVAL(params
,4);
2388 DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n",
2389 fsp_str_dbg(fsp
), (unsigned int)security_info_sent
));
2391 if (data_count
== 0) {
2392 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2396 status
= set_sd_blob(fsp
, (uint8_t *)data
, data_count
,
2397 security_info_sent
& SMB_SUPPORTED_SECINFO_FLAGS
);
2398 if (!NT_STATUS_IS_OK(status
)) {
2399 reply_nterror(req
, status
);
2404 send_nt_replies(conn
, req
, NT_STATUS_OK
, NULL
, 0, NULL
, 0);
2408 /****************************************************************************
2410 ****************************************************************************/
2412 static void call_nt_transact_ioctl(connection_struct
*conn
,
2413 struct smb_request
*req
,
2414 uint16_t **ppsetup
, uint32_t setup_count
,
2415 char **ppparams
, uint32_t parameter_count
,
2416 char **ppdata
, uint32_t data_count
,
2417 uint32_t max_data_count
)
2425 char *out_data
= NULL
;
2426 uint32_t out_data_len
= 0;
2427 char *pdata
= *ppdata
;
2428 TALLOC_CTX
*ctx
= talloc_tos();
2430 if (setup_count
!= 8) {
2431 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count
));
2432 reply_nterror(req
, NT_STATUS_NOT_SUPPORTED
);
2436 function
= IVAL(*ppsetup
, 0);
2437 fidnum
= SVAL(*ppsetup
, 4);
2438 isFSctl
= CVAL(*ppsetup
, 6);
2439 compfilter
= CVAL(*ppsetup
, 7);
2441 DEBUG(10, ("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
2442 function
, fidnum
, isFSctl
, compfilter
));
2444 fsp
=file_fsp(req
, fidnum
);
2447 * We don't really implement IOCTLs, especially on files.
2450 DEBUG(10, ("isFSctl: 0x%02X indicates IOCTL, not FSCTL!\n",
2452 reply_nterror(req
, NT_STATUS_NOT_SUPPORTED
);
2456 /* Has to be for an open file! */
2457 if (!check_fsp_open(conn
, req
, fsp
)) {
2461 SMB_PERFCOUNT_SET_IOCTL(&req
->pcd
, function
);
2464 * out_data might be allocated by the VFS module, but talloc should be
2465 * used, and should be cleaned up when the request ends.
2467 status
= SMB_VFS_FSCTL(fsp
,
2473 (uint8_t **)&out_data
,
2476 if (!NT_STATUS_IS_OK(status
)) {
2477 reply_nterror(req
, status
);
2479 send_nt_replies(conn
, req
, NT_STATUS_OK
, NULL
, 0, out_data
, out_data_len
);
2484 #ifdef HAVE_SYS_QUOTAS
2485 static enum ndr_err_code
fill_qtlist_from_sids(TALLOC_CTX
*mem_ctx
,
2486 struct files_struct
*fsp
,
2487 SMB_NTQUOTA_HANDLE
*qt_handle
,
2488 struct dom_sid
*sids
,
2492 TALLOC_CTX
*list_ctx
= NULL
;
2494 list_ctx
= talloc_init("quota_sid_list");
2496 if (list_ctx
== NULL
) {
2497 DBG_ERR("failed to allocate\n");
2498 return NDR_ERR_ALLOC
;
2501 if (qt_handle
->quota_list
!=NULL
) {
2502 free_ntquota_list(&(qt_handle
->quota_list
));
2504 for (i
= 0; i
< elems
; i
++) {
2505 SMB_NTQUOTA_STRUCT qt
;
2506 SMB_NTQUOTA_LIST
*list_item
;
2509 if (!NT_STATUS_IS_OK(vfs_get_ntquota(fsp
,
2510 SMB_USER_QUOTA_TYPE
,
2512 /* non fatal error, return empty item in result */
2518 list_item
= talloc_zero(list_ctx
, SMB_NTQUOTA_LIST
);
2519 if (list_item
== NULL
) {
2520 DBG_ERR("failed to allocate\n");
2521 return NDR_ERR_ALLOC
;
2524 ok
= sid_to_uid(&sids
[i
], &list_item
->uid
);
2526 struct dom_sid_buf buf
;
2527 DBG_WARNING("Could not convert SID %s to uid\n",
2528 dom_sid_str_buf(&sids
[i
], &buf
));
2529 /* No idea what to return here... */
2530 return NDR_ERR_INVALID_POINTER
;
2533 list_item
->quotas
= talloc_zero(list_item
, SMB_NTQUOTA_STRUCT
);
2534 if (list_item
->quotas
== NULL
) {
2535 DBG_ERR("failed to allocate\n");
2536 return NDR_ERR_ALLOC
;
2539 *list_item
->quotas
= qt
;
2540 list_item
->mem_ctx
= list_ctx
;
2541 DLIST_ADD(qt_handle
->quota_list
, list_item
);
2543 qt_handle
->tmp_list
= qt_handle
->quota_list
;
2544 return NDR_ERR_SUCCESS
;
2547 static enum ndr_err_code
extract_sids_from_buf(TALLOC_CTX
*mem_ctx
,
2548 uint32_t sidlistlength
,
2550 struct dom_sid
**sids
,
2555 enum ndr_err_code err
;
2557 struct sid_list_elem
{
2558 struct sid_list_elem
*prev
, *next
;
2562 struct sid_list_elem
*sid_list
= NULL
;
2563 struct sid_list_elem
*iter
= NULL
;
2564 TALLOC_CTX
*list_ctx
= talloc_init("sid_list");
2567 err
= NDR_ERR_ALLOC
;
2574 if (sidlistlength
) {
2575 uint32_t offset
= 0;
2576 struct ndr_pull
*ndr_pull
= NULL
;
2578 if (sidlistlength
> sid_buf
->length
) {
2579 DBG_ERR("sid_list_length 0x%x exceeds "
2580 "available bytes %zx\n",
2583 err
= NDR_ERR_OFFSET
;
2587 struct file_get_quota_info info
;
2588 struct sid_list_elem
*item
= NULL
;
2589 uint32_t new_offset
= 0;
2590 blob
.data
= sid_buf
->data
+ offset
;
2591 blob
.length
= sidlistlength
- offset
;
2592 ndr_pull
= ndr_pull_init_blob(&blob
, list_ctx
);
2595 err
= NDR_ERR_ALLOC
;
2598 err
= ndr_pull_file_get_quota_info(ndr_pull
,
2599 NDR_SCALARS
| NDR_BUFFERS
, &info
);
2600 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
2601 DBG_ERR("Failed to pull file_get_quota_info "
2602 "from sidlist buffer\n");
2605 item
= talloc_zero(list_ctx
, struct sid_list_elem
);
2608 err
= NDR_ERR_ALLOC
;
2611 item
->sid
= info
.sid
;
2612 DLIST_ADD(sid_list
, item
);
2614 if (i
== UINT32_MAX
) {
2615 DBG_ERR("Integer overflow\n");
2616 err
= NDR_ERR_ARRAY_SIZE
;
2619 new_offset
= info
.next_entry_offset
;
2621 /* if new_offset == 0 no more sid(s) to read. */
2622 if (new_offset
== 0) {
2627 if ((offset
+ new_offset
) < offset
) {
2628 DBG_ERR("Integer wrap while adding "
2629 "new_offset 0x%x to current "
2630 "buffer offset 0x%x\n",
2631 new_offset
, offset
);
2632 err
= NDR_ERR_OFFSET
;
2636 offset
+= new_offset
;
2638 /* check if new offset is outside buffer boundry. */
2639 if (offset
>= sidlistlength
) {
2640 DBG_ERR("bufsize 0x%x exceeded by "
2641 "new offset 0x%x)\n",
2644 err
= NDR_ERR_OFFSET
;
2648 *sids
= talloc_zero_array(mem_ctx
, struct dom_sid
, i
);
2649 if (*sids
== NULL
) {
2651 err
= NDR_ERR_ALLOC
;
2657 for (iter
= sid_list
, i
= 0; iter
; iter
= iter
->next
, i
++) {
2658 struct dom_sid_buf buf
;
2659 (*sids
)[i
] = iter
->sid
;
2660 DBG_DEBUG("quota SID[%u] %s\n",
2662 dom_sid_str_buf(&iter
->sid
, &buf
));
2665 err
= NDR_ERR_SUCCESS
;
2667 TALLOC_FREE(list_ctx
);
2671 NTSTATUS
smbd_do_query_getinfo_quota(TALLOC_CTX
*mem_ctx
,
2675 uint32_t sid_list_length
,
2677 uint32_t max_data_count
,
2679 uint32_t *p_data_size
)
2682 SMB_NTQUOTA_HANDLE
*qt_handle
= NULL
;
2683 SMB_NTQUOTA_LIST
*qt_list
= NULL
;
2684 DATA_BLOB blob
= data_blob_null
;
2685 enum ndr_err_code err
;
2688 (SMB_NTQUOTA_HANDLE
*)fsp
->fake_file_handle
->private_data
;
2690 if (sid_list_length
) {
2691 struct dom_sid
*sids
;
2694 * error check pulled offsets and lengths for wrap and
2695 * exceeding available bytes.
2697 if (sid_list_length
> sid_buf
->length
) {
2698 DBG_ERR("sid_list_length 0x%x exceeds "
2699 "available bytes %zx\n",
2702 return NT_STATUS_INVALID_PARAMETER
;
2705 err
= extract_sids_from_buf(mem_ctx
, sid_list_length
,
2706 sid_buf
, &sids
, &elems
);
2707 if (!NDR_ERR_CODE_IS_SUCCESS(err
) || elems
== 0) {
2708 return NT_STATUS_INVALID_PARAMETER
;
2710 err
= fill_qtlist_from_sids(mem_ctx
,
2715 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
2716 return NT_STATUS_INVALID_PARAMETER
;
2718 } else if (restart_scan
) {
2719 if (vfs_get_user_ntquota_list(fsp
,
2720 &(qt_handle
->quota_list
))!=0) {
2721 return NT_STATUS_INTERNAL_ERROR
;
2724 if (qt_handle
->quota_list
!=NULL
&&
2725 qt_handle
->tmp_list
==NULL
) {
2726 free_ntquota_list(&(qt_handle
->quota_list
));
2730 if (restart_scan
!=0 ) {
2731 qt_list
= qt_handle
->quota_list
;
2733 qt_list
= qt_handle
->tmp_list
;
2735 status
= fill_quota_buffer(mem_ctx
, qt_list
,
2739 &qt_handle
->tmp_list
);
2740 if (!NT_STATUS_IS_OK(status
)) {
2743 if (blob
.length
> max_data_count
) {
2744 return NT_STATUS_BUFFER_TOO_SMALL
;
2747 *p_data
= blob
.data
;
2748 *p_data_size
= blob
.length
;
2749 return NT_STATUS_OK
;
2752 /****************************************************************************
2753 Reply to get user quota
2754 ****************************************************************************/
2756 static void call_nt_transact_get_user_quota(connection_struct
*conn
,
2757 struct smb_request
*req
,
2759 uint32_t setup_count
,
2761 uint32_t parameter_count
,
2763 uint32_t data_count
,
2764 uint32_t max_data_count
)
2766 const struct loadparm_substitution
*lp_sub
=
2767 loadparm_s3_global_substitution();
2768 NTSTATUS nt_status
= NT_STATUS_OK
;
2769 char *params
= *ppparams
;
2770 char *pdata
= *ppdata
;
2773 files_struct
*fsp
= NULL
;
2774 DATA_BLOB blob
= data_blob_null
;
2775 struct nttrans_query_quota_params info
= {0};
2776 enum ndr_err_code err
;
2777 TALLOC_CTX
*tmp_ctx
= NULL
;
2778 uint32_t resp_len
= 0;
2779 uint8_t *resp_data
= 0;
2781 tmp_ctx
= talloc_init("ntquota_list");
2783 nt_status
= NT_STATUS_NO_MEMORY
;
2788 if (get_current_uid(conn
) != sec_initial_uid()) {
2789 DEBUG(1,("get_user_quota: access_denied service [%s] user "
2790 "[%s]\n", lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
)),
2791 conn
->session_info
->unix_info
->unix_name
));
2792 nt_status
= NT_STATUS_ACCESS_DENIED
;
2796 blob
.data
= (uint8_t*)params
;
2797 blob
.length
= parameter_count
;
2799 err
= ndr_pull_struct_blob(&blob
, tmp_ctx
, &info
,
2800 (ndr_pull_flags_fn_t
)ndr_pull_nttrans_query_quota_params
);
2802 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
2803 DEBUG(0,("TRANSACT_GET_USER_QUOTA: failed to pull "
2804 "query_quota_params."));
2805 nt_status
= NT_STATUS_INVALID_PARAMETER
;
2808 DBG_DEBUG("info.return_single_entry = %u, info.restart_scan = %u, "
2809 "info.sid_list_length = %u, info.start_sid_length = %u, "
2810 "info.start_sid_offset = %u\n",
2811 (unsigned int)info
.return_single_entry
,
2812 (unsigned int)info
.restart_scan
,
2813 (unsigned int)info
.sid_list_length
,
2814 (unsigned int)info
.start_sid_length
,
2815 (unsigned int)info
.start_sid_offset
);
2817 /* set blob to point at data for further parsing */
2818 blob
.data
= (uint8_t*)pdata
;
2819 blob
.length
= data_count
;
2821 * Although MS-SMB ref is ambiguous here, a microsoft client will
2822 * only ever send a start sid (as part of a list) with
2823 * sid_list_length & start_sid_offset both set to the actual list
2824 * length. Note: Only a single result is returned in this case
2825 * In the case where either start_sid_offset or start_sid_length
2826 * are set alone or if both set (but have different values) then
2827 * it seems windows will return a number of entries from the start
2828 * of the list of users with quotas set. This behaviour is undocumented
2829 * and windows clients do not send messages of that type. As such we
2830 * currently will reject these requests.
2832 if (info
.start_sid_length
2833 || (info
.sid_list_length
!= info
.start_sid_offset
)) {
2834 DBG_ERR("TRANSACT_GET_USER_QUOTA: unsupported single or "
2835 "compound sid format\n");
2836 nt_status
= NT_STATUS_INVALID_PARAMETER
;
2840 /* maybe we can check the quota_fnum */
2841 fsp
= file_fsp(req
, info
.fid
);
2842 if (!check_fsp_ntquota_handle(conn
, req
, fsp
)) {
2843 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2844 nt_status
= NT_STATUS_INVALID_HANDLE
;
2847 nt_status
= smbd_do_query_getinfo_quota(tmp_ctx
,
2850 info
.return_single_entry
,
2851 info
.sid_list_length
,
2856 if (!NT_STATUS_IS_OK(nt_status
)) {
2857 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_MORE_ENTRIES
)) {
2860 nt_status
= NT_STATUS_OK
;
2864 params
= nttrans_realloc(ppparams
, param_len
);
2865 if(params
== NULL
) {
2866 nt_status
= NT_STATUS_NO_MEMORY
;
2870 data_len
= resp_len
;
2871 SIVAL(params
, 0, data_len
);
2872 pdata
= nttrans_realloc(ppdata
, data_len
);
2873 memcpy(pdata
, resp_data
, data_len
);
2875 TALLOC_FREE(tmp_ctx
);
2876 send_nt_replies(conn
, req
, nt_status
, params
, param_len
,
2880 TALLOC_FREE(tmp_ctx
);
2881 reply_nterror(req
, nt_status
);
2884 /****************************************************************************
2885 Reply to set user quota
2886 ****************************************************************************/
2888 static void call_nt_transact_set_user_quota(connection_struct
*conn
,
2889 struct smb_request
*req
,
2891 uint32_t setup_count
,
2893 uint32_t parameter_count
,
2895 uint32_t data_count
,
2896 uint32_t max_data_count
)
2898 const struct loadparm_substitution
*lp_sub
=
2899 loadparm_s3_global_substitution();
2900 char *params
= *ppparams
;
2901 char *pdata
= *ppdata
;
2902 int data_len
=0,param_len
=0;
2903 SMB_NTQUOTA_STRUCT qt
;
2904 struct file_quota_information info
= {0};
2905 enum ndr_err_code err
;
2908 files_struct
*fsp
= NULL
;
2909 TALLOC_CTX
*ctx
= NULL
;
2910 NTSTATUS status
= NT_STATUS_OK
;
2914 if (get_current_uid(conn
) != sec_initial_uid()) {
2915 DEBUG(1,("set_user_quota: access_denied service [%s] user "
2916 "[%s]\n", lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
)),
2917 conn
->session_info
->unix_info
->unix_name
));
2918 status
= NT_STATUS_ACCESS_DENIED
;
2923 * Ensure minimum number of parameters sent.
2926 if (parameter_count
< 2) {
2927 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count
));
2928 status
= NT_STATUS_INVALID_PARAMETER
;
2932 /* maybe we can check the quota_fnum */
2933 fsp
= file_fsp(req
, SVAL(params
,0));
2934 if (!check_fsp_ntquota_handle(conn
, req
, fsp
)) {
2935 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2936 status
= NT_STATUS_INVALID_HANDLE
;
2940 ctx
= talloc_init("set_user_quota");
2942 status
= NT_STATUS_NO_MEMORY
;
2945 inblob
.data
= (uint8_t*)pdata
;
2946 inblob
.length
= data_count
;
2948 err
= ndr_pull_struct_blob(
2952 (ndr_pull_flags_fn_t
)ndr_pull_file_quota_information
);
2954 if (!NDR_ERR_CODE_IS_SUCCESS(err
)) {
2955 DEBUG(0,("TRANSACT_SET_USER_QUOTA: failed to pull "
2956 "file_quota_information\n"));
2957 status
= NT_STATUS_INVALID_PARAMETER
;
2960 qt
.usedspace
= info
.quota_used
;
2962 qt
.softlim
= info
.quota_threshold
;
2964 qt
.hardlim
= info
.quota_limit
;
2968 if (vfs_set_ntquota(fsp
, SMB_USER_QUOTA_TYPE
, &sid
, &qt
)!=0) {
2969 status
= NT_STATUS_INTERNAL_ERROR
;
2973 send_nt_replies(conn
, req
, NT_STATUS_OK
, params
, param_len
,
2979 reply_nterror(req
, status
);
2981 #endif /* HAVE_SYS_QUOTAS */
2983 static void handle_nttrans(connection_struct
*conn
,
2984 struct trans_state
*state
,
2985 struct smb_request
*req
)
2987 if (get_Protocol() >= PROTOCOL_NT1
) {
2988 req
->flags2
|= 0x40; /* IS_LONG_NAME */
2989 SSVAL(discard_const_p(uint8_t, req
->inbuf
),smb_flg2
,req
->flags2
);
2993 SMB_PERFCOUNT_SET_SUBOP(&req
->pcd
, state
->call
);
2995 /* Now we must call the relevant NT_TRANS function */
2996 switch(state
->call
) {
2997 case NT_TRANSACT_CREATE
:
2999 START_PROFILE(NT_transact_create
);
3000 call_nt_transact_create(
3002 &state
->setup
, state
->setup_count
,
3003 &state
->param
, state
->total_param
,
3004 &state
->data
, state
->total_data
,
3005 state
->max_data_return
);
3006 END_PROFILE(NT_transact_create
);
3010 case NT_TRANSACT_IOCTL
:
3012 START_PROFILE(NT_transact_ioctl
);
3013 call_nt_transact_ioctl(
3015 &state
->setup
, state
->setup_count
,
3016 &state
->param
, state
->total_param
,
3017 &state
->data
, state
->total_data
,
3018 state
->max_data_return
);
3019 END_PROFILE(NT_transact_ioctl
);
3023 case NT_TRANSACT_SET_SECURITY_DESC
:
3025 START_PROFILE(NT_transact_set_security_desc
);
3026 call_nt_transact_set_security_desc(
3028 &state
->setup
, state
->setup_count
,
3029 &state
->param
, state
->total_param
,
3030 &state
->data
, state
->total_data
,
3031 state
->max_data_return
);
3032 END_PROFILE(NT_transact_set_security_desc
);
3036 case NT_TRANSACT_NOTIFY_CHANGE
:
3038 START_PROFILE(NT_transact_notify_change
);
3039 call_nt_transact_notify_change(
3041 &state
->setup
, state
->setup_count
,
3042 &state
->param
, state
->total_param
,
3043 &state
->data
, state
->total_data
,
3044 state
->max_data_return
,
3045 state
->max_param_return
);
3046 END_PROFILE(NT_transact_notify_change
);
3050 case NT_TRANSACT_RENAME
:
3052 START_PROFILE(NT_transact_rename
);
3053 call_nt_transact_rename(
3055 &state
->setup
, state
->setup_count
,
3056 &state
->param
, state
->total_param
,
3057 &state
->data
, state
->total_data
,
3058 state
->max_data_return
);
3059 END_PROFILE(NT_transact_rename
);
3063 case NT_TRANSACT_QUERY_SECURITY_DESC
:
3065 START_PROFILE(NT_transact_query_security_desc
);
3066 call_nt_transact_query_security_desc(
3068 &state
->setup
, state
->setup_count
,
3069 &state
->param
, state
->total_param
,
3070 &state
->data
, state
->total_data
,
3071 state
->max_data_return
);
3072 END_PROFILE(NT_transact_query_security_desc
);
3076 #ifdef HAVE_SYS_QUOTAS
3077 case NT_TRANSACT_GET_USER_QUOTA
:
3079 START_PROFILE(NT_transact_get_user_quota
);
3080 call_nt_transact_get_user_quota(
3082 &state
->setup
, state
->setup_count
,
3083 &state
->param
, state
->total_param
,
3084 &state
->data
, state
->total_data
,
3085 state
->max_data_return
);
3086 END_PROFILE(NT_transact_get_user_quota
);
3090 case NT_TRANSACT_SET_USER_QUOTA
:
3092 START_PROFILE(NT_transact_set_user_quota
);
3093 call_nt_transact_set_user_quota(
3095 &state
->setup
, state
->setup_count
,
3096 &state
->param
, state
->total_param
,
3097 &state
->data
, state
->total_data
,
3098 state
->max_data_return
);
3099 END_PROFILE(NT_transact_set_user_quota
);
3102 #endif /* HAVE_SYS_QUOTAS */
3105 /* Error in request */
3106 DEBUG(0,("handle_nttrans: Unknown request %d in "
3107 "nttrans call\n", state
->call
));
3108 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
3114 /****************************************************************************
3115 Reply to a SMBNTtrans.
3116 ****************************************************************************/
3118 void reply_nttrans(struct smb_request
*req
)
3120 connection_struct
*conn
= req
->conn
;
3125 uint16_t function_code
;
3127 struct trans_state
*state
;
3129 START_PROFILE(SMBnttrans
);
3131 if (req
->wct
< 19) {
3132 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3133 END_PROFILE(SMBnttrans
);
3137 pscnt
= IVAL(req
->vwv
+9, 1);
3138 psoff
= IVAL(req
->vwv
+11, 1);
3139 dscnt
= IVAL(req
->vwv
+13, 1);
3140 dsoff
= IVAL(req
->vwv
+15, 1);
3141 function_code
= SVAL(req
->vwv
+18, 0);
3143 if (IS_IPC(conn
) && (function_code
!= NT_TRANSACT_CREATE
)) {
3144 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3145 END_PROFILE(SMBnttrans
);
3149 result
= allow_new_trans(conn
->pending_trans
, req
->mid
);
3150 if (!NT_STATUS_IS_OK(result
)) {
3151 DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result
)));
3152 reply_nterror(req
, result
);
3153 END_PROFILE(SMBnttrans
);
3157 if ((state
= talloc(conn
, struct trans_state
)) == NULL
) {
3158 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
3159 END_PROFILE(SMBnttrans
);
3163 state
->cmd
= SMBnttrans
;
3165 state
->mid
= req
->mid
;
3166 state
->vuid
= req
->vuid
;
3167 state
->total_data
= IVAL(req
->vwv
+3, 1);
3169 state
->total_param
= IVAL(req
->vwv
+1, 1);
3170 state
->param
= NULL
;
3171 state
->max_data_return
= IVAL(req
->vwv
+7, 1);
3172 state
->max_param_return
= IVAL(req
->vwv
+5, 1);
3174 /* setup count is in *words* */
3175 state
->setup_count
= 2*CVAL(req
->vwv
+17, 1);
3176 state
->setup
= NULL
;
3177 state
->call
= function_code
;
3179 DEBUG(10, ("num_setup=%u, "
3180 "param_total=%u, this_param=%u, max_param=%u, "
3181 "data_total=%u, this_data=%u, max_data=%u, "
3182 "param_offset=%u, data_offset=%u\n",
3183 (unsigned)state
->setup_count
,
3184 (unsigned)state
->total_param
, (unsigned)pscnt
,
3185 (unsigned)state
->max_param_return
,
3186 (unsigned)state
->total_data
, (unsigned)dscnt
,
3187 (unsigned)state
->max_data_return
,
3188 (unsigned)psoff
, (unsigned)dsoff
));
3191 * All nttrans messages we handle have smb_wct == 19 +
3192 * state->setup_count. Ensure this is so as a sanity check.
3195 if(req
->wct
!= 19 + (state
->setup_count
/2)) {
3196 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
3197 req
->wct
, 19 + (state
->setup_count
/2)));
3201 /* Don't allow more than 128mb for each value. */
3202 if ((state
->total_data
> (1024*1024*128)) ||
3203 (state
->total_param
> (1024*1024*128))) {
3204 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
3205 END_PROFILE(SMBnttrans
);
3209 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
3212 if (state
->total_data
) {
3214 if (trans_oob(state
->total_data
, 0, dscnt
)
3215 || trans_oob(smb_len(req
->inbuf
), dsoff
, dscnt
)) {
3219 /* Can't use talloc here, the core routines do realloc on the
3220 * params and data. */
3221 if ((state
->data
= (char *)SMB_MALLOC(state
->total_data
)) == NULL
) {
3222 DEBUG(0,("reply_nttrans: data malloc fail for %u "
3223 "bytes !\n", (unsigned int)state
->total_data
));
3225 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
3226 END_PROFILE(SMBnttrans
);
3230 memcpy(state
->data
,smb_base(req
->inbuf
)+dsoff
,dscnt
);
3233 if (state
->total_param
) {
3235 if (trans_oob(state
->total_param
, 0, pscnt
)
3236 || trans_oob(smb_len(req
->inbuf
), psoff
, pscnt
)) {
3240 /* Can't use talloc here, the core routines do realloc on the
3241 * params and data. */
3242 if ((state
->param
= (char *)SMB_MALLOC(state
->total_param
)) == NULL
) {
3243 DEBUG(0,("reply_nttrans: param malloc fail for %u "
3244 "bytes !\n", (unsigned int)state
->total_param
));
3245 SAFE_FREE(state
->data
);
3247 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
3248 END_PROFILE(SMBnttrans
);
3252 memcpy(state
->param
,smb_base(req
->inbuf
)+psoff
,pscnt
);
3255 state
->received_data
= dscnt
;
3256 state
->received_param
= pscnt
;
3258 if(state
->setup_count
> 0) {
3259 DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
3260 state
->setup_count
));
3263 * No overflow possible here, state->setup_count is an
3264 * unsigned int, being filled by a single byte from
3265 * CVAL(req->vwv+13, 0) above. The cast in the comparison
3266 * below is not necessary, it's here to clarify things. The
3267 * validity of req->vwv and req->wct has been checked in
3268 * init_smb_request already.
3270 if ((state
->setup_count
/2) + 19 > (unsigned int)req
->wct
) {
3274 state
->setup
= (uint16_t *)TALLOC(state
, state
->setup_count
);
3275 if (state
->setup
== NULL
) {
3276 DEBUG(0,("reply_nttrans : Out of memory\n"));
3277 SAFE_FREE(state
->data
);
3278 SAFE_FREE(state
->param
);
3280 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
3281 END_PROFILE(SMBnttrans
);
3285 memcpy(state
->setup
, req
->vwv
+19, state
->setup_count
);
3286 dump_data(10, (uint8_t *)state
->setup
, state
->setup_count
);
3289 if ((state
->received_data
== state
->total_data
) &&
3290 (state
->received_param
== state
->total_param
)) {
3291 handle_nttrans(conn
, state
, req
);
3292 SAFE_FREE(state
->param
);
3293 SAFE_FREE(state
->data
);
3295 END_PROFILE(SMBnttrans
);
3299 DLIST_ADD(conn
->pending_trans
, state
);
3301 /* We need to send an interim response then receive the rest
3302 of the parameter/data bytes */
3303 reply_outbuf(req
, 0, 0);
3304 show_msg((char *)req
->outbuf
);
3305 END_PROFILE(SMBnttrans
);
3310 DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
3311 SAFE_FREE(state
->data
);
3312 SAFE_FREE(state
->param
);
3314 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3315 END_PROFILE(SMBnttrans
);
3319 /****************************************************************************
3320 Reply to a SMBnttranss
3321 ****************************************************************************/
3323 void reply_nttranss(struct smb_request
*req
)
3325 connection_struct
*conn
= req
->conn
;
3326 uint32_t pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
3327 struct trans_state
*state
;
3329 START_PROFILE(SMBnttranss
);
3331 show_msg((const char *)req
->inbuf
);
3333 /* Windows clients expect all replies to
3334 an NT transact secondary (SMBnttranss 0xA1)
3335 to have a command code of NT transact
3336 (SMBnttrans 0xA0). See bug #8989 for details. */
3337 req
->cmd
= SMBnttrans
;
3339 if (req
->wct
< 18) {
3340 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3341 END_PROFILE(SMBnttranss
);
3345 for (state
= conn
->pending_trans
; state
!= NULL
;
3346 state
= state
->next
) {
3347 if (state
->mid
== req
->mid
) {
3352 if ((state
== NULL
) || (state
->cmd
!= SMBnttrans
)) {
3353 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3354 END_PROFILE(SMBnttranss
);
3358 /* Revise state->total_param and state->total_data in case they have
3359 changed downwards */
3360 if (IVAL(req
->vwv
+1, 1) < state
->total_param
) {
3361 state
->total_param
= IVAL(req
->vwv
+1, 1);
3363 if (IVAL(req
->vwv
+3, 1) < state
->total_data
) {
3364 state
->total_data
= IVAL(req
->vwv
+3, 1);
3367 pcnt
= IVAL(req
->vwv
+5, 1);
3368 poff
= IVAL(req
->vwv
+7, 1);
3369 pdisp
= IVAL(req
->vwv
+9, 1);
3371 dcnt
= IVAL(req
->vwv
+11, 1);
3372 doff
= IVAL(req
->vwv
+13, 1);
3373 ddisp
= IVAL(req
->vwv
+15, 1);
3375 state
->received_param
+= pcnt
;
3376 state
->received_data
+= dcnt
;
3378 if ((state
->received_data
> state
->total_data
) ||
3379 (state
->received_param
> state
->total_param
))
3383 if (trans_oob(state
->total_param
, pdisp
, pcnt
)
3384 || trans_oob(smb_len(req
->inbuf
), poff
, pcnt
)) {
3387 memcpy(state
->param
+pdisp
, smb_base(req
->inbuf
)+poff
,pcnt
);
3391 if (trans_oob(state
->total_data
, ddisp
, dcnt
)
3392 || trans_oob(smb_len(req
->inbuf
), doff
, dcnt
)) {
3395 memcpy(state
->data
+ddisp
, smb_base(req
->inbuf
)+doff
,dcnt
);
3398 if ((state
->received_param
< state
->total_param
) ||
3399 (state
->received_data
< state
->total_data
)) {
3400 END_PROFILE(SMBnttranss
);
3404 handle_nttrans(conn
, state
, req
);
3406 DLIST_REMOVE(conn
->pending_trans
, state
);
3407 SAFE_FREE(state
->data
);
3408 SAFE_FREE(state
->param
);
3410 END_PROFILE(SMBnttranss
);
3415 DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
3416 DLIST_REMOVE(conn
->pending_trans
, state
);
3417 SAFE_FREE(state
->data
);
3418 SAFE_FREE(state
->param
);
3420 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3421 END_PROFILE(SMBnttranss
);