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"
31 extern enum protocol_types Protocol;
33 #define DIR_ENTRY_SAFETY_MARGIN 4096
35 static char *store_file_unix_basic(connection_struct *conn,
38 const SMB_STRUCT_STAT *psbuf);
40 static char *store_file_unix_basic_info2(connection_struct *conn,
43 const SMB_STRUCT_STAT *psbuf);
45 /********************************************************************
46 Roundup a value to the nearest allocation roundup size boundary.
47 Only do this for Windows clients.
48 ********************************************************************/
50 uint64_t smb_roundup(connection_struct *conn, uint64_t val)
52 uint64_t rval = lp_allocation_roundup_size(SNUM(conn));
54 /* Only roundup for Windows clients. */
55 enum remote_arch_types ra_type = get_remote_arch();
56 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
57 val = SMB_ROUNDUP(val,rval);
62 /****************************************************************************
63 Utility functions for dealing with extended attributes.
64 ****************************************************************************/
66 /****************************************************************************
67 Refuse to allow clients to overwrite our private xattrs.
68 ****************************************************************************/
70 static bool samba_private_attr_name(const char *unix_ea_name)
72 static const char * const prohibited_ea_names[] = {
73 SAMBA_POSIX_INHERITANCE_EA_NAME,
74 SAMBA_XATTR_DOS_ATTRIB,
80 for (i = 0; prohibited_ea_names[i]; i++) {
81 if (strequal( prohibited_ea_names[i], unix_ea_name))
84 if (StrnCaseCmp(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
85 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
91 /****************************************************************************
92 Get one EA value. Fill in a struct ea_struct.
93 ****************************************************************************/
95 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
96 files_struct *fsp, const char *fname,
97 const char *ea_name, struct ea_struct *pea)
99 /* Get the value of this xattr. Max size is 64k. */
100 size_t attr_size = 256;
106 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
108 return NT_STATUS_NO_MEMORY;
111 if (fsp && fsp->fh->fd != -1) {
112 sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
114 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
117 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
123 return map_nt_error_from_unix(errno);
126 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
127 dump_data(10, (uint8 *)val, sizeret);
130 if (strnequal(ea_name, "user.", 5)) {
131 pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
133 pea->name = talloc_strdup(mem_ctx, ea_name);
135 if (pea->name == NULL) {
137 return NT_STATUS_NO_MEMORY;
139 pea->value.data = (unsigned char *)val;
140 pea->value.length = (size_t)sizeret;
144 NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
145 files_struct *fsp, const char *fname,
146 char ***pnames, size_t *pnum_names)
148 /* Get a list of all xattrs. Max namesize is 64k. */
149 size_t ea_namelist_size = 1024;
150 char *ea_namelist = NULL;
155 ssize_t sizeret = -1;
157 if (!lp_ea_support(SNUM(conn))) {
164 * TALLOC the result early to get the talloc hierarchy right.
167 names = TALLOC_ARRAY(mem_ctx, char *, 1);
169 DEBUG(0, ("talloc failed\n"));
170 return NT_STATUS_NO_MEMORY;
173 while (ea_namelist_size <= 65536) {
175 ea_namelist = TALLOC_REALLOC_ARRAY(
176 names, ea_namelist, char, ea_namelist_size);
177 if (ea_namelist == NULL) {
178 DEBUG(0, ("talloc failed\n"));
180 return NT_STATUS_NO_MEMORY;
183 if (fsp && fsp->fh->fd != -1) {
184 sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
187 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist,
191 if ((sizeret == -1) && (errno == ERANGE)) {
192 ea_namelist_size *= 2;
201 return map_nt_error_from_unix(errno);
204 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
205 (unsigned int)sizeret));
215 * Ensure the result is 0-terminated
218 if (ea_namelist[sizeret-1] != '\0') {
220 return NT_STATUS_INTERNAL_ERROR;
228 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
232 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names);
234 DEBUG(0, ("talloc failed\n"));
236 return NT_STATUS_NO_MEMORY;
242 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
243 names[num_names++] = p;
247 *pnum_names = num_names;
251 /****************************************************************************
252 Return a linked list of the total EA's. Plus the total size
253 ****************************************************************************/
255 static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
256 const char *fname, size_t *pea_total_len)
258 /* Get a list of all xattrs. Max namesize is 64k. */
261 struct ea_list *ea_list_head = NULL;
266 if (!lp_ea_support(SNUM(conn))) {
270 status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
273 if (!NT_STATUS_IS_OK(status) || (num_names == 0)) {
277 for (i=0; i<num_names; i++) {
278 struct ea_list *listp;
281 if (strnequal(names[i], "system.", 7)
282 || samba_private_attr_name(names[i]))
285 listp = TALLOC_P(mem_ctx, struct ea_list);
290 if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx, conn, fsp,
296 push_ascii_fstring(dos_ea_name, listp->ea.name);
299 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
301 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
302 "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
303 (unsigned int)listp->ea.value.length));
305 DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
309 /* Add on 4 for total length. */
310 if (*pea_total_len) {
314 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
315 (unsigned int)*pea_total_len));
320 /****************************************************************************
321 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
323 ****************************************************************************/
325 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
326 connection_struct *conn, struct ea_list *ea_list)
328 unsigned int ret_data_size = 4;
331 SMB_ASSERT(total_data_size >= 4);
333 if (!lp_ea_support(SNUM(conn))) {
338 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
341 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
342 dos_namelen = strlen(dos_ea_name);
343 if (dos_namelen > 255 || dos_namelen == 0) {
346 if (ea_list->ea.value.length > 65535) {
349 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
353 /* We know we have room. */
354 SCVAL(p,0,ea_list->ea.flags);
355 SCVAL(p,1,dos_namelen);
356 SSVAL(p,2,ea_list->ea.value.length);
357 fstrcpy(p+4, dos_ea_name);
358 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
360 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
361 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
364 ret_data_size = PTR_DIFF(p, pdata);
365 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
366 SIVAL(pdata,0,ret_data_size);
367 return ret_data_size;
370 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
372 size_t total_ea_len = 0;
373 TALLOC_CTX *mem_ctx = NULL;
375 if (!lp_ea_support(SNUM(conn))) {
378 mem_ctx = talloc_tos();
379 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
383 /****************************************************************************
384 Ensure the EA name is case insensitive by matching any existing EA name.
385 ****************************************************************************/
387 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
390 TALLOC_CTX *mem_ctx = talloc_tos();
391 struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
393 for (; ea_list; ea_list = ea_list->next) {
394 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
395 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
396 &unix_ea_name[5], ea_list->ea.name));
397 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
403 /****************************************************************************
404 Set or delete an extended attribute.
405 ****************************************************************************/
407 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
408 const struct smb_filename *smb_fname, struct ea_list *ea_list)
413 if (!lp_ea_support(SNUM(conn))) {
414 return NT_STATUS_EAS_NOT_SUPPORTED;
417 status = get_full_smb_filename(talloc_tos(), smb_fname,
419 if (!NT_STATUS_IS_OK(status)) {
423 for (;ea_list; ea_list = ea_list->next) {
425 fstring unix_ea_name;
427 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
428 fstrcat(unix_ea_name, ea_list->ea.name);
430 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
432 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
434 if (samba_private_attr_name(unix_ea_name)) {
435 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
436 return NT_STATUS_ACCESS_DENIED;
439 if (ea_list->ea.value.length == 0) {
440 /* Remove the attribute. */
441 if (fsp && (fsp->fh->fd != -1)) {
442 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
443 unix_ea_name, fsp->fsp_name));
444 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
446 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
447 unix_ea_name, fname));
448 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
451 /* Removing a non existent attribute always succeeds. */
452 if (ret == -1 && errno == ENOATTR) {
453 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
459 if (fsp && (fsp->fh->fd != -1)) {
460 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
461 unix_ea_name, fsp->fsp_name));
462 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
463 ea_list->ea.value.data, ea_list->ea.value.length, 0);
465 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
466 unix_ea_name, fname));
467 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
468 ea_list->ea.value.data, ea_list->ea.value.length, 0);
474 if (errno == ENOTSUP) {
475 return NT_STATUS_EAS_NOT_SUPPORTED;
478 return map_nt_error_from_unix(errno);
484 /****************************************************************************
485 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
486 ****************************************************************************/
488 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
490 struct ea_list *ea_list_head = NULL;
491 size_t converted_size, offset = 0;
493 while (offset + 2 < data_size) {
494 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
495 unsigned int namelen = CVAL(pdata,offset);
497 offset++; /* Go past the namelen byte. */
499 /* integer wrap paranioa. */
500 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
501 (offset > data_size) || (namelen > data_size) ||
502 (offset + namelen >= data_size)) {
505 /* Ensure the name is null terminated. */
506 if (pdata[offset + namelen] != '\0') {
509 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
511 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
512 "failed: %s", strerror(errno)));
518 offset += (namelen + 1); /* Go past the name + terminating zero. */
519 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
520 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
526 /****************************************************************************
527 Read one EA list entry from the buffer.
528 ****************************************************************************/
530 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
532 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
534 unsigned int namelen;
535 size_t converted_size;
545 eal->ea.flags = CVAL(pdata,0);
546 namelen = CVAL(pdata,1);
547 val_len = SVAL(pdata,2);
549 if (4 + namelen + 1 + val_len > data_size) {
553 /* Ensure the name is null terminated. */
554 if (pdata[namelen + 4] != '\0') {
557 if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
558 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
565 eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
566 if (!eal->ea.value.data) {
570 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
572 /* Ensure we're null terminated just in case we print the value. */
573 eal->ea.value.data[val_len] = '\0';
574 /* But don't count the null. */
575 eal->ea.value.length--;
578 *pbytes_used = 4 + namelen + 1 + val_len;
581 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
582 dump_data(10, eal->ea.value.data, eal->ea.value.length);
587 /****************************************************************************
588 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
589 ****************************************************************************/
591 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
593 struct ea_list *ea_list_head = NULL;
595 size_t bytes_used = 0;
597 while (offset < data_size) {
598 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
604 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
605 offset += bytes_used;
611 /****************************************************************************
612 Count the total EA size needed.
613 ****************************************************************************/
615 static size_t ea_list_size(struct ea_list *ealist)
618 struct ea_list *listp;
621 for (listp = ealist; listp; listp = listp->next) {
622 push_ascii_fstring(dos_ea_name, listp->ea.name);
623 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
625 /* Add on 4 for total length. */
633 /****************************************************************************
634 Return a union of EA's from a file list and a list of names.
635 The TALLOC context for the two lists *MUST* be identical as we steal
636 memory from one list to add to another. JRA.
637 ****************************************************************************/
639 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
641 struct ea_list *nlistp, *flistp;
643 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
644 for (flistp = file_list; flistp; flistp = flistp->next) {
645 if (strequal(nlistp->ea.name, flistp->ea.name)) {
651 /* Copy the data from this entry. */
652 nlistp->ea.flags = flistp->ea.flags;
653 nlistp->ea.value = flistp->ea.value;
656 nlistp->ea.flags = 0;
657 ZERO_STRUCT(nlistp->ea.value);
661 *total_ea_len = ea_list_size(name_list);
665 /****************************************************************************
666 Send the required number of replies back.
667 We assume all fields other than the data fields are
668 set correctly for the type of call.
669 HACK ! Always assumes smb_setup field is zero.
670 ****************************************************************************/
672 void send_trans2_replies(connection_struct *conn,
673 struct smb_request *req,
680 /* As we are using a protocol > LANMAN1 then the max_send
681 variable must have been set in the sessetupX call.
682 This takes precedence over the max_xmit field in the
683 global struct. These different max_xmit variables should
684 be merged as this is now too confusing */
686 int data_to_send = datasize;
687 int params_to_send = paramsize;
689 const char *pp = params;
690 const char *pd = pdata;
691 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
692 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
693 int data_alignment_offset = 0;
694 bool overflow = False;
695 struct smbd_server_connection *sconn = smbd_server_conn;
696 int max_send = sconn->smb1.sessions.max_send;
698 /* Modify the data_to_send and datasize and set the error if
699 we're trying to send more than max_data_bytes. We still send
700 the part of the packet(s) that fit. Strange, but needed
703 if (max_data_bytes > 0 && datasize > max_data_bytes) {
704 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
705 max_data_bytes, datasize ));
706 datasize = data_to_send = max_data_bytes;
710 /* If there genuinely are no parameters or data to send just send the empty packet */
712 if(params_to_send == 0 && data_to_send == 0) {
713 reply_outbuf(req, 10, 0);
714 show_msg((char *)req->outbuf);
718 /* When sending params and data ensure that both are nicely aligned */
719 /* Only do this alignment when there is also data to send - else
720 can cause NT redirector problems. */
722 if (((params_to_send % 4) != 0) && (data_to_send != 0))
723 data_alignment_offset = 4 - (params_to_send % 4);
725 /* Space is bufsize minus Netbios over TCP header minus SMB header */
726 /* The alignment_offset is to align the param bytes on an even byte
727 boundary. NT 4.0 Beta needs this to work correctly. */
729 useable_space = max_send - (smb_size
732 + data_alignment_offset);
734 if (useable_space < 0) {
735 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
736 "= %d!!!", useable_space));
737 exit_server_cleanly("send_trans2_replies: Not enough space");
740 while (params_to_send || data_to_send) {
741 /* Calculate whether we will totally or partially fill this packet */
743 total_sent_thistime = params_to_send + data_to_send;
745 /* We can never send more than useable_space */
747 * Note that 'useable_space' does not include the alignment offsets,
748 * but we must include the alignment offsets in the calculation of
749 * the length of the data we send over the wire, as the alignment offsets
750 * are sent here. Fix from Marc_Jacobsen@hp.com.
753 total_sent_thistime = MIN(total_sent_thistime, useable_space);
755 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
756 + data_alignment_offset);
759 * We might have SMBtrans2s in req which was transferred to
760 * the outbuf, fix that.
762 SCVAL(req->outbuf, smb_com, SMBtrans2);
764 /* Set total params and data to be sent */
765 SSVAL(req->outbuf,smb_tprcnt,paramsize);
766 SSVAL(req->outbuf,smb_tdrcnt,datasize);
768 /* Calculate how many parameters and data we can fit into
769 * this packet. Parameters get precedence
772 params_sent_thistime = MIN(params_to_send,useable_space);
773 data_sent_thistime = useable_space - params_sent_thistime;
774 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
776 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
778 /* smb_proff is the offset from the start of the SMB header to the
779 parameter bytes, however the first 4 bytes of outbuf are
780 the Netbios over TCP header. Thus use smb_base() to subtract
781 them from the calculation */
783 SSVAL(req->outbuf,smb_proff,
784 ((smb_buf(req->outbuf)+alignment_offset)
785 - smb_base(req->outbuf)));
787 if(params_sent_thistime == 0)
788 SSVAL(req->outbuf,smb_prdisp,0);
790 /* Absolute displacement of param bytes sent in this packet */
791 SSVAL(req->outbuf,smb_prdisp,pp - params);
793 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
794 if(data_sent_thistime == 0) {
795 SSVAL(req->outbuf,smb_droff,0);
796 SSVAL(req->outbuf,smb_drdisp, 0);
798 /* The offset of the data bytes is the offset of the
799 parameter bytes plus the number of parameters being sent this time */
800 SSVAL(req->outbuf, smb_droff,
801 ((smb_buf(req->outbuf)+alignment_offset)
802 - smb_base(req->outbuf))
803 + params_sent_thistime + data_alignment_offset);
804 SSVAL(req->outbuf,smb_drdisp, pd - pdata);
807 /* Initialize the padding for alignment */
809 if (alignment_offset != 0) {
810 memset(smb_buf(req->outbuf), 0, alignment_offset);
813 /* Copy the param bytes into the packet */
815 if(params_sent_thistime) {
816 memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
817 params_sent_thistime);
820 /* Copy in the data bytes */
821 if(data_sent_thistime) {
822 if (data_alignment_offset != 0) {
823 memset((smb_buf(req->outbuf)+alignment_offset+
824 params_sent_thistime), 0,
825 data_alignment_offset);
827 memcpy(smb_buf(req->outbuf)+alignment_offset
828 +params_sent_thistime+data_alignment_offset,
829 pd,data_sent_thistime);
832 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
833 params_sent_thistime, data_sent_thistime, useable_space));
834 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
835 params_to_send, data_to_send, paramsize, datasize));
838 error_packet_set((char *)req->outbuf,
839 ERRDOS,ERRbufferoverflow,
840 STATUS_BUFFER_OVERFLOW,
844 /* Send the packet */
845 show_msg((char *)req->outbuf);
846 if (!srv_send_smb(smbd_server_fd(),
849 IS_CONN_ENCRYPTED(conn),
851 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
853 TALLOC_FREE(req->outbuf);
855 pp += params_sent_thistime;
856 pd += data_sent_thistime;
858 params_to_send -= params_sent_thistime;
859 data_to_send -= data_sent_thistime;
862 if(params_to_send < 0 || data_to_send < 0) {
863 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
864 params_to_send, data_to_send));
872 /****************************************************************************
873 Reply to a TRANSACT2_OPEN.
874 ****************************************************************************/
876 static void call_trans2open(connection_struct *conn,
877 struct smb_request *req,
878 char **pparams, int total_params,
879 char **ppdata, int total_data,
880 unsigned int max_data_bytes)
882 struct smb_filename *smb_fname = NULL;
883 char *params = *pparams;
884 char *pdata = *ppdata;
889 bool return_additional_info;
902 struct ea_list *ea_list = NULL;
907 uint32 create_disposition;
908 uint32 create_options = 0;
909 TALLOC_CTX *ctx = talloc_tos();
912 * Ensure we have enough parameters to perform the operation.
915 if (total_params < 29) {
916 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
920 flags = SVAL(params, 0);
921 deny_mode = SVAL(params, 2);
922 open_attr = SVAL(params,6);
923 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
924 if (oplock_request) {
925 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
929 return_additional_info = BITSETW(params,0);
930 open_sattr = SVAL(params, 4);
931 open_time = make_unix_date3(params+8);
933 open_ofun = SVAL(params,12);
934 open_size = IVAL(params,14);
938 reply_doserror(req, ERRSRV, ERRaccess);
942 srvstr_get_path(ctx, params, req->flags2, &fname, pname,
943 total_params - 28, STR_TERMINATE,
945 if (!NT_STATUS_IS_OK(status)) {
946 reply_nterror(req, status);
950 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
951 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
952 (unsigned int)open_ofun, open_size));
954 status = filename_convert(ctx,
956 req->flags2 & FLAGS2_DFS_PATHNAMES,
960 if (!NT_STATUS_IS_OK(status)) {
961 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
963 NT_STATUS_PATH_NOT_COVERED,
967 reply_nterror(req, status);
971 if (open_ofun == 0) {
972 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
976 if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
981 reply_doserror(req, ERRDOS, ERRbadaccess);
985 /* Any data in this call is an EA list. */
986 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
987 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
991 if (total_data != 4) {
992 if (total_data < 10) {
993 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
997 if (IVAL(pdata,0) > total_data) {
998 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
999 IVAL(pdata,0), (unsigned int)total_data));
1000 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1004 ea_list = read_ea_list(talloc_tos(), pdata + 4,
1007 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1010 } else if (IVAL(pdata,0) != 4) {
1011 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1015 status = SMB_VFS_CREATE_FILE(
1018 0, /* root_dir_fid */
1019 smb_fname, /* fname */
1020 access_mask, /* access_mask */
1021 share_mode, /* share_access */
1022 create_disposition, /* create_disposition*/
1023 create_options, /* create_options */
1024 open_attr, /* file_attributes */
1025 oplock_request, /* oplock_request */
1026 open_size, /* allocation_size */
1028 ea_list, /* ea_list */
1030 &smb_action); /* psbuf */
1032 if (!NT_STATUS_IS_OK(status)) {
1033 if (open_was_deferred(req->mid)) {
1034 /* We have re-scheduled this call. */
1037 reply_openerror(req, status);
1041 size = get_file_size_stat(&smb_fname->st);
1042 fattr = dos_mode(conn, fsp->fsp_name, &smb_fname->st);
1043 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1044 inode = smb_fname->st.st_ex_ino;
1046 close_file(req, fsp, ERROR_CLOSE);
1047 reply_doserror(req, ERRDOS,ERRnoaccess);
1051 /* Realloc the size of parameters and data we will return */
1052 *pparams = (char *)SMB_REALLOC(*pparams, 30);
1053 if(*pparams == NULL ) {
1054 reply_nterror(req, NT_STATUS_NO_MEMORY);
1059 SSVAL(params,0,fsp->fnum);
1060 SSVAL(params,2,fattr);
1061 srv_put_dos_date2(params,4, mtime);
1062 SIVAL(params,8, (uint32)size);
1063 SSVAL(params,12,deny_mode);
1064 SSVAL(params,14,0); /* open_type - file or directory. */
1065 SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1067 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1068 smb_action |= EXTENDED_OPLOCK_GRANTED;
1071 SSVAL(params,18,smb_action);
1074 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1076 SIVAL(params,20,inode);
1077 SSVAL(params,24,0); /* Padding. */
1079 uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
1080 SIVAL(params, 26, ea_size);
1082 SIVAL(params, 26, 0);
1085 /* Send the required number of replies */
1086 send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
1088 TALLOC_FREE(smb_fname);
1091 /*********************************************************
1092 Routine to check if a given string matches exactly.
1093 as a special case a mask of "." does NOT match. That
1094 is required for correct wildcard semantics
1095 Case can be significant or not.
1096 **********************************************************/
1098 static bool exact_match(connection_struct *conn,
1102 if (mask[0] == '.' && mask[1] == 0)
1104 if (dptr_has_wild(conn->dirptr)) {
1107 if (conn->case_sensitive)
1108 return strcmp(str,mask)==0;
1110 return StrCaseCmp(str,mask) == 0;
1113 /****************************************************************************
1114 Return the filetype for UNIX extensions.
1115 ****************************************************************************/
1117 static uint32 unix_filetype(mode_t mode)
1120 return UNIX_TYPE_FILE;
1121 else if(S_ISDIR(mode))
1122 return UNIX_TYPE_DIR;
1124 else if(S_ISLNK(mode))
1125 return UNIX_TYPE_SYMLINK;
1128 else if(S_ISCHR(mode))
1129 return UNIX_TYPE_CHARDEV;
1132 else if(S_ISBLK(mode))
1133 return UNIX_TYPE_BLKDEV;
1136 else if(S_ISFIFO(mode))
1137 return UNIX_TYPE_FIFO;
1140 else if(S_ISSOCK(mode))
1141 return UNIX_TYPE_SOCKET;
1144 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1145 return UNIX_TYPE_UNKNOWN;
1148 /****************************************************************************
1149 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1150 ****************************************************************************/
1152 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1154 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1155 SMB_STRUCT_STAT *psbuf,
1157 enum perm_type ptype,
1162 if (perms == SMB_MODE_NO_CHANGE) {
1163 if (!VALID_STAT(*psbuf)) {
1164 return NT_STATUS_INVALID_PARAMETER;
1166 *ret_perms = psbuf->st_ex_mode;
1167 return NT_STATUS_OK;
1171 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1172 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1173 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1174 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1175 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1176 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1177 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1178 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1179 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1181 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1184 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1187 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1192 /* Apply mode mask */
1193 ret &= lp_create_mask(SNUM(conn));
1194 /* Add in force bits */
1195 ret |= lp_force_create_mode(SNUM(conn));
1198 ret &= lp_dir_mask(SNUM(conn));
1199 /* Add in force bits */
1200 ret |= lp_force_dir_mode(SNUM(conn));
1202 case PERM_EXISTING_FILE:
1203 /* Apply mode mask */
1204 ret &= lp_security_mask(SNUM(conn));
1205 /* Add in force bits */
1206 ret |= lp_force_security_mode(SNUM(conn));
1208 case PERM_EXISTING_DIR:
1209 /* Apply mode mask */
1210 ret &= lp_dir_security_mask(SNUM(conn));
1211 /* Add in force bits */
1212 ret |= lp_force_dir_security_mode(SNUM(conn));
1217 return NT_STATUS_OK;
1220 /****************************************************************************
1221 Needed to show the msdfs symlinks as directories. Modifies psbuf
1222 to be a directory if it's a msdfs link.
1223 ****************************************************************************/
1225 static bool check_msdfs_link(connection_struct *conn,
1226 const char *pathname,
1227 SMB_STRUCT_STAT *psbuf)
1229 int saved_errno = errno;
1230 if(lp_host_msdfs() &&
1231 lp_msdfs_root(SNUM(conn)) &&
1232 is_msdfs_link(conn, pathname, psbuf)) {
1234 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1237 psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
1238 errno = saved_errno;
1241 errno = saved_errno;
1246 /****************************************************************************
1247 Get a level dependent lanman2 dir entry.
1248 ****************************************************************************/
1250 static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
1251 connection_struct *conn,
1253 const char *path_mask,
1256 int requires_resume_key,
1262 int space_remaining,
1264 bool *got_exact_match,
1265 int *last_entry_off,
1266 struct ea_list *name_list)
1270 SMB_STRUCT_STAT sbuf;
1271 const char *mask = NULL;
1272 char *pathreal = NULL;
1274 char *p, *q, *pdata = *ppdata;
1278 SMB_OFF_T file_size = 0;
1279 uint64_t allocation_size = 0;
1281 struct timespec mdate_ts, adate_ts, create_date_ts;
1282 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1284 char *last_entry_ptr;
1286 uint32 nt_extmode; /* Used for NT connections instead of mode */
1287 bool needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1288 bool check_mangled_names = lp_manglednames(conn->params);
1289 char mangled_name[13]; /* mangled 8.3 name. */
1291 *out_of_space = False;
1292 *got_exact_match = False;
1294 ZERO_STRUCT(mdate_ts);
1295 ZERO_STRUCT(adate_ts);
1296 ZERO_STRUCT(create_date_ts);
1298 if (!conn->dirptr) {
1302 p = strrchr_m(path_mask,'/');
1305 mask = talloc_strdup(ctx,"*.*");
1315 bool ms_dfs_link = False;
1317 /* Needed if we run out of space */
1318 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1319 dname = dptr_ReadDirName(ctx,conn->dirptr,&curr_dirpos,&sbuf);
1322 * Due to bugs in NT client redirectors we are not using
1323 * resume keys any more - set them to zero.
1324 * Check out the related comments in findfirst/findnext.
1330 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1331 (long)conn->dirptr,curr_dirpos));
1338 * fname may get mangled, dname is never mangled.
1339 * Whenever we're accessing the filesystem we use
1340 * pathreal which is composed from dname.
1346 /* Mangle fname if it's an illegal name. */
1347 if (mangle_must_mangle(dname,conn->params)) {
1348 if (!name_to_8_3(dname,mangled_name,True,conn->params)) {
1350 continue; /* Error - couldn't mangle. */
1352 fname = talloc_strdup(ctx, mangled_name);
1358 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
1359 got_match = mask_match(fname, mask, conn->case_sensitive);
1362 if(!got_match && check_mangled_names &&
1363 !mangle_is_8_3(fname, False, conn->params)) {
1365 * It turns out that NT matches wildcards against
1366 * both long *and* short names. This may explain some
1367 * of the wildcard wierdness from old DOS clients
1368 * that some people have been seeing.... JRA.
1370 /* Force the mangling into 8.3. */
1371 if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
1373 continue; /* Error - couldn't mangle. */
1376 if(!(got_match = *got_exact_match = exact_match(conn, mangled_name, mask))) {
1377 got_match = mask_match(mangled_name, mask, conn->case_sensitive);
1382 bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
1384 if (dont_descend && !isdots) {
1391 pathreal = talloc_asprintf(ctx,
1396 pathreal = talloc_asprintf(ctx,
1407 if (INFO_LEVEL_IS_UNIX(info_level)) {
1408 if (vfs_lstat_smb_fname(conn, pathreal,
1410 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1411 pathreal,strerror(errno)));
1412 TALLOC_FREE(pathreal);
1416 } else if (!VALID_STAT(sbuf) &&
1417 vfs_stat_smb_fname(conn, pathreal,
1419 /* Needed to show the msdfs symlinks as
1422 ms_dfs_link = check_msdfs_link(conn, pathreal, &sbuf);
1424 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1425 pathreal,strerror(errno)));
1426 TALLOC_FREE(pathreal);
1433 mode = dos_mode_msdfs(conn,pathreal,&sbuf);
1435 mode = dos_mode(conn,pathreal,&sbuf);
1438 if (!dir_check_ftype(conn,mode,dirtype)) {
1439 DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
1440 TALLOC_FREE(pathreal);
1445 if (!(mode & aDIR)) {
1446 file_size = get_file_size_stat(&sbuf);
1448 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf);
1450 mdate_ts = sbuf.st_ex_mtime;
1451 adate_ts = sbuf.st_ex_atime;
1452 create_date_ts = sbuf.st_ex_btime;
1454 if (ask_sharemode) {
1455 struct timespec write_time_ts;
1456 struct file_id fileid;
1458 fileid = vfs_file_id_from_sbuf(conn, &sbuf);
1459 get_file_infos(fileid, NULL, &write_time_ts);
1460 if (!null_timespec(write_time_ts)) {
1461 mdate_ts = write_time_ts;
1465 if (lp_dos_filetime_resolution(SNUM(conn))) {
1466 dos_filetime_timespec(&create_date_ts);
1467 dos_filetime_timespec(&mdate_ts);
1468 dos_filetime_timespec(&adate_ts);
1471 create_date = convert_timespec_to_time_t(create_date_ts);
1472 mdate = convert_timespec_to_time_t(mdate_ts);
1473 adate = convert_timespec_to_time_t(adate_ts);
1475 DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",
1480 dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1490 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1492 switch (info_level) {
1493 case SMB_FIND_INFO_STANDARD:
1494 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1495 if(requires_resume_key) {
1499 srv_put_dos_date2(p,0,create_date);
1500 srv_put_dos_date2(p,4,adate);
1501 srv_put_dos_date2(p,8,mdate);
1502 SIVAL(p,12,(uint32)file_size);
1503 SIVAL(p,16,(uint32)allocation_size);
1507 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1508 p += ucs2_align(base_data, p, 0);
1510 len = srvstr_push(base_data, flags2, p,
1511 fname, PTR_DIFF(end_data, p),
1513 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1515 SCVAL(nameptr, -1, len - 2);
1517 SCVAL(nameptr, -1, 0);
1521 SCVAL(nameptr, -1, len - 1);
1523 SCVAL(nameptr, -1, 0);
1529 case SMB_FIND_EA_SIZE:
1530 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1531 if(requires_resume_key) {
1535 srv_put_dos_date2(p,0,create_date);
1536 srv_put_dos_date2(p,4,adate);
1537 srv_put_dos_date2(p,8,mdate);
1538 SIVAL(p,12,(uint32)file_size);
1539 SIVAL(p,16,(uint32)allocation_size);
1542 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1543 SIVAL(p,22,ea_size); /* Extended attributes */
1547 len = srvstr_push(base_data, flags2,
1548 p, fname, PTR_DIFF(end_data, p),
1549 STR_TERMINATE | STR_NOALIGN);
1550 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1563 SCVAL(nameptr,0,len);
1565 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1568 case SMB_FIND_EA_LIST:
1570 struct ea_list *file_list = NULL;
1573 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1577 if(requires_resume_key) {
1581 srv_put_dos_date2(p,0,create_date);
1582 srv_put_dos_date2(p,4,adate);
1583 srv_put_dos_date2(p,8,mdate);
1584 SIVAL(p,12,(uint32)file_size);
1585 SIVAL(p,16,(uint32)allocation_size);
1587 p += 22; /* p now points to the EA area. */
1589 file_list = get_ea_list_from_file(ctx, conn, NULL, pathreal, &ea_len);
1590 name_list = ea_list_union(name_list, file_list, &ea_len);
1592 /* We need to determine if this entry will fit in the space available. */
1593 /* Max string size is 255 bytes. */
1594 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1595 /* Move the dirptr back to prev_dirpos */
1596 dptr_SeekDir(conn->dirptr, prev_dirpos);
1597 *out_of_space = True;
1598 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1599 return False; /* Not finished - just out of space */
1602 /* Push the ea_data followed by the name. */
1603 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1605 len = srvstr_push(base_data, flags2,
1606 p + 1, fname, PTR_DIFF(end_data, p+1),
1607 STR_TERMINATE | STR_NOALIGN);
1608 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1621 SCVAL(nameptr,0,len);
1623 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1627 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1628 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1629 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1631 SIVAL(p,0,reskey); p += 4;
1632 put_long_date_timespec(p,create_date_ts); p += 8;
1633 put_long_date_timespec(p,adate_ts); p += 8;
1634 put_long_date_timespec(p,mdate_ts); p += 8;
1635 put_long_date_timespec(p,mdate_ts); p += 8;
1636 SOFF_T(p,0,file_size); p += 8;
1637 SOFF_T(p,0,allocation_size); p += 8;
1638 SIVAL(p,0,nt_extmode); p += 4;
1639 q = p; p += 4; /* q is placeholder for name length. */
1641 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1642 SIVAL(p,0,ea_size); /* Extended attributes */
1645 /* Clear the short name buffer. This is
1646 * IMPORTANT as not doing so will trigger
1647 * a Win2k client bug. JRA.
1649 if (!was_8_3 && check_mangled_names) {
1650 if (!name_to_8_3(fname,mangled_name,True,
1652 /* Error - mangle failed ! */
1653 memset(mangled_name,'\0',12);
1655 mangled_name[12] = 0;
1656 len = srvstr_push(base_data, flags2,
1657 p+2, mangled_name, 24,
1658 STR_UPPER|STR_UNICODE);
1660 memset(p + 2 + len,'\0',24 - len);
1667 len = srvstr_push(base_data, flags2, p,
1668 fname, PTR_DIFF(end_data, p),
1669 STR_TERMINATE_ASCII);
1672 SIVAL(p,0,0); /* Ensure any padding is null. */
1673 len = PTR_DIFF(p, pdata);
1674 len = (len + 3) & ~3;
1679 case SMB_FIND_FILE_DIRECTORY_INFO:
1680 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1682 SIVAL(p,0,reskey); p += 4;
1683 put_long_date_timespec(p,create_date_ts); p += 8;
1684 put_long_date_timespec(p,adate_ts); p += 8;
1685 put_long_date_timespec(p,mdate_ts); p += 8;
1686 put_long_date_timespec(p,mdate_ts); p += 8;
1687 SOFF_T(p,0,file_size); p += 8;
1688 SOFF_T(p,0,allocation_size); p += 8;
1689 SIVAL(p,0,nt_extmode); p += 4;
1690 len = srvstr_push(base_data, flags2,
1691 p + 4, fname, PTR_DIFF(end_data, p+4),
1692 STR_TERMINATE_ASCII);
1695 SIVAL(p,0,0); /* Ensure any padding is null. */
1696 len = PTR_DIFF(p, pdata);
1697 len = (len + 3) & ~3;
1702 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1703 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1705 SIVAL(p,0,reskey); p += 4;
1706 put_long_date_timespec(p,create_date_ts); p += 8;
1707 put_long_date_timespec(p,adate_ts); p += 8;
1708 put_long_date_timespec(p,mdate_ts); p += 8;
1709 put_long_date_timespec(p,mdate_ts); p += 8;
1710 SOFF_T(p,0,file_size); p += 8;
1711 SOFF_T(p,0,allocation_size); p += 8;
1712 SIVAL(p,0,nt_extmode); p += 4;
1713 q = p; p += 4; /* q is placeholder for name length. */
1715 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1716 SIVAL(p,0,ea_size); /* Extended attributes */
1719 len = srvstr_push(base_data, flags2, p,
1720 fname, PTR_DIFF(end_data, p),
1721 STR_TERMINATE_ASCII);
1725 SIVAL(p,0,0); /* Ensure any padding is null. */
1726 len = PTR_DIFF(p, pdata);
1727 len = (len + 3) & ~3;
1732 case SMB_FIND_FILE_NAMES_INFO:
1733 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1735 SIVAL(p,0,reskey); p += 4;
1737 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1738 acl on a dir (tridge) */
1739 len = srvstr_push(base_data, flags2, p,
1740 fname, PTR_DIFF(end_data, p),
1741 STR_TERMINATE_ASCII);
1744 SIVAL(p,0,0); /* Ensure any padding is null. */
1745 len = PTR_DIFF(p, pdata);
1746 len = (len + 3) & ~3;
1751 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1752 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1754 SIVAL(p,0,reskey); p += 4;
1755 put_long_date_timespec(p,create_date_ts); p += 8;
1756 put_long_date_timespec(p,adate_ts); p += 8;
1757 put_long_date_timespec(p,mdate_ts); p += 8;
1758 put_long_date_timespec(p,mdate_ts); p += 8;
1759 SOFF_T(p,0,file_size); p += 8;
1760 SOFF_T(p,0,allocation_size); p += 8;
1761 SIVAL(p,0,nt_extmode); p += 4;
1762 q = p; p += 4; /* q is placeholder for name length. */
1764 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1765 SIVAL(p,0,ea_size); /* Extended attributes */
1768 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1769 SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
1770 SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
1771 len = srvstr_push(base_data, flags2, p,
1772 fname, PTR_DIFF(end_data, p),
1773 STR_TERMINATE_ASCII);
1776 SIVAL(p,0,0); /* Ensure any padding is null. */
1777 len = PTR_DIFF(p, pdata);
1778 len = (len + 3) & ~3;
1783 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1784 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1785 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1787 SIVAL(p,0,reskey); p += 4;
1788 put_long_date_timespec(p,create_date_ts); p += 8;
1789 put_long_date_timespec(p,adate_ts); p += 8;
1790 put_long_date_timespec(p,mdate_ts); p += 8;
1791 put_long_date_timespec(p,mdate_ts); p += 8;
1792 SOFF_T(p,0,file_size); p += 8;
1793 SOFF_T(p,0,allocation_size); p += 8;
1794 SIVAL(p,0,nt_extmode); p += 4;
1795 q = p; p += 4; /* q is placeholder for name length */
1797 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1798 SIVAL(p,0,ea_size); /* Extended attributes */
1801 /* Clear the short name buffer. This is
1802 * IMPORTANT as not doing so will trigger
1803 * a Win2k client bug. JRA.
1805 if (!was_8_3 && check_mangled_names) {
1806 if (!name_to_8_3(fname,mangled_name,True,
1808 /* Error - mangle failed ! */
1809 memset(mangled_name,'\0',12);
1811 mangled_name[12] = 0;
1812 len = srvstr_push(base_data, flags2,
1813 p+2, mangled_name, 24,
1814 STR_UPPER|STR_UNICODE);
1817 memset(p + 2 + len,'\0',24 - len);
1824 SSVAL(p,0,0); p += 2; /* Reserved ? */
1825 SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
1826 SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
1827 len = srvstr_push(base_data, flags2, p,
1828 fname, PTR_DIFF(end_data, p),
1829 STR_TERMINATE_ASCII);
1832 SIVAL(p,0,0); /* Ensure any padding is null. */
1833 len = PTR_DIFF(p, pdata);
1834 len = (len + 3) & ~3;
1839 /* CIFS UNIX Extension. */
1841 case SMB_FIND_FILE_UNIX:
1842 case SMB_FIND_FILE_UNIX_INFO2:
1844 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1846 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1848 if (info_level == SMB_FIND_FILE_UNIX) {
1849 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1850 p = store_file_unix_basic(conn, p,
1852 len = srvstr_push(base_data, flags2, p,
1853 fname, PTR_DIFF(end_data, p),
1856 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1857 p = store_file_unix_basic_info2(conn, p,
1861 len = srvstr_push(base_data, flags2, p, fname,
1862 PTR_DIFF(end_data, p), 0);
1863 SIVAL(nameptr, 0, len);
1867 SIVAL(p,0,0); /* Ensure any padding is null. */
1869 len = PTR_DIFF(p, pdata);
1870 len = (len + 3) & ~3;
1871 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1873 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1883 if (PTR_DIFF(p,pdata) > space_remaining) {
1884 /* Move the dirptr back to prev_dirpos */
1885 dptr_SeekDir(conn->dirptr, prev_dirpos);
1886 *out_of_space = True;
1887 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1888 return False; /* Not finished - just out of space */
1891 /* Setup the last entry pointer, as an offset from base_data */
1892 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1893 /* Advance the data pointer to the next slot */
1899 /****************************************************************************
1900 Reply to a TRANS2_FINDFIRST.
1901 ****************************************************************************/
1903 static void call_trans2findfirst(connection_struct *conn,
1904 struct smb_request *req,
1905 char **pparams, int total_params,
1906 char **ppdata, int total_data,
1907 unsigned int max_data_bytes)
1909 /* We must be careful here that we don't return more than the
1910 allowed number of data bytes. If this means returning fewer than
1911 maxentries then so be it. We assume that the redirector has
1912 enough room for the fixed number of parameter bytes it has
1914 struct smb_filename *smb_dname = NULL;
1915 char *params = *pparams;
1916 char *pdata = *ppdata;
1920 uint16 findfirst_flags;
1921 bool close_after_first;
1923 bool requires_resume_key;
1925 char *directory = NULL;
1928 int last_entry_off=0;
1932 bool finished = False;
1933 bool dont_descend = False;
1934 bool out_of_space = False;
1935 int space_remaining;
1936 bool mask_contains_wcard = False;
1937 struct ea_list *ea_list = NULL;
1938 NTSTATUS ntstatus = NT_STATUS_OK;
1939 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1940 TALLOC_CTX *ctx = talloc_tos();
1942 if (total_params < 13) {
1943 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1947 dirtype = SVAL(params,0);
1948 maxentries = SVAL(params,2);
1949 findfirst_flags = SVAL(params,4);
1950 close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1951 close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1952 requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1953 info_level = SVAL(params,6);
1955 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
1956 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1957 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1958 info_level, max_data_bytes));
1961 /* W2K3 seems to treat zero as 1. */
1965 switch (info_level) {
1966 case SMB_FIND_INFO_STANDARD:
1967 case SMB_FIND_EA_SIZE:
1968 case SMB_FIND_EA_LIST:
1969 case SMB_FIND_FILE_DIRECTORY_INFO:
1970 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1971 case SMB_FIND_FILE_NAMES_INFO:
1972 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1973 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1974 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1976 case SMB_FIND_FILE_UNIX:
1977 case SMB_FIND_FILE_UNIX_INFO2:
1978 /* Always use filesystem for UNIX mtime query. */
1979 ask_sharemode = false;
1980 if (!lp_unix_extensions()) {
1981 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1986 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1990 srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
1991 params+12, total_params - 12,
1992 STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1993 if (!NT_STATUS_IS_OK(ntstatus)) {
1994 reply_nterror(req, ntstatus);
1998 ntstatus = resolve_dfspath_wcard(ctx, conn,
1999 req->flags2 & FLAGS2_DFS_PATHNAMES,
2002 &mask_contains_wcard);
2003 if (!NT_STATUS_IS_OK(ntstatus)) {
2004 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
2005 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2006 ERRSRV, ERRbadpath);
2009 reply_nterror(req, ntstatus);
2013 ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
2014 (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
2015 if (!NT_STATUS_IS_OK(ntstatus)) {
2016 reply_nterror(req, ntstatus);
2020 mask = smb_dname->original_lcomp;
2022 ntstatus = get_full_smb_filename(ctx, smb_dname, &directory);
2023 TALLOC_FREE(smb_dname);
2024 if (!NT_STATUS_IS_OK(ntstatus)) {
2025 reply_nterror(req, ntstatus);
2029 ntstatus = check_name(conn, directory);
2030 if (!NT_STATUS_IS_OK(ntstatus)) {
2031 reply_nterror(req, ntstatus);
2035 p = strrchr_m(directory,'/');
2037 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2038 if((directory[0] == '.') && (directory[1] == '\0')) {
2039 mask = talloc_strdup(ctx,"*");
2041 reply_nterror(req, NT_STATUS_NO_MEMORY);
2044 mask_contains_wcard = True;
2046 directory = talloc_strdup(talloc_tos(), "./");
2048 reply_nterror(req, NT_STATUS_NO_MEMORY);
2055 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2057 if (info_level == SMB_FIND_EA_LIST) {
2060 if (total_data < 4) {
2061 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2065 ea_size = IVAL(pdata,0);
2066 if (ea_size != total_data) {
2067 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2068 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2069 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2073 if (!lp_ea_support(SNUM(conn))) {
2074 reply_doserror(req, ERRDOS, ERReasnotsupported);
2078 /* Pull out the list of names. */
2079 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2081 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2086 *ppdata = (char *)SMB_REALLOC(
2087 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2088 if(*ppdata == NULL ) {
2089 reply_nterror(req, NT_STATUS_NO_MEMORY);
2093 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2095 /* Realloc the params space */
2096 *pparams = (char *)SMB_REALLOC(*pparams, 10);
2097 if (*pparams == NULL) {
2098 reply_nterror(req, NT_STATUS_NO_MEMORY);
2103 /* Save the wildcard match and attribs we are using on this directory -
2104 needed as lanman2 assumes these are being saved between calls */
2106 ntstatus = dptr_create(conn,
2112 mask_contains_wcard,
2116 if (!NT_STATUS_IS_OK(ntstatus)) {
2117 reply_nterror(req, ntstatus);
2121 dptr_num = dptr_dnum(conn->dirptr);
2122 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2124 /* Initialize per TRANS2_FIND_FIRST operation data */
2125 dptr_init_search_op(conn->dirptr);
2127 /* We don't need to check for VOL here as this is returned by
2128 a different TRANS2 call. */
2130 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
2131 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2132 dont_descend = True;
2135 space_remaining = max_data_bytes;
2136 out_of_space = False;
2138 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2139 bool got_exact_match = False;
2141 /* this is a heuristic to avoid seeking the dirptr except when
2142 absolutely necessary. It allows for a filename of about 40 chars */
2143 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2144 out_of_space = True;
2147 finished = !get_lanman2_dir_entry(ctx,
2150 mask,dirtype,info_level,
2151 requires_resume_key,dont_descend,
2154 space_remaining, &out_of_space,
2156 &last_entry_off, ea_list);
2159 if (finished && out_of_space)
2162 if (!finished && !out_of_space)
2166 * As an optimisation if we know we aren't looking
2167 * for a wildcard name (ie. the name matches the wildcard exactly)
2168 * then we can finish on any (first) match.
2169 * This speeds up large directory searches. JRA.
2175 /* Ensure space_remaining never goes -ve. */
2176 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2177 space_remaining = 0;
2178 out_of_space = true;
2180 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2184 /* Check if we can close the dirptr */
2185 if(close_after_first || (finished && close_if_end)) {
2186 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2187 dptr_close(&dptr_num);
2191 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2192 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2193 * the protocol level is less than NT1. Tested with smbclient. JRA.
2194 * This should fix the OS/2 client bug #2335.
2197 if(numentries == 0) {
2198 dptr_close(&dptr_num);
2199 if (Protocol < PROTOCOL_NT1) {
2200 reply_doserror(req, ERRDOS, ERRnofiles);
2203 reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2204 ERRDOS, ERRbadfile);
2209 /* At this point pdata points to numentries directory entries. */
2211 /* Set up the return parameter block */
2212 SSVAL(params,0,dptr_num);
2213 SSVAL(params,2,numentries);
2214 SSVAL(params,4,finished);
2215 SSVAL(params,6,0); /* Never an EA error */
2216 SSVAL(params,8,last_entry_off);
2218 send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
2221 if ((! *directory) && dptr_path(dptr_num)) {
2222 directory = talloc_strdup(talloc_tos(),dptr_path(dptr_num));
2224 reply_nterror(req, NT_STATUS_NO_MEMORY);
2228 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2229 smb_fn_name(req->cmd),
2230 mask, directory, dirtype, numentries ) );
2233 * Force a name mangle here to ensure that the
2234 * mask as an 8.3 name is top of the mangled cache.
2235 * The reasons for this are subtle. Don't remove
2236 * this code unless you know what you are doing
2237 * (see PR#13758). JRA.
2240 if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2241 char mangled_name[13];
2242 name_to_8_3(mask, mangled_name, True, conn->params);
2248 /****************************************************************************
2249 Reply to a TRANS2_FINDNEXT.
2250 ****************************************************************************/
2252 static void call_trans2findnext(connection_struct *conn,
2253 struct smb_request *req,
2254 char **pparams, int total_params,
2255 char **ppdata, int total_data,
2256 unsigned int max_data_bytes)
2258 /* We must be careful here that we don't return more than the
2259 allowed number of data bytes. If this means returning fewer than
2260 maxentries then so be it. We assume that the redirector has
2261 enough room for the fixed number of parameter bytes it has
2263 char *params = *pparams;
2264 char *pdata = *ppdata;
2270 uint16 findnext_flags;
2271 bool close_after_request;
2273 bool requires_resume_key;
2275 bool mask_contains_wcard = False;
2276 char *resume_name = NULL;
2277 const char *mask = NULL;
2278 const char *directory = NULL;
2282 int i, last_entry_off=0;
2283 bool finished = False;
2284 bool dont_descend = False;
2285 bool out_of_space = False;
2286 int space_remaining;
2287 struct ea_list *ea_list = NULL;
2288 NTSTATUS ntstatus = NT_STATUS_OK;
2289 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2290 TALLOC_CTX *ctx = talloc_tos();
2292 if (total_params < 13) {
2293 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2297 dptr_num = SVAL(params,0);
2298 maxentries = SVAL(params,2);
2299 info_level = SVAL(params,4);
2300 resume_key = IVAL(params,6);
2301 findnext_flags = SVAL(params,10);
2302 close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2303 close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2304 requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2305 continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2307 srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2309 total_params - 12, STR_TERMINATE, &ntstatus,
2310 &mask_contains_wcard);
2311 if (!NT_STATUS_IS_OK(ntstatus)) {
2312 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2313 complain (it thinks we're asking for the directory above the shared
2314 path or an invalid name). Catch this as the resume name is only compared, never used in
2315 a file access. JRA. */
2316 srvstr_pull_talloc(ctx, params, req->flags2,
2317 &resume_name, params+12,
2321 if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2322 reply_nterror(req, ntstatus);
2327 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2328 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2329 resume_key = %d resume name = %s continue=%d level = %d\n",
2330 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
2331 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
2334 /* W2K3 seems to treat zero as 1. */
2338 switch (info_level) {
2339 case SMB_FIND_INFO_STANDARD:
2340 case SMB_FIND_EA_SIZE:
2341 case SMB_FIND_EA_LIST:
2342 case SMB_FIND_FILE_DIRECTORY_INFO:
2343 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2344 case SMB_FIND_FILE_NAMES_INFO:
2345 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2346 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2347 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2349 case SMB_FIND_FILE_UNIX:
2350 case SMB_FIND_FILE_UNIX_INFO2:
2351 /* Always use filesystem for UNIX mtime query. */
2352 ask_sharemode = false;
2353 if (!lp_unix_extensions()) {
2354 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2359 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2363 if (info_level == SMB_FIND_EA_LIST) {
2366 if (total_data < 4) {
2367 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2371 ea_size = IVAL(pdata,0);
2372 if (ea_size != total_data) {
2373 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2374 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2375 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2379 if (!lp_ea_support(SNUM(conn))) {
2380 reply_doserror(req, ERRDOS, ERReasnotsupported);
2384 /* Pull out the list of names. */
2385 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2387 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2392 *ppdata = (char *)SMB_REALLOC(
2393 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2394 if(*ppdata == NULL) {
2395 reply_nterror(req, NT_STATUS_NO_MEMORY);
2400 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2402 /* Realloc the params space */
2403 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2404 if(*pparams == NULL ) {
2405 reply_nterror(req, NT_STATUS_NO_MEMORY);
2411 /* Check that the dptr is valid */
2412 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2413 reply_doserror(req, ERRDOS, ERRnofiles);
2417 string_set(&conn->dirpath,dptr_path(dptr_num));
2419 /* Get the wildcard mask from the dptr */
2420 if((p = dptr_wcard(dptr_num))== NULL) {
2421 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2422 reply_doserror(req, ERRDOS, ERRnofiles);
2427 directory = conn->dirpath;
2429 /* Get the attr mask from the dptr */
2430 dirtype = dptr_attr(dptr_num);
2432 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2433 dptr_num, mask, dirtype,
2435 dptr_TellDir(conn->dirptr)));
2437 /* Initialize per TRANS2_FIND_NEXT operation data */
2438 dptr_init_search_op(conn->dirptr);
2440 /* We don't need to check for VOL here as this is returned by
2441 a different TRANS2 call. */
2443 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2444 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2445 dont_descend = True;
2448 space_remaining = max_data_bytes;
2449 out_of_space = False;
2452 * Seek to the correct position. We no longer use the resume key but
2453 * depend on the last file name instead.
2456 if(*resume_name && !continue_bit) {
2459 long current_pos = 0;
2461 * Remember, name_to_8_3 is called by
2462 * get_lanman2_dir_entry(), so the resume name
2463 * could be mangled. Ensure we check the unmangled name.
2466 if (mangle_is_mangled(resume_name, conn->params)) {
2467 char *new_resume_name = NULL;
2468 mangle_lookup_name_from_8_3(ctx,
2472 if (new_resume_name) {
2473 resume_name = new_resume_name;
2478 * Fix for NT redirector problem triggered by resume key indexes
2479 * changing between directory scans. We now return a resume key of 0
2480 * and instead look for the filename to continue from (also given
2481 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2482 * findfirst/findnext (as is usual) then the directory pointer
2483 * should already be at the correct place.
2486 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
2487 } /* end if resume_name && !continue_bit */
2489 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2490 bool got_exact_match = False;
2492 /* this is a heuristic to avoid seeking the dirptr except when
2493 absolutely necessary. It allows for a filename of about 40 chars */
2494 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2495 out_of_space = True;
2498 finished = !get_lanman2_dir_entry(ctx,
2501 mask,dirtype,info_level,
2502 requires_resume_key,dont_descend,
2505 space_remaining, &out_of_space,
2507 &last_entry_off, ea_list);
2510 if (finished && out_of_space)
2513 if (!finished && !out_of_space)
2517 * As an optimisation if we know we aren't looking
2518 * for a wildcard name (ie. the name matches the wildcard exactly)
2519 * then we can finish on any (first) match.
2520 * This speeds up large directory searches. JRA.
2526 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2529 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2530 smb_fn_name(req->cmd),
2531 mask, directory, dirtype, numentries ) );
2533 /* Check if we can close the dirptr */
2534 if(close_after_request || (finished && close_if_end)) {
2535 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2536 dptr_close(&dptr_num); /* This frees up the saved mask */
2539 /* Set up the return parameter block */
2540 SSVAL(params,0,numentries);
2541 SSVAL(params,2,finished);
2542 SSVAL(params,4,0); /* Never an EA error */
2543 SSVAL(params,6,last_entry_off);
2545 send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
2551 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
2553 E_md4hash(lp_servicename(SNUM(conn)),objid);
2557 static void samba_extended_info_version(struct smb_extended_info *extended_info)
2559 SMB_ASSERT(extended_info != NULL);
2561 extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
2562 extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
2563 | ((SAMBA_VERSION_MINOR & 0xff) << 16)
2564 | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
2565 #ifdef SAMBA_VERSION_REVISION
2566 extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
2568 extended_info->samba_subversion = 0;
2569 #ifdef SAMBA_VERSION_RC_RELEASE
2570 extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
2572 #ifdef SAMBA_VERSION_PRE_RELEASE
2573 extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
2576 #ifdef SAMBA_VERSION_VENDOR_PATCH
2577 extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
2579 extended_info->samba_gitcommitdate = 0;
2580 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2581 unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
2584 memset(extended_info->samba_version_string, 0,
2585 sizeof(extended_info->samba_version_string));
2587 snprintf (extended_info->samba_version_string,
2588 sizeof(extended_info->samba_version_string),
2589 "%s", samba_version_string());
2592 /****************************************************************************
2593 Reply to a TRANS2_QFSINFO (query filesystem info).
2594 ****************************************************************************/
2596 static void call_trans2qfsinfo(connection_struct *conn,
2597 struct smb_request *req,
2598 char **pparams, int total_params,
2599 char **ppdata, int total_data,
2600 unsigned int max_data_bytes)
2602 char *pdata, *end_data;
2603 char *params = *pparams;
2607 const char *vname = volume_label(SNUM(conn));
2608 int snum = SNUM(conn);
2609 char *fstype = lp_fstype(SNUM(conn));
2610 uint32 additional_flags = 0;
2612 if (total_params < 2) {
2613 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2617 info_level = SVAL(params,0);
2620 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2621 DEBUG(0,("call_trans2qfsinfo: not an allowed "
2622 "info level (0x%x) on IPC$.\n",
2623 (unsigned int)info_level));
2624 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2629 if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
2630 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2631 DEBUG(0,("call_trans2qfsinfo: encryption required "
2632 "and info level 0x%x sent.\n",
2633 (unsigned int)info_level));
2634 exit_server_cleanly("encryption required "
2640 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2642 if(vfs_stat_smb_fname(conn,".",&st)!=0) {
2643 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2644 reply_doserror(req, ERRSRV, ERRinvdevice);
2648 *ppdata = (char *)SMB_REALLOC(
2649 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2650 if (*ppdata == NULL ) {
2651 reply_nterror(req, NT_STATUS_NO_MEMORY);
2656 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2657 end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2659 switch (info_level) {
2660 case SMB_INFO_ALLOCATION:
2662 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2664 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2665 reply_unixerror(req, ERRHRD, ERRgeneral);
2669 block_size = lp_block_size(snum);
2670 if (bsize < block_size) {
2671 uint64_t factor = block_size/bsize;
2676 if (bsize > block_size) {
2677 uint64_t factor = bsize/block_size;
2682 bytes_per_sector = 512;
2683 sectors_per_unit = bsize/bytes_per_sector;
2685 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2686 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2687 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2689 SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
2690 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2691 SIVAL(pdata,l1_cUnit,dsize);
2692 SIVAL(pdata,l1_cUnitAvail,dfree);
2693 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2697 case SMB_INFO_VOLUME:
2698 /* Return volume name */
2700 * Add volume serial number - hash of a combination of
2701 * the called hostname and the service name.
2703 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2705 * Win2k3 and previous mess this up by sending a name length
2706 * one byte short. I believe only older clients (OS/2 Win9x) use
2707 * this call so try fixing this by adding a terminating null to
2708 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2712 pdata+l2_vol_szVolLabel, vname,
2713 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
2714 STR_NOALIGN|STR_TERMINATE);
2715 SCVAL(pdata,l2_vol_cch,len);
2716 data_len = l2_vol_szVolLabel + len;
2717 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2718 (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
2722 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2723 case SMB_FS_ATTRIBUTE_INFORMATION:
2725 additional_flags = 0;
2726 #if defined(HAVE_SYS_QUOTAS)
2727 additional_flags |= FILE_VOLUME_QUOTAS;
2730 if(lp_nt_acl_support(SNUM(conn))) {
2731 additional_flags |= FILE_PERSISTENT_ACLS;
2734 /* Capabilities are filled in at connection time through STATVFS call */
2735 additional_flags |= conn->fs_capabilities;
2737 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2738 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
2739 additional_flags); /* FS ATTRIBUTES */
2741 SIVAL(pdata,4,255); /* Max filename component length */
2742 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2743 and will think we can't do long filenames */
2744 len = srvstr_push(pdata, req->flags2, pdata+12, fstype,
2745 PTR_DIFF(end_data, pdata+12),
2748 data_len = 12 + len;
2751 case SMB_QUERY_FS_LABEL_INFO:
2752 case SMB_FS_LABEL_INFORMATION:
2753 len = srvstr_push(pdata, req->flags2, pdata+4, vname,
2754 PTR_DIFF(end_data, pdata+4), 0);
2759 case SMB_QUERY_FS_VOLUME_INFO:
2760 case SMB_FS_VOLUME_INFORMATION:
2763 * Add volume serial number - hash of a combination of
2764 * the called hostname and the service name.
2766 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2767 (str_checksum(get_local_machine_name())<<16));
2769 /* Max label len is 32 characters. */
2770 len = srvstr_push(pdata, req->flags2, pdata+18, vname,
2771 PTR_DIFF(end_data, pdata+18),
2773 SIVAL(pdata,12,len);
2776 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2777 (int)strlen(vname),vname, lp_servicename(snum)));
2780 case SMB_QUERY_FS_SIZE_INFO:
2781 case SMB_FS_SIZE_INFORMATION:
2783 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2785 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2786 reply_unixerror(req, ERRHRD, ERRgeneral);
2789 block_size = lp_block_size(snum);
2790 if (bsize < block_size) {
2791 uint64_t factor = block_size/bsize;
2796 if (bsize > block_size) {
2797 uint64_t factor = bsize/block_size;
2802 bytes_per_sector = 512;
2803 sectors_per_unit = bsize/bytes_per_sector;
2804 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2805 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2806 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2807 SBIG_UINT(pdata,0,dsize);
2808 SBIG_UINT(pdata,8,dfree);
2809 SIVAL(pdata,16,sectors_per_unit);
2810 SIVAL(pdata,20,bytes_per_sector);
2814 case SMB_FS_FULL_SIZE_INFORMATION:
2816 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2818 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2819 reply_unixerror(req, ERRHRD, ERRgeneral);
2822 block_size = lp_block_size(snum);
2823 if (bsize < block_size) {
2824 uint64_t factor = block_size/bsize;
2829 if (bsize > block_size) {
2830 uint64_t factor = bsize/block_size;
2835 bytes_per_sector = 512;
2836 sectors_per_unit = bsize/bytes_per_sector;
2837 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2838 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2839 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2840 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2841 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2842 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2843 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2844 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2848 case SMB_QUERY_FS_DEVICE_INFO:
2849 case SMB_FS_DEVICE_INFORMATION:
2851 SIVAL(pdata,0,0); /* dev type */
2852 SIVAL(pdata,4,0); /* characteristics */
2855 #ifdef HAVE_SYS_QUOTAS
2856 case SMB_FS_QUOTA_INFORMATION:
2858 * what we have to send --metze:
2860 * Unknown1: 24 NULL bytes
2861 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
2862 * Hard Quota Limit: 8 bytes seems like uint64_t or so
2863 * Quota Flags: 2 byte :
2864 * Unknown3: 6 NULL bytes
2868 * details for Quota Flags:
2870 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2871 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2872 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2873 * 0x0001 Enable Quotas: enable quota for this fs
2877 /* we need to fake up a fsp here,
2878 * because its not send in this call
2881 SMB_NTQUOTA_STRUCT quotas;
2884 ZERO_STRUCT(quotas);
2890 if (conn->server_info->utok.uid != 0) {
2891 DEBUG(0,("set_user_quota: access_denied "
2892 "service [%s] user [%s]\n",
2893 lp_servicename(SNUM(conn)),
2894 conn->server_info->unix_name));
2895 reply_doserror(req, ERRDOS, ERRnoaccess);
2899 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2900 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2901 reply_doserror(req, ERRSRV, ERRerror);
2907 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2909 /* Unknown1 24 NULL bytes*/
2910 SBIG_UINT(pdata,0,(uint64_t)0);
2911 SBIG_UINT(pdata,8,(uint64_t)0);
2912 SBIG_UINT(pdata,16,(uint64_t)0);
2914 /* Default Soft Quota 8 bytes */
2915 SBIG_UINT(pdata,24,quotas.softlim);
2917 /* Default Hard Quota 8 bytes */
2918 SBIG_UINT(pdata,32,quotas.hardlim);
2920 /* Quota flag 2 bytes */
2921 SSVAL(pdata,40,quotas.qflags);
2923 /* Unknown3 6 NULL bytes */
2929 #endif /* HAVE_SYS_QUOTAS */
2930 case SMB_FS_OBJECTID_INFORMATION:
2932 unsigned char objid[16];
2933 struct smb_extended_info extended_info;
2934 memcpy(pdata,create_volume_objectid(conn, objid),16);
2935 samba_extended_info_version (&extended_info);
2936 SIVAL(pdata,16,extended_info.samba_magic);
2937 SIVAL(pdata,20,extended_info.samba_version);
2938 SIVAL(pdata,24,extended_info.samba_subversion);
2939 SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
2940 memcpy(pdata+36,extended_info.samba_version_string,28);
2946 * Query the version and capabilities of the CIFS UNIX extensions
2950 case SMB_QUERY_CIFS_UNIX_INFO:
2952 bool large_write = lp_min_receive_file_size() &&
2953 !srv_is_signing_active(smbd_server_conn);
2954 bool large_read = !srv_is_signing_active(smbd_server_conn);
2955 int encrypt_caps = 0;
2957 if (!lp_unix_extensions()) {
2958 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2962 switch (conn->encrypt_level) {
2968 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
2971 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
2972 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
2973 large_write = false;
2979 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2980 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2982 /* We have POSIX ACLs, pathname, encryption,
2983 * large read/write, and locking capability. */
2985 SBIG_UINT(pdata,4,((uint64_t)(
2986 CIFS_UNIX_POSIX_ACLS_CAP|
2987 CIFS_UNIX_POSIX_PATHNAMES_CAP|
2988 CIFS_UNIX_FCNTL_LOCKS_CAP|
2989 CIFS_UNIX_EXTATTR_CAP|
2990 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
2992 (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
2994 CIFS_UNIX_LARGE_WRITE_CAP : 0))));