CVE-2022-2031 tests/krb5: Allow requesting a TGT to a different sname and realm
[Samba.git] / source3 / smbd / nttrans.c
blob2b74241107106f82478a3dc78868079c0516f016
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"
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)
40 if (ptr==NULL) {
41 smb_panic("nttrans_realloc() called with NULL ptr");
44 *ptr = (char *)SMB_REALLOC(*ptr, size);
45 if(*ptr == NULL) {
46 return NULL;
48 memset(*ptr,'\0',size);
49 return *ptr;
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;
66 int useable_space;
67 char *pp = params;
68 char *pd = pdata;
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
77 * the empty packet.
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,
84 0, 0, nt_error,
85 __LINE__,__FILE__);
87 show_msg((char *)req->outbuf);
88 if (!srv_send_smb(xconn,
89 (char *)req->outbuf,
90 true, req->seqnum+1,
91 IS_CONN_ENCRYPTED(conn),
92 &req->pcd)) {
93 exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
95 TALLOC_FREE(req->outbuf);
96 return;
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
117 + 2 * 18 /* wct */
118 + alignment_offset
119 + data_alignment_offset);
121 if (useable_space < 0) {
122 char *msg = talloc_asprintf(
123 talloc_tos(),
124 "send_nt_replies failed sanity useable_space = %d!!!",
125 useable_space);
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);
170 } else {
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,
186 pp - params);
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);
198 } else {
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,
218 alignment_offset);
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,
246 0, 0, nt_error,
247 __LINE__,__FILE__);
250 /* Send the packet */
251 show_msg((char *)req->outbuf);
252 if (!srv_send_smb(xconn,
253 (char *)req->outbuf,
254 true, req->seqnum+1,
255 IS_CONN_ENCRYPTED(conn),
256 &req->pcd)) {
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;
269 * Sanity check
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)
287 files_struct *fsp;
288 NTSTATUS status;
290 DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
292 /* Strip \\ off the name if present. */
293 while (fname[0] == '\\') {
294 fname++;
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,
301 ERRDOS, ERRbadpipe);
302 return;
304 reply_nterror(req, status);
305 return;
308 *ppnum = fsp->fnum;
309 return;
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)
319 char *fname = NULL;
320 uint16_t pnum = FNUM_FIELD_INVALID;
321 char *p = NULL;
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);
327 if (!fname) {
328 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
329 ERRDOS, ERRbadpipe);
330 return;
332 nt_open_pipe(fname, conn, req, &pnum);
334 if (req->outbuf) {
335 /* error reply */
336 return;
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);
351 } else {
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;
359 p++;
360 SSVAL(p,0,pnum);
361 p += 2;
362 SIVAL(p,0,FILE_WAS_OPENED);
363 p += 4;
364 p += 32;
365 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
366 p += 20;
367 /* File type. */
368 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
369 /* Device state. */
370 SSVAL(p,2, 0x5FF); /* ? */
371 p += 4;
373 if (flags & EXTENDED_RESPONSE_REQUIRED) {
374 p += 25;
375 SIVAL(p,0,FILE_GENERIC_ALL);
377 * For pipes W2K3 seems to return
378 * 0x12019B next.
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;
389 bool case_sensitive;
390 bool case_preserve;
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;
403 return 0;
406 /****************************************************************************
407 Save case semantics.
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))) {
416 return NULL;
419 result->conn = conn;
420 result->case_sensitive = conn->case_sensitive;
421 result->case_preserve = conn->case_preserve;
422 result->short_case_preserve = conn->short_case_preserve;
424 /* Set to POSIX. */
425 conn->case_sensitive = True;
426 conn->case_preserve = True;
427 conn->short_case_preserve = True;
429 talloc_set_destructor(result, restore_case_semantics);
431 return result;
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,
440 char *path,
441 char **path_out)
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) {
464 char *stream = NULL;
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);
488 } else {
490 * Copy in the base directory name.
493 new_path = talloc_asprintf(talloc_tos(),
494 "%s/%s",
495 dir_fsp->fsp_name->base_name,
496 path);
498 if (new_path == NULL) {
499 return NT_STATUS_NO_MEMORY;
502 *path_out = new_path;
503 return NT_STATUS_OK;
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;
514 char *fname = NULL;
515 uint32_t flags;
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. */
525 uint32_t fattr=0;
526 off_t file_len = 0;
527 int info = 0;
528 files_struct *fsp = NULL;
529 char *p = NULL;
530 struct timespec create_timespec;
531 struct timespec c_timespec;
532 struct timespec a_timespec;
533 struct timespec m_timespec;
534 NTSTATUS status;
535 int oplock_request;
536 uint8_t oplock_granted = NO_OPLOCK_RETURN;
537 struct case_semantics_state *case_state = NULL;
538 uint32_t ucf_flags;
539 TALLOC_CTX *ctx = talloc_tos();
541 START_PROFILE(SMBntcreateX);
543 if (req->wct < 24) {
544 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
545 goto out;
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);
563 goto out;
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",
570 (unsigned int)flags,
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,
577 fname));
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.
589 if (IS_IPC(conn)) {
590 if (lp_nt_pipe_support()) {
591 do_ntcreate_pipe_open(conn, req);
592 goto out;
594 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
595 goto out;
598 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
599 if (oplock_request) {
600 oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
601 ? BATCH_OPLOCK : 0;
604 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
605 case_state = set_posix_case_semantics(ctx, conn);
606 if (!case_state) {
607 reply_nterror(req, NT_STATUS_NO_MEMORY);
608 goto out;
612 if (root_dir_fid != 0) {
613 char *new_fname = NULL;
615 status = get_relative_fid_filename(conn,
616 req,
617 root_dir_fid,
618 fname,
619 &new_fname);
620 if (!NT_STATUS_IS_OK(status)) {
621 reply_nterror(req, status);
622 goto out;
624 fname = new_fname;
627 ucf_flags = filename_create_ucf_flags(req, create_disposition);
628 status = filename_convert(ctx,
629 conn,
630 fname,
631 ucf_flags,
633 &smb_fname);
635 TALLOC_FREE(case_state);
637 if (!NT_STATUS_IS_OK(status)) {
638 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
639 reply_botherror(req,
640 NT_STATUS_PATH_NOT_COVERED,
641 ERRSRV, ERRbadpath);
642 goto out;
644 reply_nterror(req, status);
645 goto out;
649 * Bug #6898 - clients using Windows opens should
650 * never be able to set this attribute into the
651 * VFS.
653 file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
655 status = SMB_VFS_CREATE_FILE(
656 conn, /* conn */
657 req, /* req */
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 */
665 NULL, /* lease */
666 allocation_size, /* allocation_size */
667 0, /* private_flags */
668 NULL, /* sd */
669 NULL, /* ea_list */
670 &fsp, /* result */
671 &info, /* pinfo */
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. */
677 goto out;
679 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
680 bool ok = defer_smb1_sharing_violation(req);
681 if (ok) {
682 goto out;
685 reply_openerror(req, status);
686 goto out;
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;
709 } else {
710 oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
712 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
713 oplock_granted = LEVEL_II_OPLOCK_RETURN;
714 } else {
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);
728 } else {
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);
739 p++;
740 SSVAL(p,0,fsp->fnum);
741 p += 2;
742 if ((create_disposition == FILE_SUPERSEDE)
743 && (info == FILE_WAS_OVERWRITTEN)) {
744 SIVAL(p,0,FILE_WAS_SUPERSEDED);
745 } else {
746 SIVAL(p,0,info);
748 p += 4;
750 fattr = fdos_mode(fsp);
751 if (fattr == 0) {
752 fattr = FILE_ATTRIBUTE_NORMAL;
755 /* Create time. */
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. */
769 p += 8;
770 put_long_date_full_timespec(conn->ts_res, p, &a_timespec); /* access time */
771 p += 8;
772 put_long_date_full_timespec(conn->ts_res, p, &m_timespec); /* write time */
773 p += 8;
774 put_long_date_full_timespec(conn->ts_res, p, &c_timespec); /* change time */
775 p += 8;
776 SIVAL(p,0,fattr); /* File Attributes. */
777 p += 4;
778 SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&smb_fname->st));
779 p += 8;
780 SOFF_T(p,0,file_len);
781 p += 8;
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);
806 p += 4;
807 SCVAL(p,0,fsp->fsp_flags.is_directory ? 1 : 0);
809 if (flags & EXTENDED_RESPONSE_REQUIRED) {
810 uint32_t perms = 0;
811 p += 25;
812 if (fsp->fsp_flags.is_directory ||
813 fsp->fsp_flags.can_write ||
814 can_write_to_fsp(fsp))
816 perms = FILE_GENERIC_ALL;
817 } else {
818 perms = FILE_GENERIC_READ|FILE_EXECUTE;
820 SIVAL(p,0,perms);
823 DEBUG(5,("reply_ntcreate_and_X: %s, open name = %s\n",
824 fsp_fnum_dbg(fsp), smb_fname_str_dbg(smb_fname)));
826 out:
827 END_PROFILE(SMBntcreateX);
828 return;
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)
841 char *fname = NULL;
842 char *params = *ppparams;
843 uint16_t pnum = FNUM_FIELD_INVALID;
844 char *p = NULL;
845 NTSTATUS status;
846 size_t param_len;
847 uint32_t flags;
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);
857 return;
860 flags = IVAL(params,0);
862 if (req->posix_pathnames) {
863 srvstr_get_path_posix(ctx,
864 params,
865 req->flags2,
866 &fname,
867 params+53,
868 parameter_count-53,
869 STR_TERMINATE,
870 &status);
871 } else {
872 srvstr_get_path(ctx,
873 params,
874 req->flags2,
875 &fname,
876 params+53,
877 parameter_count-53,
878 STR_TERMINATE,
879 &status);
881 if (!NT_STATUS_IS_OK(status)) {
882 reply_nterror(req, status);
883 return;
886 nt_open_pipe(fname, conn, req, &pnum);
888 if (req->outbuf) {
889 /* Error return */
890 return;
893 /* Realloc the size of parameters and data we will return */
894 if (flags & EXTENDED_RESPONSE_REQUIRED) {
895 /* Extended response is 32 more byyes. */
896 param_len = 101;
897 } else {
898 param_len = 69;
900 params = nttrans_realloc(ppparams, param_len);
901 if(params == NULL) {
902 reply_nterror(req, NT_STATUS_NO_MEMORY);
903 return;
906 p = params;
907 SCVAL(p,0,NO_OPLOCK_RETURN);
909 p += 2;
910 SSVAL(p,0,pnum);
911 p += 2;
912 SIVAL(p,0,FILE_WAS_OPENED);
913 p += 8;
915 p += 32;
916 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
917 p += 20;
918 /* File type. */
919 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
920 /* Device state. */
921 SSVAL(p,2, 0x5FF); /* ? */
922 p += 4;
924 if (flags & EXTENDED_RESPONSE_REQUIRED) {
925 p += 25;
926 SIVAL(p,0,FILE_GENERIC_ALL);
928 * For pipes W2K3 seems to return
929 * 0x12019B next.
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);
940 return;
943 /*********************************************************************
944 Windows seems to do canonicalization of inheritance bits. Do the
945 same.
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.
959 * See:
961 * http://social.msdn.microsoft.com/Forums/eu/os_fileservices/thread/11f77b68-731e-407d-b1b3-064750716531
963 * for details.
966 if (!lp_acl_flag_inherited_canonicalization(SNUM(fsp->conn))) {
967 psd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
968 return;
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;
990 NTSTATUS status;
992 if (!CAN_WRITE(fsp->conn)) {
993 return NT_STATUS_ACCESS_DENIED;
996 if (!lp_nt_acl_support(SNUM(fsp->conn))) {
997 return NT_STATUS_OK;
1000 status = refuse_symlink_fsp(fsp);
1001 if (!NT_STATUS_IS_OK(status)) {
1002 DBG_DEBUG("ACL set on symlink %s denied.\n",
1003 fsp_str_dbg(fsp));
1004 return status;
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. */
1038 if (psd->dacl) {
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. */
1055 if (psd->sacl) {
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);
1076 TALLOC_FREE(psd);
1078 return status;
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;
1089 NTSTATUS status;
1091 if (sd_len == 0) {
1092 return NT_STATUS_INVALID_PARAMETER;
1095 status = unmarshall_sec_desc(talloc_tos(), data, sd_len, &psd);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 return 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;
1116 char *fname = NULL;
1117 char *params = *ppparams;
1118 char *data = *ppdata;
1119 /* Breakout the oplock request bits so we can set the reply bits separately. */
1120 uint32_t fattr=0;
1121 off_t file_len = 0;
1122 int info = 0;
1123 files_struct *fsp = NULL;
1124 char *p = NULL;
1125 uint32_t flags;
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;
1131 uint32_t sd_len;
1132 struct security_descriptor *sd = NULL;
1133 uint32_t ea_len;
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;
1140 NTSTATUS status;
1141 size_t param_len;
1142 uint64_t allocation_size;
1143 int oplock_request;
1144 uint8_t oplock_granted;
1145 struct case_semantics_state *case_state = NULL;
1146 uint32_t ucf_flags;
1147 TALLOC_CTX *ctx = talloc_tos();
1149 DEBUG(5,("call_nt_transact_create\n"));
1152 * If it's an IPC, use the pipe handler.
1155 if (IS_IPC(conn)) {
1156 if (lp_nt_pipe_support()) {
1157 do_nt_transact_create_pipe(
1158 conn, req,
1159 ppsetup, setup_count,
1160 ppparams, parameter_count,
1161 ppdata, data_count);
1162 goto out;
1164 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1165 goto out;
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);
1175 goto out;
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,
1197 params,
1198 req->flags2,
1199 &fname,
1200 params+53,
1201 parameter_count-53,
1202 STR_TERMINATE,
1203 &status);
1204 } else {
1205 srvstr_get_path(ctx,
1206 params,
1207 req->flags2,
1208 &fname,
1209 params+53,
1210 parameter_count-53,
1211 STR_TERMINATE,
1212 &status);
1214 if (!NT_STATUS_IS_OK(status)) {
1215 reply_nterror(req, status);
1216 goto out;
1219 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1220 case_state = set_posix_case_semantics(ctx, conn);
1221 if (!case_state) {
1222 reply_nterror(req, NT_STATUS_NO_MEMORY);
1223 goto out;
1227 if (root_dir_fid != 0) {
1228 char *new_fname = NULL;
1230 status = get_relative_fid_filename(conn,
1231 req,
1232 root_dir_fid,
1233 fname,
1234 &new_fname);
1235 if (!NT_STATUS_IS_OK(status)) {
1236 reply_nterror(req, status);
1237 goto out;
1239 fname = new_fname;
1242 ucf_flags = filename_create_ucf_flags(req, create_disposition);
1243 status = filename_convert(ctx,
1244 conn,
1245 fname,
1246 ucf_flags,
1248 &smb_fname);
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);
1257 goto out;
1259 reply_nterror(req, status);
1260 goto out;
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);
1271 goto out;
1274 if (sd_len) {
1275 DEBUG(10, ("call_nt_transact_create - sd_len = %d\n",
1276 sd_len));
1278 status = unmarshall_sec_desc(ctx, (uint8_t *)data, sd_len,
1279 &sd);
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);
1285 goto out;
1289 if (ea_len) {
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);
1295 goto out;
1298 if (ea_len < 10) {
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);
1303 goto out;
1306 /* We have already checked that ea_len <= data_count here. */
1307 ea_list = read_nttrans_ea_list(talloc_tos(), data + sd_len,
1308 ea_len);
1309 if (ea_list == NULL) {
1310 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1311 goto out;
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. */
1319 param_len = 101;
1320 } else {
1321 param_len = 69;
1323 params = nttrans_realloc(ppparams, param_len);
1324 if(params == NULL) {
1325 reply_nterror(req, NT_STATUS_NO_MEMORY);
1326 goto out;
1329 memset(params, '\0', param_len);
1330 send_nt_replies(conn, req, STATUS_INVALID_EA_NAME,
1331 params, param_len, NULL, 0);
1332 goto out;
1336 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1337 if (oplock_request) {
1338 oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
1339 ? BATCH_OPLOCK : 0;
1343 * Bug #6898 - clients using Windows opens should
1344 * never be able to set this attribute into the
1345 * VFS.
1347 file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
1349 status = SMB_VFS_CREATE_FILE(
1350 conn, /* conn */
1351 req, /* req */
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 */
1359 NULL, /* lease */
1360 allocation_size, /* allocation_size */
1361 0, /* private_flags */
1362 sd, /* sd */
1363 ea_list, /* ea_list */
1364 &fsp, /* result */
1365 &info, /* pinfo */
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. */
1371 return;
1373 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
1374 bool ok = defer_smb1_sharing_violation(req);
1375 if (ok) {
1376 return;
1379 reply_openerror(req, status);
1380 goto out;
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;
1403 } else {
1404 oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
1406 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
1407 oplock_granted = LEVEL_II_OPLOCK_RETURN;
1408 } else {
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. */
1417 param_len = 101;
1418 } else {
1419 param_len = 69;
1421 params = nttrans_realloc(ppparams, param_len);
1422 if(params == NULL) {
1423 reply_nterror(req, NT_STATUS_NO_MEMORY);
1424 goto out;
1427 p = params;
1428 SCVAL(p, 0, oplock_granted);
1430 p += 2;
1431 SSVAL(p,0,fsp->fnum);
1432 p += 2;
1433 if ((create_disposition == FILE_SUPERSEDE)
1434 && (info == FILE_WAS_OVERWRITTEN)) {
1435 SIVAL(p,0,FILE_WAS_SUPERSEDED);
1436 } else {
1437 SIVAL(p,0,info);
1439 p += 8;
1441 fattr = fdos_mode(fsp);
1442 if (fattr == 0) {
1443 fattr = FILE_ATTRIBUTE_NORMAL;
1446 /* Create time. */
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. */
1460 p += 8;
1461 put_long_date_full_timespec(conn->ts_res, p, &a_timespec); /* access time */
1462 p += 8;
1463 put_long_date_full_timespec(conn->ts_res, p, &m_timespec); /* write time */
1464 p += 8;
1465 put_long_date_full_timespec(conn->ts_res, p, &c_timespec); /* change time */
1466 p += 8;
1467 SIVAL(p,0,fattr); /* File Attributes. */
1468 p += 4;
1469 SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st));
1470 p += 8;
1471 SOFF_T(p,0,file_len);
1472 p += 8;
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);
1497 p += 4;
1498 SCVAL(p,0,fsp->fsp_flags.is_directory ? 1 : 0);
1500 if (flags & EXTENDED_RESPONSE_REQUIRED) {
1501 uint32_t perms = 0;
1502 p += 25;
1503 if (fsp->fsp_flags.is_directory ||
1504 fsp->fsp_flags.can_write ||
1505 can_write_to_fsp(fsp))
1507 perms = FILE_GENERIC_ALL;
1508 } else {
1509 perms = FILE_GENERIC_READ|FILE_EXECUTE;
1511 SIVAL(p,0,perms);
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);
1519 out:
1520 return;
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;
1532 bool found;
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);
1541 if (!found) {
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);
1549 return;
1552 /****************************************************************************
1553 Copy a file.
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,
1561 uint32_t attrs)
1563 files_struct *fsp1,*fsp2;
1564 uint32_t fattr;
1565 int info;
1566 off_t ret=-1;
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;
1573 goto out;
1576 /* Source must already exist. */
1577 if (!VALID_STAT(smb_fname_src->st)) {
1578 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1579 goto out;
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;
1586 goto out;
1589 /* Disallow if dst file already exists. */
1590 if (VALID_STAT(smb_fname_dst->st)) {
1591 status = NT_STATUS_OBJECT_NAME_COLLISION;
1592 goto out;
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;
1598 goto out;
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(
1606 conn, /* conn */
1607 req, /* req */
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 */
1612 FILE_SHARE_DELETE),
1613 FILE_OPEN, /* create_disposition*/
1614 0, /* create_options */
1615 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
1616 NO_OPLOCK, /* oplock_request */
1617 NULL, /* lease */
1618 0, /* allocation_size */
1619 0, /* private_flags */
1620 NULL, /* sd */
1621 NULL, /* ea_list */
1622 &fsp1, /* result */
1623 &info, /* pinfo */
1624 NULL, NULL); /* create context */
1626 if (!NT_STATUS_IS_OK(status)) {
1627 goto out;
1630 status = SMB_VFS_CREATE_FILE(
1631 conn, /* conn */
1632 req, /* req */
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 */
1637 FILE_SHARE_DELETE),
1638 FILE_CREATE, /* create_disposition*/
1639 0, /* create_options */
1640 fattr, /* file_attributes */
1641 NO_OPLOCK, /* oplock_request */
1642 NULL, /* lease */
1643 0, /* allocation_size */
1644 0, /* private_flags */
1645 NULL, /* sd */
1646 NULL, /* ea_list */
1647 &fsp2, /* result */
1648 &info, /* pinfo */
1649 NULL, NULL); /* create context */
1651 if (!NT_STATUS_IS_OK(status)) {
1652 close_file(NULL, fsp1, ERROR_CLOSE);
1653 goto out;
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
1664 * close of fsp1.
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
1675 case. JRA */
1677 status = SMB_VFS_PARENT_PATHNAME(conn,
1678 talloc_tos(),
1679 smb_fname_dst,
1680 &parent,
1681 NULL);
1682 if (!NT_STATUS_IS_OK(status)) {
1683 goto out;
1685 if (smb_fname_dst->fsp == NULL) {
1686 status = synthetic_pathref(parent,
1687 conn->cwd_fsp,
1688 smb_fname_dst->base_name,
1689 smb_fname_dst->stream_name,
1690 NULL,
1691 smb_fname_dst->twrp,
1692 smb_fname_dst->flags,
1693 &pathref);
1695 /* should we handle NT_STATUS_OBJECT_NAME_NOT_FOUND specially here ???? */
1696 if (!NT_STATUS_IS_OK(status)) {
1697 TALLOC_FREE(parent);
1698 goto out;
1700 file_set_dosmode(conn, pathref, fattr, parent, false);
1701 smb_fname_dst->st.st_ex_mode = pathref->st.st_ex_mode;
1702 } else {
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;
1709 goto out;
1711 out:
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)));
1718 return status;
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;
1733 const char *p;
1734 NTSTATUS status;
1735 uint32_t attrs;
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);
1744 if (req->wct < 4) {
1745 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1746 goto out;
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,
1754 &status);
1755 if (!NT_STATUS_IS_OK(status)) {
1756 reply_nterror(req, status);
1757 goto out;
1760 if (!req->posix_pathnames && ms_has_wild(oldname)) {
1761 reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
1762 goto out;
1765 p++;
1766 p += srvstr_get_path_req(ctx, req, &newname, p, STR_TERMINATE,
1767 &status);
1768 if (!NT_STATUS_IS_OK(status)) {
1769 reply_nterror(req, status);
1770 goto out;
1773 if (!req->posix_pathnames && ms_has_wild(newname)) {
1774 reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
1775 goto out;
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);
1784 goto out;
1786 stream_rename = true;
1790 /* rename_internals() calls unix_convert(), so don't call it here. */
1791 status = filename_convert(ctx, conn,
1792 oldname,
1793 ucf_flags_src,
1795 &smb_fname_old);
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);
1802 goto out;
1804 reply_nterror(req, status);
1805 goto out;
1808 /* Get the last component of the destination for rename_internals(). */
1809 dst_original_lcomp = get_original_lcomp(ctx,
1810 conn,
1811 newname,
1812 ucf_flags_dst);
1813 if (dst_original_lcomp == NULL) {
1814 reply_nterror(req, NT_STATUS_NO_MEMORY);
1815 goto out;
1818 status = filename_convert(ctx, conn,
1819 newname,
1820 ucf_flags_dst,
1822 &smb_fname_new);
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);
1829 goto out;
1831 reply_nterror(req, status);
1832 goto out;
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);
1842 goto out;
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,
1853 conn,
1854 req,
1855 smb_fname_old,
1856 smb_fname_new,
1857 dst_original_lcomp,
1858 attrs,
1859 false,
1860 DELETE_ACCESS);
1861 break;
1862 case RENAME_FLAG_HARD_LINK:
1863 status = hardlink_internals(ctx,
1864 conn,
1865 req,
1866 false,
1867 smb_fname_old,
1868 smb_fname_new);
1869 break;
1870 case RENAME_FLAG_COPY:
1871 status = copy_internals(ctx,
1872 conn,
1873 req,
1874 smb_fname_old,
1875 smb_fname_new,
1876 attrs);
1877 break;
1878 case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
1879 status = NT_STATUS_INVALID_PARAMETER;
1880 break;
1881 default:
1882 status = NT_STATUS_ACCESS_DENIED; /* Default error. */
1883 break;
1886 if (!NT_STATUS_IS_OK(status)) {
1887 if (open_was_deferred(req->xconn, req->mid)) {
1888 /* We have re-scheduled this call. */
1889 goto out;
1891 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
1892 bool ok = defer_smb1_sharing_violation(req);
1893 if (ok) {
1894 goto out;
1898 reply_nterror(req, status);
1899 goto out;
1902 reply_outbuf(req, 0, 0);
1903 out:
1904 END_PROFILE(SMBntrename);
1905 return;
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,
1922 uint16_t **ppsetup,
1923 uint32_t setup_count,
1924 char **ppparams,
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;
1931 files_struct *fsp;
1932 uint32_t filter;
1933 NTSTATUS status;
1934 bool recursive;
1936 if(setup_count < 6) {
1937 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1938 return;
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"));
1947 if(!fsp) {
1948 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1949 return;
1953 char *filter_string;
1955 if (!(filter_string = notify_filter_string(NULL, filter))) {
1956 reply_nterror(req,NT_STATUS_NO_MEMORY);
1957 return;
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);
1969 return;
1972 if (fsp->notify == NULL) {
1974 status = change_notify_create(fsp,
1975 max_param_count,
1976 filter,
1977 recursive);
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);
1982 return;
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
1994 * here.
1997 change_notify_reply(req,
1998 NT_STATUS_OK,
1999 max_param_count,
2000 fsp->notify,
2001 smbd_smb1_notify_reply);
2004 * change_notify_reply() above has independently sent its
2005 * results
2007 return;
2011 * No changes pending, queue the request
2014 status = change_notify_add_request(req,
2015 max_param_count,
2016 filter,
2017 recursive, fsp,
2018 smbd_smb1_notify_reply);
2019 if (!NT_STATUS_IS_OK(status)) {
2020 reply_nterror(req, status);
2022 return;
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;
2039 NTSTATUS status;
2040 TALLOC_CTX *ctx = talloc_tos();
2042 if(parameter_count < 5) {
2043 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2044 return;
2047 fsp = file_fsp(req, SVAL(params, 0));
2048 if (!check_fsp(conn, req, fsp)) {
2049 return;
2051 if (req->posix_pathnames) {
2052 srvstr_get_path_posix(ctx,
2053 params,
2054 req->flags2,
2055 &new_name,
2056 params+4,
2057 parameter_count - 4,
2058 STR_TERMINATE,
2059 &status);
2060 } else {
2061 srvstr_get_path(ctx,
2062 params,
2063 req->flags2,
2064 &new_name,
2065 params+4,
2066 parameter_count - 4,
2067 STR_TERMINATE,
2068 &status);
2071 if (!NT_STATUS_IS_OK(status)) {
2072 reply_nterror(req, status);
2073 return;
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));
2085 return;
2088 /******************************************************************************
2089 Fake up a completely empty SD.
2090 *******************************************************************************/
2092 static NTSTATUS get_null_nt_acl(TALLOC_CTX *mem_ctx, struct security_descriptor **ppsd)
2094 size_t sd_size;
2096 *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
2097 if(!*ppsd) {
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
2109 the required size.
2110 ****************************************************************************/
2112 NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
2113 TALLOC_CTX *mem_ctx,
2114 files_struct *fsp,
2115 uint32_t security_info_wanted,
2116 uint32_t max_data_count,
2117 uint8_t **ppmarshalled_sd,
2118 size_t *psd_size)
2120 NTSTATUS status;
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"));
2132 TALLOC_FREE(frame);
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"));
2139 TALLOC_FREE(frame);
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",
2146 fsp_str_dbg(fsp));
2147 TALLOC_FREE(frame);
2148 return status;
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
2161 * smb2.sdread test.
2163 need_to_read_sd = true;
2166 if (lp_nt_acl_support(SNUM(conn)) &&
2167 ((security_info_wanted & SECINFO_LABEL) == 0) &&
2168 need_to_read_sd)
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);
2180 } else {
2181 status = get_null_nt_acl(frame, &psd);
2184 if (!NT_STATUS_IS_OK(status)) {
2185 TALLOC_FREE(frame);
2186 return 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;
2197 psd->dacl = NULL;
2199 if (!(security_info_wanted & SECINFO_SACL)) {
2200 psd->type &= ~SEC_DESC_SACL_PRESENT;
2201 psd->sacl = NULL;
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;
2217 psd->dacl = NULL;
2218 psd->sacl = 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",
2229 fsp_str_dbg(fsp)));
2230 NDR_PRINT_DEBUG(security_descriptor, psd);
2233 if (max_data_count < *psd_size) {
2234 TALLOC_FREE(frame);
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)) {
2242 TALLOC_FREE(frame);
2243 return status;
2246 TALLOC_FREE(frame);
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,
2256 uint16_t **ppsetup,
2257 uint32_t setup_count,
2258 char **ppparams,
2259 uint32_t parameter_count,
2260 char **ppdata,
2261 uint32_t data_count,
2262 uint32_t max_data_count)
2264 char *params = *ppparams;
2265 char *data = *ppdata;
2266 size_t sd_size = 0;
2267 uint32_t security_info_wanted;
2268 files_struct *fsp = NULL;
2269 NTSTATUS status;
2270 uint8_t *marshalled_sd = NULL;
2272 if(parameter_count < 8) {
2273 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2274 return;
2277 fsp = file_fsp(req, SVAL(params,0));
2278 if(!fsp) {
2279 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2280 return;
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);
2292 return;
2296 * Get the permissions to return.
2299 status = smbd_do_query_security_desc(conn,
2300 talloc_tos(),
2301 fsp,
2302 security_info_wanted &
2303 SMB_SUPPORTED_SECINFO_FLAGS,
2304 max_data_count,
2305 &marshalled_sd,
2306 &sd_size);
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);
2312 return;
2315 if (!NT_STATUS_IS_OK(status)) {
2316 reply_nterror(req, status);
2317 return;
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);
2327 return;
2331 * Allocate the data we will return.
2334 data = nttrans_realloc(ppdata, sd_size);
2335 if(data == NULL) {
2336 reply_nterror(req, NT_STATUS_NO_MEMORY);
2337 return;
2340 memcpy(data, marshalled_sd, sd_size);
2342 send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
2344 return;
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,
2353 uint16_t **ppsetup,
2354 uint32_t setup_count,
2355 char **ppparams,
2356 uint32_t parameter_count,
2357 char **ppdata,
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;
2365 NTSTATUS status;
2367 if(parameter_count < 8) {
2368 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2369 return;
2372 if((fsp = file_fsp(req, SVAL(params,0))) == NULL) {
2373 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2374 return;
2377 if (!CAN_WRITE(fsp->conn)) {
2378 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2379 return;
2382 if(!lp_nt_acl_support(SNUM(conn))) {
2383 goto done;
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);
2393 return;
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);
2400 return;
2403 done:
2404 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
2405 return;
2408 /****************************************************************************
2409 Reply to NT IOCTL
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)
2419 NTSTATUS status;
2420 uint32_t function;
2421 uint16_t fidnum;
2422 files_struct *fsp;
2423 uint8_t isFSctl;
2424 uint8_t compfilter;
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);
2433 return;
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.
2449 if (!isFSctl) {
2450 DEBUG(10, ("isFSctl: 0x%02X indicates IOCTL, not FSCTL!\n",
2451 isFSctl));
2452 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2453 return;
2456 /* Has to be for an open file! */
2457 if (!check_fsp_open(conn, req, fsp)) {
2458 return;
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,
2468 ctx,
2469 function,
2470 req->flags2,
2471 (uint8_t *)pdata,
2472 data_count,
2473 (uint8_t **)&out_data,
2474 max_data_count,
2475 &out_data_len);
2476 if (!NT_STATUS_IS_OK(status)) {
2477 reply_nterror(req, status);
2478 } else {
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,
2489 uint32_t elems)
2491 uint32_t i;
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;
2507 bool ok;
2509 if (!NT_STATUS_IS_OK(vfs_get_ntquota(fsp,
2510 SMB_USER_QUOTA_TYPE,
2511 &sids[i], &qt))) {
2512 /* non fatal error, return empty item in result */
2513 ZERO_STRUCT(qt);
2514 continue;
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);
2525 if (!ok) {
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,
2549 DATA_BLOB *sid_buf,
2550 struct dom_sid **sids,
2551 uint32_t *num)
2553 DATA_BLOB blob;
2554 uint32_t i = 0;
2555 enum ndr_err_code err;
2557 struct sid_list_elem {
2558 struct sid_list_elem *prev, *next;
2559 struct dom_sid sid;
2562 struct sid_list_elem *sid_list = NULL;
2563 struct sid_list_elem *iter = NULL;
2564 TALLOC_CTX *list_ctx = talloc_init("sid_list");
2565 if (!list_ctx) {
2566 DBG_ERR("OOM\n");
2567 err = NDR_ERR_ALLOC;
2568 goto done;
2571 *num = 0;
2572 *sids = NULL;
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",
2581 sidlistlength,
2582 sid_buf->length);
2583 err = NDR_ERR_OFFSET;
2584 goto done;
2586 while (true) {
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);
2593 if (!ndr_pull) {
2594 DBG_ERR("OOM\n");
2595 err = NDR_ERR_ALLOC;
2596 goto done;
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");
2603 goto done;
2605 item = talloc_zero(list_ctx, struct sid_list_elem);
2606 if (!item) {
2607 DBG_ERR("OOM\n");
2608 err = NDR_ERR_ALLOC;
2609 goto done;
2611 item->sid = info.sid;
2612 DLIST_ADD(sid_list, item);
2613 i++;
2614 if (i == UINT32_MAX) {
2615 DBG_ERR("Integer overflow\n");
2616 err = NDR_ERR_ARRAY_SIZE;
2617 goto done;
2619 new_offset = info.next_entry_offset;
2621 /* if new_offset == 0 no more sid(s) to read. */
2622 if (new_offset == 0) {
2623 break;
2626 /* Integer wrap? */
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;
2633 goto done;
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",
2642 sidlistlength,
2643 offset);
2644 err = NDR_ERR_OFFSET;
2645 goto done;
2648 *sids = talloc_zero_array(mem_ctx, struct dom_sid, i);
2649 if (*sids == NULL) {
2650 DBG_ERR("OOM\n");
2651 err = NDR_ERR_ALLOC;
2652 goto done;
2655 *num = i;
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",
2661 (unsigned int)i,
2662 dom_sid_str_buf(&iter->sid, &buf));
2665 err = NDR_ERR_SUCCESS;
2666 done:
2667 TALLOC_FREE(list_ctx);
2668 return err;
2671 NTSTATUS smbd_do_query_getinfo_quota(TALLOC_CTX *mem_ctx,
2672 files_struct *fsp,
2673 bool restart_scan,
2674 bool return_single,
2675 uint32_t sid_list_length,
2676 DATA_BLOB *sid_buf,
2677 uint32_t max_data_count,
2678 uint8_t **p_data,
2679 uint32_t *p_data_size)
2681 NTSTATUS status;
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;
2687 qt_handle =
2688 (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->private_data;
2690 if (sid_list_length ) {
2691 struct dom_sid *sids;
2692 uint32_t elems = 0;
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",
2700 sid_list_length,
2701 sid_buf->length);
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,
2711 fsp,
2712 qt_handle,
2713 sids,
2714 elems);
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;
2723 } else {
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;
2732 } else {
2733 qt_list = qt_handle->tmp_list;
2735 status = fill_quota_buffer(mem_ctx, qt_list,
2736 return_single != 0,
2737 max_data_count,
2738 &blob,
2739 &qt_handle->tmp_list);
2740 if (!NT_STATUS_IS_OK(status)) {
2741 return 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,
2758 uint16_t **ppsetup,
2759 uint32_t setup_count,
2760 char **ppparams,
2761 uint32_t parameter_count,
2762 char **ppdata,
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;
2771 int data_len = 0;
2772 int param_len = 0;
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");
2782 if (!tmp_ctx) {
2783 nt_status = NT_STATUS_NO_MEMORY;
2784 goto error;
2787 /* access check */
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;
2793 goto error;
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;
2806 goto error;
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;
2837 goto error;
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;
2845 goto error;
2847 nt_status = smbd_do_query_getinfo_quota(tmp_ctx,
2848 fsp,
2849 info.restart_scan,
2850 info.return_single_entry,
2851 info.sid_list_length,
2852 &blob,
2853 max_data_count,
2854 &resp_data,
2855 &resp_len);
2856 if (!NT_STATUS_IS_OK(nt_status)) {
2857 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) {
2858 goto error;
2860 nt_status = NT_STATUS_OK;
2863 param_len = 4;
2864 params = nttrans_realloc(ppparams, param_len);
2865 if(params == NULL) {
2866 nt_status = NT_STATUS_NO_MEMORY;
2867 goto error;
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,
2877 pdata, data_len);
2878 return;
2879 error:
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,
2890 uint16_t **ppsetup,
2891 uint32_t setup_count,
2892 char **ppparams,
2893 uint32_t parameter_count,
2894 char **ppdata,
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;
2906 struct dom_sid sid;
2907 DATA_BLOB inblob;
2908 files_struct *fsp = NULL;
2909 TALLOC_CTX *ctx = NULL;
2910 NTSTATUS status = NT_STATUS_OK;
2911 ZERO_STRUCT(qt);
2913 /* access check */
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;
2919 goto error;
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;
2929 goto error;
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;
2937 goto error;
2940 ctx = talloc_init("set_user_quota");
2941 if (!ctx) {
2942 status = NT_STATUS_NO_MEMORY;
2943 goto error;
2945 inblob.data = (uint8_t*)pdata;
2946 inblob.length = data_count;
2948 err = ndr_pull_struct_blob(
2949 &inblob,
2950 ctx,
2951 &info,
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;
2958 goto error;
2960 qt.usedspace = info.quota_used;
2962 qt.softlim = info.quota_threshold;
2964 qt.hardlim = info.quota_limit;
2966 sid = info.sid;
2968 if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2969 status = NT_STATUS_INTERNAL_ERROR;
2970 goto error;
2973 send_nt_replies(conn, req, NT_STATUS_OK, params, param_len,
2974 pdata, data_len);
2975 TALLOC_FREE(ctx);
2976 return;
2977 error:
2978 TALLOC_FREE(ctx);
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(
3001 conn, req,
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);
3007 break;
3010 case NT_TRANSACT_IOCTL:
3012 START_PROFILE(NT_transact_ioctl);
3013 call_nt_transact_ioctl(
3014 conn, req,
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);
3020 break;
3023 case NT_TRANSACT_SET_SECURITY_DESC:
3025 START_PROFILE(NT_transact_set_security_desc);
3026 call_nt_transact_set_security_desc(
3027 conn, req,
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);
3033 break;
3036 case NT_TRANSACT_NOTIFY_CHANGE:
3038 START_PROFILE(NT_transact_notify_change);
3039 call_nt_transact_notify_change(
3040 conn, req,
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);
3047 break;
3050 case NT_TRANSACT_RENAME:
3052 START_PROFILE(NT_transact_rename);
3053 call_nt_transact_rename(
3054 conn, req,
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);
3060 break;
3063 case NT_TRANSACT_QUERY_SECURITY_DESC:
3065 START_PROFILE(NT_transact_query_security_desc);
3066 call_nt_transact_query_security_desc(
3067 conn, req,
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);
3073 break;
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(
3081 conn, req,
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);
3087 break;
3090 case NT_TRANSACT_SET_USER_QUOTA:
3092 START_PROFILE(NT_transact_set_user_quota);
3093 call_nt_transact_set_user_quota(
3094 conn, req,
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);
3100 break;
3102 #endif /* HAVE_SYS_QUOTAS */
3104 default:
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);
3109 return;
3111 return;
3114 /****************************************************************************
3115 Reply to a SMBNTtrans.
3116 ****************************************************************************/
3118 void reply_nttrans(struct smb_request *req)
3120 connection_struct *conn = req->conn;
3121 uint32_t pscnt;
3122 uint32_t psoff;
3123 uint32_t dscnt;
3124 uint32_t dsoff;
3125 uint16_t function_code;
3126 NTSTATUS result;
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);
3134 return;
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);
3146 return;
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);
3154 return;
3157 if ((state = talloc(conn, struct trans_state)) == NULL) {
3158 reply_nterror(req, NT_STATUS_NO_MEMORY);
3159 END_PROFILE(SMBnttrans);
3160 return;
3163 state->cmd = SMBnttrans;
3165 state->mid = req->mid;
3166 state->vuid = req->vuid;
3167 state->total_data = IVAL(req->vwv+3, 1);
3168 state->data = NULL;
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)));
3198 goto bad_param;
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);
3206 return;
3209 if ((dscnt > state->total_data) || (pscnt > state->total_param))
3210 goto bad_param;
3212 if (state->total_data) {
3214 if (trans_oob(state->total_data, 0, dscnt)
3215 || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
3216 goto bad_param;
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));
3224 TALLOC_FREE(state);
3225 reply_nterror(req, NT_STATUS_NO_MEMORY);
3226 END_PROFILE(SMBnttrans);
3227 return;
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)) {
3237 goto bad_param;
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);
3246 TALLOC_FREE(state);
3247 reply_nterror(req, NT_STATUS_NO_MEMORY);
3248 END_PROFILE(SMBnttrans);
3249 return;
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) {
3271 goto bad_param;
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);
3279 TALLOC_FREE(state);
3280 reply_nterror(req, NT_STATUS_NO_MEMORY);
3281 END_PROFILE(SMBnttrans);
3282 return;
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);
3294 TALLOC_FREE(state);
3295 END_PROFILE(SMBnttrans);
3296 return;
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);
3306 return;
3308 bad_param:
3310 DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
3311 SAFE_FREE(state->data);
3312 SAFE_FREE(state->param);
3313 TALLOC_FREE(state);
3314 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3315 END_PROFILE(SMBnttrans);
3316 return;
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);
3342 return;
3345 for (state = conn->pending_trans; state != NULL;
3346 state = state->next) {
3347 if (state->mid == req->mid) {
3348 break;
3352 if ((state == NULL) || (state->cmd != SMBnttrans)) {
3353 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3354 END_PROFILE(SMBnttranss);
3355 return;
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))
3380 goto bad_param;
3382 if (pcnt) {
3383 if (trans_oob(state->total_param, pdisp, pcnt)
3384 || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
3385 goto bad_param;
3387 memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,pcnt);
3390 if (dcnt) {
3391 if (trans_oob(state->total_data, ddisp, dcnt)
3392 || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
3393 goto bad_param;
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);
3401 return;
3404 handle_nttrans(conn, state, req);
3406 DLIST_REMOVE(conn->pending_trans, state);
3407 SAFE_FREE(state->data);
3408 SAFE_FREE(state->param);
3409 TALLOC_FREE(state);
3410 END_PROFILE(SMBnttranss);
3411 return;
3413 bad_param:
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);
3419 TALLOC_FREE(state);
3420 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3421 END_PROFILE(SMBnttranss);
3422 return;