2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2007
5 Copyright (C) Stefan (metze) Metzmacher 2003
6 Copyright (C) Volker Lendecke 2005-2007
7 Copyright (C) Steve French 2005
8 Copyright (C) James Peach 2006-2007
10 Extensively modified by Andrew Tridgell, 1995
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include "smbd/globals.h"
29 #include "../libcli/auth/libcli_auth.h"
30 #include "../librpc/gen_ndr/xattr.h"
32 #define DIR_ENTRY_SAFETY_MARGIN 4096
34 static char *store_file_unix_basic(connection_struct *conn,
37 const SMB_STRUCT_STAT *psbuf);
39 static char *store_file_unix_basic_info2(connection_struct *conn,
42 const SMB_STRUCT_STAT *psbuf);
44 /********************************************************************
45 Roundup a value to the nearest allocation roundup size boundary.
46 Only do this for Windows clients.
47 ********************************************************************/
49 uint64_t smb_roundup(connection_struct *conn, uint64_t val)
51 uint64_t rval = lp_allocation_roundup_size(SNUM(conn));
53 /* Only roundup for Windows clients. */
54 enum remote_arch_types ra_type = get_remote_arch();
55 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
56 val = SMB_ROUNDUP(val,rval);
61 /****************************************************************************
62 Utility functions for dealing with extended attributes.
63 ****************************************************************************/
65 /****************************************************************************
66 Refuse to allow clients to overwrite our private xattrs.
67 ****************************************************************************/
69 static bool samba_private_attr_name(const char *unix_ea_name)
71 static const char * const prohibited_ea_names[] = {
72 SAMBA_POSIX_INHERITANCE_EA_NAME,
73 SAMBA_XATTR_DOS_ATTRIB,
81 for (i = 0; prohibited_ea_names[i]; i++) {
82 if (strequal( prohibited_ea_names[i], unix_ea_name))
85 if (StrnCaseCmp(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
86 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
92 /****************************************************************************
93 Get one EA value. Fill in a struct ea_struct.
94 ****************************************************************************/
96 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
97 files_struct *fsp, const char *fname,
98 const char *ea_name, struct ea_struct *pea)
100 /* Get the value of this xattr. Max size is 64k. */
101 size_t attr_size = 256;
107 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
109 return NT_STATUS_NO_MEMORY;
112 if (fsp && fsp->fh->fd != -1) {
113 sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
115 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
118 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
124 return map_nt_error_from_unix(errno);
127 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
128 dump_data(10, (uint8 *)val, sizeret);
131 if (strnequal(ea_name, "user.", 5)) {
132 pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
134 pea->name = talloc_strdup(mem_ctx, ea_name);
136 if (pea->name == NULL) {
138 return NT_STATUS_NO_MEMORY;
140 pea->value.data = (unsigned char *)val;
141 pea->value.length = (size_t)sizeret;
145 NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
146 files_struct *fsp, const char *fname,
147 char ***pnames, size_t *pnum_names)
149 /* Get a list of all xattrs. Max namesize is 64k. */
150 size_t ea_namelist_size = 1024;
151 char *ea_namelist = NULL;
156 ssize_t sizeret = -1;
158 if (!lp_ea_support(SNUM(conn))) {
167 * TALLOC the result early to get the talloc hierarchy right.
170 names = TALLOC_ARRAY(mem_ctx, char *, 1);
172 DEBUG(0, ("talloc failed\n"));
173 return NT_STATUS_NO_MEMORY;
176 while (ea_namelist_size <= 65536) {
178 ea_namelist = TALLOC_REALLOC_ARRAY(
179 names, ea_namelist, char, ea_namelist_size);
180 if (ea_namelist == NULL) {
181 DEBUG(0, ("talloc failed\n"));
183 return NT_STATUS_NO_MEMORY;
186 if (fsp && fsp->fh->fd != -1) {
187 sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
190 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist,
194 if ((sizeret == -1) && (errno == ERANGE)) {
195 ea_namelist_size *= 2;
204 return map_nt_error_from_unix(errno);
207 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
208 (unsigned int)sizeret));
220 * Ensure the result is 0-terminated
223 if (ea_namelist[sizeret-1] != '\0') {
225 return NT_STATUS_INTERNAL_ERROR;
233 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
237 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names);
239 DEBUG(0, ("talloc failed\n"));
241 return NT_STATUS_NO_MEMORY;
247 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
248 names[num_names++] = p;
256 *pnum_names = num_names;
260 /****************************************************************************
261 Return a linked list of the total EA's. Plus the total size
262 ****************************************************************************/
264 static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
265 const char *fname, size_t *pea_total_len)
267 /* Get a list of all xattrs. Max namesize is 64k. */
270 struct ea_list *ea_list_head = NULL;
275 if (!lp_ea_support(SNUM(conn))) {
279 status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
282 if (!NT_STATUS_IS_OK(status) || (num_names == 0)) {
286 for (i=0; i<num_names; i++) {
287 struct ea_list *listp;
290 if (strnequal(names[i], "system.", 7)
291 || samba_private_attr_name(names[i]))
294 listp = TALLOC_P(mem_ctx, struct ea_list);
299 if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx, conn, fsp,
305 push_ascii_fstring(dos_ea_name, listp->ea.name);
308 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
310 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
311 "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
312 (unsigned int)listp->ea.value.length));
314 DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
318 /* Add on 4 for total length. */
319 if (*pea_total_len) {
323 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
324 (unsigned int)*pea_total_len));
329 /****************************************************************************
330 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
332 ****************************************************************************/
334 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
335 connection_struct *conn, struct ea_list *ea_list)
337 unsigned int ret_data_size = 4;
340 SMB_ASSERT(total_data_size >= 4);
342 if (!lp_ea_support(SNUM(conn))) {
347 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
350 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
351 dos_namelen = strlen(dos_ea_name);
352 if (dos_namelen > 255 || dos_namelen == 0) {
355 if (ea_list->ea.value.length > 65535) {
358 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
362 /* We know we have room. */
363 SCVAL(p,0,ea_list->ea.flags);
364 SCVAL(p,1,dos_namelen);
365 SSVAL(p,2,ea_list->ea.value.length);
366 fstrcpy(p+4, dos_ea_name);
367 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
369 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
370 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
373 ret_data_size = PTR_DIFF(p, pdata);
374 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
375 SIVAL(pdata,0,ret_data_size);
376 return ret_data_size;
379 static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
381 unsigned int total_data_size,
382 unsigned int *ret_data_size,
383 connection_struct *conn,
384 struct ea_list *ea_list)
386 uint8_t *p = (uint8_t *)pdata;
387 uint8_t *last_start = NULL;
391 if (!lp_ea_support(SNUM(conn))) {
392 return NT_STATUS_NO_EAS_ON_FILE;
395 for (; ea_list; ea_list = ea_list->next) {
401 SIVAL(last_start, 0, PTR_DIFF(p, last_start));
405 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
406 dos_namelen = strlen(dos_ea_name);
407 if (dos_namelen > 255 || dos_namelen == 0) {
408 return NT_STATUS_INTERNAL_ERROR;
410 if (ea_list->ea.value.length > 65535) {
411 return NT_STATUS_INTERNAL_ERROR;
414 this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
417 size_t pad = 4 - (this_size % 4);
421 if (this_size > total_data_size) {
422 return NT_STATUS_INFO_LENGTH_MISMATCH;
425 /* We know we have room. */
426 SIVAL(p, 0x00, 0); /* next offset */
427 SCVAL(p, 0x04, ea_list->ea.flags);
428 SCVAL(p, 0x05, dos_namelen);
429 SSVAL(p, 0x06, ea_list->ea.value.length);
430 fstrcpy((char *)(p+0x08), dos_ea_name);
431 memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
433 total_data_size -= this_size;
437 *ret_data_size = PTR_DIFF(p, pdata);
438 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
442 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
444 size_t total_ea_len = 0;
445 TALLOC_CTX *mem_ctx = NULL;
447 if (!lp_ea_support(SNUM(conn))) {
450 mem_ctx = talloc_tos();
451 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
455 /****************************************************************************
456 Ensure the EA name is case insensitive by matching any existing EA name.
457 ****************************************************************************/
459 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
462 TALLOC_CTX *mem_ctx = talloc_tos();
463 struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
465 for (; ea_list; ea_list = ea_list->next) {
466 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
467 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
468 &unix_ea_name[5], ea_list->ea.name));
469 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
475 /****************************************************************************
476 Set or delete an extended attribute.
477 ****************************************************************************/
479 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
480 const struct smb_filename *smb_fname, struct ea_list *ea_list)
484 if (!lp_ea_support(SNUM(conn))) {
485 return NT_STATUS_EAS_NOT_SUPPORTED;
488 /* For now setting EAs on streams isn't supported. */
489 fname = smb_fname->base_name;
491 for (;ea_list; ea_list = ea_list->next) {
493 fstring unix_ea_name;
495 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
496 fstrcat(unix_ea_name, ea_list->ea.name);
498 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
500 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
502 if (samba_private_attr_name(unix_ea_name)) {
503 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
504 return NT_STATUS_ACCESS_DENIED;
507 if (ea_list->ea.value.length == 0) {
508 /* Remove the attribute. */
509 if (fsp && (fsp->fh->fd != -1)) {
510 DEBUG(10,("set_ea: deleting ea name %s on "
511 "file %s by file descriptor.\n",
512 unix_ea_name, fsp_str_dbg(fsp)));
513 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
515 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
516 unix_ea_name, fname));
517 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
520 /* Removing a non existent attribute always succeeds. */
521 if (ret == -1 && errno == ENOATTR) {
522 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
528 if (fsp && (fsp->fh->fd != -1)) {
529 DEBUG(10,("set_ea: setting ea name %s on file "
530 "%s by file descriptor.\n",
531 unix_ea_name, fsp_str_dbg(fsp)));
532 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
533 ea_list->ea.value.data, ea_list->ea.value.length, 0);
535 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
536 unix_ea_name, fname));
537 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
538 ea_list->ea.value.data, ea_list->ea.value.length, 0);
544 if (errno == ENOTSUP) {
545 return NT_STATUS_EAS_NOT_SUPPORTED;
548 return map_nt_error_from_unix(errno);
554 /****************************************************************************
555 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
556 ****************************************************************************/
558 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
560 struct ea_list *ea_list_head = NULL;
561 size_t converted_size, offset = 0;
563 while (offset + 2 < data_size) {
564 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
565 unsigned int namelen = CVAL(pdata,offset);
567 offset++; /* Go past the namelen byte. */
569 /* integer wrap paranioa. */
570 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
571 (offset > data_size) || (namelen > data_size) ||
572 (offset + namelen >= data_size)) {
575 /* Ensure the name is null terminated. */
576 if (pdata[offset + namelen] != '\0') {
579 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
581 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
582 "failed: %s", strerror(errno)));
588 offset += (namelen + 1); /* Go past the name + terminating zero. */
589 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
590 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
596 /****************************************************************************
597 Read one EA list entry from the buffer.
598 ****************************************************************************/
600 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
602 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
604 unsigned int namelen;
605 size_t converted_size;
615 eal->ea.flags = CVAL(pdata,0);
616 namelen = CVAL(pdata,1);
617 val_len = SVAL(pdata,2);
619 if (4 + namelen + 1 + val_len > data_size) {
623 /* Ensure the name is null terminated. */
624 if (pdata[namelen + 4] != '\0') {
627 if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
628 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
635 eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
636 if (!eal->ea.value.data) {
640 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
642 /* Ensure we're null terminated just in case we print the value. */
643 eal->ea.value.data[val_len] = '\0';
644 /* But don't count the null. */
645 eal->ea.value.length--;
648 *pbytes_used = 4 + namelen + 1 + val_len;
651 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
652 dump_data(10, eal->ea.value.data, eal->ea.value.length);
657 /****************************************************************************
658 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
659 ****************************************************************************/
661 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
663 struct ea_list *ea_list_head = NULL;
665 size_t bytes_used = 0;
667 while (offset < data_size) {
668 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
674 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
675 offset += bytes_used;
681 /****************************************************************************
682 Count the total EA size needed.
683 ****************************************************************************/
685 static size_t ea_list_size(struct ea_list *ealist)
688 struct ea_list *listp;
691 for (listp = ealist; listp; listp = listp->next) {
692 push_ascii_fstring(dos_ea_name, listp->ea.name);
693 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
695 /* Add on 4 for total length. */
703 /****************************************************************************
704 Return a union of EA's from a file list and a list of names.
705 The TALLOC context for the two lists *MUST* be identical as we steal
706 memory from one list to add to another. JRA.
707 ****************************************************************************/
709 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
711 struct ea_list *nlistp, *flistp;
713 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
714 for (flistp = file_list; flistp; flistp = flistp->next) {
715 if (strequal(nlistp->ea.name, flistp->ea.name)) {
721 /* Copy the data from this entry. */
722 nlistp->ea.flags = flistp->ea.flags;
723 nlistp->ea.value = flistp->ea.value;
726 nlistp->ea.flags = 0;
727 ZERO_STRUCT(nlistp->ea.value);
731 *total_ea_len = ea_list_size(name_list);
735 /****************************************************************************
736 Send the required number of replies back.
737 We assume all fields other than the data fields are
738 set correctly for the type of call.
739 HACK ! Always assumes smb_setup field is zero.
740 ****************************************************************************/
742 void send_trans2_replies(connection_struct *conn,
743 struct smb_request *req,
750 /* As we are using a protocol > LANMAN1 then the max_send
751 variable must have been set in the sessetupX call.
752 This takes precedence over the max_xmit field in the
753 global struct. These different max_xmit variables should
754 be merged as this is now too confusing */
756 int data_to_send = datasize;
757 int params_to_send = paramsize;
759 const char *pp = params;
760 const char *pd = pdata;
761 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
762 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
763 int data_alignment_offset = 0;
764 bool overflow = False;
765 struct smbd_server_connection *sconn = smbd_server_conn;
766 int max_send = sconn->smb1.sessions.max_send;
768 /* Modify the data_to_send and datasize and set the error if
769 we're trying to send more than max_data_bytes. We still send
770 the part of the packet(s) that fit. Strange, but needed
773 if (max_data_bytes > 0 && datasize > max_data_bytes) {
774 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
775 max_data_bytes, datasize ));
776 datasize = data_to_send = max_data_bytes;
780 /* If there genuinely are no parameters or data to send just send the empty packet */
782 if(params_to_send == 0 && data_to_send == 0) {
783 reply_outbuf(req, 10, 0);
784 show_msg((char *)req->outbuf);
785 if (!srv_send_smb(smbd_server_fd(),
788 IS_CONN_ENCRYPTED(conn),
790 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
792 TALLOC_FREE(req->outbuf);
796 /* When sending params and data ensure that both are nicely aligned */
797 /* Only do this alignment when there is also data to send - else
798 can cause NT redirector problems. */
800 if (((params_to_send % 4) != 0) && (data_to_send != 0))
801 data_alignment_offset = 4 - (params_to_send % 4);
803 /* Space is bufsize minus Netbios over TCP header minus SMB header */
804 /* The alignment_offset is to align the param bytes on an even byte
805 boundary. NT 4.0 Beta needs this to work correctly. */
807 useable_space = max_send - (smb_size
810 + data_alignment_offset);
812 if (useable_space < 0) {
813 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
814 "= %d!!!", useable_space));
815 exit_server_cleanly("send_trans2_replies: Not enough space");
818 while (params_to_send || data_to_send) {
819 /* Calculate whether we will totally or partially fill this packet */
821 total_sent_thistime = params_to_send + data_to_send;
823 /* We can never send more than useable_space */
825 * Note that 'useable_space' does not include the alignment offsets,
826 * but we must include the alignment offsets in the calculation of
827 * the length of the data we send over the wire, as the alignment offsets
828 * are sent here. Fix from Marc_Jacobsen@hp.com.
831 total_sent_thistime = MIN(total_sent_thistime, useable_space);
833 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
834 + data_alignment_offset);
837 * We might have SMBtrans2s in req which was transferred to
838 * the outbuf, fix that.
840 SCVAL(req->outbuf, smb_com, SMBtrans2);
842 /* Set total params and data to be sent */
843 SSVAL(req->outbuf,smb_tprcnt,paramsize);
844 SSVAL(req->outbuf,smb_tdrcnt,datasize);
846 /* Calculate how many parameters and data we can fit into
847 * this packet. Parameters get precedence
850 params_sent_thistime = MIN(params_to_send,useable_space);
851 data_sent_thistime = useable_space - params_sent_thistime;
852 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
854 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
856 /* smb_proff is the offset from the start of the SMB header to the
857 parameter bytes, however the first 4 bytes of outbuf are
858 the Netbios over TCP header. Thus use smb_base() to subtract
859 them from the calculation */
861 SSVAL(req->outbuf,smb_proff,
862 ((smb_buf(req->outbuf)+alignment_offset)
863 - smb_base(req->outbuf)));
865 if(params_sent_thistime == 0)
866 SSVAL(req->outbuf,smb_prdisp,0);
868 /* Absolute displacement of param bytes sent in this packet */
869 SSVAL(req->outbuf,smb_prdisp,pp - params);
871 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
872 if(data_sent_thistime == 0) {
873 SSVAL(req->outbuf,smb_droff,0);
874 SSVAL(req->outbuf,smb_drdisp, 0);
876 /* The offset of the data bytes is the offset of the
877 parameter bytes plus the number of parameters being sent this time */
878 SSVAL(req->outbuf, smb_droff,
879 ((smb_buf(req->outbuf)+alignment_offset)
880 - smb_base(req->outbuf))
881 + params_sent_thistime + data_alignment_offset);
882 SSVAL(req->outbuf,smb_drdisp, pd - pdata);
885 /* Initialize the padding for alignment */
887 if (alignment_offset != 0) {
888 memset(smb_buf(req->outbuf), 0, alignment_offset);
891 /* Copy the param bytes into the packet */
893 if(params_sent_thistime) {
894 memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
895 params_sent_thistime);
898 /* Copy in the data bytes */
899 if(data_sent_thistime) {
900 if (data_alignment_offset != 0) {
901 memset((smb_buf(req->outbuf)+alignment_offset+
902 params_sent_thistime), 0,
903 data_alignment_offset);
905 memcpy(smb_buf(req->outbuf)+alignment_offset
906 +params_sent_thistime+data_alignment_offset,
907 pd,data_sent_thistime);
910 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
911 params_sent_thistime, data_sent_thistime, useable_space));
912 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
913 params_to_send, data_to_send, paramsize, datasize));
916 error_packet_set((char *)req->outbuf,
917 ERRDOS,ERRbufferoverflow,
918 STATUS_BUFFER_OVERFLOW,
922 /* Send the packet */
923 show_msg((char *)req->outbuf);
924 if (!srv_send_smb(smbd_server_fd(),
927 IS_CONN_ENCRYPTED(conn),
929 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
931 TALLOC_FREE(req->outbuf);
933 pp += params_sent_thistime;
934 pd += data_sent_thistime;
936 params_to_send -= params_sent_thistime;
937 data_to_send -= data_sent_thistime;
940 if(params_to_send < 0 || data_to_send < 0) {
941 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
942 params_to_send, data_to_send));
950 /****************************************************************************
951 Reply to a TRANSACT2_OPEN.
952 ****************************************************************************/
954 static void call_trans2open(connection_struct *conn,
955 struct smb_request *req,
956 char **pparams, int total_params,
957 char **ppdata, int total_data,
958 unsigned int max_data_bytes)
960 struct smb_filename *smb_fname = NULL;
961 char *params = *pparams;
962 char *pdata = *ppdata;
967 bool return_additional_info;
980 struct ea_list *ea_list = NULL;
985 uint32 create_disposition;
986 uint32 create_options = 0;
987 uint32_t private_flags = 0;
988 TALLOC_CTX *ctx = talloc_tos();
991 * Ensure we have enough parameters to perform the operation.
994 if (total_params < 29) {
995 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
999 flags = SVAL(params, 0);
1000 deny_mode = SVAL(params, 2);
1001 open_attr = SVAL(params,6);
1002 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1003 if (oplock_request) {
1004 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1008 return_additional_info = BITSETW(params,0);
1009 open_sattr = SVAL(params, 4);
1010 open_time = make_unix_date3(params+8);
1012 open_ofun = SVAL(params,12);
1013 open_size = IVAL(params,14);
1014 pname = ¶ms[28];
1017 reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
1021 srvstr_get_path(ctx, params, req->flags2, &fname, pname,
1022 total_params - 28, STR_TERMINATE,
1024 if (!NT_STATUS_IS_OK(status)) {
1025 reply_nterror(req, status);
1029 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1030 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
1031 (unsigned int)open_ofun, open_size));
1033 status = filename_convert(ctx,
1035 req->flags2 & FLAGS2_DFS_PATHNAMES,
1040 if (!NT_STATUS_IS_OK(status)) {
1041 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1042 reply_botherror(req,
1043 NT_STATUS_PATH_NOT_COVERED,
1044 ERRSRV, ERRbadpath);
1047 reply_nterror(req, status);
1051 if (open_ofun == 0) {
1052 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
1056 if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun,
1057 &access_mask, &share_mode,
1058 &create_disposition,
1061 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1065 /* Any data in this call is an EA list. */
1066 if (total_data && (total_data != 4)) {
1067 if (total_data < 10) {
1068 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1072 if (IVAL(pdata,0) > total_data) {
1073 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1074 IVAL(pdata,0), (unsigned int)total_data));
1075 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1079 ea_list = read_ea_list(talloc_tos(), pdata + 4,
1082 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1086 if (!lp_ea_support(SNUM(conn))) {
1087 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1092 status = SMB_VFS_CREATE_FILE(
1095 0, /* root_dir_fid */
1096 smb_fname, /* fname */
1097 access_mask, /* access_mask */
1098 share_mode, /* share_access */
1099 create_disposition, /* create_disposition*/
1100 create_options, /* create_options */
1101 open_attr, /* file_attributes */
1102 oplock_request, /* oplock_request */
1103 open_size, /* allocation_size */
1106 ea_list, /* ea_list */
1108 &smb_action); /* psbuf */
1110 if (!NT_STATUS_IS_OK(status)) {
1111 if (open_was_deferred(req->mid)) {
1112 /* We have re-scheduled this call. */
1115 reply_openerror(req, status);
1119 size = get_file_size_stat(&smb_fname->st);
1120 fattr = dos_mode(conn, smb_fname);
1121 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1122 inode = smb_fname->st.st_ex_ino;
1124 close_file(req, fsp, ERROR_CLOSE);
1125 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1129 /* Realloc the size of parameters and data we will return */
1130 *pparams = (char *)SMB_REALLOC(*pparams, 30);
1131 if(*pparams == NULL ) {
1132 reply_nterror(req, NT_STATUS_NO_MEMORY);
1137 SSVAL(params,0,fsp->fnum);
1138 SSVAL(params,2,fattr);
1139 srv_put_dos_date2(params,4, mtime);
1140 SIVAL(params,8, (uint32)size);
1141 SSVAL(params,12,deny_mode);
1142 SSVAL(params,14,0); /* open_type - file or directory. */
1143 SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1145 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1146 smb_action |= EXTENDED_OPLOCK_GRANTED;
1149 SSVAL(params,18,smb_action);
1152 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1154 SIVAL(params,20,inode);
1155 SSVAL(params,24,0); /* Padding. */
1157 uint32 ea_size = estimate_ea_size(conn, fsp,
1158 fsp->fsp_name->base_name);
1159 SIVAL(params, 26, ea_size);
1161 SIVAL(params, 26, 0);
1164 /* Send the required number of replies */
1165 send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
1167 TALLOC_FREE(smb_fname);
1170 /*********************************************************
1171 Routine to check if a given string matches exactly.
1172 as a special case a mask of "." does NOT match. That
1173 is required for correct wildcard semantics
1174 Case can be significant or not.
1175 **********************************************************/
1177 static bool exact_match(bool has_wild,
1178 bool case_sensitive,
1182 if (mask[0] == '.' && mask[1] == 0) {
1190 if (case_sensitive) {
1191 return strcmp(str,mask)==0;
1193 return StrCaseCmp(str,mask) == 0;
1197 /****************************************************************************
1198 Return the filetype for UNIX extensions.
1199 ****************************************************************************/
1201 static uint32 unix_filetype(mode_t mode)
1204 return UNIX_TYPE_FILE;
1205 else if(S_ISDIR(mode))
1206 return UNIX_TYPE_DIR;
1208 else if(S_ISLNK(mode))
1209 return UNIX_TYPE_SYMLINK;
1212 else if(S_ISCHR(mode))
1213 return UNIX_TYPE_CHARDEV;
1216 else if(S_ISBLK(mode))
1217 return UNIX_TYPE_BLKDEV;
1220 else if(S_ISFIFO(mode))
1221 return UNIX_TYPE_FIFO;
1224 else if(S_ISSOCK(mode))
1225 return UNIX_TYPE_SOCKET;
1228 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1229 return UNIX_TYPE_UNKNOWN;
1232 /****************************************************************************
1233 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1234 ****************************************************************************/
1236 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1238 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1239 const SMB_STRUCT_STAT *psbuf,
1241 enum perm_type ptype,
1246 if (perms == SMB_MODE_NO_CHANGE) {
1247 if (!VALID_STAT(*psbuf)) {
1248 return NT_STATUS_INVALID_PARAMETER;
1250 *ret_perms = psbuf->st_ex_mode;
1251 return NT_STATUS_OK;
1255 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1256 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1257 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1258 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1259 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1260 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1261 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1262 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1263 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1265 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1268 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1271 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1276 /* Apply mode mask */
1277 ret &= lp_create_mask(SNUM(conn));
1278 /* Add in force bits */
1279 ret |= lp_force_create_mode(SNUM(conn));
1282 ret &= lp_dir_mask(SNUM(conn));
1283 /* Add in force bits */
1284 ret |= lp_force_dir_mode(SNUM(conn));
1286 case PERM_EXISTING_FILE:
1287 /* Apply mode mask */
1288 ret &= lp_security_mask(SNUM(conn));
1289 /* Add in force bits */
1290 ret |= lp_force_security_mode(SNUM(conn));
1292 case PERM_EXISTING_DIR:
1293 /* Apply mode mask */
1294 ret &= lp_dir_security_mask(SNUM(conn));
1295 /* Add in force bits */
1296 ret |= lp_force_dir_security_mode(SNUM(conn));
1301 return NT_STATUS_OK;
1304 /****************************************************************************
1305 Needed to show the msdfs symlinks as directories. Modifies psbuf
1306 to be a directory if it's a msdfs link.
1307 ****************************************************************************/
1309 static bool check_msdfs_link(connection_struct *conn,
1310 const char *pathname,
1311 SMB_STRUCT_STAT *psbuf)
1313 int saved_errno = errno;
1314 if(lp_host_msdfs() &&
1315 lp_msdfs_root(SNUM(conn)) &&
1316 is_msdfs_link(conn, pathname, psbuf)) {
1318 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1321 psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
1322 errno = saved_errno;
1325 errno = saved_errno;
1330 /****************************************************************************
1331 Get a level dependent lanman2 dir entry.
1332 ****************************************************************************/
1334 struct smbd_dirptr_lanman2_state {
1335 connection_struct *conn;
1336 uint32_t info_level;
1337 bool check_mangled_names;
1339 bool got_exact_match;
1342 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX *ctx,
1348 struct smbd_dirptr_lanman2_state *state =
1349 (struct smbd_dirptr_lanman2_state *)private_data;
1351 char mangled_name[13]; /* mangled 8.3 name. */
1355 /* Mangle fname if it's an illegal name. */
1356 if (mangle_must_mangle(dname, state->conn->params)) {
1357 ok = name_to_8_3(dname, mangled_name,
1358 true, state->conn->params);
1362 fname = mangled_name;
1367 got_match = exact_match(state->has_wild,
1368 state->conn->case_sensitive,
1370 state->got_exact_match = got_match;
1372 got_match = mask_match(fname, mask,
1373 state->conn->case_sensitive);
1376 if(!got_match && state->check_mangled_names &&
1377 !mangle_is_8_3(fname, false, state->conn->params)) {
1379 * It turns out that NT matches wildcards against
1380 * both long *and* short names. This may explain some
1381 * of the wildcard wierdness from old DOS clients
1382 * that some people have been seeing.... JRA.
1384 /* Force the mangling into 8.3. */
1385 ok = name_to_8_3(fname, mangled_name,
1386 false, state->conn->params);
1391 got_match = exact_match(state->has_wild,
1392 state->conn->case_sensitive,
1393 mangled_name, mask);
1394 state->got_exact_match = got_match;
1396 got_match = mask_match(mangled_name, mask,
1397 state->conn->case_sensitive);
1405 *_fname = talloc_strdup(ctx, fname);
1406 if (*_fname == NULL) {
1413 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
1415 struct smb_filename *smb_fname,
1418 struct smbd_dirptr_lanman2_state *state =
1419 (struct smbd_dirptr_lanman2_state *)private_data;
1420 bool ms_dfs_link = false;
1423 if (INFO_LEVEL_IS_UNIX(state->info_level)) {
1424 if (SMB_VFS_LSTAT(state->conn, smb_fname) != 0) {
1425 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1426 "Couldn't lstat [%s] (%s)\n",
1427 smb_fname_str_dbg(smb_fname),
1431 } else if (!VALID_STAT(smb_fname->st) &&
1432 SMB_VFS_STAT(state->conn, smb_fname) != 0) {
1433 /* Needed to show the msdfs symlinks as
1436 ms_dfs_link = check_msdfs_link(state->conn,
1437 smb_fname->base_name,
1440 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1441 "Couldn't stat [%s] (%s)\n",
1442 smb_fname_str_dbg(smb_fname),
1449 mode = dos_mode_msdfs(state->conn, smb_fname);
1451 mode = dos_mode(state->conn, smb_fname);
1458 static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
1459 connection_struct *conn,
1461 uint32_t info_level,
1462 struct ea_list *name_list,
1463 bool check_mangled_names,
1464 bool requires_resume_key,
1467 const struct smb_filename *smb_fname,
1468 int space_remaining,
1475 uint64_t *last_entry_off)
1477 char *p, *q, *pdata = *ppdata;
1479 uint64_t file_size = 0;
1480 uint64_t allocation_size = 0;
1482 struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts;
1483 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1484 time_t c_date = (time_t)0;
1486 char *last_entry_ptr;
1491 *out_of_space = false;
1493 ZERO_STRUCT(mdate_ts);
1494 ZERO_STRUCT(adate_ts);
1495 ZERO_STRUCT(create_date_ts);
1496 ZERO_STRUCT(cdate_ts);
1498 if (!(mode & aDIR)) {
1499 file_size = get_file_size_stat(&smb_fname->st);
1501 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
1503 mdate_ts = smb_fname->st.st_ex_mtime;
1504 adate_ts = smb_fname->st.st_ex_atime;
1505 create_date_ts = get_create_timespec(conn, NULL, smb_fname);
1506 cdate_ts = get_change_timespec(conn, NULL, smb_fname);
1508 if (lp_dos_filetime_resolution(SNUM(conn))) {
1509 dos_filetime_timespec(&create_date_ts);
1510 dos_filetime_timespec(&mdate_ts);
1511 dos_filetime_timespec(&adate_ts);
1512 dos_filetime_timespec(&cdate_ts);
1515 create_date = convert_timespec_to_time_t(create_date_ts);
1516 mdate = convert_timespec_to_time_t(mdate_ts);
1517 adate = convert_timespec_to_time_t(adate_ts);
1518 c_date = convert_timespec_to_time_t(cdate_ts);
1520 /* align the record */
1521 SMB_ASSERT(align >= 1);
1523 off = (int)PTR_DIFF(pdata, base_data);
1524 pad = (off + (align-1)) & ~(align-1);
1527 /* initialize padding to 0 */
1529 memset(pdata, 0, pad);
1531 space_remaining -= pad;
1533 DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1543 switch (info_level) {
1544 case SMB_FIND_INFO_STANDARD:
1545 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1546 if(requires_resume_key) {
1550 srv_put_dos_date2(p,0,create_date);
1551 srv_put_dos_date2(p,4,adate);
1552 srv_put_dos_date2(p,8,mdate);
1553 SIVAL(p,12,(uint32)file_size);
1554 SIVAL(p,16,(uint32)allocation_size);
1558 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1559 p += ucs2_align(base_data, p, 0);
1561 len = srvstr_push(base_data, flags2, p,
1562 fname, PTR_DIFF(end_data, p),
1564 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1566 SCVAL(nameptr, -1, len - 2);
1568 SCVAL(nameptr, -1, 0);
1572 SCVAL(nameptr, -1, len - 1);
1574 SCVAL(nameptr, -1, 0);
1580 case SMB_FIND_EA_SIZE:
1581 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1582 if (requires_resume_key) {
1586 srv_put_dos_date2(p,0,create_date);
1587 srv_put_dos_date2(p,4,adate);
1588 srv_put_dos_date2(p,8,mdate);
1589 SIVAL(p,12,(uint32)file_size);
1590 SIVAL(p,16,(uint32)allocation_size);
1593 unsigned int ea_size = estimate_ea_size(conn, NULL,
1594 smb_fname->base_name);
1595 SIVAL(p,22,ea_size); /* Extended attributes */
1599 len = srvstr_push(base_data, flags2,
1600 p, fname, PTR_DIFF(end_data, p),
1601 STR_TERMINATE | STR_NOALIGN);
1602 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1615 SCVAL(nameptr,0,len);
1617 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1620 case SMB_FIND_EA_LIST:
1622 struct ea_list *file_list = NULL;
1625 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1629 if (requires_resume_key) {
1633 srv_put_dos_date2(p,0,create_date);
1634 srv_put_dos_date2(p,4,adate);
1635 srv_put_dos_date2(p,8,mdate);
1636 SIVAL(p,12,(uint32)file_size);
1637 SIVAL(p,16,(uint32)allocation_size);
1639 p += 22; /* p now points to the EA area. */
1641 file_list = get_ea_list_from_file(ctx, conn, NULL,
1642 smb_fname->base_name,
1644 name_list = ea_list_union(name_list, file_list, &ea_len);
1646 /* We need to determine if this entry will fit in the space available. */
1647 /* Max string size is 255 bytes. */
1648 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1649 *out_of_space = true;
1650 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1651 "(wanted %u, had %d)\n",
1652 (unsigned int)PTR_DIFF(p + 255 + ea_len,pdata),
1654 return False; /* Not finished - just out of space */
1657 /* Push the ea_data followed by the name. */
1658 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1660 len = srvstr_push(base_data, flags2,
1661 p + 1, fname, PTR_DIFF(end_data, p+1),
1662 STR_TERMINATE | STR_NOALIGN);
1663 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1676 SCVAL(nameptr,0,len);
1678 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1682 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1683 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1684 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1686 SIVAL(p,0,reskey); p += 4;
1687 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
1688 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
1689 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
1690 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
1691 SOFF_T(p,0,file_size); p += 8;
1692 SOFF_T(p,0,allocation_size); p += 8;
1693 SIVAL(p,0,mode); p += 4;
1694 q = p; p += 4; /* q is placeholder for name length. */
1696 unsigned int ea_size = estimate_ea_size(conn, NULL,
1697 smb_fname->base_name);
1698 SIVAL(p,0,ea_size); /* Extended attributes */
1701 /* Clear the short name buffer. This is
1702 * IMPORTANT as not doing so will trigger
1703 * a Win2k client bug. JRA.
1705 if (!was_8_3 && check_mangled_names) {
1706 char mangled_name[13]; /* mangled 8.3 name. */
1707 if (!name_to_8_3(fname,mangled_name,True,
1709 /* Error - mangle failed ! */
1710 memset(mangled_name,'\0',12);
1712 mangled_name[12] = 0;
1713 len = srvstr_push(base_data, flags2,
1714 p+2, mangled_name, 24,
1715 STR_UPPER|STR_UNICODE);
1717 memset(p + 2 + len,'\0',24 - len);
1724 len = srvstr_push(base_data, flags2, p,
1725 fname, PTR_DIFF(end_data, p),
1726 STR_TERMINATE_ASCII);
1730 len = PTR_DIFF(p, pdata);
1731 pad = (len + (align-1)) & ~(align-1);
1733 * offset to the next entry, the caller
1734 * will overwrite it for the last entry
1735 * that's why we always include the padding
1739 * set padding to zero
1742 memset(p, 0, pad - len);
1749 case SMB_FIND_FILE_DIRECTORY_INFO:
1750 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1752 SIVAL(p,0,reskey); p += 4;
1753 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
1754 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
1755 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
1756 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
1757 SOFF_T(p,0,file_size); p += 8;
1758 SOFF_T(p,0,allocation_size); p += 8;
1759 SIVAL(p,0,mode); p += 4;
1760 len = srvstr_push(base_data, flags2,
1761 p + 4, fname, PTR_DIFF(end_data, p+4),
1762 STR_TERMINATE_ASCII);
1766 len = PTR_DIFF(p, pdata);
1767 pad = (len + (align-1)) & ~(align-1);
1769 * offset to the next entry, the caller
1770 * will overwrite it for the last entry
1771 * that's why we always include the padding
1775 * set padding to zero
1778 memset(p, 0, pad - len);
1785 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1786 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1788 SIVAL(p,0,reskey); p += 4;
1789 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
1790 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
1791 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
1792 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
1793 SOFF_T(p,0,file_size); p += 8;
1794 SOFF_T(p,0,allocation_size); p += 8;
1795 SIVAL(p,0,mode); p += 4;
1796 q = p; p += 4; /* q is placeholder for name length. */
1798 unsigned int ea_size = estimate_ea_size(conn, NULL,
1799 smb_fname->base_name);
1800 SIVAL(p,0,ea_size); /* Extended attributes */
1803 len = srvstr_push(base_data, flags2, p,
1804 fname, PTR_DIFF(end_data, p),
1805 STR_TERMINATE_ASCII);
1809 len = PTR_DIFF(p, pdata);
1810 pad = (len + (align-1)) & ~(align-1);
1812 * offset to the next entry, the caller
1813 * will overwrite it for the last entry
1814 * that's why we always include the padding
1818 * set padding to zero
1821 memset(p, 0, pad - len);
1828 case SMB_FIND_FILE_NAMES_INFO:
1829 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1831 SIVAL(p,0,reskey); p += 4;
1833 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1834 acl on a dir (tridge) */
1835 len = srvstr_push(base_data, flags2, p,
1836 fname, PTR_DIFF(end_data, p),
1837 STR_TERMINATE_ASCII);
1841 len = PTR_DIFF(p, pdata);
1842 pad = (len + (align-1)) & ~(align-1);
1844 * offset to the next entry, the caller
1845 * will overwrite it for the last entry
1846 * that's why we always include the padding
1850 * set padding to zero
1853 memset(p, 0, pad - len);
1860 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1861 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1863 SIVAL(p,0,reskey); p += 4;
1864 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
1865 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
1866 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
1867 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
1868 SOFF_T(p,0,file_size); p += 8;
1869 SOFF_T(p,0,allocation_size); p += 8;
1870 SIVAL(p,0,mode); p += 4;
1871 q = p; p += 4; /* q is placeholder for name length. */
1873 unsigned int ea_size = estimate_ea_size(conn, NULL,
1874 smb_fname->base_name);
1875 SIVAL(p,0,ea_size); /* Extended attributes */
1878 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1879 SIVAL(p,0,smb_fname->st.st_ex_ino); p += 4; /* FileIndexLow */
1880 SIVAL(p,0,smb_fname->st.st_ex_dev); p += 4; /* FileIndexHigh */
1881 len = srvstr_push(base_data, flags2, p,
1882 fname, PTR_DIFF(end_data, p),
1883 STR_TERMINATE_ASCII);
1887 len = PTR_DIFF(p, pdata);
1888 pad = (len + (align-1)) & ~(align-1);
1890 * offset to the next entry, the caller
1891 * will overwrite it for the last entry
1892 * that's why we always include the padding
1896 * set padding to zero
1899 memset(p, 0, pad - len);
1906 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1907 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1908 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1910 SIVAL(p,0,reskey); p += 4;
1911 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
1912 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
1913 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
1914 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
1915 SOFF_T(p,0,file_size); p += 8;
1916 SOFF_T(p,0,allocation_size); p += 8;
1917 SIVAL(p,0,mode); p += 4;
1918 q = p; p += 4; /* q is placeholder for name length */
1920 unsigned int ea_size = estimate_ea_size(conn, NULL,
1921 smb_fname->base_name);
1922 SIVAL(p,0,ea_size); /* Extended attributes */
1925 /* Clear the short name buffer. This is
1926 * IMPORTANT as not doing so will trigger
1927 * a Win2k client bug. JRA.
1929 if (!was_8_3 && check_mangled_names) {
1930 char mangled_name[13]; /* mangled 8.3 name. */
1931 if (!name_to_8_3(fname,mangled_name,True,
1933 /* Error - mangle failed ! */
1934 memset(mangled_name,'\0',12);
1936 mangled_name[12] = 0;
1937 len = srvstr_push(base_data, flags2,
1938 p+2, mangled_name, 24,
1939 STR_UPPER|STR_UNICODE);
1942 memset(p + 2 + len,'\0',24 - len);
1949 SSVAL(p,0,0); p += 2; /* Reserved ? */
1950 SIVAL(p,0,smb_fname->st.st_ex_ino); p += 4; /* FileIndexLow */
1951 SIVAL(p,0,smb_fname->st.st_ex_dev); p += 4; /* FileIndexHigh */
1952 len = srvstr_push(base_data, flags2, p,
1953 fname, PTR_DIFF(end_data, p),
1954 STR_TERMINATE_ASCII);
1958 len = PTR_DIFF(p, pdata);
1959 pad = (len + (align-1)) & ~(align-1);
1961 * offset to the next entry, the caller
1962 * will overwrite it for the last entry
1963 * that's why we always include the padding
1967 * set padding to zero
1970 memset(p, 0, pad - len);
1977 /* CIFS UNIX Extension. */
1979 case SMB_FIND_FILE_UNIX:
1980 case SMB_FIND_FILE_UNIX_INFO2:
1982 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1984 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1986 if (info_level == SMB_FIND_FILE_UNIX) {
1987 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
1988 p = store_file_unix_basic(conn, p,
1989 NULL, &smb_fname->st);
1990 len = srvstr_push(base_data, flags2, p,
1991 fname, PTR_DIFF(end_data, p),
1994 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1995 p = store_file_unix_basic_info2(conn, p,
1996 NULL, &smb_fname->st);
1999 len = srvstr_push(base_data, flags2, p, fname,
2000 PTR_DIFF(end_data, p), 0);
2001 SIVAL(nameptr, 0, len);
2006 len = PTR_DIFF(p, pdata);
2007 pad = (len + (align-1)) & ~(align-1);
2009 * offset to the next entry, the caller
2010 * will overwrite it for the last entry
2011 * that's why we always include the padding
2015 * set padding to zero
2018 memset(p, 0, pad - len);
2023 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2031 if (PTR_DIFF(p,pdata) > space_remaining) {
2032 *out_of_space = true;
2033 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2034 "(wanted %u, had %d)\n",
2035 (unsigned int)PTR_DIFF(p,pdata),
2037 return false; /* Not finished - just out of space */
2040 /* Setup the last entry pointer, as an offset from base_data */
2041 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
2042 /* Advance the data pointer to the next slot */
2048 bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
2049 connection_struct *conn,
2050 struct dptr_struct *dirptr,
2052 const char *path_mask,
2055 int requires_resume_key,
2063 int space_remaining,
2065 bool *got_exact_match,
2066 int *_last_entry_off,
2067 struct ea_list *name_list)
2070 const char *mask = NULL;
2071 long prev_dirpos = 0;
2074 struct smb_filename *smb_fname = NULL;
2075 struct smbd_dirptr_lanman2_state state;
2077 uint64_t last_entry_off = 0;
2081 state.info_level = info_level;
2082 state.check_mangled_names = lp_manglednames(conn->params);
2083 state.has_wild = dptr_has_wild(dirptr);
2084 state.got_exact_match = false;
2086 *out_of_space = false;
2087 *got_exact_match = false;
2089 p = strrchr_m(path_mask,'/');
2100 ok = smbd_dirptr_get_entry(ctx,
2106 smbd_dirptr_lanman2_match_fn,
2107 smbd_dirptr_lanman2_mode_fn,
2117 *got_exact_match = state.got_exact_match;
2119 ok = smbd_marshall_dir_entry(ctx,
2124 state.check_mangled_names,
2125 requires_resume_key,
2138 TALLOC_FREE(smb_fname);
2139 if (*out_of_space) {
2140 dptr_SeekDir(dirptr, prev_dirpos);
2147 *_last_entry_off = last_entry_off;
2151 static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
2152 connection_struct *conn,
2153 struct dptr_struct *dirptr,
2155 const char *path_mask,
2158 bool requires_resume_key,
2164 int space_remaining,
2166 bool *got_exact_match,
2167 int *last_entry_off,
2168 struct ea_list *name_list)
2171 const bool do_pad = true;
2173 if (info_level >= 1 && info_level <= 3) {
2174 /* No alignment on earlier info levels. */
2178 return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
2179 path_mask, dirtype, info_level,
2180 requires_resume_key, dont_descend, ask_sharemode,
2182 ppdata, base_data, end_data,
2184 out_of_space, got_exact_match,
2185 last_entry_off, name_list);
2188 /****************************************************************************
2189 Reply to a TRANS2_FINDFIRST.
2190 ****************************************************************************/
2192 static void call_trans2findfirst(connection_struct *conn,
2193 struct smb_request *req,
2194 char **pparams, int total_params,
2195 char **ppdata, int total_data,
2196 unsigned int max_data_bytes)
2198 /* We must be careful here that we don't return more than the
2199 allowed number of data bytes. If this means returning fewer than
2200 maxentries then so be it. We assume that the redirector has
2201 enough room for the fixed number of parameter bytes it has
2203 struct smb_filename *smb_dname = NULL;
2204 char *params = *pparams;
2205 char *pdata = *ppdata;
2209 uint16 findfirst_flags;
2210 bool close_after_first;
2212 bool requires_resume_key;
2214 char *directory = NULL;
2217 int last_entry_off=0;
2221 bool finished = False;
2222 bool dont_descend = False;
2223 bool out_of_space = False;
2224 int space_remaining;
2225 bool mask_contains_wcard = False;
2226 struct ea_list *ea_list = NULL;
2227 NTSTATUS ntstatus = NT_STATUS_OK;
2228 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2229 TALLOC_CTX *ctx = talloc_tos();
2230 struct dptr_struct *dirptr = NULL;
2231 struct smbd_server_connection *sconn = smbd_server_conn;
2233 if (total_params < 13) {
2234 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2238 dirtype = SVAL(params,0);
2239 maxentries = SVAL(params,2);
2240 findfirst_flags = SVAL(params,4);
2241 close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
2242 close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2243 requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2244 info_level = SVAL(params,6);
2246 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2247 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
2248 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
2249 info_level, max_data_bytes));
2252 /* W2K3 seems to treat zero as 1. */
2256 switch (info_level) {
2257 case SMB_FIND_INFO_STANDARD:
2258 case SMB_FIND_EA_SIZE:
2259 case SMB_FIND_EA_LIST:
2260 case SMB_FIND_FILE_DIRECTORY_INFO:
2261 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2262 case SMB_FIND_FILE_NAMES_INFO:
2263 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2264 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2265 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2267 case SMB_FIND_FILE_UNIX:
2268 case SMB_FIND_FILE_UNIX_INFO2:
2269 /* Always use filesystem for UNIX mtime query. */
2270 ask_sharemode = false;
2271 if (!lp_unix_extensions()) {
2272 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2277 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2281 srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
2282 params+12, total_params - 12,
2283 STR_TERMINATE, &ntstatus, &mask_contains_wcard);
2284 if (!NT_STATUS_IS_OK(ntstatus)) {
2285 reply_nterror(req, ntstatus);
2289 ntstatus = filename_convert(ctx, conn,
2290 req->flags2 & FLAGS2_DFS_PATHNAMES,
2293 UCF_ALWAYS_ALLOW_WCARD_LCOMP),
2294 &mask_contains_wcard,
2296 if (!NT_STATUS_IS_OK(ntstatus)) {
2297 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
2298 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2299 ERRSRV, ERRbadpath);
2302 reply_nterror(req, ntstatus);
2306 mask = smb_dname->original_lcomp;
2308 directory = smb_dname->base_name;
2310 p = strrchr_m(directory,'/');
2312 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2313 if((directory[0] == '.') && (directory[1] == '\0')) {
2314 mask = talloc_strdup(ctx,"*");
2316 reply_nterror(req, NT_STATUS_NO_MEMORY);
2319 mask_contains_wcard = True;
2321 directory = talloc_strdup(talloc_tos(), "./");
2323 reply_nterror(req, NT_STATUS_NO_MEMORY);
2330 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2332 if (info_level == SMB_FIND_EA_LIST) {
2335 if (total_data < 4) {
2336 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2340 ea_size = IVAL(pdata,0);
2341 if (ea_size != total_data) {
2342 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2343 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2344 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2348 if (!lp_ea_support(SNUM(conn))) {
2349 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2353 /* Pull out the list of names. */
2354 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2356 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2361 *ppdata = (char *)SMB_REALLOC(
2362 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2363 if(*ppdata == NULL ) {
2364 reply_nterror(req, NT_STATUS_NO_MEMORY);
2368 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2370 /* Realloc the params space */
2371 *pparams = (char *)SMB_REALLOC(*pparams, 10);
2372 if (*pparams == NULL) {
2373 reply_nterror(req, NT_STATUS_NO_MEMORY);
2378 /* Save the wildcard match and attribs we are using on this directory -
2379 needed as lanman2 assumes these are being saved between calls */
2381 ntstatus = dptr_create(conn,
2387 mask_contains_wcard,
2391 if (!NT_STATUS_IS_OK(ntstatus)) {
2392 reply_nterror(req, ntstatus);
2396 dptr_num = dptr_dnum(dirptr);
2397 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2399 /* Initialize per TRANS2_FIND_FIRST operation data */
2400 dptr_init_search_op(dirptr);
2402 /* We don't need to check for VOL here as this is returned by
2403 a different TRANS2 call. */
2405 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2406 directory,lp_dontdescend(SNUM(conn))));
2407 if (in_list(directory,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2408 dont_descend = True;
2411 space_remaining = max_data_bytes;
2412 out_of_space = False;
2414 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2415 bool got_exact_match = False;
2417 /* this is a heuristic to avoid seeking the dirptr except when
2418 absolutely necessary. It allows for a filename of about 40 chars */
2419 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2420 out_of_space = True;
2423 finished = !get_lanman2_dir_entry(ctx,
2427 mask,dirtype,info_level,
2428 requires_resume_key,dont_descend,
2431 space_remaining, &out_of_space,
2433 &last_entry_off, ea_list);
2436 if (finished && out_of_space)
2439 if (!finished && !out_of_space)
2443 * As an optimisation if we know we aren't looking
2444 * for a wildcard name (ie. the name matches the wildcard exactly)
2445 * then we can finish on any (first) match.
2446 * This speeds up large directory searches. JRA.
2452 /* Ensure space_remaining never goes -ve. */
2453 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2454 space_remaining = 0;
2455 out_of_space = true;
2457 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2461 /* Check if we can close the dirptr */
2462 if(close_after_first || (finished && close_if_end)) {
2463 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2464 dptr_close(sconn, &dptr_num);
2468 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2469 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2470 * the protocol level is less than NT1. Tested with smbclient. JRA.
2471 * This should fix the OS/2 client bug #2335.
2474 if(numentries == 0) {
2475 dptr_close(sconn, &dptr_num);
2476 if (get_Protocol() < PROTOCOL_NT1) {
2477 reply_force_doserror(req, ERRDOS, ERRnofiles);
2480 reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2481 ERRDOS, ERRbadfile);
2486 /* At this point pdata points to numentries directory entries. */
2488 /* Set up the return parameter block */
2489 SSVAL(params,0,dptr_num);
2490 SSVAL(params,2,numentries);
2491 SSVAL(params,4,finished);
2492 SSVAL(params,6,0); /* Never an EA error */
2493 SSVAL(params,8,last_entry_off);
2495 send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
2498 if ((! *directory) && dptr_path(sconn, dptr_num)) {
2499 directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
2501 reply_nterror(req, NT_STATUS_NO_MEMORY);
2505 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2506 smb_fn_name(req->cmd),
2507 mask, directory, dirtype, numentries ) );
2510 * Force a name mangle here to ensure that the
2511 * mask as an 8.3 name is top of the mangled cache.
2512 * The reasons for this are subtle. Don't remove
2513 * this code unless you know what you are doing
2514 * (see PR#13758). JRA.
2517 if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2518 char mangled_name[13];
2519 name_to_8_3(mask, mangled_name, True, conn->params);
2522 TALLOC_FREE(smb_dname);
2526 /****************************************************************************
2527 Reply to a TRANS2_FINDNEXT.
2528 ****************************************************************************/
2530 static void call_trans2findnext(connection_struct *conn,
2531 struct smb_request *req,
2532 char **pparams, int total_params,
2533 char **ppdata, int total_data,
2534 unsigned int max_data_bytes)
2536 /* We must be careful here that we don't return more than the
2537 allowed number of data bytes. If this means returning fewer than
2538 maxentries then so be it. We assume that the redirector has
2539 enough room for the fixed number of parameter bytes it has
2541 char *params = *pparams;
2542 char *pdata = *ppdata;
2548 uint16 findnext_flags;
2549 bool close_after_request;
2551 bool requires_resume_key;
2553 bool mask_contains_wcard = False;
2554 char *resume_name = NULL;
2555 const char *mask = NULL;
2556 const char *directory = NULL;
2560 int i, last_entry_off=0;
2561 bool finished = False;
2562 bool dont_descend = False;
2563 bool out_of_space = False;
2564 int space_remaining;
2565 struct ea_list *ea_list = NULL;
2566 NTSTATUS ntstatus = NT_STATUS_OK;
2567 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2568 TALLOC_CTX *ctx = talloc_tos();
2569 struct dptr_struct *dirptr;
2570 struct smbd_server_connection *sconn = smbd_server_conn;
2572 if (total_params < 13) {
2573 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2577 dptr_num = SVAL(params,0);
2578 maxentries = SVAL(params,2);
2579 info_level = SVAL(params,4);
2580 resume_key = IVAL(params,6);
2581 findnext_flags = SVAL(params,10);
2582 close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2583 close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2584 requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2585 continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2587 if (!continue_bit) {
2588 /* We only need resume_name if continue_bit is zero. */
2589 srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2591 total_params - 12, STR_TERMINATE, &ntstatus,
2592 &mask_contains_wcard);
2593 if (!NT_STATUS_IS_OK(ntstatus)) {
2594 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2595 complain (it thinks we're asking for the directory above the shared
2596 path or an invalid name). Catch this as the resume name is only compared, never used in
2597 a file access. JRA. */
2598 srvstr_pull_talloc(ctx, params, req->flags2,
2599 &resume_name, params+12,
2603 if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2604 reply_nterror(req, ntstatus);
2610 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2611 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2612 resume_key = %d resume name = %s continue=%d level = %d\n",
2613 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
2614 requires_resume_key, resume_key,
2615 resume_name ? resume_name : "(NULL)", continue_bit, info_level));
2618 /* W2K3 seems to treat zero as 1. */
2622 switch (info_level) {
2623 case SMB_FIND_INFO_STANDARD:
2624 case SMB_FIND_EA_SIZE:
2625 case SMB_FIND_EA_LIST:
2626 case SMB_FIND_FILE_DIRECTORY_INFO:
2627 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2628 case SMB_FIND_FILE_NAMES_INFO:
2629 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2630 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2631 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2633 case SMB_FIND_FILE_UNIX:
2634 case SMB_FIND_FILE_UNIX_INFO2:
2635 /* Always use filesystem for UNIX mtime query. */
2636 ask_sharemode = false;
2637 if (!lp_unix_extensions()) {
2638 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2643 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2647 if (info_level == SMB_FIND_EA_LIST) {
2650 if (total_data < 4) {
2651 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2655 ea_size = IVAL(pdata,0);
2656 if (ea_size != total_data) {
2657 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2658 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2659 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2663 if (!lp_ea_support(SNUM(conn))) {
2664 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2668 /* Pull out the list of names. */
2669 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2671 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2676 *ppdata = (char *)SMB_REALLOC(
2677 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2678 if(*ppdata == NULL) {
2679 reply_nterror(req, NT_STATUS_NO_MEMORY);
2684 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2686 /* Realloc the params space */
2687 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2688 if(*pparams == NULL ) {
2689 reply_nterror(req, NT_STATUS_NO_MEMORY);
2695 /* Check that the dptr is valid */
2696 if(!(dirptr = dptr_fetch_lanman2(sconn, dptr_num))) {
2697 reply_nterror(req, STATUS_NO_MORE_FILES);
2701 directory = dptr_path(sconn, dptr_num);
2703 /* Get the wildcard mask from the dptr */
2704 if((p = dptr_wcard(sconn, dptr_num))== NULL) {
2705 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2706 reply_nterror(req, STATUS_NO_MORE_FILES);
2712 /* Get the attr mask from the dptr */
2713 dirtype = dptr_attr(sconn, dptr_num);
2715 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2716 dptr_num, mask, dirtype,
2718 dptr_TellDir(dirptr)));
2720 /* Initialize per TRANS2_FIND_NEXT operation data */
2721 dptr_init_search_op(dirptr);
2723 /* We don't need to check for VOL here as this is returned by
2724 a different TRANS2 call. */
2726 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2727 directory,lp_dontdescend(SNUM(conn))));
2728 if (in_list(directory,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2729 dont_descend = True;
2732 space_remaining = max_data_bytes;
2733 out_of_space = False;
2736 * Seek to the correct position. We no longer use the resume key but
2737 * depend on the last file name instead.
2740 if(!continue_bit && resume_name && *resume_name) {
2743 long current_pos = 0;
2745 * Remember, name_to_8_3 is called by
2746 * get_lanman2_dir_entry(), so the resume name
2747 * could be mangled. Ensure we check the unmangled name.
2750 if (mangle_is_mangled(resume_name, conn->params)) {
2751 char *new_resume_name = NULL;
2752 mangle_lookup_name_from_8_3(ctx,
2756 if (new_resume_name) {
2757 resume_name = new_resume_name;
2762 * Fix for NT redirector problem triggered by resume key indexes
2763 * changing between directory scans. We now return a resume key of 0
2764 * and instead look for the filename to continue from (also given
2765 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2766 * findfirst/findnext (as is usual) then the directory pointer
2767 * should already be at the correct place.
2770 finished = !dptr_SearchDir(dirptr, resume_name, ¤t_pos, &st);
2771 } /* end if resume_name && !continue_bit */
2773 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2774 bool got_exact_match = False;
2776 /* this is a heuristic to avoid seeking the dirptr except when
2777 absolutely necessary. It allows for a filename of about 40 chars */
2778 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2779 out_of_space = True;
2782 finished = !get_lanman2_dir_entry(ctx,
2786 mask,dirtype,info_level,
2787 requires_resume_key,dont_descend,
2790 space_remaining, &out_of_space,
2792 &last_entry_off, ea_list);
2795 if (finished && out_of_space)
2798 if (!finished && !out_of_space)
2802 * As an optimisation if we know we aren't looking
2803 * for a wildcard name (ie. the name matches the wildcard exactly)
2804 * then we can finish on any (first) match.
2805 * This speeds up large directory searches. JRA.
2811 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2814 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2815 smb_fn_name(req->cmd),
2816 mask, directory, dirtype, numentries ) );
2818 /* Check if we can close the dirptr */
2819 if(close_after_request || (finished && close_if_end)) {
2820 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2821 dptr_close(sconn, &dptr_num); /* This frees up the saved mask */
2824 /* Set up the return parameter block */
2825 SSVAL(params,0,numentries);
2826 SSVAL(params,2,finished);
2827 SSVAL(params,4,0); /* Never an EA error */
2828 SSVAL(params,6,last_entry_off);
2830 send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
2836 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
2838 E_md4hash(lp_servicename(SNUM(conn)),objid);
2842 static void samba_extended_info_version(struct smb_extended_info *extended_info)
2844 SMB_ASSERT(extended_info != NULL);
2846 extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
2847 extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
2848 | ((SAMBA_VERSION_MINOR & 0xff) << 16)
2849 | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
2850 #ifdef SAMBA_VERSION_REVISION
2851 extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
2853 extended_info->samba_subversion = 0;
2854 #ifdef SAMBA_VERSION_RC_RELEASE
2855 extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
2857 #ifdef SAMBA_VERSION_PRE_RELEASE
2858 extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
2861 #ifdef SAMBA_VERSION_VENDOR_PATCH
2862 extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
2864 extended_info->samba_gitcommitdate = 0;
2865 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2866 unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
2869 memset(extended_info->samba_version_string, 0,
2870 sizeof(extended_info->samba_version_string));
2872 snprintf (extended_info->samba_version_string,
2873 sizeof(extended_info->samba_version_string),
2874 "%s", samba_version_string());
2877 NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
2878 TALLOC_CTX *mem_ctx,
2879 uint16_t info_level,
2881 unsigned int max_data_bytes,
2885 char *pdata, *end_data;
2886 int data_len = 0, len;
2887 const char *vname = volume_label(SNUM(conn));
2888 int snum = SNUM(conn);
2889 char *fstype = lp_fstype(SNUM(conn));
2890 uint32 additional_flags = 0;
2891 struct smb_filename smb_fname_dot;
2895 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2896 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
2897 "info level (0x%x) on IPC$.\n",
2898 (unsigned int)info_level));
2899 return NT_STATUS_ACCESS_DENIED;
2903 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
2905 ZERO_STRUCT(smb_fname_dot);
2906 smb_fname_dot.base_name = discard_const_p(char, ".");
2908 if(SMB_VFS_STAT(conn, &smb_fname_dot) != 0) {
2909 DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
2910 return map_nt_error_from_unix(errno);
2913 st = smb_fname_dot.st;
2915 *ppdata = (char *)SMB_REALLOC(
2916 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2917 if (*ppdata == NULL) {
2918 return NT_STATUS_NO_MEMORY;
2922 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2923 end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2925 switch (info_level) {
2926 case SMB_INFO_ALLOCATION:
2928 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2930 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2931 return map_nt_error_from_unix(errno);
2934 block_size = lp_block_size(snum);
2935 if (bsize < block_size) {
2936 uint64_t factor = block_size/bsize;
2941 if (bsize > block_size) {
2942 uint64_t factor = bsize/block_size;
2947 bytes_per_sector = 512;
2948 sectors_per_unit = bsize/bytes_per_sector;
2950 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2951 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2952 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2954 SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
2955 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2956 SIVAL(pdata,l1_cUnit,dsize);
2957 SIVAL(pdata,l1_cUnitAvail,dfree);
2958 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2962 case SMB_INFO_VOLUME:
2963 /* Return volume name */
2965 * Add volume serial number - hash of a combination of
2966 * the called hostname and the service name.
2968 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2970 * Win2k3 and previous mess this up by sending a name length
2971 * one byte short. I believe only older clients (OS/2 Win9x) use
2972 * this call so try fixing this by adding a terminating null to
2973 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2977 pdata+l2_vol_szVolLabel, vname,
2978 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
2979 STR_NOALIGN|STR_TERMINATE);
2980 SCVAL(pdata,l2_vol_cch,len);
2981 data_len = l2_vol_szVolLabel + len;
2982 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
2983 (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
2987 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2988 case SMB_FS_ATTRIBUTE_INFORMATION:
2990 additional_flags = 0;
2991 #if defined(HAVE_SYS_QUOTAS)
2992 additional_flags |= FILE_VOLUME_QUOTAS;
2995 if(lp_nt_acl_support(SNUM(conn))) {
2996 additional_flags |= FILE_PERSISTENT_ACLS;
2999 /* Capabilities are filled in at connection time through STATVFS call */
3000 additional_flags |= conn->fs_capabilities;
3001 additional_flags |= lp_parm_int(conn->params->service,
3002 "share", "fake_fscaps",
3005 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
3006 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
3007 additional_flags); /* FS ATTRIBUTES */
3009 SIVAL(pdata,4,255); /* Max filename component length */
3010 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3011 and will think we can't do long filenames */
3012 len = srvstr_push(pdata, flags2, pdata+12, fstype,
3013 PTR_DIFF(end_data, pdata+12),
3016 data_len = 12 + len;
3019 case SMB_QUERY_FS_LABEL_INFO:
3020 case SMB_FS_LABEL_INFORMATION:
3021 len = srvstr_push(pdata, flags2, pdata+4, vname,
3022 PTR_DIFF(end_data, pdata+4), 0);
3027 case SMB_QUERY_FS_VOLUME_INFO:
3028 case SMB_FS_VOLUME_INFORMATION:
3031 * Add volume serial number - hash of a combination of
3032 * the called hostname and the service name.
3034 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
3035 (str_checksum(get_local_machine_name())<<16));
3037 /* Max label len is 32 characters. */
3038 len = srvstr_push(pdata, flags2, pdata+18, vname,
3039 PTR_DIFF(end_data, pdata+18),
3041 SIVAL(pdata,12,len);
3044 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3045 (int)strlen(vname),vname, lp_servicename(snum)));
3048 case SMB_QUERY_FS_SIZE_INFO:
3049 case SMB_FS_SIZE_INFORMATION:
3051 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
3053 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
3054 return map_nt_error_from_unix(errno);
3056 block_size = lp_block_size(snum);
3057 if (bsize < block_size) {
3058 uint64_t factor = block_size/bsize;
3063 if (bsize > block_size) {
3064 uint64_t factor = bsize/block_size;
3069 bytes_per_sector = 512;
3070 sectors_per_unit = bsize/bytes_per_sector;
3071 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3072 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
3073 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3074 SBIG_UINT(pdata,0,dsize);
3075 SBIG_UINT(pdata,8,dfree);
3076 SIVAL(pdata,16,sectors_per_unit);
3077 SIVAL(pdata,20,bytes_per_sector);
3081 case SMB_FS_FULL_SIZE_INFORMATION:
3083 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
3085 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
3086 return map_nt_error_from_unix(errno);
3088 block_size = lp_block_size(snum);
3089 if (bsize < block_size) {
3090 uint64_t factor = block_size/bsize;
3095 if (bsize > block_size) {
3096 uint64_t factor = bsize/block_size;
3101 bytes_per_sector = 512;
3102 sectors_per_unit = bsize/bytes_per_sector;
3103 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3104 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
3105 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3106 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
3107 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
3108 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
3109 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
3110 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
3114 case SMB_QUERY_FS_DEVICE_INFO:
3115 case SMB_FS_DEVICE_INFORMATION:
3117 SIVAL(pdata,0,0); /* dev type */
3118 SIVAL(pdata,4,0); /* characteristics */
3121 #ifdef HAVE_SYS_QUOTAS
3122 case SMB_FS_QUOTA_INFORMATION:
3124 * what we have to send --metze:
3126 * Unknown1: 24 NULL bytes
3127 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3128 * Hard Quota Limit: 8 bytes seems like uint64_t or so
3129 * Quota Flags: 2 byte :
3130 * Unknown3: 6 NULL bytes
3134 * details for Quota Flags:
3136 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3137 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
3138 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3139 * 0x0001 Enable Quotas: enable quota for this fs
3143 /* we need to fake up a fsp here,
3144 * because its not send in this call
3147 SMB_NTQUOTA_STRUCT quotas;
3150 ZERO_STRUCT(quotas);
3156 if (conn->server_info->utok.uid != sec_initial_uid()) {
3157 DEBUG(0,("set_user_quota: access_denied "
3158 "service [%s] user [%s]\n",
3159 lp_servicename(SNUM(conn)),
3160 conn->server_info->unix_name));
3161 return NT_STATUS_ACCESS_DENIED;
3164 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
3165 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
3166 return map_nt_error_from_unix(errno);
3171 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3172 lp_servicename(SNUM(conn))));
3174 /* Unknown1 24 NULL bytes*/
3175 SBIG_UINT(pdata,0,(uint64_t)0);
3176 SBIG_UINT(pdata,8,(uint64_t)0);
3177 SBIG_UINT(pdata,16,(uint64_t)0);
3179 /* Default Soft Quota 8 bytes */
3180 SBIG_UINT(pdata,24,quotas.softlim);
3182 /* Default Hard Quota 8 bytes */
3183 SBIG_UINT(pdata,32,quotas.hardlim);
3185 /* Quota flag 2 bytes */
3186 SSVAL(pdata,40,quotas.qflags);
3188 /* Unknown3 6 NULL bytes */
3194 #endif /* HAVE_SYS_QUOTAS */
3195 case SMB_FS_OBJECTID_INFORMATION:
3197 unsigned char objid[16];
3198 struct smb_extended_info extended_info;
3199 memcpy(pdata,create_volume_objectid(conn, objid),16);
3200 samba_extended_info_version (&extended_info);
3201 SIVAL(pdata,16,extended_info.samba_magic);
3202 SIVAL(pdata,20,extended_info.samba_version);
3203 SIVAL(pdata,24,extended_info.samba_subversion);
3204 SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
3205 memcpy(pdata+36,extended_info.samba_version_string,28);
3211 * Query the version and capabilities of the CIFS UNIX extensions
3215 case SMB_QUERY_CIFS_UNIX_INFO:
3217 bool large_write = lp_min_receive_file_size() &&
3218 !srv_is_signing_active(smbd_server_conn);
3219 bool large_read = !srv_is_signing_active(smbd_server_conn);
3220 int encrypt_caps = 0;
3222 if (!lp_unix_extensions()) {
3223 return NT_STATUS_INVALID_LEVEL;
3226 switch (conn->encrypt_level) {
3232 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
3235 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
3236 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
3237 large_write = false;
3243 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
3244 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
3246 /* We have POSIX ACLs, pathname, encryption,
3247 * large read/write, and locking capability. */
3249 SBIG_UINT(pdata,4,((uint64_t)(
3250 CIFS_UNIX_POSIX_ACLS_CAP|
3251 CIFS_UNIX_POSIX_PATHNAMES_CAP|
3252 CIFS_UNIX_FCNTL_LOCKS_CAP|
3253 CIFS_UNIX_EXTATTR_CAP|
3254 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
3256 (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
3258 CIFS_UNIX_LARGE_WRITE_CAP : 0))));
3262 case SMB_QUERY_POSIX_FS_INFO:
3265 vfs_statvfs_struct svfs;
3267 if (!lp_unix_extensions()) {
3268 return NT_STATUS_INVALID_LEVEL;
3271 rc = SMB_VFS_STATVFS(conn, ".", &svfs);
3275 SIVAL(pdata,0,svfs.OptimalTransferSize);
3276 SIVAL(pdata,4,svfs.BlockSize);
3277 SBIG_UINT(pdata,8,svfs.TotalBlocks);
3278 SBIG_UINT(pdata,16,svfs.BlocksAvail);
3279 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
3280 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
3281 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
3282 SBIG_UINT(pdata,48,svfs.FsIdentifier);
3283 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3285 } else if (rc == EOPNOTSUPP) {
3286 return NT_STATUS_INVALID_LEVEL;
3287 #endif /* EOPNOTSUPP */
3289 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
3290 return NT_STATUS_DOS(ERRSRV, ERRerror);
3295 case SMB_QUERY_POSIX_WHOAMI:
3301 if (!lp_unix_extensions()) {
3302 return NT_STATUS_INVALID_LEVEL;
3305 if (max_data_bytes < 40) {
3306 return NT_STATUS_BUFFER_TOO_SMALL;
3309 /* We ARE guest if global_sid_Builtin_Guests is
3310 * in our list of SIDs.
3312 if (nt_token_check_sid(&global_sid_Builtin_Guests,
3313 conn->server_info->ptok)) {
3314 flags |= SMB_WHOAMI_GUEST;
3317 /* We are NOT guest if global_sid_Authenticated_Users
3318 * is in our list of SIDs.
3320 if (nt_token_check_sid(&global_sid_Authenticated_Users,
3321 conn->server_info->ptok)) {
3322 flags &= ~SMB_WHOAMI_GUEST;
3325 /* NOTE: 8 bytes for UID/GID, irrespective of native
3326 * platform size. This matches
3327 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3329 data_len = 4 /* flags */
3336 + 4 /* pad/reserved */
3337 + (conn->server_info->utok.ngroups * 8)
3339 + (conn->server_info->ptok->num_sids *
3343 SIVAL(pdata, 0, flags);
3344 SIVAL(pdata, 4, SMB_WHOAMI_MASK);
3346 (uint64_t)conn->server_info->utok.uid);
3347 SBIG_UINT(pdata, 16,
3348 (uint64_t)conn->server_info->utok.gid);
3351 if (data_len >= max_data_bytes) {
3352 /* Potential overflow, skip the GIDs and SIDs. */
3354 SIVAL(pdata, 24, 0); /* num_groups */
3355 SIVAL(pdata, 28, 0); /* num_sids */
3356 SIVAL(pdata, 32, 0); /* num_sid_bytes */
3357 SIVAL(pdata, 36, 0); /* reserved */
3363 SIVAL(pdata, 24, conn->server_info->utok.ngroups);
3364 SIVAL(pdata, 28, conn->server_info->num_sids);
3366 /* We walk the SID list twice, but this call is fairly
3367 * infrequent, and I don't expect that it's performance
3368 * sensitive -- jpeach
3370 for (i = 0, sid_bytes = 0;
3371 i < conn->server_info->ptok->num_sids; ++i) {
3372 sid_bytes += ndr_size_dom_sid(
3373 &conn->server_info->ptok->user_sids[i],
3378 /* SID list byte count */
3379 SIVAL(pdata, 32, sid_bytes);
3381 /* 4 bytes pad/reserved - must be zero */
3382 SIVAL(pdata, 36, 0);
3386 for (i = 0; i < conn->server_info->utok.ngroups; ++i) {
3387 SBIG_UINT(pdata, data_len,
3388 (uint64_t)conn->server_info->utok.groups[i]);
3394 i < conn->server_info->ptok->num_sids; ++i) {
3395 int sid_len = ndr_size_dom_sid(
3396 &conn->server_info->ptok->user_sids[i],
3400 sid_linearize(pdata + data_len, sid_len,
3401 &conn->server_info->ptok->user_sids[i]);
3402 data_len += sid_len;
3408 case SMB_MAC_QUERY_FS_INFO:
3410 * Thursby MAC extension... ONLY on NTFS filesystems
3411 * once we do streams then we don't need this
3413 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
3415 SIVAL(pdata,84,0x100); /* Don't support mac... */
3420 return NT_STATUS_INVALID_LEVEL;
3423 *ret_data_len = data_len;
3424 return NT_STATUS_OK;
3427 /****************************************************************************
3428 Reply to a TRANS2_QFSINFO (query filesystem info).
3429 ****************************************************************************/
3431 static void call_trans2qfsinfo(connection_struct *conn,
3432 struct smb_request *req,
3433 char **pparams, int total_params,
3434 char **ppdata, int total_data,
3435 unsigned int max_data_bytes)
3437 char *params = *pparams;
3438 uint16_t info_level;
3442 if (total_params < 2) {
3443 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3447 info_level = SVAL(params,0);
3449 if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
3450 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
3451 DEBUG(0,("call_trans2qfsinfo: encryption required "
3452 "and info level 0x%x sent.\n",
3453 (unsigned int)info_level));
3454 exit_server_cleanly("encryption required "
3460 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
3462 status = smbd_do_qfsinfo(conn, req,
3467 if (!NT_STATUS_IS_OK(status)) {
3468 reply_nterror(req, status);
3472 send_trans2_replies(conn, req, params, 0, *ppdata, data_len,
3475 DEBUG( 4, ( "%s info_level = %d\n",
3476 smb_fn_name(req->cmd), info_level) );
3481 /****************************************************************************
3482 Reply to a TRANS2_SETFSINFO (set filesystem info).
3483 ****************************************************************************/
3485 static void call_trans2setfsinfo(connection_struct *conn,
3486 struct smb_request *req,
3487 char **pparams, int total_params,
3488 char **ppdata, int total_data,
3489 unsigned int max_data_bytes)
3491 char *pdata = *ppdata;
3492 char *params = *pparams;
3495 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
3498 if (total_params < 4) {
3499 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3501 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3505 info_level = SVAL(params,2);
3508 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
3509 info_level != SMB_SET_CIFS_UNIX_INFO) {
3510 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3511 "info level (0x%x) on IPC$.\n",
3512 (unsigned int)info_level));
3513 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3518 if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
3519 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
3520 DEBUG(0,("call_trans2setfsinfo: encryption required "
3521 "and info level 0x%x sent.\n",
3522 (unsigned int)info_level));
3523 exit_server_cleanly("encryption required "
3529 switch(info_level) {
3530 case SMB_SET_CIFS_UNIX_INFO:
3532 uint16 client_unix_major;
3533 uint16 client_unix_minor;
3534 uint32 client_unix_cap_low;
3535 uint32 client_unix_cap_high;
3537 if (!lp_unix_extensions()) {
3539 NT_STATUS_INVALID_LEVEL);
3543 /* There should be 12 bytes of capabilities set. */
3544 if (total_data < 8) {
3547 NT_STATUS_INVALID_PARAMETER);
3550 client_unix_major = SVAL(pdata,0);
3551 client_unix_minor = SVAL(pdata,2);
3552 client_unix_cap_low = IVAL(pdata,4);
3553 client_unix_cap_high = IVAL(pdata,8);
3554 /* Just print these values for now. */
3555 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
3556 cap_low = 0x%x, cap_high = 0x%x\n",
3557 (unsigned int)client_unix_major,
3558 (unsigned int)client_unix_minor,
3559 (unsigned int)client_unix_cap_low,
3560 (unsigned int)client_unix_cap_high ));
3562 /* Here is where we must switch to posix pathname processing... */
3563 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
3564 lp_set_posix_pathnames();
3565 mangle_change_to_posix();
3568 if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
3569 !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
3570 /* Client that knows how to do posix locks,
3571 * but not posix open/mkdir operations. Set a
3572 * default type for read/write checks. */
3574 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
3580 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
3583 size_t param_len = 0;
3584 size_t data_len = total_data;
3586 if (!lp_unix_extensions()) {
3589 NT_STATUS_INVALID_LEVEL);
3593 if (lp_smb_encrypt(SNUM(conn)) == false) {
3596 NT_STATUS_NOT_SUPPORTED);
3600 if (smbd_server_conn->smb1.echo_handler.trusted_fde) {
3601 DEBUG( 2,("call_trans2setfsinfo: "
3602 "request transport encryption disabled"
3603 "with 'fork echo handler = yes'\n"));
3606 NT_STATUS_NOT_SUPPORTED);
3610 DEBUG( 4,("call_trans2setfsinfo: "
3611 "request transport encryption.\n"));
3613 status = srv_request_encryption_setup(conn,
3614 (unsigned char **)ppdata,
3616 (unsigned char **)pparams,
3619 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
3620 !NT_STATUS_IS_OK(status)) {
3621 reply_nterror(req, status);
3625 send_trans2_replies(conn, req,
3632 if (NT_STATUS_IS_OK(status)) {
3633 /* Server-side transport
3634 * encryption is now *on*. */
3635 status = srv_encryption_start(conn);
3636 if (!NT_STATUS_IS_OK(status)) {
3637 exit_server_cleanly(
3638 "Failure in setting "
3639 "up encrypted transport");
3645 case SMB_FS_QUOTA_INFORMATION:
3647 files_struct *fsp = NULL;
3648 SMB_NTQUOTA_STRUCT quotas;
3650 ZERO_STRUCT(quotas);
3653 if ((conn->server_info->utok.uid != sec_initial_uid())
3654 ||!CAN_WRITE(conn)) {
3655 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3656 lp_servicename(SNUM(conn)),
3657 conn->server_info->unix_name));
3658 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3662 /* note: normaly there're 48 bytes,
3663 * but we didn't use the last 6 bytes for now
3666 fsp = file_fsp(req, SVAL(params,0));
3668 if (!check_fsp_ntquota_handle(conn, req,
3670 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3672 req, NT_STATUS_INVALID_HANDLE);
3676 if (total_data < 42) {
3677 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3681 NT_STATUS_INVALID_PARAMETER);
3685 /* unknown_1 24 NULL bytes in pdata*/
3687 /* the soft quotas 8 bytes (uint64_t)*/
3688 quotas.softlim = (uint64_t)IVAL(pdata,24);
3689 #ifdef LARGE_SMB_OFF_T
3690 quotas.softlim |= (((uint64_t)IVAL(pdata,28)) << 32);
3691 #else /* LARGE_SMB_OFF_T */
3692 if ((IVAL(pdata,28) != 0)&&
3693 ((quotas.softlim != 0xFFFFFFFF)||
3694 (IVAL(pdata,28)!=0xFFFFFFFF))) {
3695 /* more than 32 bits? */
3698 NT_STATUS_INVALID_PARAMETER);
3701 #endif /* LARGE_SMB_OFF_T */
3703 /* the hard quotas 8 bytes (uint64_t)*/
3704 quotas.hardlim = (uint64_t)IVAL(pdata,32);
3705 #ifdef LARGE_SMB_OFF_T
3706 quotas.hardlim |= (((uint64_t)IVAL(pdata,36)) << 32);
3707 #else /* LARGE_SMB_OFF_T */
3708 if ((IVAL(pdata,36) != 0)&&
3709 ((quotas.hardlim != 0xFFFFFFFF)||
3710 (IVAL(pdata,36)!=0xFFFFFFFF))) {
3711 /* more than 32 bits? */
3714 NT_STATUS_INVALID_PARAMETER);
3717 #endif /* LARGE_SMB_OFF_T */
3719 /* quota_flags 2 bytes **/
3720 quotas.qflags = SVAL(pdata,40);
3722 /* unknown_2 6 NULL bytes follow*/
3724 /* now set the quotas */
3725 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
3726 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
3727 reply_nterror(req, map_nt_error_from_unix(errno));
3734 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3736 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3742 * sending this reply works fine,
3743 * but I'm not sure it's the same
3744 * like windows do...
3747 reply_outbuf(req, 10, 0);
3750 #if defined(HAVE_POSIX_ACLS)
3751 /****************************************************************************
3752 Utility function to count the number of entries in a POSIX acl.
3753 ****************************************************************************/
3755 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
3757 unsigned int ace_count = 0;
3758 int entry_id = SMB_ACL_FIRST_ENTRY;
3759 SMB_ACL_ENTRY_T entry;
3761 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
3763 if (entry_id == SMB_ACL_FIRST_ENTRY) {
3764 entry_id = SMB_ACL_NEXT_ENTRY;
3771 /****************************************************************************
3772 Utility function to marshall a POSIX acl into wire format.
3773 ****************************************************************************/
3775 static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
3777 int entry_id = SMB_ACL_FIRST_ENTRY;
3778 SMB_ACL_ENTRY_T entry;
3780 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
3781 SMB_ACL_TAG_T tagtype;
3782 SMB_ACL_PERMSET_T permset;
3783 unsigned char perms = 0;
3784 unsigned int own_grp;
3787 if (entry_id == SMB_ACL_FIRST_ENTRY) {
3788 entry_id = SMB_ACL_NEXT_ENTRY;
3791 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
3792 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3796 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
3797 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3801 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
3802 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
3803 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
3805 SCVAL(pdata,1,perms);
3808 case SMB_ACL_USER_OBJ:
3809 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
3810 own_grp = (unsigned int)pst->st_ex_uid;
3811 SIVAL(pdata,2,own_grp);
3816 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
3818 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3821 own_grp = (unsigned int)*puid;
3822 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
3823 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
3824 SIVAL(pdata,2,own_grp);
3828 case SMB_ACL_GROUP_OBJ:
3829 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
3830 own_grp = (unsigned int)pst->st_ex_gid;
3831 SIVAL(pdata,2,own_grp);
3836 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
3838 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3841 own_grp = (unsigned int)*pgid;
3842 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
3843 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
3844 SIVAL(pdata,2,own_grp);
3849 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
3850 SIVAL(pdata,2,0xFFFFFFFF);
3851 SIVAL(pdata,6,0xFFFFFFFF);
3854 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
3855 SIVAL(pdata,2,0xFFFFFFFF);
3856 SIVAL(pdata,6,0xFFFFFFFF);
3859 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
3862 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
3869 /****************************************************************************
3870 Store the FILE_UNIX_BASIC info.
3871 ****************************************************************************/
3873 static char *store_file_unix_basic(connection_struct *conn,
3876 const SMB_STRUCT_STAT *psbuf)
3878 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
3879 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
3881 SOFF_T(pdata,0,get_file_size_stat(psbuf)); /* File size 64 Bit */
3884 SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
3887 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, psbuf->st_ex_ctime); /* Change Time 64 Bit */
3888 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */
3889 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */
3892 SIVAL(pdata,0,psbuf->st_ex_uid); /* user id for the owner */
3896 SIVAL(pdata,0,psbuf->st_ex_gid); /* group id of owner */
3900 SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
3903 SIVAL(pdata,0,unix_dev_major(psbuf->st_ex_rdev)); /* Major device number if type is device */
3907 SIVAL(pdata,0,unix_dev_minor(psbuf->st_ex_rdev)); /* Minor device number if type is device */
3911 SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ex_ino); /* inode number */
3914 SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode)); /* Standard UNIX file permissions */
3918 SIVAL(pdata,0,psbuf->st_ex_nlink); /* number of hard links */
3925 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
3926 * the chflags(2) (or equivalent) flags.
3928 * XXX: this really should be behind the VFS interface. To do this, we would
3929 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
3930 * Each VFS module could then implement its own mapping as appropriate for the
3931 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
3933 static const struct {unsigned stat_fflag; unsigned smb_fflag;}
3937 { UF_NODUMP, EXT_DO_NOT_BACKUP },
3941 { UF_IMMUTABLE, EXT_IMMUTABLE },
3945 { UF_APPEND, EXT_OPEN_APPEND_ONLY },
3949 { UF_HIDDEN, EXT_HIDDEN },
3952 /* Do not remove. We need to guarantee that this array has at least one
3953 * entry to build on HP-UX.
3959 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
3960 uint32 *smb_fflags, uint32 *smb_fmask)
3964 for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
3965 *smb_fmask |= info2_flags_map[i].smb_fflag;
3966 if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
3967 *smb_fflags |= info2_flags_map[i].smb_fflag;
3972 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
3973 const uint32 smb_fflags,
3974 const uint32 smb_fmask,
3977 uint32 max_fmask = 0;
3980 *stat_fflags = psbuf->st_ex_flags;
3982 /* For each flags requested in smb_fmask, check the state of the
3983 * corresponding flag in smb_fflags and set or clear the matching
3987 for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
3988 max_fmask |= info2_flags_map[i].smb_fflag;
3989 if (smb_fmask & info2_flags_map[i].smb_fflag) {
3990 if (smb_fflags & info2_flags_map[i].smb_fflag) {
3991 *stat_fflags |= info2_flags_map[i].stat_fflag;
3993 *stat_fflags &= ~info2_flags_map[i].stat_fflag;
3998 /* If smb_fmask is asking to set any bits that are not supported by
3999 * our flag mappings, we should fail.
4001 if ((smb_fmask & max_fmask) != smb_fmask) {
4009 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4010 * of file flags and birth (create) time.
4012 static char *store_file_unix_basic_info2(connection_struct *conn,
4015 const SMB_STRUCT_STAT *psbuf)
4017 uint32 file_flags = 0;
4018 uint32 flags_mask = 0;
4020 pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4022 /* Create (birth) time 64 bit */
4023 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, psbuf->st_ex_btime);
4026 map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
4027 SIVAL(pdata, 0, file_flags); /* flags */
4028 SIVAL(pdata, 4, flags_mask); /* mask */
4034 static NTSTATUS marshall_stream_info(unsigned int num_streams,
4035 const struct stream_struct *streams,
4037 unsigned int max_data_bytes,
4038 unsigned int *data_size)
4041 unsigned int ofs = 0;
4043 for (i = 0; i < num_streams && ofs <= max_data_bytes; i++) {
4044 unsigned int next_offset;
4046 smb_ucs2_t *namebuf;
4048 if (!push_ucs2_talloc(talloc_tos(), &namebuf,
4049 streams[i].name, &namelen) ||
4052 return NT_STATUS_INVALID_PARAMETER;
4056 * name_buf is now null-terminated, we need to marshall as not
4062 SIVAL(data, ofs+4, namelen);
4063 SOFF_T(data, ofs+8, streams[i].size);
4064 SOFF_T(data, ofs+16, streams[i].alloc_size);
4065 memcpy(data+ofs+24, namebuf, namelen);
4066 TALLOC_FREE(namebuf);
4068 next_offset = ofs + 24 + namelen;
4070 if (i == num_streams-1) {
4071 SIVAL(data, ofs, 0);
4074 unsigned int align = ndr_align_size(next_offset, 8);
4076 memset(data+next_offset, 0, align);
4077 next_offset += align;
4079 SIVAL(data, ofs, next_offset - ofs);
4088 return NT_STATUS_OK;
4091 /****************************************************************************
4092 Reply to a TRANSACT2_QFILEINFO on a PIPE !
4093 ****************************************************************************/
4095 static void call_trans2qpipeinfo(connection_struct *conn,
4096 struct smb_request *req,
4097 unsigned int tran_call,
4098 char **pparams, int total_params,
4099 char **ppdata, int total_data,
4100 unsigned int max_data_bytes)
4102 char *params = *pparams;
4103 char *pdata = *ppdata;
4104 unsigned int data_size = 0;
4105 unsigned int param_size = 2;
4110 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4114 if (total_params < 4) {
4115 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4119 fsp = file_fsp(req, SVAL(params,0));
4120 if (!fsp_is_np(fsp)) {
4121 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
4125 info_level = SVAL(params,2);
4127 *pparams = (char *)SMB_REALLOC(*pparams,2);
4128 if (*pparams == NULL) {
4129 reply_nterror(req, NT_STATUS_NO_MEMORY);
4134 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
4135 *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
4136 if (*ppdata == NULL ) {
4137 reply_nterror(req, NT_STATUS_NO_MEMORY);
4142 switch (info_level) {
4143 case SMB_FILE_STANDARD_INFORMATION:
4145 SOFF_T(pdata,0,4096LL);
4152 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4156 send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
4162 NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
4163 TALLOC_CTX *mem_ctx,
4164 uint16_t info_level,
4166 struct smb_filename *smb_fname,
4167 bool delete_pending,
4168 struct timespec write_time_ts,
4169 struct ea_list *ea_list,
4170 int lock_data_count,
4173 unsigned int max_data_bytes,
4175 unsigned int *pdata_size)
4177 char *pdata = *ppdata;
4178 char *dstart, *dend;
4179 unsigned int data_size;
4180 struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
4181 time_t create_time, mtime, atime, c_time;
4182 SMB_STRUCT_STAT *psbuf = &smb_fname->st;
4189 uint64_t file_size = 0;
4191 uint64_t allocation_size = 0;
4192 uint64_t file_index = 0;
4193 uint32_t access_mask = 0;
4195 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
4196 return NT_STATUS_INVALID_LEVEL;
4199 DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
4200 smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1,
4201 info_level, max_data_bytes));
4203 mode = dos_mode(conn, smb_fname);
4204 nlink = psbuf->st_ex_nlink;
4206 if (nlink && (mode&aDIR)) {
4210 if ((nlink > 0) && delete_pending) {
4214 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
4215 *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
4216 if (*ppdata == NULL) {
4217 return NT_STATUS_NO_MEMORY;
4221 dend = dstart + data_size - 1;
4223 if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
4224 update_stat_ex_mtime(psbuf, write_time_ts);
4227 create_time_ts = get_create_timespec(conn, fsp, smb_fname);
4228 mtime_ts = psbuf->st_ex_mtime;
4229 atime_ts = psbuf->st_ex_atime;
4230 ctime_ts = get_change_timespec(conn, fsp, smb_fname);
4232 if (lp_dos_filetime_resolution(SNUM(conn))) {
4233 dos_filetime_timespec(&create_time_ts);
4234 dos_filetime_timespec(&mtime_ts);
4235 dos_filetime_timespec(&atime_ts);
4236 dos_filetime_timespec(&ctime_ts);
4239 create_time = convert_timespec_to_time_t(create_time_ts);
4240 mtime = convert_timespec_to_time_t(mtime_ts);
4241 atime = convert_timespec_to_time_t(atime_ts);
4242 c_time = convert_timespec_to_time_t(ctime_ts);
4244 p = strrchr_m(smb_fname->base_name,'/');
4246 base_name = smb_fname->base_name;
4250 /* NT expects the name to be in an exact form of the *full*
4251 filename. See the trans2 torture test */
4252 if (ISDOT(base_name)) {
4253 dos_fname = talloc_strdup(mem_ctx, "\\");
4255 return NT_STATUS_NO_MEMORY;
4258 dos_fname = talloc_asprintf(mem_ctx,
4260 smb_fname->base_name);
4262 return NT_STATUS_NO_MEMORY;
4264 if (is_ntfs_stream_smb_fname(smb_fname)) {
4265 dos_fname = talloc_asprintf(dos_fname, "%s",
4266 smb_fname->stream_name);
4268 return NT_STATUS_NO_MEMORY;
4272 string_replace(dos_fname, '/', '\\');
4275 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
4278 /* Do we have this path open ? */
4280 struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
4281 fsp1 = file_find_di_first(fileid);
4282 if (fsp1 && fsp1->initial_allocation_size) {
4283 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
4287 if (!(mode & aDIR)) {
4288 file_size = get_file_size_stat(psbuf);
4292 pos = fsp->fh->position_information;
4296 access_mask = fsp->access_mask;
4298 /* GENERIC_EXECUTE mapping from Windows */
4299 access_mask = 0x12019F;
4302 /* This should be an index number - looks like
4305 I think this causes us to fail the IFSKIT
4306 BasicFileInformationTest. -tpot */
4307 file_index = ((psbuf->st_ex_ino) & UINT32_MAX); /* FileIndexLow */
4308 file_index |= ((uint64_t)((psbuf->st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
4310 switch (info_level) {
4311 case SMB_INFO_STANDARD:
4312 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4314 srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
4315 srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
4316 srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
4317 SIVAL(pdata,l1_cbFile,(uint32)file_size);
4318 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
4319 SSVAL(pdata,l1_attrFile,mode);
4322 case SMB_INFO_QUERY_EA_SIZE:
4324 unsigned int ea_size =
4325 estimate_ea_size(conn, fsp,
4326 smb_fname->base_name);
4327 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4329 srv_put_dos_date2(pdata,0,create_time);
4330 srv_put_dos_date2(pdata,4,atime);
4331 srv_put_dos_date2(pdata,8,mtime); /* write time */
4332 SIVAL(pdata,12,(uint32)file_size);
4333 SIVAL(pdata,16,(uint32)allocation_size);
4334 SSVAL(pdata,20,mode);
4335 SIVAL(pdata,22,ea_size);
4339 case SMB_INFO_IS_NAME_VALID:
4340 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4342 /* os/2 needs this ? really ?*/
4343 return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
4345 /* This is only reached for qpathinfo */
4349 case SMB_INFO_QUERY_EAS_FROM_LIST:
4351 size_t total_ea_len = 0;
4352 struct ea_list *ea_file_list = NULL;
4354 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4357 get_ea_list_from_file(mem_ctx, conn, fsp,
4358 smb_fname->base_name,
4360 ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
4362 if (!ea_list || (total_ea_len > data_size)) {
4364 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
4368 data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
4372 case SMB_INFO_QUERY_ALL_EAS:
4374 /* We have data_size bytes to put EA's into. */
4375 size_t total_ea_len = 0;
4377 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4379 ea_list = get_ea_list_from_file(mem_ctx, conn, fsp,
4380 smb_fname->base_name,
4382 if (!ea_list || (total_ea_len > data_size)) {
4384 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
4388 data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
4392 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4394 /* This is FileFullEaInformation - 0xF which maps to
4395 * 1015 (decimal) in smbd_do_setfilepathinfo. */
4397 /* We have data_size bytes to put EA's into. */
4398 size_t total_ea_len = 0;
4399 struct ea_list *ea_file_list = NULL;
4401 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4403 /*TODO: add filtering and index handling */
4406 get_ea_list_from_file(mem_ctx, conn, fsp,
4407 smb_fname->base_name,
4409 if (!ea_file_list) {
4410 return NT_STATUS_NO_EAS_ON_FILE;
4413 status = fill_ea_chained_buffer(mem_ctx,
4417 conn, ea_file_list);
4418 if (!NT_STATUS_IS_OK(status)) {
4424 case SMB_FILE_BASIC_INFORMATION:
4425 case SMB_QUERY_FILE_BASIC_INFO:
4427 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
4428 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4429 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
4431 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4435 put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4436 put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4437 put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4438 put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4439 SIVAL(pdata,32,mode);
4441 DEBUG(5,("SMB_QFBI - "));
4442 DEBUG(5,("create: %s ", ctime(&create_time)));
4443 DEBUG(5,("access: %s ", ctime(&atime)));
4444 DEBUG(5,("write: %s ", ctime(&mtime)));
4445 DEBUG(5,("change: %s ", ctime(&c_time)));
4446 DEBUG(5,("mode: %x\n", mode));
4449 case SMB_FILE_STANDARD_INFORMATION:
4450 case SMB_QUERY_FILE_STANDARD_INFO:
4452 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4454 SOFF_T(pdata,0,allocation_size);
4455 SOFF_T(pdata,8,file_size);
4456 SIVAL(pdata,16,nlink);
4457 SCVAL(pdata,20,delete_pending?1:0);
4458 SCVAL(pdata,21,(mode&aDIR)?1:0);
4459 SSVAL(pdata,22,0); /* Padding. */
4462 case SMB_FILE_EA_INFORMATION:
4463 case SMB_QUERY_FILE_EA_INFO:
4465 unsigned int ea_size =
4466 estimate_ea_size(conn, fsp, smb_fname->base_name);
4467 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4469 SIVAL(pdata,0,ea_size);
4473 /* Get the 8.3 name - used if NT SMB was negotiated. */
4474 case SMB_QUERY_FILE_ALT_NAME_INFO:
4475 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
4478 char mangled_name[13];
4479 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4480 if (!name_to_8_3(base_name,mangled_name,
4481 True,conn->params)) {
4482 return NT_STATUS_NO_MEMORY;
4484 len = srvstr_push(dstart, flags2,
4485 pdata+4, mangled_name,
4486 PTR_DIFF(dend, pdata+4),
4488 data_size = 4 + len;
4493 case SMB_QUERY_FILE_NAME_INFO:
4497 this must be *exactly* right for ACLs on mapped drives to work
4499 len = srvstr_push(dstart, flags2,
4501 PTR_DIFF(dend, pdata+4),
4503 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4504 data_size = 4 + len;
4509 case SMB_FILE_ALLOCATION_INFORMATION:
4510 case SMB_QUERY_FILE_ALLOCATION_INFO:
4511 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4513 SOFF_T(pdata,0,allocation_size);
4516 case SMB_FILE_END_OF_FILE_INFORMATION:
4517 case SMB_QUERY_FILE_END_OF_FILEINFO:
4518 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4520 SOFF_T(pdata,0,file_size);
4523 case SMB_QUERY_FILE_ALL_INFO:
4524 case SMB_FILE_ALL_INFORMATION:
4527 unsigned int ea_size =
4528 estimate_ea_size(conn, fsp, smb_fname->base_name);
4529 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4530 put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4531 put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4532 put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4533 put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4534 SIVAL(pdata,32,mode);
4535 SIVAL(pdata,36,0); /* padding. */
4537 SOFF_T(pdata,0,allocation_size);
4538 SOFF_T(pdata,8,file_size);
4539 SIVAL(pdata,16,nlink);
4540 SCVAL(pdata,20,delete_pending);
4541 SCVAL(pdata,21,(mode&aDIR)?1:0);
4544 SIVAL(pdata,0,ea_size);
4545 pdata += 4; /* EA info */
4546 len = srvstr_push(dstart, flags2,
4548 PTR_DIFF(dend, pdata+4),
4552 data_size = PTR_DIFF(pdata,(*ppdata));
4556 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4559 unsigned int ea_size =
4560 estimate_ea_size(conn, fsp, smb_fname->base_name);
4561 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4562 put_long_date_timespec(conn->ts_res,pdata+0x00,create_time_ts);
4563 put_long_date_timespec(conn->ts_res,pdata+0x08,atime_ts);
4564 put_long_date_timespec(conn->ts_res,pdata+0x10,mtime_ts); /* write time */
4565 put_long_date_timespec(conn->ts_res,pdata+0x18,ctime_ts); /* change time */
4566 SIVAL(pdata, 0x20, mode);
4567 SIVAL(pdata, 0x24, 0); /* padding. */
4568 SBVAL(pdata, 0x28, allocation_size);
4569 SBVAL(pdata, 0x30, file_size);
4570 SIVAL(pdata, 0x38, nlink);
4571 SCVAL(pdata, 0x3C, delete_pending);
4572 SCVAL(pdata, 0x3D, (mode&aDIR)?1:0);
4573 SSVAL(pdata, 0x3E, 0); /* padding */
4574 SBVAL(pdata, 0x40, file_index);
4575 SIVAL(pdata, 0x48, ea_size);
4576 SIVAL(pdata, 0x4C, access_mask);
4577 SBVAL(pdata, 0x50, pos);
4578 SIVAL(pdata, 0x58, mode); /*TODO: mode != mode fix this!!! */
4579 SIVAL(pdata, 0x5C, 0); /* No alignment needed. */
4583 len = srvstr_push(dstart, flags2,
4585 PTR_DIFF(dend, pdata+4),
4589 data_size = PTR_DIFF(pdata,(*ppdata));
4592 case SMB_FILE_INTERNAL_INFORMATION:
4594 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4595 SBVAL(pdata, 0, file_index);
4599 case SMB_FILE_ACCESS_INFORMATION:
4600 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4601 SIVAL(pdata, 0, access_mask);
4605 case SMB_FILE_NAME_INFORMATION:
4606 /* Pathname with leading '\'. */
4609 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
4610 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4611 SIVAL(pdata,0,byte_len);
4612 data_size = 4 + byte_len;
4616 case SMB_FILE_DISPOSITION_INFORMATION:
4617 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4619 SCVAL(pdata,0,delete_pending);
4622 case SMB_FILE_POSITION_INFORMATION:
4623 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4625 SOFF_T(pdata,0,pos);
4628 case SMB_FILE_MODE_INFORMATION:
4629 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4630 SIVAL(pdata,0,mode);
4634 case SMB_FILE_ALIGNMENT_INFORMATION:
4635 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4636 SIVAL(pdata,0,0); /* No alignment needed. */
4641 * NT4 server just returns "invalid query" to this - if we try
4642 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4645 /* The first statement above is false - verified using Thursby
4646 * client against NT4 -- gcolley.
4648 case SMB_QUERY_FILE_STREAM_INFO:
4649 case SMB_FILE_STREAM_INFORMATION: {
4650 unsigned int num_streams;
4651 struct stream_struct *streams;
4653 DEBUG(10,("smbd_do_qfilepathinfo: "
4654 "SMB_FILE_STREAM_INFORMATION\n"));
4656 if (is_ntfs_stream_smb_fname(smb_fname)) {
4657 return NT_STATUS_INVALID_PARAMETER;
4660 status = SMB_VFS_STREAMINFO(
4661 conn, fsp, smb_fname->base_name, talloc_tos(),
4662 &num_streams, &streams);
4664 if (!NT_STATUS_IS_OK(status)) {
4665 DEBUG(10, ("could not get stream info: %s\n",
4666 nt_errstr(status)));
4670 status = marshall_stream_info(num_streams, streams,
4671 pdata, max_data_bytes,
4674 if (!NT_STATUS_IS_OK(status)) {
4675 DEBUG(10, ("marshall_stream_info failed: %s\n",
4676 nt_errstr(status)));
4680 TALLOC_FREE(streams);
4684 case SMB_QUERY_COMPRESSION_INFO:
4685 case SMB_FILE_COMPRESSION_INFORMATION:
4686 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4687 SOFF_T(pdata,0,file_size);
4688 SIVAL(pdata,8,0); /* ??? */
4689 SIVAL(pdata,12,0); /* ??? */
4693 case SMB_FILE_NETWORK_OPEN_INFORMATION:
4694 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4695 put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4696 put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4697 put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4698 put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4699 SOFF_T(pdata,32,allocation_size);
4700 SOFF_T(pdata,40,file_size);
4701 SIVAL(pdata,48,mode);
4702 SIVAL(pdata,52,0); /* ??? */
4706 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
4707 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4708 SIVAL(pdata,0,mode);
4714 * CIFS UNIX Extensions.
4717 case SMB_QUERY_FILE_UNIX_BASIC:
4719 pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4720 data_size = PTR_DIFF(pdata,(*ppdata));
4724 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
4726 for (i=0; i<100; i++)
4727 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
4733 case SMB_QUERY_FILE_UNIX_INFO2:
4735 pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
4736 data_size = PTR_DIFF(pdata,(*ppdata));
4740 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4742 for (i=0; i<100; i++)
4743 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
4749 case SMB_QUERY_FILE_UNIX_LINK:
4752 char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
4755 return NT_STATUS_NO_MEMORY;
4758 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4760 if(!S_ISLNK(psbuf->st_ex_mode)) {
4761 return NT_STATUS_DOS(ERRSRV, ERRbadlink);
4764 return NT_STATUS_DOS(ERRDOS, ERRbadlink);
4766 len = SMB_VFS_READLINK(conn,
4767 smb_fname->base_name,
4770 return map_nt_error_from_unix(errno);
4773 len = srvstr_push(dstart, flags2,
4775 PTR_DIFF(dend, pdata),
4778 data_size = PTR_DIFF(pdata,(*ppdata));
4783 #if defined(HAVE_POSIX_ACLS)
4784 case SMB_QUERY_POSIX_ACL:
4786 SMB_ACL_T file_acl = NULL;
4787 SMB_ACL_T def_acl = NULL;
4788 uint16 num_file_acls = 0;
4789 uint16 num_def_acls = 0;
4791 if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
4792 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
4795 SMB_VFS_SYS_ACL_GET_FILE(conn,
4796 smb_fname->base_name,
4797 SMB_ACL_TYPE_ACCESS);
4800 if (file_acl == NULL && no_acl_syscall_error(errno)) {
4801 DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4802 "not implemented on "
4803 "filesystem containing %s\n",
4804 smb_fname->base_name));
4805 return NT_STATUS_NOT_IMPLEMENTED;
4808 if (S_ISDIR(psbuf->st_ex_mode)) {
4809 if (fsp && fsp->is_directory) {
4811 SMB_VFS_SYS_ACL_GET_FILE(
4813 fsp->fsp_name->base_name,
4814 SMB_ACL_TYPE_DEFAULT);
4817 SMB_VFS_SYS_ACL_GET_FILE(
4819 smb_fname->base_name,
4820 SMB_ACL_TYPE_DEFAULT);
4822 def_acl = free_empty_sys_acl(conn, def_acl);
4825 num_file_acls = count_acl_entries(conn, file_acl);
4826 num_def_acls = count_acl_entries(conn, def_acl);
4828 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
4829 DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
4831 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
4832 SMB_POSIX_ACL_HEADER_SIZE) ));
4834 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4837 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4839 return NT_STATUS_BUFFER_TOO_SMALL;
4842 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
4843 SSVAL(pdata,2,num_file_acls);
4844 SSVAL(pdata,4,num_def_acls);
4845 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, psbuf, file_acl)) {
4847 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4850 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4852 return NT_STATUS_INTERNAL_ERROR;
4854 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), psbuf, def_acl)) {
4856 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4859 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4861 return NT_STATUS_INTERNAL_ERROR;
4865 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4868 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4870 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
4876 case SMB_QUERY_POSIX_LOCK:
4881 enum brl_type lock_type;
4883 /* We need an open file with a real fd for this. */
4884 if (!fsp || fsp->is_directory || fsp->fh->fd == -1) {
4885 return NT_STATUS_INVALID_LEVEL;
4888 if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
4889 return NT_STATUS_INVALID_PARAMETER;
4892 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
4893 case POSIX_LOCK_TYPE_READ:
4894 lock_type = READ_LOCK;
4896 case POSIX_LOCK_TYPE_WRITE:
4897 lock_type = WRITE_LOCK;
4899 case POSIX_LOCK_TYPE_UNLOCK:
4901 /* There's no point in asking for an unlock... */
4902 return NT_STATUS_INVALID_PARAMETER;
4905 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
4906 #if defined(HAVE_LONGLONG)
4907 offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
4908 ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
4909 count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
4910 ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
4911 #else /* HAVE_LONGLONG */
4912 offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
4913 count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
4914 #endif /* HAVE_LONGLONG */
4916 status = query_lock(fsp,
4923 if (ERROR_WAS_LOCK_DENIED(status)) {
4924 /* Here we need to report who has it locked... */
4925 data_size = POSIX_LOCK_DATA_SIZE;
4927 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
4928 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
4929 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid);
4930 #if defined(HAVE_LONGLONG)
4931 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
4932 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
4933 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
4934 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
4935 #else /* HAVE_LONGLONG */
4936 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
4937 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
4938 #endif /* HAVE_LONGLONG */
4940 } else if (NT_STATUS_IS_OK(status)) {
4941 /* For success we just return a copy of what we sent
4942 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
4943 data_size = POSIX_LOCK_DATA_SIZE;
4944 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
4945 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
4953 return NT_STATUS_INVALID_LEVEL;
4956 *pdata_size = data_size;
4957 return NT_STATUS_OK;
4960 /****************************************************************************
4961 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
4962 file name or file id).
4963 ****************************************************************************/
4965 static void call_trans2qfilepathinfo(connection_struct *conn,
4966 struct smb_request *req,
4967 unsigned int tran_call,
4968 char **pparams, int total_params,
4969 char **ppdata, int total_data,
4970 unsigned int max_data_bytes)
4972 char *params = *pparams;
4973 char *pdata = *ppdata;
4975 unsigned int data_size = 0;
4976 unsigned int param_size = 2;
4977 struct smb_filename *smb_fname = NULL;
4978 bool delete_pending = False;
4979 struct timespec write_time_ts;
4980 files_struct *fsp = NULL;
4981 struct file_id fileid;
4982 struct ea_list *ea_list = NULL;
4983 int lock_data_count = 0;
4984 char *lock_data = NULL;
4985 NTSTATUS status = NT_STATUS_OK;
4988 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4992 ZERO_STRUCT(write_time_ts);
4994 if (tran_call == TRANSACT2_QFILEINFO) {
4995 if (total_params < 4) {
4996 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5001 call_trans2qpipeinfo(conn, req, tran_call,
5002 pparams, total_params,
5008 fsp = file_fsp(req, SVAL(params,0));
5009 info_level = SVAL(params,2);
5011 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
5013 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5014 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5018 /* Initial check for valid fsp ptr. */
5019 if (!check_fsp_open(conn, req, fsp)) {
5023 status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
5025 if (!NT_STATUS_IS_OK(status)) {
5026 reply_nterror(req, status);
5030 if(fsp->fake_file_handle) {
5032 * This is actually for the QUOTA_FAKE_FILE --metze
5035 /* We know this name is ok, it's already passed the checks. */
5037 } else if(fsp->is_directory || fsp->fh->fd == -1) {
5039 * This is actually a QFILEINFO on a directory
5040 * handle (returned from an NT SMB). NT5.0 seems
5041 * to do this call. JRA.
5044 if (INFO_LEVEL_IS_UNIX(info_level)) {
5045 /* Always do lstat for UNIX calls. */
5046 if (SMB_VFS_LSTAT(conn, smb_fname)) {
5047 DEBUG(3,("call_trans2qfilepathinfo: "
5048 "SMB_VFS_LSTAT of %s failed "
5050 smb_fname_str_dbg(smb_fname),
5053 map_nt_error_from_unix(errno));
5056 } else if (SMB_VFS_STAT(conn, smb_fname)) {
5057 DEBUG(3,("call_trans2qfilepathinfo: "
5058 "SMB_VFS_STAT of %s failed (%s)\n",
5059 smb_fname_str_dbg(smb_fname),
5062 map_nt_error_from_unix(errno));
5066 fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5067 get_file_infos(fileid, &delete_pending, &write_time_ts);
5070 * Original code - this is an open file.
5072 if (!check_fsp(conn, req, fsp)) {
5076 if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
5077 DEBUG(3, ("fstat of fnum %d failed (%s)\n",
5078 fsp->fnum, strerror(errno)));
5080 map_nt_error_from_unix(errno));
5083 fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5084 get_file_infos(fileid, &delete_pending, &write_time_ts);
5091 if (total_params < 7) {
5092 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5096 info_level = SVAL(params,0);
5098 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
5100 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5101 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5105 srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
5107 STR_TERMINATE, &status);
5108 if (!NT_STATUS_IS_OK(status)) {
5109 reply_nterror(req, status);
5113 status = filename_convert(req,
5115 req->flags2 & FLAGS2_DFS_PATHNAMES,
5120 if (!NT_STATUS_IS_OK(status)) {
5121 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5122 reply_botherror(req,
5123 NT_STATUS_PATH_NOT_COVERED,
5124 ERRSRV, ERRbadpath);
5127 reply_nterror(req, status);
5131 /* If this is a stream, check if there is a delete_pending. */
5132 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5133 && is_ntfs_stream_smb_fname(smb_fname)) {
5134 struct smb_filename *smb_fname_base = NULL;
5136 /* Create an smb_filename with stream_name == NULL. */
5138 create_synthetic_smb_fname(talloc_tos(),
5139 smb_fname->base_name,
5142 if (!NT_STATUS_IS_OK(status)) {
5143 reply_nterror(req, status);
5147 if (INFO_LEVEL_IS_UNIX(info_level)) {
5148 /* Always do lstat for UNIX calls. */
5149 if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
5150 DEBUG(3,("call_trans2qfilepathinfo: "
5151 "SMB_VFS_LSTAT of %s failed "
5153 smb_fname_str_dbg(smb_fname_base),
5155 TALLOC_FREE(smb_fname_base);
5157 map_nt_error_from_unix(errno));
5161 if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
5162 DEBUG(3,("call_trans2qfilepathinfo: "
5163 "fileinfo of %s failed "
5165 smb_fname_str_dbg(smb_fname_base),
5167 TALLOC_FREE(smb_fname_base);
5169 map_nt_error_from_unix(errno));
5174 fileid = vfs_file_id_from_sbuf(conn,
5175 &smb_fname_base->st);
5176 TALLOC_FREE(smb_fname_base);
5177 get_file_infos(fileid, &delete_pending, NULL);
5178 if (delete_pending) {
5179 reply_nterror(req, NT_STATUS_DELETE_PENDING);
5184 if (INFO_LEVEL_IS_UNIX(info_level)) {
5185 /* Always do lstat for UNIX calls. */
5186 if (SMB_VFS_LSTAT(conn, smb_fname)) {
5187 DEBUG(3,("call_trans2qfilepathinfo: "
5188 "SMB_VFS_LSTAT of %s failed (%s)\n",
5189 smb_fname_str_dbg(smb_fname),
5192 map_nt_error_from_unix(errno));
5197 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
5198 DEBUG(3,("call_trans2qfilepathinfo: "
5199 "SMB_VFS_STAT of %s failed (%s)\n",
5200 smb_fname_str_dbg(smb_fname),
5203 map_nt_error_from_unix(errno));
5208 fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5209 get_file_infos(fileid, &delete_pending, &write_time_ts);
5210 if (delete_pending) {
5211 reply_nterror(req, NT_STATUS_DELETE_PENDING);
5216 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
5217 "total_data=%d\n", smb_fname_str_dbg(smb_fname),
5218 fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
5220 /* Pull out any data sent here before we realloc. */
5221 switch (info_level) {
5222 case SMB_INFO_QUERY_EAS_FROM_LIST:
5224 /* Pull any EA list from the data portion. */
5227 if (total_data < 4) {
5229 req, NT_STATUS_INVALID_PARAMETER);
5232 ea_size = IVAL(pdata,0);
5234 if (total_data > 0 && ea_size != total_data) {
5235 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5236 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
5238 req, NT_STATUS_INVALID_PARAMETER);
5242 if (!lp_ea_support(SNUM(conn))) {
5243 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
5247 /* Pull out the list of names. */
5248 ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
5251 req, NT_STATUS_INVALID_PARAMETER);
5257 case SMB_QUERY_POSIX_LOCK:
5259 if (fsp == NULL || fsp->fh->fd == -1) {
5260 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
5264 if (total_data != POSIX_LOCK_DATA_SIZE) {
5266 req, NT_STATUS_INVALID_PARAMETER);
5270 /* Copy the lock range data. */
5271 lock_data = (char *)TALLOC_MEMDUP(
5272 req, pdata, total_data);
5274 reply_nterror(req, NT_STATUS_NO_MEMORY);
5277 lock_data_count = total_data;
5283 *pparams = (char *)SMB_REALLOC(*pparams,2);
5284 if (*pparams == NULL) {
5285 reply_nterror(req, NT_STATUS_NO_MEMORY);
5292 * draft-leach-cifs-v1-spec-02.txt
5293 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5296 * The requested information is placed in the Data portion of the
5297 * transaction response. For the information levels greater than 0x100,
5298 * the transaction response has 1 parameter word which should be
5299 * ignored by the client.
5301 * However Windows only follows this rule for the IS_NAME_VALID call.
5303 switch (info_level) {
5304 case SMB_INFO_IS_NAME_VALID:
5309 if ((info_level & 0xFF00) == 0xFF00) {
5311 * We use levels that start with 0xFF00
5312 * internally to represent SMB2 specific levels
5314 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5318 status = smbd_do_qfilepathinfo(conn, req, info_level,
5320 delete_pending, write_time_ts,
5322 lock_data_count, lock_data,
5323 req->flags2, max_data_bytes,
5324 ppdata, &data_size);
5325 if (!NT_STATUS_IS_OK(status)) {
5326 reply_nterror(req, status);
5330 send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
5336 /****************************************************************************
5337 Set a hard link (called by UNIX extensions and by NT rename with HARD link
5339 ****************************************************************************/
5341 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
5342 connection_struct *conn,
5343 const struct smb_filename *smb_fname_old,
5344 const struct smb_filename *smb_fname_new)
5346 NTSTATUS status = NT_STATUS_OK;
5348 /* source must already exist. */
5349 if (!VALID_STAT(smb_fname_old->st)) {
5350 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5353 /* Disallow if newname already exists. */
5354 if (VALID_STAT(smb_fname_new->st)) {
5355 return NT_STATUS_OBJECT_NAME_COLLISION;
5358 /* No links from a directory. */
5359 if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
5360 return NT_STATUS_FILE_IS_A_DIRECTORY;
5363 /* Setting a hardlink to/from a stream isn't currently supported. */
5364 if (is_ntfs_stream_smb_fname(smb_fname_old) ||
5365 is_ntfs_stream_smb_fname(smb_fname_new)) {
5366 return NT_STATUS_INVALID_PARAMETER;
5369 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5370 smb_fname_old->base_name, smb_fname_new->base_name));
5372 if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
5373 smb_fname_new->base_name) != 0) {
5374 status = map_nt_error_from_unix(errno);
5375 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5376 nt_errstr(status), smb_fname_old->base_name,
5377 smb_fname_new->base_name));
5382 /****************************************************************************
5383 Deal with setting the time from any of the setfilepathinfo functions.
5384 ****************************************************************************/
5386 NTSTATUS smb_set_file_time(connection_struct *conn,
5388 const struct smb_filename *smb_fname,
5389 struct smb_file_time *ft,
5390 bool setting_write_time)
5392 struct smb_filename smb_fname_base;
5394 FILE_NOTIFY_CHANGE_LAST_ACCESS
5395 |FILE_NOTIFY_CHANGE_LAST_WRITE
5396 |FILE_NOTIFY_CHANGE_CREATION;
5398 if (!VALID_STAT(smb_fname->st)) {
5399 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5402 /* get some defaults (no modifications) if any info is zero or -1. */
5403 if (null_timespec(ft->create_time)) {
5404 action &= ~FILE_NOTIFY_CHANGE_CREATION;
5407 if (null_timespec(ft->atime)) {
5408 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
5411 if (null_timespec(ft->mtime)) {
5412 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
5415 if (!setting_write_time) {
5416 /* ft->mtime comes from change time, not write time. */
5417 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
5420 /* Ensure the resolution is the correct for
5421 * what we can store on this filesystem. */
5423 round_timespec(conn->ts_res, &ft->create_time);
5424 round_timespec(conn->ts_res, &ft->ctime);
5425 round_timespec(conn->ts_res, &ft->atime);
5426 round_timespec(conn->ts_res, &ft->mtime);
5428 DEBUG(5,("smb_set_filetime: actime: %s\n ",
5429 time_to_asc(convert_timespec_to_time_t(ft->atime))));
5430 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5431 time_to_asc(convert_timespec_to_time_t(ft->mtime))));
5432 DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5433 time_to_asc(convert_timespec_to_time_t(ft->ctime))));
5434 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5435 time_to_asc(convert_timespec_to_time_t(ft->create_time))));
5437 if (setting_write_time) {
5439 * This was a Windows setfileinfo on an open file.
5440 * NT does this a lot. We also need to
5441 * set the time here, as it can be read by
5442 * FindFirst/FindNext and with the patch for bug #2045
5443 * in smbd/fileio.c it ensures that this timestamp is
5444 * kept sticky even after a write. We save the request
5445 * away and will set it on file close and after a write. JRA.
5448 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5449 time_to_asc(convert_timespec_to_time_t(ft->mtime))));
5452 if (fsp->base_fsp) {
5453 set_sticky_write_time_fsp(fsp->base_fsp,
5456 set_sticky_write_time_fsp(fsp, ft->mtime);
5459 set_sticky_write_time_path(
5460 vfs_file_id_from_sbuf(conn, &smb_fname->st),
5465 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5467 /* Always call ntimes on the base, even if a stream was passed in. */
5468 smb_fname_base = *smb_fname;
5469 smb_fname_base.stream_name = NULL;
5471 if(file_ntimes(conn, &smb_fname_base, ft)!=0) {
5472 return map_nt_error_from_unix(errno);
5475 notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
5476 smb_fname->base_name);
5477 return NT_STATUS_OK;
5480 /****************************************************************************
5481 Deal with setting the dosmode from any of the setfilepathinfo functions.
5482 ****************************************************************************/
5484 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
5485 const struct smb_filename *smb_fname,
5488 struct smb_filename *smb_fname_base = NULL;
5491 if (!VALID_STAT(smb_fname->st)) {
5492 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5495 /* Always operate on the base_name, even if a stream was passed in. */
5496 status = create_synthetic_smb_fname(talloc_tos(), smb_fname->base_name,
5497 NULL, &smb_fname->st,
5499 if (!NT_STATUS_IS_OK(status)) {
5504 if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
5511 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
5513 /* check the mode isn't different, before changing it */
5514 if ((dosmode != 0) && (dosmode != dos_mode(conn, smb_fname_base))) {
5515 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5516 "0x%x\n", smb_fname_str_dbg(smb_fname_base),
5517 (unsigned int)dosmode));
5519 if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL,
5521 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5523 smb_fname_str_dbg(smb_fname_base),
5525 status = map_nt_error_from_unix(errno);
5529 status = NT_STATUS_OK;
5531 TALLOC_FREE(smb_fname_base);
5535 /****************************************************************************
5536 Deal with setting the size from any of the setfilepathinfo functions.
5537 ****************************************************************************/
5539 static NTSTATUS smb_set_file_size(connection_struct *conn,
5540 struct smb_request *req,
5542 const struct smb_filename *smb_fname,
5543 const SMB_STRUCT_STAT *psbuf,
5545 bool fail_after_createfile)
5547 NTSTATUS status = NT_STATUS_OK;
5548 struct smb_filename *smb_fname_tmp = NULL;
5549 files_struct *new_fsp = NULL;
5551 if (!VALID_STAT(*psbuf)) {
5552 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5555 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
5557 if (size == get_file_size_stat(psbuf)) {
5558 return NT_STATUS_OK;
5561 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5562 smb_fname_str_dbg(smb_fname), (double)size));
5564 if (fsp && fsp->fh->fd != -1) {
5565 /* Handle based call. */
5566 if (vfs_set_filelen(fsp, size) == -1) {
5567 return map_nt_error_from_unix(errno);
5569 trigger_write_time_update_immediate(fsp);
5570 return NT_STATUS_OK;
5573 status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
5574 if (!NT_STATUS_IS_OK(status)) {
5578 smb_fname_tmp->st = *psbuf;
5580 status = SMB_VFS_CREATE_FILE(
5583 0, /* root_dir_fid */
5584 smb_fname_tmp, /* fname */
5585 FILE_WRITE_DATA, /* access_mask */
5586 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
5588 FILE_OPEN, /* create_disposition*/
5589 0, /* create_options */
5590 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5591 FORCE_OPLOCK_BREAK_TO_NONE, /* oplock_request */
5592 0, /* allocation_size */
5593 0, /* private_flags */
5596 &new_fsp, /* result */
5599 TALLOC_FREE(smb_fname_tmp);
5601 if (!NT_STATUS_IS_OK(status)) {
5602 /* NB. We check for open_was_deferred in the caller. */
5606 /* See RAW-SFILEINFO-END-OF-FILE */
5607 if (fail_after_createfile) {
5608 close_file(req, new_fsp,NORMAL_CLOSE);
5609 return NT_STATUS_INVALID_LEVEL;
5612 if (vfs_set_filelen(new_fsp, size) == -1) {
5613 status = map_nt_error_from_unix(errno);
5614 close_file(req, new_fsp,NORMAL_CLOSE);
5618 trigger_write_time_update_immediate(new_fsp);
5619 close_file(req, new_fsp,NORMAL_CLOSE);
5620 return NT_STATUS_OK;
5623 /****************************************************************************
5624 Deal with SMB_INFO_SET_EA.
5625 ****************************************************************************/
5627 static NTSTATUS smb_info_set_ea(connection_struct *conn,
5631 const struct smb_filename *smb_fname)
5633 struct ea_list *ea_list = NULL;
5634 TALLOC_CTX *ctx = NULL;
5635 NTSTATUS status = NT_STATUS_OK;
5637 if (total_data < 10) {
5639 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5640 length. They seem to have no effect. Bug #3212. JRA */
5642 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
5643 /* We're done. We only get EA info in this call. */
5644 return NT_STATUS_OK;
5647 return NT_STATUS_INVALID_PARAMETER;
5650 if (IVAL(pdata,0) > total_data) {
5651 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5652 IVAL(pdata,0), (unsigned int)total_data));
5653 return NT_STATUS_INVALID_PARAMETER;
5657 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
5659 return NT_STATUS_INVALID_PARAMETER;
5661 status = set_ea(conn, fsp, smb_fname, ea_list);
5666 /****************************************************************************
5667 Deal with SMB_FILE_FULL_EA_INFORMATION set.
5668 ****************************************************************************/
5670 static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
5675 struct ea_list *ea_list = NULL;
5679 return NT_STATUS_INVALID_HANDLE;
5682 if (!lp_ea_support(SNUM(conn))) {
5683 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5684 "EA's not supported.\n",
5685 (unsigned int)total_data));
5686 return NT_STATUS_EAS_NOT_SUPPORTED;
5689 if (total_data < 10) {
5690 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5692 (unsigned int)total_data));
5693 return NT_STATUS_INVALID_PARAMETER;
5696 ea_list = read_nttrans_ea_list(talloc_tos(),
5701 return NT_STATUS_INVALID_PARAMETER;
5703 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
5705 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5706 smb_fname_str_dbg(fsp->fsp_name),
5707 nt_errstr(status) ));
5713 /****************************************************************************
5714 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5715 ****************************************************************************/
5717 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
5721 struct smb_filename *smb_fname)
5723 NTSTATUS status = NT_STATUS_OK;
5724 bool delete_on_close;
5727 if (total_data < 1) {
5728 return NT_STATUS_INVALID_PARAMETER;
5732 return NT_STATUS_INVALID_HANDLE;
5735 delete_on_close = (CVAL(pdata,0) ? True : False);
5736 dosmode = dos_mode(conn, smb_fname);
5738 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5739 "delete_on_close = %u\n",
5740 smb_fname_str_dbg(smb_fname),
5741 (unsigned int)dosmode,
5742 (unsigned int)delete_on_close ));
5744 if (delete_on_close) {
5745 status = can_set_delete_on_close(fsp, dosmode);
5746 if (!NT_STATUS_IS_OK(status)) {
5751 /* The set is across all open files on this dev/inode pair. */
5752 if (!set_delete_on_close(fsp, delete_on_close,
5753 &conn->server_info->utok)) {
5754 return NT_STATUS_ACCESS_DENIED;
5756 return NT_STATUS_OK;
5759 /****************************************************************************
5760 Deal with SMB_FILE_POSITION_INFORMATION.
5761 ****************************************************************************/
5763 static NTSTATUS smb_file_position_information(connection_struct *conn,
5768 uint64_t position_information;
5770 if (total_data < 8) {
5771 return NT_STATUS_INVALID_PARAMETER;
5775 /* Ignore on pathname based set. */
5776 return NT_STATUS_OK;
5779 position_information = (uint64_t)IVAL(pdata,0);
5780 #ifdef LARGE_SMB_OFF_T
5781 position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
5782 #else /* LARGE_SMB_OFF_T */
5783 if (IVAL(pdata,4) != 0) {
5784 /* more than 32 bits? */
5785 return NT_STATUS_INVALID_PARAMETER;
5787 #endif /* LARGE_SMB_OFF_T */
5789 DEBUG(10,("smb_file_position_information: Set file position "
5790 "information for file %s to %.0f\n", fsp_str_dbg(fsp),
5791 (double)position_information));
5792 fsp->fh->position_information = position_information;
5793 return NT_STATUS_OK;
5796 /****************************************************************************
5797 Deal with SMB_FILE_MODE_INFORMATION.
5798 ****************************************************************************/
5800 static NTSTATUS smb_file_mode_information(connection_struct *conn,
5806 if (total_data < 4) {
5807 return NT_STATUS_INVALID_PARAMETER;
5809 mode = IVAL(pdata,0);
5810 if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
5811 return NT_STATUS_INVALID_PARAMETER;
5813 return NT_STATUS_OK;
5816 /****************************************************************************
5817 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
5818 ****************************************************************************/
5820 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
5821 struct smb_request *req,
5824 const struct smb_filename *smb_fname)
5826 char *link_target = NULL;
5827 const char *newname = smb_fname->base_name;
5828 TALLOC_CTX *ctx = talloc_tos();
5830 /* Set a symbolic link. */
5831 /* Don't allow this if follow links is false. */
5833 if (total_data == 0) {
5834 return NT_STATUS_INVALID_PARAMETER;
5837 if (!lp_symlinks(SNUM(conn))) {
5838 return NT_STATUS_ACCESS_DENIED;
5841 srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
5842 total_data, STR_TERMINATE);
5845 return NT_STATUS_INVALID_PARAMETER;
5848 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
5849 newname, link_target ));
5851 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) {
5852 return map_nt_error_from_unix(errno);
5855 return NT_STATUS_OK;
5858 /****************************************************************************
5859 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
5860 ****************************************************************************/
5862 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
5863 struct smb_request *req,
5864 const char *pdata, int total_data,
5865 const struct smb_filename *smb_fname_new)
5867 char *oldname = NULL;
5868 struct smb_filename *smb_fname_old = NULL;
5869 TALLOC_CTX *ctx = talloc_tos();
5870 NTSTATUS status = NT_STATUS_OK;
5872 /* Set a hard link. */
5873 if (total_data == 0) {
5874 return NT_STATUS_INVALID_PARAMETER;
5877 srvstr_get_path(ctx, pdata, req->flags2, &oldname, pdata,
5878 total_data, STR_TERMINATE, &status);
5879 if (!NT_STATUS_IS_OK(status)) {
5883 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
5884 smb_fname_str_dbg(smb_fname_new), oldname));
5886 status = filename_convert(ctx,
5888 req->flags2 & FLAGS2_DFS_PATHNAMES,
5893 if (!NT_STATUS_IS_OK(status)) {
5897 return hardlink_internals(ctx, conn, smb_fname_old, smb_fname_new);
5900 /****************************************************************************
5901 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
5902 ****************************************************************************/
5904 static NTSTATUS smb2_file_rename_information(connection_struct *conn,
5905 struct smb_request *req,
5909 struct smb_filename *smb_fname_src)
5913 char *newname = NULL;
5914 struct smb_filename *smb_fname_dst = NULL;
5915 NTSTATUS status = NT_STATUS_OK;
5916 TALLOC_CTX *ctx = talloc_tos();
5919 return NT_STATUS_INVALID_HANDLE;
5922 if (total_data < 20) {
5923 return NT_STATUS_INVALID_PARAMETER;
5926 overwrite = (CVAL(pdata,0) ? True : False);
5927 len = IVAL(pdata,16);
5929 if (len > (total_data - 20) || (len == 0)) {
5930 return NT_STATUS_INVALID_PARAMETER;
5933 srvstr_get_path(ctx, pdata, req->flags2, &newname,
5934 &pdata[20], len, STR_TERMINATE,
5936 if (!NT_STATUS_IS_OK(status)) {
5940 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
5943 status = filename_convert(ctx,
5945 req->flags2 & FLAGS2_DFS_PATHNAMES,
5950 if (!NT_STATUS_IS_OK(status)) {
5954 if (fsp && fsp->base_fsp) {
5955 /* newname must be a stream name. */
5956 if (newname[0] != ':') {
5957 return NT_STATUS_NOT_SUPPORTED;
5960 /* Create an smb_fname to call rename_internals_fsp() with. */
5961 status = create_synthetic_smb_fname(talloc_tos(),
5962 fsp->base_fsp->fsp_name->base_name, newname, NULL,
5964 if (!NT_STATUS_IS_OK(status)) {
5969 * Set the original last component, since
5970 * rename_internals_fsp() requires it.
5972 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
5974 if (smb_fname_dst->original_lcomp == NULL) {
5975 status = NT_STATUS_NO_MEMORY;
5981 DEBUG(10,("smb2_file_rename_information: "
5982 "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
5983 fsp->fnum, fsp_str_dbg(fsp),
5984 smb_fname_str_dbg(smb_fname_dst)));
5985 status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
5989 TALLOC_FREE(smb_fname_dst);
5994 /****************************************************************************
5995 Deal with SMB_FILE_RENAME_INFORMATION.
5996 ****************************************************************************/
5998 static NTSTATUS smb_file_rename_information(connection_struct *conn,
5999 struct smb_request *req,
6003 struct smb_filename *smb_fname_src)
6008 char *newname = NULL;
6009 struct smb_filename *smb_fname_dst = NULL;
6010 bool dest_has_wcard = False;
6011 NTSTATUS status = NT_STATUS_OK;
6013 TALLOC_CTX *ctx = talloc_tos();
6015 if (total_data < 13) {
6016 return NT_STATUS_INVALID_PARAMETER;
6019 overwrite = (CVAL(pdata,0) ? True : False);
6020 root_fid = IVAL(pdata,4);
6021 len = IVAL(pdata,8);
6023 if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
6024 return NT_STATUS_INVALID_PARAMETER;
6027 srvstr_get_path_wcard(ctx, pdata, req->flags2, &newname, &pdata[12],
6030 if (!NT_STATUS_IS_OK(status)) {
6034 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6037 status = resolve_dfspath_wcard(ctx, conn,
6038 req->flags2 & FLAGS2_DFS_PATHNAMES,
6043 if (!NT_STATUS_IS_OK(status)) {
6047 /* Check the new name has no '/' characters. */
6048 if (strchr_m(newname, '/')) {
6049 return NT_STATUS_NOT_SUPPORTED;
6052 if (fsp && fsp->base_fsp) {
6053 /* newname must be a stream name. */
6054 if (newname[0] != ':') {
6055 return NT_STATUS_NOT_SUPPORTED;
6058 /* Create an smb_fname to call rename_internals_fsp() with. */
6059 status = create_synthetic_smb_fname(talloc_tos(),
6060 fsp->base_fsp->fsp_name->base_name, newname, NULL,
6062 if (!NT_STATUS_IS_OK(status)) {
6067 * Set the original last component, since
6068 * rename_internals_fsp() requires it.
6070 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
6072 if (smb_fname_dst->original_lcomp == NULL) {
6073 status = NT_STATUS_NO_MEMORY;
6079 * Build up an smb_fname_dst based on the filename passed in.
6080 * We basically just strip off the last component, and put on
6081 * the newname instead.
6083 char *base_name = NULL;
6085 /* newname must *not* be a stream name. */
6086 if (newname[0] == ':') {
6087 return NT_STATUS_NOT_SUPPORTED;
6091 * Strip off the last component (filename) of the path passed
6094 base_name = talloc_strdup(ctx, smb_fname_src->base_name);
6096 return NT_STATUS_NO_MEMORY;
6098 p = strrchr_m(base_name, '/');
6102 base_name = talloc_strdup(ctx, "./");
6104 return NT_STATUS_NO_MEMORY;
6107 /* Append the new name. */
6108 base_name = talloc_asprintf_append(base_name,
6112 return NT_STATUS_NO_MEMORY;
6115 status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
6118 UCF_ALWAYS_ALLOW_WCARD_LCOMP :
6121 /* If an error we expect this to be
6122 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6124 if (!NT_STATUS_IS_OK(status)) {
6125 if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
6129 /* Create an smb_fname to call rename_internals_fsp() */
6130 status = create_synthetic_smb_fname(ctx,
6134 if (!NT_STATUS_IS_OK(status)) {
6141 DEBUG(10,("smb_file_rename_information: "
6142 "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6143 fsp->fnum, fsp_str_dbg(fsp),
6144 smb_fname_str_dbg(smb_fname_dst)));
6145 status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
6148 DEBUG(10,("smb_file_rename_information: "
6149 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6150 smb_fname_str_dbg(smb_fname_src),
6151 smb_fname_str_dbg(smb_fname_dst)));
6152 status = rename_internals(ctx, conn, req, smb_fname_src,
6153 smb_fname_dst, 0, overwrite, false,
6155 FILE_WRITE_ATTRIBUTES);
6158 TALLOC_FREE(smb_fname_dst);
6162 /****************************************************************************
6163 Deal with SMB_SET_POSIX_ACL.
6164 ****************************************************************************/
6166 #if defined(HAVE_POSIX_ACLS)
6167 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
6171 const struct smb_filename *smb_fname)
6173 uint16 posix_acl_version;
6174 uint16 num_file_acls;
6175 uint16 num_def_acls;
6176 bool valid_file_acls = True;
6177 bool valid_def_acls = True;
6179 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
6180 return NT_STATUS_INVALID_PARAMETER;
6182 posix_acl_version = SVAL(pdata,0);
6183 num_file_acls = SVAL(pdata,2);
6184 num_def_acls = SVAL(pdata,4);
6186 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
6187 valid_file_acls = False;
6191 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
6192 valid_def_acls = False;
6196 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
6197 return NT_STATUS_INVALID_PARAMETER;
6200 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
6201 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
6202 return NT_STATUS_INVALID_PARAMETER;
6205 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6206 smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
6207 (unsigned int)num_file_acls,
6208 (unsigned int)num_def_acls));
6210 if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
6211 smb_fname->base_name, num_file_acls,
6212 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
6213 return map_nt_error_from_unix(errno);
6216 if (valid_def_acls && !set_unix_posix_default_acl(conn,
6217 smb_fname->base_name, &smb_fname->st, num_def_acls,
6218 pdata + SMB_POSIX_ACL_HEADER_SIZE +
6219 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
6220 return map_nt_error_from_unix(errno);
6222 return NT_STATUS_OK;
6226 /****************************************************************************
6227 Deal with SMB_SET_POSIX_LOCK.
6228 ****************************************************************************/
6230 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
6231 struct smb_request *req,
6239 bool blocking_lock = False;
6240 enum brl_type lock_type;
6242 NTSTATUS status = NT_STATUS_OK;
6244 if (fsp == NULL || fsp->fh->fd == -1) {
6245 return NT_STATUS_INVALID_HANDLE;
6248 if (total_data != POSIX_LOCK_DATA_SIZE) {
6249 return NT_STATUS_INVALID_PARAMETER;
6252 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
6253 case POSIX_LOCK_TYPE_READ:
6254 lock_type = READ_LOCK;
6256 case POSIX_LOCK_TYPE_WRITE:
6257 /* Return the right POSIX-mappable error code for files opened read-only. */
6258 if (!fsp->can_write) {
6259 return NT_STATUS_INVALID_HANDLE;
6261 lock_type = WRITE_LOCK;
6263 case POSIX_LOCK_TYPE_UNLOCK:
6264 lock_type = UNLOCK_LOCK;
6267 return NT_STATUS_INVALID_PARAMETER;
6270 if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
6271 blocking_lock = False;
6272 } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
6273 blocking_lock = True;
6275 return NT_STATUS_INVALID_PARAMETER;
6278 if (!lp_blocking_locks(SNUM(conn))) {
6279 blocking_lock = False;
6282 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
6283 #if defined(HAVE_LONGLONG)
6284 offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
6285 ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
6286 count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
6287 ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
6288 #else /* HAVE_LONGLONG */
6289 offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
6290 count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
6291 #endif /* HAVE_LONGLONG */
6293 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6294 "lock_pid = %u, count = %.0f, offset = %.0f\n",
6296 (unsigned int)lock_type,
6297 (unsigned int)lock_pid,
6301 if (lock_type == UNLOCK_LOCK) {
6302 status = do_unlock(smbd_messaging_context(),
6309 uint32 block_smbpid;
6311 struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(),
6323 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6325 * A blocking lock was requested. Package up
6326 * this smb into a queued request and push it
6327 * onto the blocking lock queue.
6329 if(push_blocking_lock_request(br_lck,
6332 -1, /* infinite timeout. */
6340 TALLOC_FREE(br_lck);
6344 TALLOC_FREE(br_lck);
6350 /****************************************************************************
6351 Deal with SMB_SET_FILE_BASIC_INFO.
6352 ****************************************************************************/
6354 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
6358 const struct smb_filename *smb_fname)
6360 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6361 struct smb_file_time ft;
6363 NTSTATUS status = NT_STATUS_OK;
6367 if (total_data < 36) {
6368 return NT_STATUS_INVALID_PARAMETER;
6371 /* Set the attributes */
6372 dosmode = IVAL(pdata,32);
6373 status = smb_set_file_dosmode(conn, smb_fname, dosmode);
6374 if (!NT_STATUS_IS_OK(status)) {
6379 ft.create_time = interpret_long_date(pdata);
6382 ft.atime = interpret_long_date(pdata+8);
6385 ft.mtime = interpret_long_date(pdata+16);
6388 ft.ctime = interpret_long_date(pdata+24);
6390 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6391 smb_fname_str_dbg(smb_fname)));
6393 return smb_set_file_time(conn, fsp, smb_fname, &ft,
6397 /****************************************************************************
6398 Deal with SMB_INFO_STANDARD.
6399 ****************************************************************************/
6401 static NTSTATUS smb_set_info_standard(connection_struct *conn,
6405 const struct smb_filename *smb_fname)
6407 struct smb_file_time ft;
6411 if (total_data < 12) {
6412 return NT_STATUS_INVALID_PARAMETER;
6416 ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
6418 ft.atime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+4));
6420 ft.mtime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+8));
6422 DEBUG(10,("smb_set_info_standard: file %s\n",
6423 smb_fname_str_dbg(smb_fname)));
6425 return smb_set_file_time(conn,
6432 /****************************************************************************
6433 Deal with SMB_SET_FILE_ALLOCATION_INFO.
6434 ****************************************************************************/
6436 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
6437 struct smb_request *req,
6441 struct smb_filename *smb_fname)
6443 uint64_t allocation_size = 0;
6444 NTSTATUS status = NT_STATUS_OK;
6445 files_struct *new_fsp = NULL;
6447 if (!VALID_STAT(smb_fname->st)) {
6448 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6451 if (total_data < 8) {
6452 return NT_STATUS_INVALID_PARAMETER;
6455 allocation_size = (uint64_t)IVAL(pdata,0);
6456 #ifdef LARGE_SMB_OFF_T
6457 allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
6458 #else /* LARGE_SMB_OFF_T */
6459 if (IVAL(pdata,4) != 0) {
6460 /* more than 32 bits? */
6461 return NT_STATUS_INVALID_PARAMETER;
6463 #endif /* LARGE_SMB_OFF_T */
6465 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6466 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
6467 (double)allocation_size));
6469 if (allocation_size) {
6470 allocation_size = smb_roundup(conn, allocation_size);
6473 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6474 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
6475 (double)allocation_size));
6477 if (fsp && fsp->fh->fd != -1) {
6478 /* Open file handle. */
6479 /* Only change if needed. */
6480 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
6481 if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
6482 return map_nt_error_from_unix(errno);
6485 /* But always update the time. */
6487 * This is equivalent to a write. Ensure it's seen immediately
6488 * if there are no pending writes.
6490 trigger_write_time_update_immediate(fsp);
6491 return NT_STATUS_OK;
6494 /* Pathname or stat or directory file. */
6495 status = SMB_VFS_CREATE_FILE(
6498 0, /* root_dir_fid */
6499 smb_fname, /* fname */
6500 FILE_WRITE_DATA, /* access_mask */
6501 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
6503 FILE_OPEN, /* create_disposition*/
6504 0, /* create_options */
6505 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
6506 FORCE_OPLOCK_BREAK_TO_NONE, /* oplock_request */
6507 0, /* allocation_size */
6508 0, /* private_flags */
6511 &new_fsp, /* result */
6514 if (!NT_STATUS_IS_OK(status)) {
6515 /* NB. We check for open_was_deferred in the caller. */
6519 /* Only change if needed. */
6520 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
6521 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
6522 status = map_nt_error_from_unix(errno);
6523 close_file(req, new_fsp, NORMAL_CLOSE);
6528 /* Changing the allocation size should set the last mod time. */
6530 * This is equivalent to a write. Ensure it's seen immediately
6531 * if there are no pending writes.
6533 trigger_write_time_update_immediate(new_fsp);
6535 close_file(req, new_fsp, NORMAL_CLOSE);
6536 return NT_STATUS_OK;
6539 /****************************************************************************
6540 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6541 ****************************************************************************/
6543 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
6544 struct smb_request *req,
6548 const struct smb_filename *smb_fname,
6549 bool fail_after_createfile)
6553 if (total_data < 8) {
6554 return NT_STATUS_INVALID_PARAMETER;
6557 size = IVAL(pdata,0);
6558 #ifdef LARGE_SMB_OFF_T
6559 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
6560 #else /* LARGE_SMB_OFF_T */
6561 if (IVAL(pdata,4) != 0) {
6562 /* more than 32 bits? */
6563 return NT_STATUS_INVALID_PARAMETER;
6565 #endif /* LARGE_SMB_OFF_T */
6566 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6567 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
6570 return smb_set_file_size(conn, req,
6575 fail_after_createfile);
6578 /****************************************************************************
6579 Allow a UNIX info mknod.
6580 ****************************************************************************/
6582 static NTSTATUS smb_unix_mknod(connection_struct *conn,
6585 const struct smb_filename *smb_fname)
6587 uint32 file_type = IVAL(pdata,56);
6588 #if defined(HAVE_MAKEDEV)
6589 uint32 dev_major = IVAL(pdata,60);
6590 uint32 dev_minor = IVAL(pdata,68);
6592 SMB_DEV_T dev = (SMB_DEV_T)0;
6593 uint32 raw_unixmode = IVAL(pdata,84);
6597 if (total_data < 100) {
6598 return NT_STATUS_INVALID_PARAMETER;
6601 status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
6602 PERM_NEW_FILE, &unixmode);
6603 if (!NT_STATUS_IS_OK(status)) {
6607 #if defined(HAVE_MAKEDEV)
6608 dev = makedev(dev_major, dev_minor);
6611 switch (file_type) {
6612 #if defined(S_IFIFO)
6613 case UNIX_TYPE_FIFO:
6614 unixmode |= S_IFIFO;
6617 #if defined(S_IFSOCK)
6618 case UNIX_TYPE_SOCKET:
6619 unixmode |= S_IFSOCK;
6622 #if defined(S_IFCHR)
6623 case UNIX_TYPE_CHARDEV:
6624 unixmode |= S_IFCHR;
6627 #if defined(S_IFBLK)
6628 case UNIX_TYPE_BLKDEV:
6629 unixmode |= S_IFBLK;
6633 return NT_STATUS_INVALID_PARAMETER;
6636 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6637 "%.0f mode 0%o for file %s\n", (double)dev,
6638 (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
6640 /* Ok - do the mknod. */
6641 if (SMB_VFS_MKNOD(conn, smb_fname->base_name, unixmode, dev) != 0) {
6642 return map_nt_error_from_unix(errno);
6645 /* If any of the other "set" calls fail we
6646 * don't want to end up with a half-constructed mknod.
6649 if (lp_inherit_perms(SNUM(conn))) {
6651 if (!parent_dirname(talloc_tos(), smb_fname->base_name,
6653 return NT_STATUS_NO_MEMORY;
6655 inherit_access_posix_acl(conn, parent, smb_fname->base_name,
6657 TALLOC_FREE(parent);
6660 return NT_STATUS_OK;
6663 /****************************************************************************
6664 Deal with SMB_SET_FILE_UNIX_BASIC.
6665 ****************************************************************************/
6667 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
6668 struct smb_request *req,
6672 const struct smb_filename *smb_fname)
6674 struct smb_file_time ft;
6675 uint32 raw_unixmode;
6678 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
6679 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
6680 NTSTATUS status = NT_STATUS_OK;
6681 bool delete_on_fail = False;
6682 enum perm_type ptype;
6683 files_struct *all_fsps = NULL;
6684 bool modify_mtime = true;
6686 SMB_STRUCT_STAT sbuf;
6690 if (total_data < 100) {
6691 return NT_STATUS_INVALID_PARAMETER;
6694 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
6695 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
6696 size=IVAL(pdata,0); /* first 8 Bytes are size */
6697 #ifdef LARGE_SMB_OFF_T
6698 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
6699 #else /* LARGE_SMB_OFF_T */
6700 if (IVAL(pdata,4) != 0) {
6701 /* more than 32 bits? */
6702 return NT_STATUS_INVALID_PARAMETER;
6704 #endif /* LARGE_SMB_OFF_T */
6707 ft.atime = interpret_long_date(pdata+24); /* access_time */
6708 ft.mtime = interpret_long_date(pdata+32); /* modification_time */
6709 set_owner = (uid_t)IVAL(pdata,40);
6710 set_grp = (gid_t)IVAL(pdata,48);
6711 raw_unixmode = IVAL(pdata,84);
6713 if (VALID_STAT(smb_fname->st)) {
6714 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
6715 ptype = PERM_EXISTING_DIR;
6717 ptype = PERM_EXISTING_FILE;
6720 ptype = PERM_NEW_FILE;
6723 status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
6725 if (!NT_STATUS_IS_OK(status)) {
6729 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
6730 "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
6731 smb_fname_str_dbg(smb_fname), (double)size,
6732 (unsigned int)set_owner, (unsigned int)set_grp,
6733 (int)raw_unixmode));
6735 sbuf = smb_fname->st;
6737 if (!VALID_STAT(sbuf)) {
6738 struct smb_filename *smb_fname_tmp = NULL;
6740 * The only valid use of this is to create character and block
6741 * devices, and named pipes. This is deprecated (IMHO) and
6742 * a new info level should be used for mknod. JRA.
6745 status = smb_unix_mknod(conn,
6749 if (!NT_STATUS_IS_OK(status)) {
6753 status = copy_smb_filename(talloc_tos(), smb_fname,
6755 if (!NT_STATUS_IS_OK(status)) {
6759 if (SMB_VFS_STAT(conn, smb_fname_tmp) != 0) {
6760 status = map_nt_error_from_unix(errno);
6761 TALLOC_FREE(smb_fname_tmp);
6762 SMB_VFS_UNLINK(conn, smb_fname);
6766 sbuf = smb_fname_tmp->st;
6767 TALLOC_FREE(smb_fname_tmp);
6769 /* Ensure we don't try and change anything else. */
6770 raw_unixmode = SMB_MODE_NO_CHANGE;
6771 size = get_file_size_stat(&sbuf);
6772 ft.atime = sbuf.st_ex_atime;
6773 ft.mtime = sbuf.st_ex_mtime;
6775 * We continue here as we might want to change the
6778 delete_on_fail = True;
6782 /* Horrible backwards compatibility hack as an old server bug
6783 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
6787 size = get_file_size_stat(&sbuf);
6792 * Deal with the UNIX specific mode set.
6795 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
6796 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
6797 "setting mode 0%o for file %s\n",
6798 (unsigned int)unixmode,
6799 smb_fname_str_dbg(smb_fname)));
6800 if (SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode) != 0) {
6801 return map_nt_error_from_unix(errno);
6806 * Deal with the UNIX specific uid set.
6809 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
6810 (sbuf.st_ex_uid != set_owner)) {
6813 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
6814 "changing owner %u for path %s\n",
6815 (unsigned int)set_owner,
6816 smb_fname_str_dbg(smb_fname)));
6818 if (S_ISLNK(sbuf.st_ex_mode)) {
6819 ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
6820 set_owner, (gid_t)-1);
6822 ret = SMB_VFS_CHOWN(conn, smb_fname->base_name,
6823 set_owner, (gid_t)-1);
6827 status = map_nt_error_from_unix(errno);
6828 if (delete_on_fail) {
6829 SMB_VFS_UNLINK(conn, smb_fname);
6836 * Deal with the UNIX specific gid set.
6839 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
6840 (sbuf.st_ex_gid != set_grp)) {
6841 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
6842 "changing group %u for file %s\n",
6843 (unsigned int)set_owner,
6844 smb_fname_str_dbg(smb_fname)));
6845 if (SMB_VFS_CHOWN(conn, smb_fname->base_name, (uid_t)-1,
6847 status = map_nt_error_from_unix(errno);
6848 if (delete_on_fail) {
6849 SMB_VFS_UNLINK(conn, smb_fname);
6855 /* Deal with any size changes. */
6857 status = smb_set_file_size(conn, req,
6863 if (!NT_STATUS_IS_OK(status)) {
6867 /* Deal with any time changes. */
6868 if (null_timespec(ft.mtime) && null_timespec(ft.atime)) {
6869 /* No change, don't cancel anything. */
6873 id = vfs_file_id_from_sbuf(conn, &sbuf);
6874 for(all_fsps = file_find_di_first(id); all_fsps;
6875 all_fsps = file_find_di_next(all_fsps)) {
6877 * We're setting the time explicitly for UNIX.
6878 * Cancel any pending changes over all handles.
6880 all_fsps->update_write_time_on_close = false;
6881 TALLOC_FREE(all_fsps->update_write_time_event);
6885 * Override the "setting_write_time"
6886 * parameter here as it almost does what
6887 * we need. Just remember if we modified
6888 * mtime and send the notify ourselves.
6890 if (null_timespec(ft.mtime)) {
6891 modify_mtime = false;
6894 status = smb_set_file_time(conn,
6900 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
6901 FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
6906 /****************************************************************************
6907 Deal with SMB_SET_FILE_UNIX_INFO2.
6908 ****************************************************************************/
6910 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
6911 struct smb_request *req,
6915 const struct smb_filename *smb_fname)
6921 if (total_data < 116) {
6922 return NT_STATUS_INVALID_PARAMETER;
6925 /* Start by setting all the fields that are common between UNIX_BASIC
6928 status = smb_set_file_unix_basic(conn, req, pdata, total_data,
6930 if (!NT_STATUS_IS_OK(status)) {
6934 smb_fflags = IVAL(pdata, 108);
6935 smb_fmask = IVAL(pdata, 112);
6937 /* NB: We should only attempt to alter the file flags if the client
6938 * sends a non-zero mask.
6940 if (smb_fmask != 0) {
6941 int stat_fflags = 0;
6943 if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
6944 smb_fmask, &stat_fflags)) {
6945 /* Client asked to alter a flag we don't understand. */
6946 return NT_STATUS_INVALID_PARAMETER;
6949 if (fsp && fsp->fh->fd != -1) {
6950 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
6951 return NT_STATUS_NOT_SUPPORTED;
6953 if (SMB_VFS_CHFLAGS(conn, smb_fname->base_name,
6954 stat_fflags) != 0) {
6955 return map_nt_error_from_unix(errno);
6960 /* XXX: need to add support for changing the create_time here. You
6961 * can do this for paths on Darwin with setattrlist(2). The right way
6962 * to hook this up is probably by extending the VFS utimes interface.
6965 return NT_STATUS_OK;
6968 /****************************************************************************
6969 Create a directory with POSIX semantics.
6970 ****************************************************************************/
6972 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
6973 struct smb_request *req,
6976 struct smb_filename *smb_fname,
6977 int *pdata_return_size)
6979 NTSTATUS status = NT_STATUS_OK;
6980 uint32 raw_unixmode = 0;
6981 uint32 mod_unixmode = 0;
6982 mode_t unixmode = (mode_t)0;
6983 files_struct *fsp = NULL;
6984 uint16 info_level_return = 0;
6986 char *pdata = *ppdata;
6988 if (total_data < 18) {
6989 return NT_STATUS_INVALID_PARAMETER;
6992 raw_unixmode = IVAL(pdata,8);
6993 /* Next 4 bytes are not yet defined. */
6995 status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
6996 PERM_NEW_DIR, &unixmode);
6997 if (!NT_STATUS_IS_OK(status)) {
7001 mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
7003 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7004 smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
7006 status = SMB_VFS_CREATE_FILE(
7009 0, /* root_dir_fid */
7010 smb_fname, /* fname */
7011 FILE_READ_ATTRIBUTES, /* access_mask */
7012 FILE_SHARE_NONE, /* share_access */
7013 FILE_CREATE, /* create_disposition*/
7014 FILE_DIRECTORY_FILE, /* create_options */
7015 mod_unixmode, /* file_attributes */
7016 0, /* oplock_request */
7017 0, /* allocation_size */
7018 0, /* private_flags */
7024 if (NT_STATUS_IS_OK(status)) {
7025 close_file(req, fsp, NORMAL_CLOSE);
7028 info_level_return = SVAL(pdata,16);
7030 if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
7031 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
7032 } else if (info_level_return == SMB_QUERY_FILE_UNIX_INFO2) {
7033 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
7035 *pdata_return_size = 12;
7038 /* Realloc the data size */
7039 *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
7040 if (*ppdata == NULL) {
7041 *pdata_return_size = 0;
7042 return NT_STATUS_NO_MEMORY;
7046 SSVAL(pdata,0,NO_OPLOCK_RETURN);
7047 SSVAL(pdata,2,0); /* No fnum. */
7048 SIVAL(pdata,4,info); /* Was directory created. */
7050 switch (info_level_return) {
7051 case SMB_QUERY_FILE_UNIX_BASIC:
7052 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
7053 SSVAL(pdata,10,0); /* Padding. */
7054 store_file_unix_basic(conn, pdata + 12, fsp,
7057 case SMB_QUERY_FILE_UNIX_INFO2:
7058 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
7059 SSVAL(pdata,10,0); /* Padding. */
7060 store_file_unix_basic_info2(conn, pdata + 12, fsp,
7064 SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
7065 SSVAL(pdata,10,0); /* Padding. */
7072 /****************************************************************************
7073 Open/Create a file with POSIX semantics.
7074 ****************************************************************************/
7076 static NTSTATUS smb_posix_open(connection_struct *conn,
7077 struct smb_request *req,
7080 struct smb_filename *smb_fname,
7081 int *pdata_return_size)
7083 bool extended_oplock_granted = False;
7084 char *pdata = *ppdata;
7086 uint32 wire_open_mode = 0;
7087 uint32 raw_unixmode = 0;
7088 uint32 mod_unixmode = 0;
7089 uint32 create_disp = 0;
7090 uint32 access_mask = 0;
7091 uint32 create_options = 0;
7092 NTSTATUS status = NT_STATUS_OK;
7093 mode_t unixmode = (mode_t)0;
7094 files_struct *fsp = NULL;
7095 int oplock_request = 0;
7097 uint16 info_level_return = 0;
7099 if (total_data < 18) {
7100 return NT_STATUS_INVALID_PARAMETER;
7103 flags = IVAL(pdata,0);
7104 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
7105 if (oplock_request) {
7106 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
7109 wire_open_mode = IVAL(pdata,4);
7111 if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
7112 return smb_posix_mkdir(conn, req,
7119 switch (wire_open_mode & SMB_ACCMODE) {
7121 access_mask = FILE_READ_DATA;
7124 access_mask = FILE_WRITE_DATA;
7127 access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
7130 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7131 (unsigned int)wire_open_mode ));
7132 return NT_STATUS_INVALID_PARAMETER;
7135 wire_open_mode &= ~SMB_ACCMODE;
7137 if((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) == (SMB_O_CREAT | SMB_O_EXCL)) {
7138 create_disp = FILE_CREATE;
7139 } else if((wire_open_mode & (SMB_O_CREAT | SMB_O_TRUNC)) == (SMB_O_CREAT | SMB_O_TRUNC)) {
7140 create_disp = FILE_OVERWRITE_IF;
7141 } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
7142 create_disp = FILE_OPEN_IF;
7143 } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC)) == 0) {
7144 create_disp = FILE_OPEN;
7146 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7147 (unsigned int)wire_open_mode ));
7148 return NT_STATUS_INVALID_PARAMETER;
7151 raw_unixmode = IVAL(pdata,8);
7152 /* Next 4 bytes are not yet defined. */
7154 status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7155 (VALID_STAT(smb_fname->st) ?
7156 PERM_EXISTING_FILE : PERM_NEW_FILE),
7159 if (!NT_STATUS_IS_OK(status)) {
7163 mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
7165 if (wire_open_mode & SMB_O_SYNC) {
7166 create_options |= FILE_WRITE_THROUGH;
7168 if (wire_open_mode & SMB_O_APPEND) {
7169 access_mask |= FILE_APPEND_DATA;
7171 if (wire_open_mode & SMB_O_DIRECT) {
7172 mod_unixmode |= FILE_FLAG_NO_BUFFERING;
7175 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7176 smb_fname_str_dbg(smb_fname),
7177 (unsigned int)wire_open_mode,
7178 (unsigned int)unixmode ));
7180 status = SMB_VFS_CREATE_FILE(
7183 0, /* root_dir_fid */
7184 smb_fname, /* fname */
7185 access_mask, /* access_mask */
7186 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
7188 create_disp, /* create_disposition*/
7189 FILE_NON_DIRECTORY_FILE, /* create_options */
7190 mod_unixmode, /* file_attributes */
7191 oplock_request, /* oplock_request */
7192 0, /* allocation_size */
7193 0, /* private_flags */
7199 if (!NT_STATUS_IS_OK(status)) {
7203 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
7204 extended_oplock_granted = True;
7207 if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
7208 extended_oplock_granted = True;
7211 info_level_return = SVAL(pdata,16);
7213 /* Allocate the correct return size. */
7215 if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
7216 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
7217 } else if (info_level_return == SMB_QUERY_FILE_UNIX_INFO2) {
7218 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
7220 *pdata_return_size = 12;
7223 /* Realloc the data size */
7224 *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
7225 if (*ppdata == NULL) {
7226 close_file(req, fsp, ERROR_CLOSE);
7227 *pdata_return_size = 0;
7228 return NT_STATUS_NO_MEMORY;
7232 if (extended_oplock_granted) {
7233 if (flags & REQUEST_BATCH_OPLOCK) {
7234 SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
7236 SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
7238 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
7239 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
7241 SSVAL(pdata,0,NO_OPLOCK_RETURN);
7244 SSVAL(pdata,2,fsp->fnum);
7245 SIVAL(pdata,4,info); /* Was file created etc. */
7247 switch (info_level_return) {
7248 case SMB_QUERY_FILE_UNIX_BASIC:
7249 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
7250 SSVAL(pdata,10,0); /* padding. */
7251 store_file_unix_basic(conn, pdata + 12, fsp,
7254 case SMB_QUERY_FILE_UNIX_INFO2:
7255 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
7256 SSVAL(pdata,10,0); /* padding. */
7257 store_file_unix_basic_info2(conn, pdata + 12, fsp,
7261 SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
7262 SSVAL(pdata,10,0); /* padding. */
7265 return NT_STATUS_OK;
7268 /****************************************************************************
7269 Delete a file with POSIX semantics.
7270 ****************************************************************************/
7272 static NTSTATUS smb_posix_unlink(connection_struct *conn,
7273 struct smb_request *req,
7276 struct smb_filename *smb_fname)
7278 NTSTATUS status = NT_STATUS_OK;
7279 files_struct *fsp = NULL;
7283 int create_options = 0;
7285 struct share_mode_lock *lck = NULL;
7287 if (total_data < 2) {
7288 return NT_STATUS_INVALID_PARAMETER;
7291 flags = SVAL(pdata,0);
7293 if (!VALID_STAT(smb_fname->st)) {
7294 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
7297 if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
7298 !VALID_STAT_OF_DIR(smb_fname->st)) {
7299 return NT_STATUS_NOT_A_DIRECTORY;
7302 DEBUG(10,("smb_posix_unlink: %s %s\n",
7303 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
7304 smb_fname_str_dbg(smb_fname)));
7306 if (VALID_STAT_OF_DIR(smb_fname->st)) {
7307 create_options |= FILE_DIRECTORY_FILE;
7310 status = SMB_VFS_CREATE_FILE(
7313 0, /* root_dir_fid */
7314 smb_fname, /* fname */
7315 DELETE_ACCESS, /* access_mask */
7316 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
7318 FILE_OPEN, /* create_disposition*/
7319 create_options, /* create_options */
7320 FILE_FLAG_POSIX_SEMANTICS|0777, /* file_attributes */
7321 0, /* oplock_request */
7322 0, /* allocation_size */
7323 0, /* private_flags */
7329 if (!NT_STATUS_IS_OK(status)) {
7334 * Don't lie to client. If we can't really delete due to
7335 * non-POSIX opens return SHARING_VIOLATION.
7338 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
7341 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7342 "lock for file %s\n", fsp_str_dbg(fsp)));
7343 close_file(req, fsp, NORMAL_CLOSE);
7344 return NT_STATUS_INVALID_PARAMETER;
7348 * See if others still have the file open. If this is the case, then
7349 * don't delete. If all opens are POSIX delete we can set the delete
7350 * on close disposition.
7352 for (i=0; i<lck->num_share_modes; i++) {
7353 struct share_mode_entry *e = &lck->share_modes[i];
7354 if (is_valid_share_mode_entry(e)) {
7355 if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
7358 /* Fail with sharing violation. */
7359 close_file(req, fsp, NORMAL_CLOSE);
7361 return NT_STATUS_SHARING_VIOLATION;
7366 * Set the delete on close.
7368 status = smb_set_file_disposition_info(conn,
7374 if (!NT_STATUS_IS_OK(status)) {
7375 close_file(req, fsp, NORMAL_CLOSE);
7380 return close_file(req, fsp, NORMAL_CLOSE);
7383 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
7384 struct smb_request *req,
7385 TALLOC_CTX *mem_ctx,
7386 uint16_t info_level,
7388 struct smb_filename *smb_fname,
7389 char **ppdata, int total_data,
7392 char *pdata = *ppdata;
7393 NTSTATUS status = NT_STATUS_OK;
7394 int data_return_size = 0;
7398 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
7399 return NT_STATUS_INVALID_LEVEL;
7402 if (!CAN_WRITE(conn)) {
7403 /* Allow POSIX opens. The open path will deny
7404 * any non-readonly opens. */
7405 if (info_level != SMB_POSIX_PATH_OPEN) {
7406 return NT_STATUS_DOS(ERRSRV, ERRaccess);
7410 DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
7411 "totdata=%d\n", smb_fname_str_dbg(smb_fname),
7412 fsp ? fsp->fnum : -1, info_level, total_data));
7414 switch (info_level) {
7416 case SMB_INFO_STANDARD:
7418 status = smb_set_info_standard(conn,
7426 case SMB_INFO_SET_EA:
7428 status = smb_info_set_ea(conn,
7436 case SMB_SET_FILE_BASIC_INFO:
7437 case SMB_FILE_BASIC_INFORMATION:
7439 status = smb_set_file_basic_info(conn,
7447 case SMB_FILE_ALLOCATION_INFORMATION:
7448 case SMB_SET_FILE_ALLOCATION_INFO:
7450 status = smb_set_file_allocation_info(conn, req,
7458 case SMB_FILE_END_OF_FILE_INFORMATION:
7459 case SMB_SET_FILE_END_OF_FILE_INFO:
7462 * XP/Win7 both fail after the createfile with
7463 * SMB_SET_FILE_END_OF_FILE_INFO but not
7464 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7465 * The level is known here, so pass it down
7469 (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
7471 status = smb_set_file_end_of_file_info(conn, req,
7480 case SMB_FILE_DISPOSITION_INFORMATION:
7481 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
7484 /* JRA - We used to just ignore this on a path ?
7485 * Shouldn't this be invalid level on a pathname
7488 if (tran_call != TRANSACT2_SETFILEINFO) {
7489 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
7492 status = smb_set_file_disposition_info(conn,
7500 case SMB_FILE_POSITION_INFORMATION:
7502 status = smb_file_position_information(conn,
7509 case SMB_FILE_FULL_EA_INFORMATION:
7511 status = smb_set_file_full_ea_info(conn,
7518 /* From tridge Samba4 :
7519 * MODE_INFORMATION in setfileinfo (I have no
7520 * idea what "mode information" on a file is - it takes a value of 0,
7521 * 2, 4 or 6. What could it be?).
7524 case SMB_FILE_MODE_INFORMATION:
7526 status = smb_file_mode_information(conn,
7533 * CIFS UNIX extensions.
7536 case SMB_SET_FILE_UNIX_BASIC:
7538 status = smb_set_file_unix_basic(conn, req,
7546 case SMB_SET_FILE_UNIX_INFO2:
7548 status = smb_set_file_unix_info2(conn, req,
7556 case SMB_SET_FILE_UNIX_LINK:
7559 /* We must have a pathname for this. */
7560 return NT_STATUS_INVALID_LEVEL;
7562 status = smb_set_file_unix_link(conn, req, pdata,
7563 total_data, smb_fname);
7567 case SMB_SET_FILE_UNIX_HLINK:
7570 /* We must have a pathname for this. */
7571 return NT_STATUS_INVALID_LEVEL;
7573 status = smb_set_file_unix_hlink(conn, req,
7579 case SMB_FILE_RENAME_INFORMATION:
7581 status = smb_file_rename_information(conn, req,
7587 case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
7589 /* SMB2 rename information. */
7590 status = smb2_file_rename_information(conn, req,
7596 #if defined(HAVE_POSIX_ACLS)
7597 case SMB_SET_POSIX_ACL:
7599 status = smb_set_posix_acl(conn,
7608 case SMB_SET_POSIX_LOCK:
7611 return NT_STATUS_INVALID_LEVEL;
7613 status = smb_set_posix_lock(conn, req,
7614 pdata, total_data, fsp);
7618 case SMB_POSIX_PATH_OPEN:
7621 /* We must have a pathname for this. */
7622 return NT_STATUS_INVALID_LEVEL;
7625 status = smb_posix_open(conn, req,
7633 case SMB_POSIX_PATH_UNLINK:
7636 /* We must have a pathname for this. */
7637 return NT_STATUS_INVALID_LEVEL;
7640 status = smb_posix_unlink(conn, req,
7648 return NT_STATUS_INVALID_LEVEL;
7651 if (!NT_STATUS_IS_OK(status)) {
7655 *ret_data_size = data_return_size;
7656 return NT_STATUS_OK;
7659 /****************************************************************************
7660 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
7661 ****************************************************************************/
7663 static void call_trans2setfilepathinfo(connection_struct *conn,
7664 struct smb_request *req,
7665 unsigned int tran_call,
7666 char **pparams, int total_params,
7667 char **ppdata, int total_data,
7668 unsigned int max_data_bytes)
7670 char *params = *pparams;
7671 char *pdata = *ppdata;
7673 struct smb_filename *smb_fname = NULL;
7674 files_struct *fsp = NULL;
7675 NTSTATUS status = NT_STATUS_OK;
7676 int data_return_size = 0;
7679 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7683 if (tran_call == TRANSACT2_SETFILEINFO) {
7684 if (total_params < 4) {
7685 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7689 fsp = file_fsp(req, SVAL(params,0));
7690 /* Basic check for non-null fsp. */
7691 if (!check_fsp_open(conn, req, fsp)) {
7694 info_level = SVAL(params,2);
7696 status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
7698 if (!NT_STATUS_IS_OK(status)) {
7699 reply_nterror(req, status);
7703 if(fsp->is_directory || fsp->fh->fd == -1) {
7705 * This is actually a SETFILEINFO on a directory
7706 * handle (returned from an NT SMB). NT5.0 seems
7707 * to do this call. JRA.
7709 if (INFO_LEVEL_IS_UNIX(info_level)) {
7710 /* Always do lstat for UNIX calls. */
7711 if (SMB_VFS_LSTAT(conn, smb_fname)) {
7712 DEBUG(3,("call_trans2setfilepathinfo: "
7713 "SMB_VFS_LSTAT of %s failed "
7715 smb_fname_str_dbg(smb_fname),
7717 reply_nterror(req, map_nt_error_from_unix(errno));
7721 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
7722 DEBUG(3,("call_trans2setfilepathinfo: "
7723 "fileinfo of %s failed (%s)\n",
7724 smb_fname_str_dbg(smb_fname),
7726 reply_nterror(req, map_nt_error_from_unix(errno));
7730 } else if (fsp->print_file) {
7732 * Doing a DELETE_ON_CLOSE should cancel a print job.
7734 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
7735 fsp->fh->private_options |= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE;
7737 DEBUG(3,("call_trans2setfilepathinfo: "
7738 "Cancelling print job (%s)\n",
7742 send_trans2_replies(conn, req, params, 2,
7748 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7753 * Original code - this is an open file.
7755 if (!check_fsp(conn, req, fsp)) {
7759 if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
7760 DEBUG(3,("call_trans2setfilepathinfo: fstat "
7761 "of fnum %d failed (%s)\n", fsp->fnum,
7763 reply_nterror(req, map_nt_error_from_unix(errno));
7771 if (total_params < 7) {
7772 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7776 info_level = SVAL(params,0);
7777 srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
7778 total_params - 6, STR_TERMINATE,
7780 if (!NT_STATUS_IS_OK(status)) {
7781 reply_nterror(req, status);
7785 status = filename_convert(req, conn,
7786 req->flags2 & FLAGS2_DFS_PATHNAMES,
7791 if (!NT_STATUS_IS_OK(status)) {
7792 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
7793 reply_botherror(req,
7794 NT_STATUS_PATH_NOT_COVERED,
7795 ERRSRV, ERRbadpath);
7798 reply_nterror(req, status);
7802 if (INFO_LEVEL_IS_UNIX(info_level)) {
7804 * For CIFS UNIX extensions the target name may not exist.
7807 /* Always do lstat for UNIX calls. */
7808 SMB_VFS_LSTAT(conn, smb_fname);
7810 } else if (!VALID_STAT(smb_fname->st) &&
7811 SMB_VFS_STAT(conn, smb_fname)) {
7812 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
7814 smb_fname_str_dbg(smb_fname),
7816 reply_nterror(req, map_nt_error_from_unix(errno));
7821 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
7822 "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
7823 fsp ? fsp->fnum : -1, info_level,total_data));
7825 /* Realloc the parameter size */
7826 *pparams = (char *)SMB_REALLOC(*pparams,2);
7827 if (*pparams == NULL) {
7828 reply_nterror(req, NT_STATUS_NO_MEMORY);
7835 status = smbd_do_setfilepathinfo(conn, req, req,
7841 if (!NT_STATUS_IS_OK(status)) {
7842 if (open_was_deferred(req->mid)) {
7843 /* We have re-scheduled this call. */
7846 if (blocking_lock_was_deferred_smb1(req->mid)) {
7847 /* We have re-scheduled this call. */
7850 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
7851 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
7852 ERRSRV, ERRbadpath);
7855 if (info_level == SMB_POSIX_PATH_OPEN) {
7856 reply_openerror(req, status);
7860 reply_nterror(req, status);
7864 send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
7870 /****************************************************************************
7871 Reply to a TRANS2_MKDIR (make directory with extended attributes).
7872 ****************************************************************************/
7874 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
7875 char **pparams, int total_params,
7876 char **ppdata, int total_data,
7877 unsigned int max_data_bytes)
7879 struct smb_filename *smb_dname = NULL;
7880 char *params = *pparams;
7881 char *pdata = *ppdata;
7882 char *directory = NULL;
7883 NTSTATUS status = NT_STATUS_OK;
7884 struct ea_list *ea_list = NULL;
7885 TALLOC_CTX *ctx = talloc_tos();
7887 if (!CAN_WRITE(conn)) {
7888 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
7892 if (total_params < 5) {
7893 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7897 srvstr_get_path(ctx, params, req->flags2, &directory, ¶ms[4],
7898 total_params - 4, STR_TERMINATE,
7900 if (!NT_STATUS_IS_OK(status)) {
7901 reply_nterror(req, status);
7905 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
7907 status = filename_convert(ctx,
7909 req->flags2 & FLAGS2_DFS_PATHNAMES,
7915 if (!NT_STATUS_IS_OK(status)) {
7916 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
7917 reply_botherror(req,
7918 NT_STATUS_PATH_NOT_COVERED,
7919 ERRSRV, ERRbadpath);
7922 reply_nterror(req, status);
7927 * OS/2 workplace shell seems to send SET_EA requests of "null"
7928 * length (4 bytes containing IVAL 4).
7929 * They seem to have no effect. Bug #3212. JRA.
7932 if (total_data && (total_data != 4)) {
7933 /* Any data in this call is an EA list. */
7934 if (total_data < 10) {
7935 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7939 if (IVAL(pdata,0) > total_data) {
7940 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
7941 IVAL(pdata,0), (unsigned int)total_data));
7942 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7946 ea_list = read_ea_list(talloc_tos(), pdata + 4,
7949 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7953 if (!lp_ea_support(SNUM(conn))) {
7954 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
7958 /* If total_data == 4 Windows doesn't care what values
7959 * are placed in that field, it just ignores them.
7960 * The System i QNTC IBM SMB client puts bad values here,
7961 * so ignore them. */
7963 status = create_directory(conn, req, smb_dname);
7965 if (!NT_STATUS_IS_OK(status)) {
7966 reply_nterror(req, status);
7970 /* Try and set any given EA. */
7972 status = set_ea(conn, NULL, smb_dname, ea_list);
7973 if (!NT_STATUS_IS_OK(status)) {
7974 reply_nterror(req, status);
7979 /* Realloc the parameter and data sizes */
7980 *pparams = (char *)SMB_REALLOC(*pparams,2);
7981 if(*pparams == NULL) {
7982 reply_nterror(req, NT_STATUS_NO_MEMORY);
7989 send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
7992 TALLOC_FREE(smb_dname);
7996 /****************************************************************************
7997 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
7998 We don't actually do this - we just send a null response.
7999 ****************************************************************************/
8001 static void call_trans2findnotifyfirst(connection_struct *conn,
8002 struct smb_request *req,
8003 char **pparams, int total_params,
8004 char **ppdata, int total_data,
8005 unsigned int max_data_bytes)
8007 char *params = *pparams;
8010 if (total_params < 6) {
8011 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8015 info_level = SVAL(params,4);
8016 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
8018 switch (info_level) {
8023 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
8027 /* Realloc the parameter and data sizes */
8028 *pparams = (char *)SMB_REALLOC(*pparams,6);
8029 if (*pparams == NULL) {
8030 reply_nterror(req, NT_STATUS_NO_MEMORY);
8035 SSVAL(params,0,fnf_handle);
8036 SSVAL(params,2,0); /* No changes */
8037 SSVAL(params,4,0); /* No EA errors */
8044 send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
8049 /****************************************************************************
8050 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
8051 changes). Currently this does nothing.
8052 ****************************************************************************/
8054 static void call_trans2findnotifynext(connection_struct *conn,
8055 struct smb_request *req,
8056 char **pparams, int total_params,
8057 char **ppdata, int total_data,
8058 unsigned int max_data_bytes)
8060 char *params = *pparams;
8062 DEBUG(3,("call_trans2findnotifynext\n"));
8064 /* Realloc the parameter and data sizes */
8065 *pparams = (char *)SMB_REALLOC(*pparams,4);
8066 if (*pparams == NULL) {
8067 reply_nterror(req, NT_STATUS_NO_MEMORY);
8072 SSVAL(params,0,0); /* No changes */
8073 SSVAL(params,2,0); /* No EA errors */
8075 send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
8080 /****************************************************************************
8081 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8082 ****************************************************************************/
8084 static void call_trans2getdfsreferral(connection_struct *conn,
8085 struct smb_request *req,
8086 char **pparams, int total_params,
8087 char **ppdata, int total_data,
8088 unsigned int max_data_bytes)
8090 char *params = *pparams;
8091 char *pathname = NULL;
8093 int max_referral_level;
8094 NTSTATUS status = NT_STATUS_OK;
8095 TALLOC_CTX *ctx = talloc_tos();
8097 DEBUG(10,("call_trans2getdfsreferral\n"));
8099 if (total_params < 3) {
8100 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8104 max_referral_level = SVAL(params,0);
8106 if(!lp_host_msdfs()) {
8107 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8111 srvstr_pull_talloc(ctx, params, req->flags2, &pathname, ¶ms[2],
8112 total_params - 2, STR_TERMINATE);
8114 reply_nterror(req, NT_STATUS_NOT_FOUND);
8117 if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
8118 ppdata,&status)) < 0) {
8119 reply_nterror(req, status);
8123 SSVAL(req->inbuf, smb_flg2,
8124 SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
8125 send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
8130 #define LMCAT_SPL 0x53
8131 #define LMFUNC_GETJOBID 0x60
8133 /****************************************************************************
8134 Reply to a TRANS2_IOCTL - used for OS/2 printing.
8135 ****************************************************************************/
8137 static void call_trans2ioctl(connection_struct *conn,
8138 struct smb_request *req,
8139 char **pparams, int total_params,
8140 char **ppdata, int total_data,
8141 unsigned int max_data_bytes)
8143 char *pdata = *ppdata;
8144 files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
8146 /* check for an invalid fid before proceeding */
8149 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
8153 if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
8154 && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
8155 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
8156 if (*ppdata == NULL) {
8157 reply_nterror(req, NT_STATUS_NO_MEMORY);
8162 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8163 CAN ACCEPT THIS IN UNICODE. JRA. */
8166 if (fsp->print_file) {
8167 SSVAL(pdata, 0, fsp->print_file->rap_jobid);
8171 srvstr_push(pdata, req->flags2, pdata + 2,
8172 global_myname(), 15,
8173 STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
8174 srvstr_push(pdata, req->flags2, pdata+18,
8175 lp_servicename(SNUM(conn)), 13,
8176 STR_ASCII|STR_TERMINATE); /* Service name */
8177 send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
8182 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8183 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8186 /****************************************************************************
8187 Reply to a SMBfindclose (stop trans2 directory search).
8188 ****************************************************************************/
8190 void reply_findclose(struct smb_request *req)
8193 struct smbd_server_connection *sconn = smbd_server_conn;
8195 START_PROFILE(SMBfindclose);
8198 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8199 END_PROFILE(SMBfindclose);
8203 dptr_num = SVALS(req->vwv+0, 0);
8205 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
8207 dptr_close(sconn, &dptr_num);
8209 reply_outbuf(req, 0, 0);
8211 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
8213 END_PROFILE(SMBfindclose);
8217 /****************************************************************************
8218 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8219 ****************************************************************************/
8221 void reply_findnclose(struct smb_request *req)
8225 START_PROFILE(SMBfindnclose);
8228 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8229 END_PROFILE(SMBfindnclose);
8233 dptr_num = SVAL(req->vwv+0, 0);
8235 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
8237 /* We never give out valid handles for a
8238 findnotifyfirst - so any dptr_num is ok here.
8241 reply_outbuf(req, 0, 0);
8243 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
8245 END_PROFILE(SMBfindnclose);
8249 static void handle_trans2(connection_struct *conn, struct smb_request *req,
8250 struct trans_state *state)
8252 if (get_Protocol() >= PROTOCOL_NT1) {
8253 req->flags2 |= 0x40; /* IS_LONG_NAME */
8254 SSVAL(req->inbuf,smb_flg2,req->flags2);
8257 if (conn->encrypt_level == Required && !req->encrypted) {
8258 if (state->call != TRANSACT2_QFSINFO &&
8259 state->call != TRANSACT2_SETFSINFO) {
8260 DEBUG(0,("handle_trans2: encryption required "
8262 (unsigned int)state->call));
8263 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8268 SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
8270 /* Now we must call the relevant TRANS2 function */
8271 switch(state->call) {
8272 case TRANSACT2_OPEN:
8274 START_PROFILE(Trans2_open);
8275 call_trans2open(conn, req,
8276 &state->param, state->total_param,
8277 &state->data, state->total_data,
8278 state->max_data_return);
8279 END_PROFILE(Trans2_open);
8283 case TRANSACT2_FINDFIRST:
8285 START_PROFILE(Trans2_findfirst);
8286 call_trans2findfirst(conn, req,
8287 &state->param, state->total_param,
8288 &state->data, state->total_data,
8289 state->max_data_return);
8290 END_PROFILE(Trans2_findfirst);
8294 case TRANSACT2_FINDNEXT:
8296 START_PROFILE(Trans2_findnext);
8297 call_trans2findnext(conn, req,
8298 &state->param, state->total_param,
8299 &state->data, state->total_data,
8300 state->max_data_return);
8301 END_PROFILE(Trans2_findnext);
8305 case TRANSACT2_QFSINFO:
8307 START_PROFILE(Trans2_qfsinfo);
8308 call_trans2qfsinfo(conn, req,
8309 &state->param, state->total_param,
8310 &state->data, state->total_data,
8311 state->max_data_return);
8312 END_PROFILE(Trans2_qfsinfo);
8316 case TRANSACT2_SETFSINFO:
8318 START_PROFILE(Trans2_setfsinfo);
8319 call_trans2setfsinfo(conn, req,
8320 &state->param, state->total_param,
8321 &state->data, state->total_data,
8322 state->max_data_return);
8323 END_PROFILE(Trans2_setfsinfo);
8327 case TRANSACT2_QPATHINFO:
8328 case TRANSACT2_QFILEINFO:
8330 START_PROFILE(Trans2_qpathinfo);
8331 call_trans2qfilepathinfo(conn, req, state->call,
8332 &state->param, state->total_param,
8333 &state->data, state->total_data,
8334 state->max_data_return);
8335 END_PROFILE(Trans2_qpathinfo);
8339 case TRANSACT2_SETPATHINFO:
8340 case TRANSACT2_SETFILEINFO:
8342 START_PROFILE(Trans2_setpathinfo);
8343 call_trans2setfilepathinfo(conn, req, state->call,
8344 &state->param, state->total_param,
8345 &state->data, state->total_data,
8346 state->max_data_return);
8347 END_PROFILE(Trans2_setpathinfo);
8351 case TRANSACT2_FINDNOTIFYFIRST:
8353 START_PROFILE(Trans2_findnotifyfirst);
8354 call_trans2findnotifyfirst(conn, req,
8355 &state->param, state->total_param,
8356 &state->data, state->total_data,
8357 state->max_data_return);
8358 END_PROFILE(Trans2_findnotifyfirst);
8362 case TRANSACT2_FINDNOTIFYNEXT:
8364 START_PROFILE(Trans2_findnotifynext);
8365 call_trans2findnotifynext(conn, req,
8366 &state->param, state->total_param,
8367 &state->data, state->total_data,
8368 state->max_data_return);
8369 END_PROFILE(Trans2_findnotifynext);
8373 case TRANSACT2_MKDIR:
8375 START_PROFILE(Trans2_mkdir);
8376 call_trans2mkdir(conn, req,
8377 &state->param, state->total_param,
8378 &state->data, state->total_data,
8379 state->max_data_return);
8380 END_PROFILE(Trans2_mkdir);
8384 case TRANSACT2_GET_DFS_REFERRAL:
8386 START_PROFILE(Trans2_get_dfs_referral);
8387 call_trans2getdfsreferral(conn, req,
8388 &state->param, state->total_param,
8389 &state->data, state->total_data,
8390 state->max_data_return);
8391 END_PROFILE(Trans2_get_dfs_referral);
8395 case TRANSACT2_IOCTL:
8397 START_PROFILE(Trans2_ioctl);
8398 call_trans2ioctl(conn, req,
8399 &state->param, state->total_param,
8400 &state->data, state->total_data,
8401 state->max_data_return);
8402 END_PROFILE(Trans2_ioctl);
8407 /* Error in request */
8408 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
8409 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8413 /****************************************************************************
8414 Reply to a SMBtrans2.
8415 ****************************************************************************/
8417 void reply_trans2(struct smb_request *req)
8419 connection_struct *conn = req->conn;
8424 unsigned int tran_call;
8425 struct trans_state *state;
8428 START_PROFILE(SMBtrans2);
8430 if (req->wct < 14) {
8431 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8432 END_PROFILE(SMBtrans2);
8436 dsoff = SVAL(req->vwv+12, 0);
8437 dscnt = SVAL(req->vwv+11, 0);
8438 psoff = SVAL(req->vwv+10, 0);
8439 pscnt = SVAL(req->vwv+9, 0);
8440 tran_call = SVAL(req->vwv+14, 0);
8442 result = allow_new_trans(conn->pending_trans, req->mid);
8443 if (!NT_STATUS_IS_OK(result)) {
8444 DEBUG(2, ("Got invalid trans2 request: %s\n",
8445 nt_errstr(result)));
8446 reply_nterror(req, result);
8447 END_PROFILE(SMBtrans2);
8452 switch (tran_call) {
8453 /* List the allowed trans2 calls on IPC$ */
8454 case TRANSACT2_OPEN:
8455 case TRANSACT2_GET_DFS_REFERRAL:
8456 case TRANSACT2_QFILEINFO:
8457 case TRANSACT2_QFSINFO:
8458 case TRANSACT2_SETFSINFO:
8461 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8462 END_PROFILE(SMBtrans2);
8467 if ((state = TALLOC_P(conn, struct trans_state)) == NULL) {
8468 DEBUG(0, ("talloc failed\n"));
8469 reply_nterror(req, NT_STATUS_NO_MEMORY);
8470 END_PROFILE(SMBtrans2);
8474 state->cmd = SMBtrans2;
8476 state->mid = req->mid;
8477 state->vuid = req->vuid;
8478 state->setup_count = SVAL(req->vwv+13, 0);
8479 state->setup = NULL;
8480 state->total_param = SVAL(req->vwv+0, 0);
8481 state->param = NULL;
8482 state->total_data = SVAL(req->vwv+1, 0);
8484 state->max_param_return = SVAL(req->vwv+2, 0);
8485 state->max_data_return = SVAL(req->vwv+3, 0);
8486 state->max_setup_return = SVAL(req->vwv+4, 0);
8487 state->close_on_completion = BITSETW(req->vwv+5, 0);
8488 state->one_way = BITSETW(req->vwv+5, 1);
8490 state->call = tran_call;
8492 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8493 is so as a sanity check */
8494 if (state->setup_count != 1) {
8496 * Need to have rc=0 for ioctl to get job id for OS/2.
8497 * Network printing will fail if function is not successful.
8498 * Similar function in reply.c will be used if protocol
8499 * is LANMAN1.0 instead of LM1.2X002.
8500 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
8501 * outbuf doesn't have to be set(only job id is used).
8503 if ( (state->setup_count == 4)
8504 && (tran_call == TRANSACT2_IOCTL)
8505 && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
8506 && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
8507 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8509 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
8510 DEBUG(2,("Transaction is %d\n",tran_call));
8512 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8513 END_PROFILE(SMBtrans2);
8518 if ((dscnt > state->total_data) || (pscnt > state->total_param))
8521 if (state->total_data) {
8523 if (trans_oob(state->total_data, 0, dscnt)
8524 || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
8528 /* Can't use talloc here, the core routines do realloc on the
8529 * params and data. */
8530 state->data = (char *)SMB_MALLOC(state->total_data);
8531 if (state->data == NULL) {
8532 DEBUG(0,("reply_trans2: data malloc fail for %u "
8533 "bytes !\n", (unsigned int)state->total_data));
8535 reply_nterror(req, NT_STATUS_NO_MEMORY);
8536 END_PROFILE(SMBtrans2);
8540 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
8543 if (state->total_param) {
8545 if (trans_oob(state->total_param, 0, pscnt)
8546 || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
8550 /* Can't use talloc here, the core routines do realloc on the
8551 * params and data. */
8552 state->param = (char *)SMB_MALLOC(state->total_param);
8553 if (state->param == NULL) {
8554 DEBUG(0,("reply_trans: param malloc fail for %u "
8555 "bytes !\n", (unsigned int)state->total_param));
8556 SAFE_FREE(state->data);
8558 reply_nterror(req, NT_STATUS_NO_MEMORY);
8559 END_PROFILE(SMBtrans2);
8563 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
8566 state->received_data = dscnt;
8567 state->received_param = pscnt;
8569 if ((state->received_param == state->total_param) &&
8570 (state->received_data == state->total_data)) {
8572 handle_trans2(conn, req, state);
8574 SAFE_FREE(state->data);
8575 SAFE_FREE(state->param);
8577 END_PROFILE(SMBtrans2);
8581 DLIST_ADD(conn->pending_trans, state);
8583 /* We need to send an interim response then receive the rest
8584 of the parameter/data bytes */
8585 reply_outbuf(req, 0, 0);
8586 show_msg((char *)req->outbuf);
8587 END_PROFILE(SMBtrans2);
8592 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8593 SAFE_FREE(state->data);
8594 SAFE_FREE(state->param);
8596 END_PROFILE(SMBtrans2);
8597 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8601 /****************************************************************************
8602 Reply to a SMBtranss2
8603 ****************************************************************************/
8605 void reply_transs2(struct smb_request *req)
8607 connection_struct *conn = req->conn;
8608 unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
8609 struct trans_state *state;
8611 START_PROFILE(SMBtranss2);
8613 show_msg((char *)req->inbuf);
8616 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8617 END_PROFILE(SMBtranss2);
8621 for (state = conn->pending_trans; state != NULL;
8622 state = state->next) {
8623 if (state->mid == req->mid) {
8628 if ((state == NULL) || (state->cmd != SMBtrans2)) {
8629 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8630 END_PROFILE(SMBtranss2);
8634 /* Revise state->total_param and state->total_data in case they have
8635 changed downwards */
8637 if (SVAL(req->vwv+0, 0) < state->total_param)
8638 state->total_param = SVAL(req->vwv+0, 0);
8639 if (SVAL(req->vwv+1, 0) < state->total_data)
8640 state->total_data = SVAL(req->vwv+1, 0);
8642 pcnt = SVAL(req->vwv+2, 0);
8643 poff = SVAL(req->vwv+3, 0);
8644 pdisp = SVAL(req->vwv+4, 0);
8646 dcnt = SVAL(req->vwv+5, 0);
8647 doff = SVAL(req->vwv+6, 0);
8648 ddisp = SVAL(req->vwv+7, 0);
8650 state->received_param += pcnt;
8651 state->received_data += dcnt;
8653 if ((state->received_data > state->total_data) ||
8654 (state->received_param > state->total_param))
8658 if (trans_oob(state->total_param, pdisp, pcnt)
8659 || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
8662 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
8666 if (trans_oob(state->total_data, ddisp, dcnt)
8667 || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
8670 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
8673 if ((state->received_param < state->total_param) ||
8674 (state->received_data < state->total_data)) {
8675 END_PROFILE(SMBtranss2);
8679 handle_trans2(conn, req, state);
8681 DLIST_REMOVE(conn->pending_trans, state);
8682 SAFE_FREE(state->data);
8683 SAFE_FREE(state->param);
8686 END_PROFILE(SMBtranss2);
8691 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
8692 DLIST_REMOVE(conn->pending_trans, state);
8693 SAFE_FREE(state->data);
8694 SAFE_FREE(state->param);
8696 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8697 END_PROFILE(SMBtranss2);