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 NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
372 unsigned int total_data_size,
373 unsigned int *ret_data_size,
374 connection_struct *conn,
375 struct ea_list *ea_list)
377 uint8_t *p = (uint8_t *)pdata;
378 uint8_t *last_start = NULL;
382 if (!lp_ea_support(SNUM(conn))) {
383 return NT_STATUS_NO_EAS_ON_FILE;
386 for (; ea_list; ea_list = ea_list->next) {
392 SIVAL(last_start, 0, PTR_DIFF(p, last_start));
396 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
397 dos_namelen = strlen(dos_ea_name);
398 if (dos_namelen > 255 || dos_namelen == 0) {
399 return NT_STATUS_INTERNAL_ERROR;
401 if (ea_list->ea.value.length > 65535) {
402 return NT_STATUS_INTERNAL_ERROR;
405 this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
408 size_t pad = 4 - (this_size % 4);
412 if (this_size > total_data_size) {
413 return NT_STATUS_INFO_LENGTH_MISMATCH;
416 /* We know we have room. */
417 SIVAL(p, 0x00, 0); /* next offset */
418 SCVAL(p, 0x04, ea_list->ea.flags);
419 SCVAL(p, 0x05, dos_namelen);
420 SSVAL(p, 0x06, ea_list->ea.value.length);
421 fstrcpy((char *)(p+0x08), dos_ea_name);
422 memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
424 total_data_size -= this_size;
428 *ret_data_size = PTR_DIFF(p, pdata);
429 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
433 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
435 size_t total_ea_len = 0;
436 TALLOC_CTX *mem_ctx = NULL;
438 if (!lp_ea_support(SNUM(conn))) {
441 mem_ctx = talloc_tos();
442 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
446 /****************************************************************************
447 Ensure the EA name is case insensitive by matching any existing EA name.
448 ****************************************************************************/
450 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
453 TALLOC_CTX *mem_ctx = talloc_tos();
454 struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
456 for (; ea_list; ea_list = ea_list->next) {
457 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
458 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
459 &unix_ea_name[5], ea_list->ea.name));
460 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
466 /****************************************************************************
467 Set or delete an extended attribute.
468 ****************************************************************************/
470 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
471 const struct smb_filename *smb_fname, struct ea_list *ea_list)
476 if (!lp_ea_support(SNUM(conn))) {
477 return NT_STATUS_EAS_NOT_SUPPORTED;
480 status = get_full_smb_filename(talloc_tos(), smb_fname,
482 if (!NT_STATUS_IS_OK(status)) {
486 for (;ea_list; ea_list = ea_list->next) {
488 fstring unix_ea_name;
490 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
491 fstrcat(unix_ea_name, ea_list->ea.name);
493 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
495 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
497 if (samba_private_attr_name(unix_ea_name)) {
498 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
499 return NT_STATUS_ACCESS_DENIED;
502 if (ea_list->ea.value.length == 0) {
503 /* Remove the attribute. */
504 if (fsp && (fsp->fh->fd != -1)) {
505 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
506 unix_ea_name, fsp->fsp_name));
507 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
509 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
510 unix_ea_name, fname));
511 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
514 /* Removing a non existent attribute always succeeds. */
515 if (ret == -1 && errno == ENOATTR) {
516 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
522 if (fsp && (fsp->fh->fd != -1)) {
523 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
524 unix_ea_name, fsp->fsp_name));
525 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
526 ea_list->ea.value.data, ea_list->ea.value.length, 0);
528 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
529 unix_ea_name, fname));
530 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
531 ea_list->ea.value.data, ea_list->ea.value.length, 0);
537 if (errno == ENOTSUP) {
538 return NT_STATUS_EAS_NOT_SUPPORTED;
541 return map_nt_error_from_unix(errno);
547 /****************************************************************************
548 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
549 ****************************************************************************/
551 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
553 struct ea_list *ea_list_head = NULL;
554 size_t converted_size, offset = 0;
556 while (offset + 2 < data_size) {
557 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
558 unsigned int namelen = CVAL(pdata,offset);
560 offset++; /* Go past the namelen byte. */
562 /* integer wrap paranioa. */
563 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
564 (offset > data_size) || (namelen > data_size) ||
565 (offset + namelen >= data_size)) {
568 /* Ensure the name is null terminated. */
569 if (pdata[offset + namelen] != '\0') {
572 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
574 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
575 "failed: %s", strerror(errno)));
581 offset += (namelen + 1); /* Go past the name + terminating zero. */
582 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
583 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
589 /****************************************************************************
590 Read one EA list entry from the buffer.
591 ****************************************************************************/
593 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
595 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
597 unsigned int namelen;
598 size_t converted_size;
608 eal->ea.flags = CVAL(pdata,0);
609 namelen = CVAL(pdata,1);
610 val_len = SVAL(pdata,2);
612 if (4 + namelen + 1 + val_len > data_size) {
616 /* Ensure the name is null terminated. */
617 if (pdata[namelen + 4] != '\0') {
620 if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
621 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
628 eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
629 if (!eal->ea.value.data) {
633 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
635 /* Ensure we're null terminated just in case we print the value. */
636 eal->ea.value.data[val_len] = '\0';
637 /* But don't count the null. */
638 eal->ea.value.length--;
641 *pbytes_used = 4 + namelen + 1 + val_len;
644 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
645 dump_data(10, eal->ea.value.data, eal->ea.value.length);
650 /****************************************************************************
651 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
652 ****************************************************************************/
654 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
656 struct ea_list *ea_list_head = NULL;
658 size_t bytes_used = 0;
660 while (offset < data_size) {
661 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
667 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
668 offset += bytes_used;
674 /****************************************************************************
675 Count the total EA size needed.
676 ****************************************************************************/
678 static size_t ea_list_size(struct ea_list *ealist)
681 struct ea_list *listp;
684 for (listp = ealist; listp; listp = listp->next) {
685 push_ascii_fstring(dos_ea_name, listp->ea.name);
686 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
688 /* Add on 4 for total length. */
696 /****************************************************************************
697 Return a union of EA's from a file list and a list of names.
698 The TALLOC context for the two lists *MUST* be identical as we steal
699 memory from one list to add to another. JRA.
700 ****************************************************************************/
702 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
704 struct ea_list *nlistp, *flistp;
706 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
707 for (flistp = file_list; flistp; flistp = flistp->next) {
708 if (strequal(nlistp->ea.name, flistp->ea.name)) {
714 /* Copy the data from this entry. */
715 nlistp->ea.flags = flistp->ea.flags;
716 nlistp->ea.value = flistp->ea.value;
719 nlistp->ea.flags = 0;
720 ZERO_STRUCT(nlistp->ea.value);
724 *total_ea_len = ea_list_size(name_list);
728 /****************************************************************************
729 Send the required number of replies back.
730 We assume all fields other than the data fields are
731 set correctly for the type of call.
732 HACK ! Always assumes smb_setup field is zero.
733 ****************************************************************************/
735 void send_trans2_replies(connection_struct *conn,
736 struct smb_request *req,
743 /* As we are using a protocol > LANMAN1 then the max_send
744 variable must have been set in the sessetupX call.
745 This takes precedence over the max_xmit field in the
746 global struct. These different max_xmit variables should
747 be merged as this is now too confusing */
749 int data_to_send = datasize;
750 int params_to_send = paramsize;
752 const char *pp = params;
753 const char *pd = pdata;
754 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
755 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
756 int data_alignment_offset = 0;
757 bool overflow = False;
758 struct smbd_server_connection *sconn = smbd_server_conn;
759 int max_send = sconn->smb1.sessions.max_send;
761 /* Modify the data_to_send and datasize and set the error if
762 we're trying to send more than max_data_bytes. We still send
763 the part of the packet(s) that fit. Strange, but needed
766 if (max_data_bytes > 0 && datasize > max_data_bytes) {
767 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
768 max_data_bytes, datasize ));
769 datasize = data_to_send = max_data_bytes;
773 /* If there genuinely are no parameters or data to send just send the empty packet */
775 if(params_to_send == 0 && data_to_send == 0) {
776 reply_outbuf(req, 10, 0);
777 show_msg((char *)req->outbuf);
778 if (!srv_send_smb(smbd_server_fd(),
781 IS_CONN_ENCRYPTED(conn),
783 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
785 TALLOC_FREE(req->outbuf);
789 /* When sending params and data ensure that both are nicely aligned */
790 /* Only do this alignment when there is also data to send - else
791 can cause NT redirector problems. */
793 if (((params_to_send % 4) != 0) && (data_to_send != 0))
794 data_alignment_offset = 4 - (params_to_send % 4);
796 /* Space is bufsize minus Netbios over TCP header minus SMB header */
797 /* The alignment_offset is to align the param bytes on an even byte
798 boundary. NT 4.0 Beta needs this to work correctly. */
800 useable_space = max_send - (smb_size
803 + data_alignment_offset);
805 if (useable_space < 0) {
806 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
807 "= %d!!!", useable_space));
808 exit_server_cleanly("send_trans2_replies: Not enough space");
811 while (params_to_send || data_to_send) {
812 /* Calculate whether we will totally or partially fill this packet */
814 total_sent_thistime = params_to_send + data_to_send;
816 /* We can never send more than useable_space */
818 * Note that 'useable_space' does not include the alignment offsets,
819 * but we must include the alignment offsets in the calculation of
820 * the length of the data we send over the wire, as the alignment offsets
821 * are sent here. Fix from Marc_Jacobsen@hp.com.
824 total_sent_thistime = MIN(total_sent_thistime, useable_space);
826 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
827 + data_alignment_offset);
830 * We might have SMBtrans2s in req which was transferred to
831 * the outbuf, fix that.
833 SCVAL(req->outbuf, smb_com, SMBtrans2);
835 /* Set total params and data to be sent */
836 SSVAL(req->outbuf,smb_tprcnt,paramsize);
837 SSVAL(req->outbuf,smb_tdrcnt,datasize);
839 /* Calculate how many parameters and data we can fit into
840 * this packet. Parameters get precedence
843 params_sent_thistime = MIN(params_to_send,useable_space);
844 data_sent_thistime = useable_space - params_sent_thistime;
845 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
847 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
849 /* smb_proff is the offset from the start of the SMB header to the
850 parameter bytes, however the first 4 bytes of outbuf are
851 the Netbios over TCP header. Thus use smb_base() to subtract
852 them from the calculation */
854 SSVAL(req->outbuf,smb_proff,
855 ((smb_buf(req->outbuf)+alignment_offset)
856 - smb_base(req->outbuf)));
858 if(params_sent_thistime == 0)
859 SSVAL(req->outbuf,smb_prdisp,0);
861 /* Absolute displacement of param bytes sent in this packet */
862 SSVAL(req->outbuf,smb_prdisp,pp - params);
864 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
865 if(data_sent_thistime == 0) {
866 SSVAL(req->outbuf,smb_droff,0);
867 SSVAL(req->outbuf,smb_drdisp, 0);
869 /* The offset of the data bytes is the offset of the
870 parameter bytes plus the number of parameters being sent this time */
871 SSVAL(req->outbuf, smb_droff,
872 ((smb_buf(req->outbuf)+alignment_offset)
873 - smb_base(req->outbuf))
874 + params_sent_thistime + data_alignment_offset);
875 SSVAL(req->outbuf,smb_drdisp, pd - pdata);
878 /* Initialize the padding for alignment */
880 if (alignment_offset != 0) {
881 memset(smb_buf(req->outbuf), 0, alignment_offset);
884 /* Copy the param bytes into the packet */
886 if(params_sent_thistime) {
887 memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
888 params_sent_thistime);
891 /* Copy in the data bytes */
892 if(data_sent_thistime) {
893 if (data_alignment_offset != 0) {
894 memset((smb_buf(req->outbuf)+alignment_offset+
895 params_sent_thistime), 0,
896 data_alignment_offset);
898 memcpy(smb_buf(req->outbuf)+alignment_offset
899 +params_sent_thistime+data_alignment_offset,
900 pd,data_sent_thistime);
903 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
904 params_sent_thistime, data_sent_thistime, useable_space));
905 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
906 params_to_send, data_to_send, paramsize, datasize));
909 error_packet_set((char *)req->outbuf,
910 ERRDOS,ERRbufferoverflow,
911 STATUS_BUFFER_OVERFLOW,
915 /* Send the packet */
916 show_msg((char *)req->outbuf);
917 if (!srv_send_smb(smbd_server_fd(),
920 IS_CONN_ENCRYPTED(conn),
922 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
924 TALLOC_FREE(req->outbuf);
926 pp += params_sent_thistime;
927 pd += data_sent_thistime;
929 params_to_send -= params_sent_thistime;
930 data_to_send -= data_sent_thistime;
933 if(params_to_send < 0 || data_to_send < 0) {
934 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
935 params_to_send, data_to_send));
943 /****************************************************************************
944 Reply to a TRANSACT2_OPEN.
945 ****************************************************************************/
947 static void call_trans2open(connection_struct *conn,
948 struct smb_request *req,
949 char **pparams, int total_params,
950 char **ppdata, int total_data,
951 unsigned int max_data_bytes)
953 struct smb_filename *smb_fname = NULL;
954 char *params = *pparams;
955 char *pdata = *ppdata;
960 bool return_additional_info;
973 struct ea_list *ea_list = NULL;
978 uint32 create_disposition;
979 uint32 create_options = 0;
980 TALLOC_CTX *ctx = talloc_tos();
983 * Ensure we have enough parameters to perform the operation.
986 if (total_params < 29) {
987 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
991 flags = SVAL(params, 0);
992 deny_mode = SVAL(params, 2);
993 open_attr = SVAL(params,6);
994 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
995 if (oplock_request) {
996 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1000 return_additional_info = BITSETW(params,0);
1001 open_sattr = SVAL(params, 4);
1002 open_time = make_unix_date3(params+8);
1004 open_ofun = SVAL(params,12);
1005 open_size = IVAL(params,14);
1006 pname = ¶ms[28];
1009 reply_doserror(req, ERRSRV, ERRaccess);
1013 srvstr_get_path(ctx, params, req->flags2, &fname, pname,
1014 total_params - 28, STR_TERMINATE,
1016 if (!NT_STATUS_IS_OK(status)) {
1017 reply_nterror(req, status);
1021 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1022 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
1023 (unsigned int)open_ofun, open_size));
1025 status = filename_convert(ctx,
1027 req->flags2 & FLAGS2_DFS_PATHNAMES,
1031 if (!NT_STATUS_IS_OK(status)) {
1032 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1033 reply_botherror(req,
1034 NT_STATUS_PATH_NOT_COVERED,
1035 ERRSRV, ERRbadpath);
1038 reply_nterror(req, status);
1042 if (open_ofun == 0) {
1043 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
1047 if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
1051 &create_disposition,
1053 reply_doserror(req, ERRDOS, ERRbadaccess);
1057 /* Any data in this call is an EA list. */
1058 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
1059 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1063 if (total_data != 4) {
1064 if (total_data < 10) {
1065 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1069 if (IVAL(pdata,0) > total_data) {
1070 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1071 IVAL(pdata,0), (unsigned int)total_data));
1072 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1076 ea_list = read_ea_list(talloc_tos(), pdata + 4,
1079 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1082 } else if (IVAL(pdata,0) != 4) {
1083 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1087 status = SMB_VFS_CREATE_FILE(
1090 0, /* root_dir_fid */
1091 smb_fname, /* fname */
1092 access_mask, /* access_mask */
1093 share_mode, /* share_access */
1094 create_disposition, /* create_disposition*/
1095 create_options, /* create_options */
1096 open_attr, /* file_attributes */
1097 oplock_request, /* oplock_request */
1098 open_size, /* allocation_size */
1100 ea_list, /* ea_list */
1102 &smb_action); /* psbuf */
1104 if (!NT_STATUS_IS_OK(status)) {
1105 if (open_was_deferred(req->mid)) {
1106 /* We have re-scheduled this call. */
1109 reply_openerror(req, status);
1113 size = get_file_size_stat(&smb_fname->st);
1114 fattr = dos_mode(conn, smb_fname);
1115 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1116 inode = smb_fname->st.st_ex_ino;
1118 close_file(req, fsp, ERROR_CLOSE);
1119 reply_doserror(req, ERRDOS,ERRnoaccess);
1123 /* Realloc the size of parameters and data we will return */
1124 *pparams = (char *)SMB_REALLOC(*pparams, 30);
1125 if(*pparams == NULL ) {
1126 reply_nterror(req, NT_STATUS_NO_MEMORY);
1131 SSVAL(params,0,fsp->fnum);
1132 SSVAL(params,2,fattr);
1133 srv_put_dos_date2(params,4, mtime);
1134 SIVAL(params,8, (uint32)size);
1135 SSVAL(params,12,deny_mode);
1136 SSVAL(params,14,0); /* open_type - file or directory. */
1137 SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1139 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1140 smb_action |= EXTENDED_OPLOCK_GRANTED;
1143 SSVAL(params,18,smb_action);
1146 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1148 SIVAL(params,20,inode);
1149 SSVAL(params,24,0); /* Padding. */
1151 uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
1152 SIVAL(params, 26, ea_size);
1154 SIVAL(params, 26, 0);
1157 /* Send the required number of replies */
1158 send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
1160 TALLOC_FREE(smb_fname);
1163 /*********************************************************
1164 Routine to check if a given string matches exactly.
1165 as a special case a mask of "." does NOT match. That
1166 is required for correct wildcard semantics
1167 Case can be significant or not.
1168 **********************************************************/
1170 static bool exact_match(connection_struct *conn,
1174 if (mask[0] == '.' && mask[1] == 0)
1176 if (dptr_has_wild(conn->dirptr)) {
1179 if (conn->case_sensitive)
1180 return strcmp(str,mask)==0;
1182 return StrCaseCmp(str,mask) == 0;
1185 /****************************************************************************
1186 Return the filetype for UNIX extensions.
1187 ****************************************************************************/
1189 static uint32 unix_filetype(mode_t mode)
1192 return UNIX_TYPE_FILE;
1193 else if(S_ISDIR(mode))
1194 return UNIX_TYPE_DIR;
1196 else if(S_ISLNK(mode))
1197 return UNIX_TYPE_SYMLINK;
1200 else if(S_ISCHR(mode))
1201 return UNIX_TYPE_CHARDEV;
1204 else if(S_ISBLK(mode))
1205 return UNIX_TYPE_BLKDEV;
1208 else if(S_ISFIFO(mode))
1209 return UNIX_TYPE_FIFO;
1212 else if(S_ISSOCK(mode))
1213 return UNIX_TYPE_SOCKET;
1216 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1217 return UNIX_TYPE_UNKNOWN;
1220 /****************************************************************************
1221 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1222 ****************************************************************************/
1224 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1226 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1227 const SMB_STRUCT_STAT *psbuf,
1229 enum perm_type ptype,
1234 if (perms == SMB_MODE_NO_CHANGE) {
1235 if (!VALID_STAT(*psbuf)) {
1236 return NT_STATUS_INVALID_PARAMETER;
1238 *ret_perms = psbuf->st_ex_mode;
1239 return NT_STATUS_OK;
1243 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1244 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1245 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1246 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1247 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1248 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1249 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1250 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1251 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1253 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1256 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1259 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1264 /* Apply mode mask */
1265 ret &= lp_create_mask(SNUM(conn));
1266 /* Add in force bits */
1267 ret |= lp_force_create_mode(SNUM(conn));
1270 ret &= lp_dir_mask(SNUM(conn));
1271 /* Add in force bits */
1272 ret |= lp_force_dir_mode(SNUM(conn));
1274 case PERM_EXISTING_FILE:
1275 /* Apply mode mask */
1276 ret &= lp_security_mask(SNUM(conn));
1277 /* Add in force bits */
1278 ret |= lp_force_security_mode(SNUM(conn));
1280 case PERM_EXISTING_DIR:
1281 /* Apply mode mask */
1282 ret &= lp_dir_security_mask(SNUM(conn));
1283 /* Add in force bits */
1284 ret |= lp_force_dir_security_mode(SNUM(conn));
1289 return NT_STATUS_OK;
1292 /****************************************************************************
1293 Needed to show the msdfs symlinks as directories. Modifies psbuf
1294 to be a directory if it's a msdfs link.
1295 ****************************************************************************/
1297 static bool check_msdfs_link(connection_struct *conn,
1298 const char *pathname,
1299 SMB_STRUCT_STAT *psbuf)
1301 int saved_errno = errno;
1302 if(lp_host_msdfs() &&
1303 lp_msdfs_root(SNUM(conn)) &&
1304 is_msdfs_link(conn, pathname, psbuf)) {
1306 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1309 psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
1310 errno = saved_errno;
1313 errno = saved_errno;
1318 /****************************************************************************
1319 Get a level dependent lanman2 dir entry.
1320 ****************************************************************************/
1322 static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
1323 connection_struct *conn,
1325 const char *path_mask,
1328 int requires_resume_key,
1334 int space_remaining,
1336 bool *got_exact_match,
1337 int *last_entry_off,
1338 struct ea_list *name_list)
1342 SMB_STRUCT_STAT sbuf;
1343 const char *mask = NULL;
1344 char *pathreal = NULL;
1346 char *p, *q, *pdata = *ppdata;
1350 SMB_OFF_T file_size = 0;
1351 uint64_t allocation_size = 0;
1353 struct timespec mdate_ts, adate_ts, create_date_ts;
1354 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1356 char *last_entry_ptr;
1358 uint32 nt_extmode; /* Used for NT connections instead of mode */
1359 bool needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1360 bool check_mangled_names = lp_manglednames(conn->params);
1361 char mangled_name[13]; /* mangled 8.3 name. */
1363 *out_of_space = False;
1364 *got_exact_match = False;
1366 ZERO_STRUCT(mdate_ts);
1367 ZERO_STRUCT(adate_ts);
1368 ZERO_STRUCT(create_date_ts);
1370 if (!conn->dirptr) {
1374 p = strrchr_m(path_mask,'/');
1377 mask = talloc_strdup(ctx,"*.*");
1387 bool ms_dfs_link = False;
1389 /* Needed if we run out of space */
1390 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1391 dname = dptr_ReadDirName(ctx,conn->dirptr,&curr_dirpos,&sbuf);
1394 * Due to bugs in NT client redirectors we are not using
1395 * resume keys any more - set them to zero.
1396 * Check out the related comments in findfirst/findnext.
1402 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1403 (long)conn->dirptr,curr_dirpos));
1410 * fname may get mangled, dname is never mangled.
1411 * Whenever we're accessing the filesystem we use
1412 * pathreal which is composed from dname.
1418 /* Mangle fname if it's an illegal name. */
1419 if (mangle_must_mangle(dname,conn->params)) {
1420 if (!name_to_8_3(dname,mangled_name,True,conn->params)) {
1422 continue; /* Error - couldn't mangle. */
1424 fname = talloc_strdup(ctx, mangled_name);
1430 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
1431 got_match = mask_match(fname, mask, conn->case_sensitive);
1434 if(!got_match && check_mangled_names &&
1435 !mangle_is_8_3(fname, False, conn->params)) {
1437 * It turns out that NT matches wildcards against
1438 * both long *and* short names. This may explain some
1439 * of the wildcard wierdness from old DOS clients
1440 * that some people have been seeing.... JRA.
1442 /* Force the mangling into 8.3. */
1443 if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
1445 continue; /* Error - couldn't mangle. */
1448 if(!(got_match = *got_exact_match = exact_match(conn, mangled_name, mask))) {
1449 got_match = mask_match(mangled_name, mask, conn->case_sensitive);
1454 bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
1455 struct smb_filename *smb_fname = NULL;
1458 if (dont_descend && !isdots) {
1465 pathreal = talloc_asprintf(ctx,
1470 pathreal = talloc_asprintf(ctx,
1481 /* A dirent from dptr_ReadDirName isn't a stream. */
1482 status = create_synthetic_smb_fname(ctx, pathreal,
1485 if (!NT_STATUS_IS_OK(status)) {
1490 if (INFO_LEVEL_IS_UNIX(info_level)) {
1491 if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
1492 DEBUG(5,("get_lanman2_dir_entry: "
1493 "Couldn't lstat [%s] (%s)\n",
1494 smb_fname_str_dbg(smb_fname),
1496 TALLOC_FREE(smb_fname);
1497 TALLOC_FREE(pathreal);
1501 } else if (!VALID_STAT(smb_fname->st) &&
1502 SMB_VFS_STAT(conn, smb_fname) != 0) {
1503 /* Needed to show the msdfs symlinks as
1507 check_msdfs_link(conn,
1508 smb_fname->base_name,
1511 DEBUG(5,("get_lanman2_dir_entry: "
1512 "Couldn't stat [%s] (%s)\n",
1513 smb_fname_str_dbg(smb_fname),
1515 TALLOC_FREE(smb_fname);
1516 TALLOC_FREE(pathreal);
1523 mode = dos_mode_msdfs(conn, smb_fname);
1525 mode = dos_mode(conn, smb_fname);
1528 if (!dir_check_ftype(conn,mode,dirtype)) {
1529 DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
1530 TALLOC_FREE(smb_fname);
1531 TALLOC_FREE(pathreal);
1536 if (!(mode & aDIR)) {
1537 file_size = get_file_size_stat(&smb_fname->st);
1540 SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
1542 if (ask_sharemode) {
1543 struct timespec write_time_ts;
1544 struct file_id fileid;
1546 ZERO_STRUCT(write_time_ts);
1547 fileid = vfs_file_id_from_sbuf(conn,
1549 get_file_infos(fileid, NULL, &write_time_ts);
1550 if (!null_timespec(write_time_ts)) {
1551 update_stat_ex_mtime(&smb_fname->st,
1556 mdate_ts = smb_fname->st.st_ex_mtime;
1557 adate_ts = smb_fname->st.st_ex_atime;
1558 create_date_ts = smb_fname->st.st_ex_btime;
1560 if (lp_dos_filetime_resolution(SNUM(conn))) {
1561 dos_filetime_timespec(&create_date_ts);
1562 dos_filetime_timespec(&mdate_ts);
1563 dos_filetime_timespec(&adate_ts);
1566 create_date = convert_timespec_to_time_t(create_date_ts);
1567 mdate = convert_timespec_to_time_t(mdate_ts);
1568 adate = convert_timespec_to_time_t(adate_ts);
1570 DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",
1571 smb_fname_str_dbg(smb_fname), fname));
1575 dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1576 sbuf = smb_fname->st;
1578 TALLOC_FREE(smb_fname);
1588 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1590 switch (info_level) {
1591 case SMB_FIND_INFO_STANDARD:
1592 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1593 if(requires_resume_key) {
1597 srv_put_dos_date2(p,0,create_date);
1598 srv_put_dos_date2(p,4,adate);
1599 srv_put_dos_date2(p,8,mdate);
1600 SIVAL(p,12,(uint32)file_size);
1601 SIVAL(p,16,(uint32)allocation_size);
1605 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1606 p += ucs2_align(base_data, p, 0);
1608 len = srvstr_push(base_data, flags2, p,
1609 fname, PTR_DIFF(end_data, p),
1611 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1613 SCVAL(nameptr, -1, len - 2);
1615 SCVAL(nameptr, -1, 0);
1619 SCVAL(nameptr, -1, len - 1);
1621 SCVAL(nameptr, -1, 0);
1627 case SMB_FIND_EA_SIZE:
1628 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\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);
1640 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1641 SIVAL(p,22,ea_size); /* Extended attributes */
1645 len = srvstr_push(base_data, flags2,
1646 p, fname, PTR_DIFF(end_data, p),
1647 STR_TERMINATE | STR_NOALIGN);
1648 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1661 SCVAL(nameptr,0,len);
1663 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1666 case SMB_FIND_EA_LIST:
1668 struct ea_list *file_list = NULL;
1671 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1675 if(requires_resume_key) {
1679 srv_put_dos_date2(p,0,create_date);
1680 srv_put_dos_date2(p,4,adate);
1681 srv_put_dos_date2(p,8,mdate);
1682 SIVAL(p,12,(uint32)file_size);
1683 SIVAL(p,16,(uint32)allocation_size);
1685 p += 22; /* p now points to the EA area. */
1687 file_list = get_ea_list_from_file(ctx, conn, NULL, pathreal, &ea_len);
1688 name_list = ea_list_union(name_list, file_list, &ea_len);
1690 /* We need to determine if this entry will fit in the space available. */
1691 /* Max string size is 255 bytes. */
1692 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1693 /* Move the dirptr back to prev_dirpos */
1694 dptr_SeekDir(conn->dirptr, prev_dirpos);
1695 *out_of_space = True;
1696 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1697 return False; /* Not finished - just out of space */
1700 /* Push the ea_data followed by the name. */
1701 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1703 len = srvstr_push(base_data, flags2,
1704 p + 1, fname, PTR_DIFF(end_data, p+1),
1705 STR_TERMINATE | STR_NOALIGN);
1706 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1719 SCVAL(nameptr,0,len);
1721 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1725 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1726 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1727 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1729 SIVAL(p,0,reskey); p += 4;
1730 put_long_date_timespec(p,create_date_ts); p += 8;
1731 put_long_date_timespec(p,adate_ts); p += 8;
1732 put_long_date_timespec(p,mdate_ts); p += 8;
1733 put_long_date_timespec(p,mdate_ts); p += 8;
1734 SOFF_T(p,0,file_size); p += 8;
1735 SOFF_T(p,0,allocation_size); p += 8;
1736 SIVAL(p,0,nt_extmode); p += 4;
1737 q = p; p += 4; /* q is placeholder for name length. */
1739 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1740 SIVAL(p,0,ea_size); /* Extended attributes */
1743 /* Clear the short name buffer. This is
1744 * IMPORTANT as not doing so will trigger
1745 * a Win2k client bug. JRA.
1747 if (!was_8_3 && check_mangled_names) {
1748 if (!name_to_8_3(fname,mangled_name,True,
1750 /* Error - mangle failed ! */
1751 memset(mangled_name,'\0',12);
1753 mangled_name[12] = 0;
1754 len = srvstr_push(base_data, flags2,
1755 p+2, mangled_name, 24,
1756 STR_UPPER|STR_UNICODE);
1758 memset(p + 2 + len,'\0',24 - len);
1765 len = srvstr_push(base_data, flags2, p,
1766 fname, PTR_DIFF(end_data, p),
1767 STR_TERMINATE_ASCII);
1770 SIVAL(p,0,0); /* Ensure any padding is null. */
1771 len = PTR_DIFF(p, pdata);
1772 len = (len + 3) & ~3;
1777 case SMB_FIND_FILE_DIRECTORY_INFO:
1778 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1780 SIVAL(p,0,reskey); p += 4;
1781 put_long_date_timespec(p,create_date_ts); p += 8;
1782 put_long_date_timespec(p,adate_ts); p += 8;
1783 put_long_date_timespec(p,mdate_ts); p += 8;
1784 put_long_date_timespec(p,mdate_ts); p += 8;
1785 SOFF_T(p,0,file_size); p += 8;
1786 SOFF_T(p,0,allocation_size); p += 8;
1787 SIVAL(p,0,nt_extmode); p += 4;
1788 len = srvstr_push(base_data, flags2,
1789 p + 4, fname, PTR_DIFF(end_data, p+4),
1790 STR_TERMINATE_ASCII);
1793 SIVAL(p,0,0); /* Ensure any padding is null. */
1794 len = PTR_DIFF(p, pdata);
1795 len = (len + 3) & ~3;
1800 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1801 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1803 SIVAL(p,0,reskey); p += 4;
1804 put_long_date_timespec(p,create_date_ts); p += 8;
1805 put_long_date_timespec(p,adate_ts); p += 8;
1806 put_long_date_timespec(p,mdate_ts); p += 8;
1807 put_long_date_timespec(p,mdate_ts); p += 8;
1808 SOFF_T(p,0,file_size); p += 8;
1809 SOFF_T(p,0,allocation_size); p += 8;
1810 SIVAL(p,0,nt_extmode); p += 4;
1811 q = p; p += 4; /* q is placeholder for name length. */
1813 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1814 SIVAL(p,0,ea_size); /* Extended attributes */
1817 len = srvstr_push(base_data, flags2, p,
1818 fname, PTR_DIFF(end_data, p),
1819 STR_TERMINATE_ASCII);
1823 SIVAL(p,0,0); /* Ensure any padding is null. */
1824 len = PTR_DIFF(p, pdata);
1825 len = (len + 3) & ~3;
1830 case SMB_FIND_FILE_NAMES_INFO:
1831 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1833 SIVAL(p,0,reskey); p += 4;
1835 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1836 acl on a dir (tridge) */
1837 len = srvstr_push(base_data, flags2, p,
1838 fname, PTR_DIFF(end_data, p),
1839 STR_TERMINATE_ASCII);
1842 SIVAL(p,0,0); /* Ensure any padding is null. */
1843 len = PTR_DIFF(p, pdata);
1844 len = (len + 3) & ~3;
1849 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1850 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1852 SIVAL(p,0,reskey); p += 4;
1853 put_long_date_timespec(p,create_date_ts); p += 8;
1854 put_long_date_timespec(p,adate_ts); p += 8;
1855 put_long_date_timespec(p,mdate_ts); p += 8;
1856 put_long_date_timespec(p,mdate_ts); p += 8;
1857 SOFF_T(p,0,file_size); p += 8;
1858 SOFF_T(p,0,allocation_size); p += 8;
1859 SIVAL(p,0,nt_extmode); p += 4;
1860 q = p; p += 4; /* q is placeholder for name length. */
1862 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1863 SIVAL(p,0,ea_size); /* Extended attributes */
1866 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1867 SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
1868 SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
1869 len = srvstr_push(base_data, flags2, p,
1870 fname, PTR_DIFF(end_data, p),
1871 STR_TERMINATE_ASCII);
1874 SIVAL(p,0,0); /* Ensure any padding is null. */
1875 len = PTR_DIFF(p, pdata);
1876 len = (len + 3) & ~3;
1881 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1882 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1883 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1885 SIVAL(p,0,reskey); p += 4;
1886 put_long_date_timespec(p,create_date_ts); p += 8;
1887 put_long_date_timespec(p,adate_ts); p += 8;
1888 put_long_date_timespec(p,mdate_ts); p += 8;
1889 put_long_date_timespec(p,mdate_ts); p += 8;
1890 SOFF_T(p,0,file_size); p += 8;
1891 SOFF_T(p,0,allocation_size); p += 8;
1892 SIVAL(p,0,nt_extmode); p += 4;
1893 q = p; p += 4; /* q is placeholder for name length */
1895 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1896 SIVAL(p,0,ea_size); /* Extended attributes */
1899 /* Clear the short name buffer. This is
1900 * IMPORTANT as not doing so will trigger
1901 * a Win2k client bug. JRA.
1903 if (!was_8_3 && check_mangled_names) {
1904 if (!name_to_8_3(fname,mangled_name,True,
1906 /* Error - mangle failed ! */
1907 memset(mangled_name,'\0',12);
1909 mangled_name[12] = 0;
1910 len = srvstr_push(base_data, flags2,
1911 p+2, mangled_name, 24,
1912 STR_UPPER|STR_UNICODE);
1915 memset(p + 2 + len,'\0',24 - len);
1922 SSVAL(p,0,0); p += 2; /* Reserved ? */
1923 SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
1924 SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
1925 len = srvstr_push(base_data, flags2, p,
1926 fname, PTR_DIFF(end_data, p),
1927 STR_TERMINATE_ASCII);
1930 SIVAL(p,0,0); /* Ensure any padding is null. */
1931 len = PTR_DIFF(p, pdata);
1932 len = (len + 3) & ~3;
1937 /* CIFS UNIX Extension. */
1939 case SMB_FIND_FILE_UNIX:
1940 case SMB_FIND_FILE_UNIX_INFO2:
1942 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1944 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1946 if (info_level == SMB_FIND_FILE_UNIX) {
1947 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1948 p = store_file_unix_basic(conn, p,
1950 len = srvstr_push(base_data, flags2, p,
1951 fname, PTR_DIFF(end_data, p),
1954 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1955 p = store_file_unix_basic_info2(conn, p,
1959 len = srvstr_push(base_data, flags2, p, fname,
1960 PTR_DIFF(end_data, p), 0);
1961 SIVAL(nameptr, 0, len);
1965 SIVAL(p,0,0); /* Ensure any padding is null. */
1967 len = PTR_DIFF(p, pdata);
1968 len = (len + 3) & ~3;
1969 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1971 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1981 if (PTR_DIFF(p,pdata) > space_remaining) {
1982 /* Move the dirptr back to prev_dirpos */
1983 dptr_SeekDir(conn->dirptr, prev_dirpos);
1984 *out_of_space = True;
1985 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1986 return False; /* Not finished - just out of space */
1989 /* Setup the last entry pointer, as an offset from base_data */
1990 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1991 /* Advance the data pointer to the next slot */
1997 /****************************************************************************
1998 Reply to a TRANS2_FINDFIRST.
1999 ****************************************************************************/
2001 static void call_trans2findfirst(connection_struct *conn,
2002 struct smb_request *req,
2003 char **pparams, int total_params,
2004 char **ppdata, int total_data,
2005 unsigned int max_data_bytes)
2007 /* We must be careful here that we don't return more than the
2008 allowed number of data bytes. If this means returning fewer than
2009 maxentries then so be it. We assume that the redirector has
2010 enough room for the fixed number of parameter bytes it has
2012 struct smb_filename *smb_dname = NULL;
2013 char *params = *pparams;
2014 char *pdata = *ppdata;
2018 uint16 findfirst_flags;
2019 bool close_after_first;
2021 bool requires_resume_key;
2023 char *directory = NULL;
2026 int last_entry_off=0;
2030 bool finished = False;
2031 bool dont_descend = False;
2032 bool out_of_space = False;
2033 int space_remaining;
2034 bool mask_contains_wcard = False;
2035 struct ea_list *ea_list = NULL;
2036 NTSTATUS ntstatus = NT_STATUS_OK;
2037 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2038 TALLOC_CTX *ctx = talloc_tos();
2040 if (total_params < 13) {
2041 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2045 dirtype = SVAL(params,0);
2046 maxentries = SVAL(params,2);
2047 findfirst_flags = SVAL(params,4);
2048 close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
2049 close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2050 requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2051 info_level = SVAL(params,6);
2053 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2054 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
2055 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
2056 info_level, max_data_bytes));
2059 /* W2K3 seems to treat zero as 1. */
2063 switch (info_level) {
2064 case SMB_FIND_INFO_STANDARD:
2065 case SMB_FIND_EA_SIZE:
2066 case SMB_FIND_EA_LIST:
2067 case SMB_FIND_FILE_DIRECTORY_INFO:
2068 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2069 case SMB_FIND_FILE_NAMES_INFO:
2070 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2071 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2072 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2074 case SMB_FIND_FILE_UNIX:
2075 case SMB_FIND_FILE_UNIX_INFO2:
2076 /* Always use filesystem for UNIX mtime query. */
2077 ask_sharemode = false;
2078 if (!lp_unix_extensions()) {
2079 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2084 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2088 srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
2089 params+12, total_params - 12,
2090 STR_TERMINATE, &ntstatus, &mask_contains_wcard);
2091 if (!NT_STATUS_IS_OK(ntstatus)) {
2092 reply_nterror(req, ntstatus);
2096 ntstatus = resolve_dfspath_wcard(ctx, conn,
2097 req->flags2 & FLAGS2_DFS_PATHNAMES,
2100 &mask_contains_wcard);
2101 if (!NT_STATUS_IS_OK(ntstatus)) {
2102 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
2103 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2104 ERRSRV, ERRbadpath);
2107 reply_nterror(req, ntstatus);
2111 ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
2112 (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
2113 if (!NT_STATUS_IS_OK(ntstatus)) {
2114 reply_nterror(req, ntstatus);
2118 mask = smb_dname->original_lcomp;
2120 ntstatus = get_full_smb_filename(ctx, smb_dname, &directory);
2121 TALLOC_FREE(smb_dname);
2122 if (!NT_STATUS_IS_OK(ntstatus)) {
2123 reply_nterror(req, ntstatus);
2127 ntstatus = check_name(conn, directory);
2128 if (!NT_STATUS_IS_OK(ntstatus)) {
2129 reply_nterror(req, ntstatus);
2133 p = strrchr_m(directory,'/');
2135 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2136 if((directory[0] == '.') && (directory[1] == '\0')) {
2137 mask = talloc_strdup(ctx,"*");
2139 reply_nterror(req, NT_STATUS_NO_MEMORY);
2142 mask_contains_wcard = True;
2144 directory = talloc_strdup(talloc_tos(), "./");
2146 reply_nterror(req, NT_STATUS_NO_MEMORY);
2153 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2155 if (info_level == SMB_FIND_EA_LIST) {
2158 if (total_data < 4) {
2159 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2163 ea_size = IVAL(pdata,0);
2164 if (ea_size != total_data) {
2165 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2166 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2167 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2171 if (!lp_ea_support(SNUM(conn))) {
2172 reply_doserror(req, ERRDOS, ERReasnotsupported);
2176 /* Pull out the list of names. */
2177 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2179 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2184 *ppdata = (char *)SMB_REALLOC(
2185 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2186 if(*ppdata == NULL ) {
2187 reply_nterror(req, NT_STATUS_NO_MEMORY);
2191 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2193 /* Realloc the params space */
2194 *pparams = (char *)SMB_REALLOC(*pparams, 10);
2195 if (*pparams == NULL) {
2196 reply_nterror(req, NT_STATUS_NO_MEMORY);
2201 /* Save the wildcard match and attribs we are using on this directory -
2202 needed as lanman2 assumes these are being saved between calls */
2204 ntstatus = dptr_create(conn,
2210 mask_contains_wcard,
2214 if (!NT_STATUS_IS_OK(ntstatus)) {
2215 reply_nterror(req, ntstatus);
2219 dptr_num = dptr_dnum(conn->dirptr);
2220 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2222 /* Initialize per TRANS2_FIND_FIRST operation data */
2223 dptr_init_search_op(conn->dirptr);
2225 /* We don't need to check for VOL here as this is returned by
2226 a different TRANS2 call. */
2228 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
2229 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2230 dont_descend = True;
2233 space_remaining = max_data_bytes;
2234 out_of_space = False;
2236 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2237 bool got_exact_match = False;
2239 /* this is a heuristic to avoid seeking the dirptr except when
2240 absolutely necessary. It allows for a filename of about 40 chars */
2241 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2242 out_of_space = True;
2245 finished = !get_lanman2_dir_entry(ctx,
2248 mask,dirtype,info_level,
2249 requires_resume_key,dont_descend,
2252 space_remaining, &out_of_space,
2254 &last_entry_off, ea_list);
2257 if (finished && out_of_space)
2260 if (!finished && !out_of_space)
2264 * As an optimisation if we know we aren't looking
2265 * for a wildcard name (ie. the name matches the wildcard exactly)
2266 * then we can finish on any (first) match.
2267 * This speeds up large directory searches. JRA.
2273 /* Ensure space_remaining never goes -ve. */
2274 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2275 space_remaining = 0;
2276 out_of_space = true;
2278 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2282 /* Check if we can close the dirptr */
2283 if(close_after_first || (finished && close_if_end)) {
2284 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2285 dptr_close(&dptr_num);
2289 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2290 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2291 * the protocol level is less than NT1. Tested with smbclient. JRA.
2292 * This should fix the OS/2 client bug #2335.
2295 if(numentries == 0) {
2296 dptr_close(&dptr_num);
2297 if (Protocol < PROTOCOL_NT1) {
2298 reply_doserror(req, ERRDOS, ERRnofiles);
2301 reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2302 ERRDOS, ERRbadfile);
2307 /* At this point pdata points to numentries directory entries. */
2309 /* Set up the return parameter block */
2310 SSVAL(params,0,dptr_num);
2311 SSVAL(params,2,numentries);
2312 SSVAL(params,4,finished);
2313 SSVAL(params,6,0); /* Never an EA error */
2314 SSVAL(params,8,last_entry_off);
2316 send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
2319 if ((! *directory) && dptr_path(dptr_num)) {
2320 directory = talloc_strdup(talloc_tos(),dptr_path(dptr_num));
2322 reply_nterror(req, NT_STATUS_NO_MEMORY);
2326 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2327 smb_fn_name(req->cmd),
2328 mask, directory, dirtype, numentries ) );
2331 * Force a name mangle here to ensure that the
2332 * mask as an 8.3 name is top of the mangled cache.
2333 * The reasons for this are subtle. Don't remove
2334 * this code unless you know what you are doing
2335 * (see PR#13758). JRA.
2338 if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2339 char mangled_name[13];
2340 name_to_8_3(mask, mangled_name, True, conn->params);
2346 /****************************************************************************
2347 Reply to a TRANS2_FINDNEXT.
2348 ****************************************************************************/
2350 static void call_trans2findnext(connection_struct *conn,
2351 struct smb_request *req,
2352 char **pparams, int total_params,
2353 char **ppdata, int total_data,
2354 unsigned int max_data_bytes)
2356 /* We must be careful here that we don't return more than the
2357 allowed number of data bytes. If this means returning fewer than
2358 maxentries then so be it. We assume that the redirector has
2359 enough room for the fixed number of parameter bytes it has
2361 char *params = *pparams;
2362 char *pdata = *ppdata;
2368 uint16 findnext_flags;
2369 bool close_after_request;
2371 bool requires_resume_key;
2373 bool mask_contains_wcard = False;
2374 char *resume_name = NULL;
2375 const char *mask = NULL;
2376 const char *directory = NULL;
2380 int i, last_entry_off=0;
2381 bool finished = False;
2382 bool dont_descend = False;
2383 bool out_of_space = False;
2384 int space_remaining;
2385 struct ea_list *ea_list = NULL;
2386 NTSTATUS ntstatus = NT_STATUS_OK;
2387 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2388 TALLOC_CTX *ctx = talloc_tos();
2390 if (total_params < 13) {
2391 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2395 dptr_num = SVAL(params,0);
2396 maxentries = SVAL(params,2);
2397 info_level = SVAL(params,4);
2398 resume_key = IVAL(params,6);
2399 findnext_flags = SVAL(params,10);
2400 close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2401 close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2402 requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2403 continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2405 srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2407 total_params - 12, STR_TERMINATE, &ntstatus,
2408 &mask_contains_wcard);
2409 if (!NT_STATUS_IS_OK(ntstatus)) {
2410 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2411 complain (it thinks we're asking for the directory above the shared
2412 path or an invalid name). Catch this as the resume name is only compared, never used in
2413 a file access. JRA. */
2414 srvstr_pull_talloc(ctx, params, req->flags2,
2415 &resume_name, params+12,
2419 if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2420 reply_nterror(req, ntstatus);
2425 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2426 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2427 resume_key = %d resume name = %s continue=%d level = %d\n",
2428 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
2429 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
2432 /* W2K3 seems to treat zero as 1. */
2436 switch (info_level) {
2437 case SMB_FIND_INFO_STANDARD:
2438 case SMB_FIND_EA_SIZE:
2439 case SMB_FIND_EA_LIST:
2440 case SMB_FIND_FILE_DIRECTORY_INFO:
2441 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2442 case SMB_FIND_FILE_NAMES_INFO:
2443 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2444 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2445 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2447 case SMB_FIND_FILE_UNIX:
2448 case SMB_FIND_FILE_UNIX_INFO2:
2449 /* Always use filesystem for UNIX mtime query. */
2450 ask_sharemode = false;
2451 if (!lp_unix_extensions()) {
2452 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2457 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2461 if (info_level == SMB_FIND_EA_LIST) {
2464 if (total_data < 4) {
2465 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2469 ea_size = IVAL(pdata,0);
2470 if (ea_size != total_data) {
2471 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2472 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2473 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2477 if (!lp_ea_support(SNUM(conn))) {
2478 reply_doserror(req, ERRDOS, ERReasnotsupported);
2482 /* Pull out the list of names. */
2483 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2485 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2490 *ppdata = (char *)SMB_REALLOC(
2491 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2492 if(*ppdata == NULL) {
2493 reply_nterror(req, NT_STATUS_NO_MEMORY);
2498 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2500 /* Realloc the params space */
2501 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2502 if(*pparams == NULL ) {
2503 reply_nterror(req, NT_STATUS_NO_MEMORY);
2509 /* Check that the dptr is valid */
2510 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2511 reply_doserror(req, ERRDOS, ERRnofiles);
2515 string_set(&conn->dirpath,dptr_path(dptr_num));
2517 /* Get the wildcard mask from the dptr */
2518 if((p = dptr_wcard(dptr_num))== NULL) {
2519 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2520 reply_doserror(req, ERRDOS, ERRnofiles);
2525 directory = conn->dirpath;
2527 /* Get the attr mask from the dptr */
2528 dirtype = dptr_attr(dptr_num);
2530 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2531 dptr_num, mask, dirtype,
2533 dptr_TellDir(conn->dirptr)));
2535 /* Initialize per TRANS2_FIND_NEXT operation data */
2536 dptr_init_search_op(conn->dirptr);
2538 /* We don't need to check for VOL here as this is returned by
2539 a different TRANS2 call. */
2541 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2542 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2543 dont_descend = True;
2546 space_remaining = max_data_bytes;
2547 out_of_space = False;
2550 * Seek to the correct position. We no longer use the resume key but
2551 * depend on the last file name instead.
2554 if(*resume_name && !continue_bit) {
2557 long current_pos = 0;
2559 * Remember, name_to_8_3 is called by
2560 * get_lanman2_dir_entry(), so the resume name
2561 * could be mangled. Ensure we check the unmangled name.
2564 if (mangle_is_mangled(resume_name, conn->params)) {
2565 char *new_resume_name = NULL;
2566 mangle_lookup_name_from_8_3(ctx,
2570 if (new_resume_name) {
2571 resume_name = new_resume_name;
2576 * Fix for NT redirector problem triggered by resume key indexes
2577 * changing between directory scans. We now return a resume key of 0
2578 * and instead look for the filename to continue from (also given
2579 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2580 * findfirst/findnext (as is usual) then the directory pointer
2581 * should already be at the correct place.
2584 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
2585 } /* end if resume_name && !continue_bit */
2587 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2588 bool got_exact_match = False;
2590 /* this is a heuristic to avoid seeking the dirptr except when
2591 absolutely necessary. It allows for a filename of about 40 chars */
2592 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2593 out_of_space = True;
2596 finished = !get_lanman2_dir_entry(ctx,
2599 mask,dirtype,info_level,
2600 requires_resume_key,dont_descend,
2603 space_remaining, &out_of_space,
2605 &last_entry_off, ea_list);
2608 if (finished && out_of_space)
2611 if (!finished && !out_of_space)
2615 * As an optimisation if we know we aren't looking
2616 * for a wildcard name (ie. the name matches the wildcard exactly)
2617 * then we can finish on any (first) match.
2618 * This speeds up large directory searches. JRA.
2624 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2627 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2628 smb_fn_name(req->cmd),
2629 mask, directory, dirtype, numentries ) );
2631 /* Check if we can close the dirptr */
2632 if(close_after_request || (finished && close_if_end)) {
2633 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2634 dptr_close(&dptr_num); /* This frees up the saved mask */
2637 /* Set up the return parameter block */
2638 SSVAL(params,0,numentries);
2639 SSVAL(params,2,finished);
2640 SSVAL(params,4,0); /* Never an EA error */
2641 SSVAL(params,6,last_entry_off);
2643 send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
2649 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
2651 E_md4hash(lp_servicename(SNUM(conn)),objid);
2655 static void samba_extended_info_version(struct smb_extended_info *extended_info)
2657 SMB_ASSERT(extended_info != NULL);
2659 extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
2660 extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
2661 | ((SAMBA_VERSION_MINOR & 0xff) << 16)
2662 | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
2663 #ifdef SAMBA_VERSION_REVISION
2664 extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
2666 extended_info->samba_subversion = 0;
2667 #ifdef SAMBA_VERSION_RC_RELEASE
2668 extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
2670 #ifdef SAMBA_VERSION_PRE_RELEASE
2671 extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
2674 #ifdef SAMBA_VERSION_VENDOR_PATCH
2675 extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
2677 extended_info->samba_gitcommitdate = 0;
2678 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2679 unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
2682 memset(extended_info->samba_version_string, 0,
2683 sizeof(extended_info->samba_version_string));
2685 snprintf (extended_info->samba_version_string,
2686 sizeof(extended_info->samba_version_string),
2687 "%s", samba_version_string());
2690 NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
2691 TALLOC_CTX *mem_ctx,
2692 uint16_t info_level,
2695 unsigned int max_data_bytes,
2699 char *pdata, *end_data;
2700 int data_len = 0, len;
2701 const char *vname = volume_label(SNUM(conn));
2702 int snum = SNUM(conn);
2703 char *fstype = lp_fstype(SNUM(conn));
2704 uint32 additional_flags = 0;
2707 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2708 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
2709 "info level (0x%x) on IPC$.\n",
2710 (unsigned int)info_level));
2711 return NT_STATUS_ACCESS_DENIED;
2715 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
2717 *ppdata = (char *)SMB_REALLOC(
2718 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2719 if (*ppdata == NULL) {
2720 return NT_STATUS_NO_MEMORY;
2724 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2725 end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2727 switch (info_level) {
2728 case SMB_INFO_ALLOCATION:
2730 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2732 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2733 return map_nt_error_from_unix(errno);
2736 block_size = lp_block_size(snum);
2737 if (bsize < block_size) {
2738 uint64_t factor = block_size/bsize;
2743 if (bsize > block_size) {
2744 uint64_t factor = bsize/block_size;
2749 bytes_per_sector = 512;
2750 sectors_per_unit = bsize/bytes_per_sector;
2752 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2753 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2754 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2756 SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
2757 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2758 SIVAL(pdata,l1_cUnit,dsize);
2759 SIVAL(pdata,l1_cUnitAvail,dfree);
2760 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2764 case SMB_INFO_VOLUME:
2765 /* Return volume name */
2767 * Add volume serial number - hash of a combination of
2768 * the called hostname and the service name.
2770 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2772 * Win2k3 and previous mess this up by sending a name length
2773 * one byte short. I believe only older clients (OS/2 Win9x) use
2774 * this call so try fixing this by adding a terminating null to
2775 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2779 pdata+l2_vol_szVolLabel, vname,
2780 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
2781 STR_NOALIGN|STR_TERMINATE);
2782 SCVAL(pdata,l2_vol_cch,len);
2783 data_len = l2_vol_szVolLabel + len;
2784 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
2785 (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
2789 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2790 case SMB_FS_ATTRIBUTE_INFORMATION:
2792 additional_flags = 0;
2793 #if defined(HAVE_SYS_QUOTAS)
2794 additional_flags |= FILE_VOLUME_QUOTAS;
2797 if(lp_nt_acl_support(SNUM(conn))) {
2798 additional_flags |= FILE_PERSISTENT_ACLS;
2801 /* Capabilities are filled in at connection time through STATVFS call */
2802 additional_flags |= conn->fs_capabilities;
2804 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2805 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
2806 additional_flags); /* FS ATTRIBUTES */
2808 SIVAL(pdata,4,255); /* Max filename component length */
2809 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2810 and will think we can't do long filenames */
2811 len = srvstr_push(pdata, flags2, pdata+12, fstype,
2812 PTR_DIFF(end_data, pdata+12),
2815 data_len = 12 + len;
2818 case SMB_QUERY_FS_LABEL_INFO:
2819 case SMB_FS_LABEL_INFORMATION:
2820 len = srvstr_push(pdata, flags2, pdata+4, vname,
2821 PTR_DIFF(end_data, pdata+4), 0);
2826 case SMB_QUERY_FS_VOLUME_INFO:
2827 case SMB_FS_VOLUME_INFORMATION:
2830 * Add volume serial number - hash of a combination of
2831 * the called hostname and the service name.
2833 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2834 (str_checksum(get_local_machine_name())<<16));
2836 /* Max label len is 32 characters. */
2837 len = srvstr_push(pdata, flags2, pdata+18, vname,
2838 PTR_DIFF(end_data, pdata+18),
2840 SIVAL(pdata,12,len);
2843 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2844 (int)strlen(vname),vname, lp_servicename(snum)));
2847 case SMB_QUERY_FS_SIZE_INFO:
2848 case SMB_FS_SIZE_INFORMATION:
2850 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2852 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2853 return map_nt_error_from_unix(errno);
2855 block_size = lp_block_size(snum);
2856 if (bsize < block_size) {
2857 uint64_t factor = block_size/bsize;
2862 if (bsize > block_size) {
2863 uint64_t factor = bsize/block_size;
2868 bytes_per_sector = 512;
2869 sectors_per_unit = bsize/bytes_per_sector;
2870 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2871 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2872 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2873 SBIG_UINT(pdata,0,dsize);
2874 SBIG_UINT(pdata,8,dfree);
2875 SIVAL(pdata,16,sectors_per_unit);
2876 SIVAL(pdata,20,bytes_per_sector);
2880 case SMB_FS_FULL_SIZE_INFORMATION:
2882 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2884 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2885 return map_nt_error_from_unix(errno);
2887 block_size = lp_block_size(snum);
2888 if (bsize < block_size) {
2889 uint64_t factor = block_size/bsize;
2894 if (bsize > block_size) {
2895 uint64_t factor = bsize/block_size;
2900 bytes_per_sector = 512;
2901 sectors_per_unit = bsize/bytes_per_sector;
2902 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2903 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2904 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2905 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2906 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2907 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2908 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2909 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2913 case SMB_QUERY_FS_DEVICE_INFO:
2914 case SMB_FS_DEVICE_INFORMATION:
2916 SIVAL(pdata,0,0); /* dev type */
2917 SIVAL(pdata,4,0); /* characteristics */
2920 #ifdef HAVE_SYS_QUOTAS
2921 case SMB_FS_QUOTA_INFORMATION:
2923 * what we have to send --metze:
2925 * Unknown1: 24 NULL bytes
2926 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
2927 * Hard Quota Limit: 8 bytes seems like uint64_t or so
2928 * Quota Flags: 2 byte :
2929 * Unknown3: 6 NULL bytes
2933 * details for Quota Flags:
2935 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2936 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2937 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2938 * 0x0001 Enable Quotas: enable quota for this fs
2942 /* we need to fake up a fsp here,
2943 * because its not send in this call
2946 SMB_NTQUOTA_STRUCT quotas;
2949 ZERO_STRUCT(quotas);
2955 if (conn->server_info->utok.uid != 0) {
2956 DEBUG(0,("set_user_quota: access_denied "
2957 "service [%s] user [%s]\n",
2958 lp_servicename(SNUM(conn)),
2959 conn->server_info->unix_name));
2960 return NT_STATUS_DOS(ERRDOS, ERRnoaccess);
2963 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2964 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2965 return NT_STATUS_DOS(ERRSRV, ERRerror);
2970 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
2971 lp_servicename(SNUM(conn))));
2973 /* Unknown1 24 NULL bytes*/
2974 SBIG_UINT(pdata,0,(uint64_t)0);
2975 SBIG_UINT(pdata,8,(uint64_t)0);
2976 SBIG_UINT(pdata,16,(uint64_t)0);
2978 /* Default Soft Quota 8 bytes */
2979 SBIG_UINT(pdata,24,quotas.softlim);
2981 /* Default Hard Quota 8 bytes */
2982 SBIG_UINT(pdata,32,quotas.hardlim);
2984 /* Quota flag 2 bytes */
2985 SSVAL(pdata,40,quotas.qflags);
2987 /* Unknown3 6 NULL bytes */
2993 #endif /* HAVE_SYS_QUOTAS */
2994 case SMB_FS_OBJECTID_INFORMATION:
2996 unsigned char objid[16];
2997 struct smb_extended_info extended_info;
2998 memcpy(pdata,create_volume_objectid(conn, objid),16);