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)
475 if (!lp_ea_support(SNUM(conn))) {
476 return NT_STATUS_EAS_NOT_SUPPORTED;
479 /* For now setting EAs on streams isn't supported. */
480 fname = smb_fname->base_name;
482 for (;ea_list; ea_list = ea_list->next) {
484 fstring unix_ea_name;
486 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
487 fstrcat(unix_ea_name, ea_list->ea.name);
489 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
491 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
493 if (samba_private_attr_name(unix_ea_name)) {
494 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
495 return NT_STATUS_ACCESS_DENIED;
498 if (ea_list->ea.value.length == 0) {
499 /* Remove the attribute. */
500 if (fsp && (fsp->fh->fd != -1)) {
501 DEBUG(10,("set_ea: deleting ea name %s on "
502 "file %s by file descriptor.\n",
503 unix_ea_name, fsp_str_dbg(fsp)));
504 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
506 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
507 unix_ea_name, fname));
508 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
511 /* Removing a non existent attribute always succeeds. */
512 if (ret == -1 && errno == ENOATTR) {
513 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
519 if (fsp && (fsp->fh->fd != -1)) {
520 DEBUG(10,("set_ea: setting ea name %s on file "
521 "%s by file descriptor.\n",
522 unix_ea_name, fsp_str_dbg(fsp)));
523 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
524 ea_list->ea.value.data, ea_list->ea.value.length, 0);
526 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
527 unix_ea_name, fname));
528 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
529 ea_list->ea.value.data, ea_list->ea.value.length, 0);
535 if (errno == ENOTSUP) {
536 return NT_STATUS_EAS_NOT_SUPPORTED;
539 return map_nt_error_from_unix(errno);
545 /****************************************************************************
546 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
547 ****************************************************************************/
549 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
551 struct ea_list *ea_list_head = NULL;
552 size_t converted_size, offset = 0;
554 while (offset + 2 < data_size) {
555 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
556 unsigned int namelen = CVAL(pdata,offset);
558 offset++; /* Go past the namelen byte. */
560 /* integer wrap paranioa. */
561 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
562 (offset > data_size) || (namelen > data_size) ||
563 (offset + namelen >= data_size)) {
566 /* Ensure the name is null terminated. */
567 if (pdata[offset + namelen] != '\0') {
570 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
572 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
573 "failed: %s", strerror(errno)));
579 offset += (namelen + 1); /* Go past the name + terminating zero. */
580 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
581 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
587 /****************************************************************************
588 Read one EA list entry from the buffer.
589 ****************************************************************************/
591 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
593 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
595 unsigned int namelen;
596 size_t converted_size;
606 eal->ea.flags = CVAL(pdata,0);
607 namelen = CVAL(pdata,1);
608 val_len = SVAL(pdata,2);
610 if (4 + namelen + 1 + val_len > data_size) {
614 /* Ensure the name is null terminated. */
615 if (pdata[namelen + 4] != '\0') {
618 if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
619 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
626 eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
627 if (!eal->ea.value.data) {
631 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
633 /* Ensure we're null terminated just in case we print the value. */
634 eal->ea.value.data[val_len] = '\0';
635 /* But don't count the null. */
636 eal->ea.value.length--;
639 *pbytes_used = 4 + namelen + 1 + val_len;
642 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
643 dump_data(10, eal->ea.value.data, eal->ea.value.length);
648 /****************************************************************************
649 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
650 ****************************************************************************/
652 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
654 struct ea_list *ea_list_head = NULL;
656 size_t bytes_used = 0;
658 while (offset < data_size) {
659 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
665 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
666 offset += bytes_used;
672 /****************************************************************************
673 Count the total EA size needed.
674 ****************************************************************************/
676 static size_t ea_list_size(struct ea_list *ealist)
679 struct ea_list *listp;
682 for (listp = ealist; listp; listp = listp->next) {
683 push_ascii_fstring(dos_ea_name, listp->ea.name);
684 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
686 /* Add on 4 for total length. */
694 /****************************************************************************
695 Return a union of EA's from a file list and a list of names.
696 The TALLOC context for the two lists *MUST* be identical as we steal
697 memory from one list to add to another. JRA.
698 ****************************************************************************/
700 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
702 struct ea_list *nlistp, *flistp;
704 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
705 for (flistp = file_list; flistp; flistp = flistp->next) {
706 if (strequal(nlistp->ea.name, flistp->ea.name)) {
712 /* Copy the data from this entry. */
713 nlistp->ea.flags = flistp->ea.flags;
714 nlistp->ea.value = flistp->ea.value;
717 nlistp->ea.flags = 0;
718 ZERO_STRUCT(nlistp->ea.value);
722 *total_ea_len = ea_list_size(name_list);
726 /****************************************************************************
727 Send the required number of replies back.
728 We assume all fields other than the data fields are
729 set correctly for the type of call.
730 HACK ! Always assumes smb_setup field is zero.
731 ****************************************************************************/
733 void send_trans2_replies(connection_struct *conn,
734 struct smb_request *req,
741 /* As we are using a protocol > LANMAN1 then the max_send
742 variable must have been set in the sessetupX call.
743 This takes precedence over the max_xmit field in the
744 global struct. These different max_xmit variables should
745 be merged as this is now too confusing */
747 int data_to_send = datasize;
748 int params_to_send = paramsize;
750 const char *pp = params;
751 const char *pd = pdata;
752 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
753 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
754 int data_alignment_offset = 0;
755 bool overflow = False;
756 struct smbd_server_connection *sconn = smbd_server_conn;
757 int max_send = sconn->smb1.sessions.max_send;
759 /* Modify the data_to_send and datasize and set the error if
760 we're trying to send more than max_data_bytes. We still send
761 the part of the packet(s) that fit. Strange, but needed
764 if (max_data_bytes > 0 && datasize > max_data_bytes) {
765 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
766 max_data_bytes, datasize ));
767 datasize = data_to_send = max_data_bytes;
771 /* If there genuinely are no parameters or data to send just send the empty packet */
773 if(params_to_send == 0 && data_to_send == 0) {
774 reply_outbuf(req, 10, 0);
775 show_msg((char *)req->outbuf);
776 if (!srv_send_smb(smbd_server_fd(),
779 IS_CONN_ENCRYPTED(conn),
781 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
783 TALLOC_FREE(req->outbuf);
787 /* When sending params and data ensure that both are nicely aligned */
788 /* Only do this alignment when there is also data to send - else
789 can cause NT redirector problems. */
791 if (((params_to_send % 4) != 0) && (data_to_send != 0))
792 data_alignment_offset = 4 - (params_to_send % 4);
794 /* Space is bufsize minus Netbios over TCP header minus SMB header */
795 /* The alignment_offset is to align the param bytes on an even byte
796 boundary. NT 4.0 Beta needs this to work correctly. */
798 useable_space = max_send - (smb_size
801 + data_alignment_offset);
803 if (useable_space < 0) {
804 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
805 "= %d!!!", useable_space));
806 exit_server_cleanly("send_trans2_replies: Not enough space");
809 while (params_to_send || data_to_send) {
810 /* Calculate whether we will totally or partially fill this packet */
812 total_sent_thistime = params_to_send + data_to_send;
814 /* We can never send more than useable_space */
816 * Note that 'useable_space' does not include the alignment offsets,
817 * but we must include the alignment offsets in the calculation of
818 * the length of the data we send over the wire, as the alignment offsets
819 * are sent here. Fix from Marc_Jacobsen@hp.com.
822 total_sent_thistime = MIN(total_sent_thistime, useable_space);
824 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
825 + data_alignment_offset);
828 * We might have SMBtrans2s in req which was transferred to
829 * the outbuf, fix that.
831 SCVAL(req->outbuf, smb_com, SMBtrans2);
833 /* Set total params and data to be sent */
834 SSVAL(req->outbuf,smb_tprcnt,paramsize);
835 SSVAL(req->outbuf,smb_tdrcnt,datasize);
837 /* Calculate how many parameters and data we can fit into
838 * this packet. Parameters get precedence
841 params_sent_thistime = MIN(params_to_send,useable_space);
842 data_sent_thistime = useable_space - params_sent_thistime;
843 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
845 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
847 /* smb_proff is the offset from the start of the SMB header to the
848 parameter bytes, however the first 4 bytes of outbuf are
849 the Netbios over TCP header. Thus use smb_base() to subtract
850 them from the calculation */
852 SSVAL(req->outbuf,smb_proff,
853 ((smb_buf(req->outbuf)+alignment_offset)
854 - smb_base(req->outbuf)));
856 if(params_sent_thistime == 0)
857 SSVAL(req->outbuf,smb_prdisp,0);
859 /* Absolute displacement of param bytes sent in this packet */
860 SSVAL(req->outbuf,smb_prdisp,pp - params);
862 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
863 if(data_sent_thistime == 0) {
864 SSVAL(req->outbuf,smb_droff,0);
865 SSVAL(req->outbuf,smb_drdisp, 0);
867 /* The offset of the data bytes is the offset of the
868 parameter bytes plus the number of parameters being sent this time */
869 SSVAL(req->outbuf, smb_droff,
870 ((smb_buf(req->outbuf)+alignment_offset)
871 - smb_base(req->outbuf))
872 + params_sent_thistime + data_alignment_offset);
873 SSVAL(req->outbuf,smb_drdisp, pd - pdata);
876 /* Initialize the padding for alignment */
878 if (alignment_offset != 0) {
879 memset(smb_buf(req->outbuf), 0, alignment_offset);
882 /* Copy the param bytes into the packet */
884 if(params_sent_thistime) {
885 memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
886 params_sent_thistime);
889 /* Copy in the data bytes */
890 if(data_sent_thistime) {
891 if (data_alignment_offset != 0) {
892 memset((smb_buf(req->outbuf)+alignment_offset+
893 params_sent_thistime), 0,
894 data_alignment_offset);
896 memcpy(smb_buf(req->outbuf)+alignment_offset
897 +params_sent_thistime+data_alignment_offset,
898 pd,data_sent_thistime);
901 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
902 params_sent_thistime, data_sent_thistime, useable_space));
903 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
904 params_to_send, data_to_send, paramsize, datasize));
907 error_packet_set((char *)req->outbuf,
908 ERRDOS,ERRbufferoverflow,
909 STATUS_BUFFER_OVERFLOW,
913 /* Send the packet */
914 show_msg((char *)req->outbuf);
915 if (!srv_send_smb(smbd_server_fd(),
918 IS_CONN_ENCRYPTED(conn),
920 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
922 TALLOC_FREE(req->outbuf);
924 pp += params_sent_thistime;
925 pd += data_sent_thistime;
927 params_to_send -= params_sent_thistime;
928 data_to_send -= data_sent_thistime;
931 if(params_to_send < 0 || data_to_send < 0) {
932 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
933 params_to_send, data_to_send));
941 /****************************************************************************
942 Reply to a TRANSACT2_OPEN.
943 ****************************************************************************/
945 static void call_trans2open(connection_struct *conn,
946 struct smb_request *req,
947 char **pparams, int total_params,
948 char **ppdata, int total_data,
949 unsigned int max_data_bytes)
951 struct smb_filename *smb_fname = NULL;
952 char *params = *pparams;
953 char *pdata = *ppdata;
958 bool return_additional_info;
971 struct ea_list *ea_list = NULL;
976 uint32 create_disposition;
977 uint32 create_options = 0;
978 TALLOC_CTX *ctx = talloc_tos();
981 * Ensure we have enough parameters to perform the operation.
984 if (total_params < 29) {
985 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
989 flags = SVAL(params, 0);
990 deny_mode = SVAL(params, 2);
991 open_attr = SVAL(params,6);
992 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
993 if (oplock_request) {
994 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
998 return_additional_info = BITSETW(params,0);
999 open_sattr = SVAL(params, 4);
1000 open_time = make_unix_date3(params+8);
1002 open_ofun = SVAL(params,12);
1003 open_size = IVAL(params,14);
1004 pname = ¶ms[28];
1007 reply_doserror(req, ERRSRV, ERRaccess);
1011 srvstr_get_path(ctx, params, req->flags2, &fname, pname,
1012 total_params - 28, STR_TERMINATE,
1014 if (!NT_STATUS_IS_OK(status)) {
1015 reply_nterror(req, status);
1019 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1020 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
1021 (unsigned int)open_ofun, open_size));
1023 status = filename_convert(ctx,
1025 req->flags2 & FLAGS2_DFS_PATHNAMES,
1030 if (!NT_STATUS_IS_OK(status)) {
1031 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1032 reply_botherror(req,
1033 NT_STATUS_PATH_NOT_COVERED,
1034 ERRSRV, ERRbadpath);
1037 reply_nterror(req, status);
1041 if (open_ofun == 0) {
1042 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
1046 if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun,
1047 &access_mask, &share_mode,
1048 &create_disposition,
1050 reply_doserror(req, ERRDOS, ERRbadaccess);
1054 /* Any data in this call is an EA list. */
1055 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
1056 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1060 if (total_data != 4) {
1061 if (total_data < 10) {
1062 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1066 if (IVAL(pdata,0) > total_data) {
1067 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1068 IVAL(pdata,0), (unsigned int)total_data));
1069 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1073 ea_list = read_ea_list(talloc_tos(), pdata + 4,
1076 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1079 } else if (IVAL(pdata,0) != 4) {
1080 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1084 status = SMB_VFS_CREATE_FILE(
1087 0, /* root_dir_fid */
1088 smb_fname, /* fname */
1089 access_mask, /* access_mask */
1090 share_mode, /* share_access */
1091 create_disposition, /* create_disposition*/
1092 create_options, /* create_options */
1093 open_attr, /* file_attributes */
1094 oplock_request, /* oplock_request */
1095 open_size, /* allocation_size */
1097 ea_list, /* ea_list */
1099 &smb_action); /* psbuf */
1101 if (!NT_STATUS_IS_OK(status)) {
1102 if (open_was_deferred(req->mid)) {
1103 /* We have re-scheduled this call. */
1106 reply_openerror(req, status);
1110 size = get_file_size_stat(&smb_fname->st);
1111 fattr = dos_mode(conn, smb_fname);
1112 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1113 inode = smb_fname->st.st_ex_ino;
1115 close_file(req, fsp, ERROR_CLOSE);
1116 reply_doserror(req, ERRDOS,ERRnoaccess);
1120 /* Realloc the size of parameters and data we will return */
1121 *pparams = (char *)SMB_REALLOC(*pparams, 30);
1122 if(*pparams == NULL ) {
1123 reply_nterror(req, NT_STATUS_NO_MEMORY);
1128 SSVAL(params,0,fsp->fnum);
1129 SSVAL(params,2,fattr);
1130 srv_put_dos_date2(params,4, mtime);
1131 SIVAL(params,8, (uint32)size);
1132 SSVAL(params,12,deny_mode);
1133 SSVAL(params,14,0); /* open_type - file or directory. */
1134 SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1136 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1137 smb_action |= EXTENDED_OPLOCK_GRANTED;
1140 SSVAL(params,18,smb_action);
1143 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1145 SIVAL(params,20,inode);
1146 SSVAL(params,24,0); /* Padding. */
1148 uint32 ea_size = estimate_ea_size(conn, fsp,
1149 fsp->fsp_name->base_name);
1150 SIVAL(params, 26, ea_size);
1152 SIVAL(params, 26, 0);
1155 /* Send the required number of replies */
1156 send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
1158 TALLOC_FREE(smb_fname);
1161 /*********************************************************
1162 Routine to check if a given string matches exactly.
1163 as a special case a mask of "." does NOT match. That
1164 is required for correct wildcard semantics
1165 Case can be significant or not.
1166 **********************************************************/
1168 static bool exact_match(connection_struct *conn,
1172 if (mask[0] == '.' && mask[1] == 0)
1174 if (dptr_has_wild(conn->dirptr)) {
1177 if (conn->case_sensitive)
1178 return strcmp(str,mask)==0;
1180 return StrCaseCmp(str,mask) == 0;
1183 /****************************************************************************
1184 Return the filetype for UNIX extensions.
1185 ****************************************************************************/
1187 static uint32 unix_filetype(mode_t mode)
1190 return UNIX_TYPE_FILE;
1191 else if(S_ISDIR(mode))
1192 return UNIX_TYPE_DIR;
1194 else if(S_ISLNK(mode))
1195 return UNIX_TYPE_SYMLINK;
1198 else if(S_ISCHR(mode))
1199 return UNIX_TYPE_CHARDEV;
1202 else if(S_ISBLK(mode))
1203 return UNIX_TYPE_BLKDEV;
1206 else if(S_ISFIFO(mode))
1207 return UNIX_TYPE_FIFO;
1210 else if(S_ISSOCK(mode))
1211 return UNIX_TYPE_SOCKET;
1214 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1215 return UNIX_TYPE_UNKNOWN;
1218 /****************************************************************************
1219 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1220 ****************************************************************************/
1222 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1224 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1225 const SMB_STRUCT_STAT *psbuf,
1227 enum perm_type ptype,
1232 if (perms == SMB_MODE_NO_CHANGE) {
1233 if (!VALID_STAT(*psbuf)) {
1234 return NT_STATUS_INVALID_PARAMETER;
1236 *ret_perms = psbuf->st_ex_mode;
1237 return NT_STATUS_OK;
1241 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1242 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1243 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1244 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1245 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1246 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1247 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1248 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1249 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1251 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1254 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1257 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1262 /* Apply mode mask */
1263 ret &= lp_create_mask(SNUM(conn));
1264 /* Add in force bits */
1265 ret |= lp_force_create_mode(SNUM(conn));
1268 ret &= lp_dir_mask(SNUM(conn));
1269 /* Add in force bits */
1270 ret |= lp_force_dir_mode(SNUM(conn));
1272 case PERM_EXISTING_FILE:
1273 /* Apply mode mask */
1274 ret &= lp_security_mask(SNUM(conn));
1275 /* Add in force bits */
1276 ret |= lp_force_security_mode(SNUM(conn));
1278 case PERM_EXISTING_DIR:
1279 /* Apply mode mask */
1280 ret &= lp_dir_security_mask(SNUM(conn));
1281 /* Add in force bits */
1282 ret |= lp_force_dir_security_mode(SNUM(conn));
1287 return NT_STATUS_OK;
1290 /****************************************************************************
1291 Needed to show the msdfs symlinks as directories. Modifies psbuf
1292 to be a directory if it's a msdfs link.
1293 ****************************************************************************/
1295 static bool check_msdfs_link(connection_struct *conn,
1296 const char *pathname,
1297 SMB_STRUCT_STAT *psbuf)
1299 int saved_errno = errno;
1300 if(lp_host_msdfs() &&
1301 lp_msdfs_root(SNUM(conn)) &&
1302 is_msdfs_link(conn, pathname, psbuf)) {
1304 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1307 psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
1308 errno = saved_errno;
1311 errno = saved_errno;
1316 /****************************************************************************
1317 Get a level dependent lanman2 dir entry.
1318 ****************************************************************************/
1320 static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
1321 connection_struct *conn,
1323 const char *path_mask,
1326 int requires_resume_key,
1332 int space_remaining,
1334 bool *got_exact_match,
1335 int *last_entry_off,
1336 struct ea_list *name_list)
1340 SMB_STRUCT_STAT sbuf;
1341 const char *mask = NULL;
1342 char *pathreal = NULL;
1344 char *p, *q, *pdata = *ppdata;
1348 SMB_OFF_T file_size = 0;
1349 uint64_t allocation_size = 0;
1351 struct timespec mdate_ts, adate_ts, create_date_ts;
1352 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1354 char *last_entry_ptr;
1356 uint32 nt_extmode; /* Used for NT connections instead of mode */
1357 bool needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1358 bool check_mangled_names = lp_manglednames(conn->params);
1359 char mangled_name[13]; /* mangled 8.3 name. */
1361 *out_of_space = False;
1362 *got_exact_match = False;
1364 ZERO_STRUCT(mdate_ts);
1365 ZERO_STRUCT(adate_ts);
1366 ZERO_STRUCT(create_date_ts);
1368 if (!conn->dirptr) {
1372 p = strrchr_m(path_mask,'/');
1375 mask = talloc_strdup(ctx,"*.*");
1385 bool ms_dfs_link = False;
1387 /* Needed if we run out of space */
1388 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1389 dname = dptr_ReadDirName(ctx,conn->dirptr,&curr_dirpos,&sbuf);
1392 * Due to bugs in NT client redirectors we are not using
1393 * resume keys any more - set them to zero.
1394 * Check out the related comments in findfirst/findnext.
1400 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1401 (long)conn->dirptr,curr_dirpos));
1408 * fname may get mangled, dname is never mangled.
1409 * Whenever we're accessing the filesystem we use
1410 * pathreal which is composed from dname.
1416 /* Mangle fname if it's an illegal name. */
1417 if (mangle_must_mangle(dname,conn->params)) {
1418 if (!name_to_8_3(dname,mangled_name,True,conn->params)) {
1420 continue; /* Error - couldn't mangle. */
1422 fname = talloc_strdup(ctx, mangled_name);
1428 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
1429 got_match = mask_match(fname, mask, conn->case_sensitive);
1432 if(!got_match && check_mangled_names &&
1433 !mangle_is_8_3(fname, False, conn->params)) {
1435 * It turns out that NT matches wildcards against
1436 * both long *and* short names. This may explain some
1437 * of the wildcard wierdness from old DOS clients
1438 * that some people have been seeing.... JRA.
1440 /* Force the mangling into 8.3. */
1441 if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
1443 continue; /* Error - couldn't mangle. */
1446 if(!(got_match = *got_exact_match = exact_match(conn, mangled_name, mask))) {
1447 got_match = mask_match(mangled_name, mask, conn->case_sensitive);
1452 bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
1453 struct smb_filename *smb_fname = NULL;
1456 if (dont_descend && !isdots) {
1463 pathreal = talloc_asprintf(ctx,
1468 pathreal = talloc_asprintf(ctx,
1479 /* A dirent from dptr_ReadDirName isn't a stream. */
1480 status = create_synthetic_smb_fname(ctx, pathreal,
1483 if (!NT_STATUS_IS_OK(status)) {
1488 if (INFO_LEVEL_IS_UNIX(info_level)) {
1489 if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
1490 DEBUG(5,("get_lanman2_dir_entry: "
1491 "Couldn't lstat [%s] (%s)\n",
1492 smb_fname_str_dbg(smb_fname),
1494 TALLOC_FREE(smb_fname);
1495 TALLOC_FREE(pathreal);
1499 } else if (!VALID_STAT(smb_fname->st) &&
1500 SMB_VFS_STAT(conn, smb_fname) != 0) {
1501 /* Needed to show the msdfs symlinks as
1505 check_msdfs_link(conn,
1506 smb_fname->base_name,
1509 DEBUG(5,("get_lanman2_dir_entry: "
1510 "Couldn't stat [%s] (%s)\n",
1511 smb_fname_str_dbg(smb_fname),
1513 TALLOC_FREE(smb_fname);
1514 TALLOC_FREE(pathreal);
1521 mode = dos_mode_msdfs(conn, smb_fname);
1523 mode = dos_mode(conn, smb_fname);
1526 if (!dir_check_ftype(conn,mode,dirtype)) {
1527 DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
1528 TALLOC_FREE(smb_fname);
1529 TALLOC_FREE(pathreal);
1534 if (!(mode & aDIR)) {
1535 file_size = get_file_size_stat(&smb_fname->st);
1538 SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
1540 if (ask_sharemode) {
1541 struct timespec write_time_ts;
1542 struct file_id fileid;
1544 ZERO_STRUCT(write_time_ts);
1545 fileid = vfs_file_id_from_sbuf(conn,
1547 get_file_infos(fileid, NULL, &write_time_ts);
1548 if (!null_timespec(write_time_ts)) {
1549 update_stat_ex_mtime(&smb_fname->st,
1554 mdate_ts = smb_fname->st.st_ex_mtime;
1555 adate_ts = smb_fname->st.st_ex_atime;
1556 create_date_ts = smb_fname->st.st_ex_btime;
1558 if (lp_dos_filetime_resolution(SNUM(conn))) {
1559 dos_filetime_timespec(&create_date_ts);
1560 dos_filetime_timespec(&mdate_ts);
1561 dos_filetime_timespec(&adate_ts);
1564 create_date = convert_timespec_to_time_t(create_date_ts);
1565 mdate = convert_timespec_to_time_t(mdate_ts);
1566 adate = convert_timespec_to_time_t(adate_ts);
1568 DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",
1569 smb_fname_str_dbg(smb_fname), fname));
1573 dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1574 sbuf = smb_fname->st;
1576 TALLOC_FREE(smb_fname);
1586 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1588 switch (info_level) {
1589 case SMB_FIND_INFO_STANDARD:
1590 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1591 if(requires_resume_key) {
1595 srv_put_dos_date2(p,0,create_date);
1596 srv_put_dos_date2(p,4,adate);
1597 srv_put_dos_date2(p,8,mdate);
1598 SIVAL(p,12,(uint32)file_size);
1599 SIVAL(p,16,(uint32)allocation_size);
1603 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1604 p += ucs2_align(base_data, p, 0);
1606 len = srvstr_push(base_data, flags2, p,
1607 fname, PTR_DIFF(end_data, p),
1609 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1611 SCVAL(nameptr, -1, len - 2);
1613 SCVAL(nameptr, -1, 0);
1617 SCVAL(nameptr, -1, len - 1);
1619 SCVAL(nameptr, -1, 0);
1625 case SMB_FIND_EA_SIZE:
1626 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1627 if(requires_resume_key) {
1631 srv_put_dos_date2(p,0,create_date);
1632 srv_put_dos_date2(p,4,adate);
1633 srv_put_dos_date2(p,8,mdate);
1634 SIVAL(p,12,(uint32)file_size);
1635 SIVAL(p,16,(uint32)allocation_size);
1638 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1639 SIVAL(p,22,ea_size); /* Extended attributes */
1643 len = srvstr_push(base_data, flags2,
1644 p, fname, PTR_DIFF(end_data, p),
1645 STR_TERMINATE | STR_NOALIGN);
1646 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1659 SCVAL(nameptr,0,len);
1661 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1664 case SMB_FIND_EA_LIST:
1666 struct ea_list *file_list = NULL;
1669 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1673 if(requires_resume_key) {
1677 srv_put_dos_date2(p,0,create_date);
1678 srv_put_dos_date2(p,4,adate);
1679 srv_put_dos_date2(p,8,mdate);
1680 SIVAL(p,12,(uint32)file_size);
1681 SIVAL(p,16,(uint32)allocation_size);
1683 p += 22; /* p now points to the EA area. */
1685 file_list = get_ea_list_from_file(ctx, conn, NULL, pathreal, &ea_len);
1686 name_list = ea_list_union(name_list, file_list, &ea_len);
1688 /* We need to determine if this entry will fit in the space available. */
1689 /* Max string size is 255 bytes. */
1690 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1691 /* Move the dirptr back to prev_dirpos */
1692 dptr_SeekDir(conn->dirptr, prev_dirpos);
1693 *out_of_space = True;
1694 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1695 return False; /* Not finished - just out of space */
1698 /* Push the ea_data followed by the name. */
1699 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1701 len = srvstr_push(base_data, flags2,
1702 p + 1, fname, PTR_DIFF(end_data, p+1),
1703 STR_TERMINATE | STR_NOALIGN);
1704 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1717 SCVAL(nameptr,0,len);
1719 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1723 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1724 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1725 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1727 SIVAL(p,0,reskey); p += 4;
1728 put_long_date_timespec(p,create_date_ts); p += 8;
1729 put_long_date_timespec(p,adate_ts); p += 8;
1730 put_long_date_timespec(p,mdate_ts); p += 8;
1731 put_long_date_timespec(p,mdate_ts); p += 8;
1732 SOFF_T(p,0,file_size); p += 8;
1733 SOFF_T(p,0,allocation_size); p += 8;
1734 SIVAL(p,0,nt_extmode); p += 4;
1735 q = p; p += 4; /* q is placeholder for name length. */
1737 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1738 SIVAL(p,0,ea_size); /* Extended attributes */
1741 /* Clear the short name buffer. This is
1742 * IMPORTANT as not doing so will trigger
1743 * a Win2k client bug. JRA.
1745 if (!was_8_3 && check_mangled_names) {
1746 if (!name_to_8_3(fname,mangled_name,True,
1748 /* Error - mangle failed ! */
1749 memset(mangled_name,'\0',12);
1751 mangled_name[12] = 0;
1752 len = srvstr_push(base_data, flags2,
1753 p+2, mangled_name, 24,
1754 STR_UPPER|STR_UNICODE);
1756 memset(p + 2 + len,'\0',24 - len);
1763 len = srvstr_push(base_data, flags2, p,
1764 fname, PTR_DIFF(end_data, p),
1765 STR_TERMINATE_ASCII);
1768 SIVAL(p,0,0); /* Ensure any padding is null. */
1769 len = PTR_DIFF(p, pdata);
1770 len = (len + 3) & ~3;
1775 case SMB_FIND_FILE_DIRECTORY_INFO:
1776 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1778 SIVAL(p,0,reskey); p += 4;
1779 put_long_date_timespec(p,create_date_ts); p += 8;
1780 put_long_date_timespec(p,adate_ts); p += 8;
1781 put_long_date_timespec(p,mdate_ts); p += 8;
1782 put_long_date_timespec(p,mdate_ts); p += 8;
1783 SOFF_T(p,0,file_size); p += 8;
1784 SOFF_T(p,0,allocation_size); p += 8;
1785 SIVAL(p,0,nt_extmode); p += 4;
1786 len = srvstr_push(base_data, flags2,
1787 p + 4, fname, PTR_DIFF(end_data, p+4),
1788 STR_TERMINATE_ASCII);
1791 SIVAL(p,0,0); /* Ensure any padding is null. */
1792 len = PTR_DIFF(p, pdata);
1793 len = (len + 3) & ~3;
1798 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1799 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1801 SIVAL(p,0,reskey); p += 4;
1802 put_long_date_timespec(p,create_date_ts); p += 8;
1803 put_long_date_timespec(p,adate_ts); p += 8;
1804 put_long_date_timespec(p,mdate_ts); p += 8;
1805 put_long_date_timespec(p,mdate_ts); p += 8;
1806 SOFF_T(p,0,file_size); p += 8;
1807 SOFF_T(p,0,allocation_size); p += 8;
1808 SIVAL(p,0,nt_extmode); p += 4;
1809 q = p; p += 4; /* q is placeholder for name length. */
1811 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1812 SIVAL(p,0,ea_size); /* Extended attributes */
1815 len = srvstr_push(base_data, flags2, p,
1816 fname, PTR_DIFF(end_data, p),
1817 STR_TERMINATE_ASCII);
1821 SIVAL(p,0,0); /* Ensure any padding is null. */
1822 len = PTR_DIFF(p, pdata);
1823 len = (len + 3) & ~3;
1828 case SMB_FIND_FILE_NAMES_INFO:
1829 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1831 SIVAL(p,0,reskey); p += 4;
1833 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1834 acl on a dir (tridge) */
1835 len = srvstr_push(base_data, flags2, p,
1836 fname, PTR_DIFF(end_data, p),
1837 STR_TERMINATE_ASCII);
1840 SIVAL(p,0,0); /* Ensure any padding is null. */
1841 len = PTR_DIFF(p, pdata);
1842 len = (len + 3) & ~3;
1847 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1848 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1850 SIVAL(p,0,reskey); p += 4;
1851 put_long_date_timespec(p,create_date_ts); p += 8;
1852 put_long_date_timespec(p,adate_ts); p += 8;
1853 put_long_date_timespec(p,mdate_ts); p += 8;
1854 put_long_date_timespec(p,mdate_ts); p += 8;
1855 SOFF_T(p,0,file_size); p += 8;
1856 SOFF_T(p,0,allocation_size); p += 8;
1857 SIVAL(p,0,nt_extmode); p += 4;
1858 q = p; p += 4; /* q is placeholder for name length. */
1860 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1861 SIVAL(p,0,ea_size); /* Extended attributes */
1864 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1865 SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
1866 SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
1867 len = srvstr_push(base_data, flags2, p,
1868 fname, PTR_DIFF(end_data, p),
1869 STR_TERMINATE_ASCII);
1872 SIVAL(p,0,0); /* Ensure any padding is null. */
1873 len = PTR_DIFF(p, pdata);
1874 len = (len + 3) & ~3;
1879 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1880 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1881 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1883 SIVAL(p,0,reskey); p += 4;
1884 put_long_date_timespec(p,create_date_ts); p += 8;
1885 put_long_date_timespec(p,adate_ts); p += 8;
1886 put_long_date_timespec(p,mdate_ts); p += 8;
1887 put_long_date_timespec(p,mdate_ts); p += 8;
1888 SOFF_T(p,0,file_size); p += 8;
1889 SOFF_T(p,0,allocation_size); p += 8;
1890 SIVAL(p,0,nt_extmode); p += 4;
1891 q = p; p += 4; /* q is placeholder for name length */
1893 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1894 SIVAL(p,0,ea_size); /* Extended attributes */
1897 /* Clear the short name buffer. This is
1898 * IMPORTANT as not doing so will trigger
1899 * a Win2k client bug. JRA.
1901 if (!was_8_3 && check_mangled_names) {
1902 if (!name_to_8_3(fname,mangled_name,True,
1904 /* Error - mangle failed ! */
1905 memset(mangled_name,'\0',12);
1907 mangled_name[12] = 0;
1908 len = srvstr_push(base_data, flags2,
1909 p+2, mangled_name, 24,
1910 STR_UPPER|STR_UNICODE);
1913 memset(p + 2 + len,'\0',24 - len);
1920 SSVAL(p,0,0); p += 2; /* Reserved ? */
1921 SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
1922 SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
1923 len = srvstr_push(base_data, flags2, p,
1924 fname, PTR_DIFF(end_data, p),
1925 STR_TERMINATE_ASCII);
1928 SIVAL(p,0,0); /* Ensure any padding is null. */
1929 len = PTR_DIFF(p, pdata);
1930 len = (len + 3) & ~3;
1935 /* CIFS UNIX Extension. */
1937 case SMB_FIND_FILE_UNIX:
1938 case SMB_FIND_FILE_UNIX_INFO2:
1940 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1942 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1944 if (info_level == SMB_FIND_FILE_UNIX) {
1945 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1946 p = store_file_unix_basic(conn, p,
1948 len = srvstr_push(base_data, flags2, p,
1949 fname, PTR_DIFF(end_data, p),
1952 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1953 p = store_file_unix_basic_info2(conn, p,
1957 len = srvstr_push(base_data, flags2, p, fname,
1958 PTR_DIFF(end_data, p), 0);
1959 SIVAL(nameptr, 0, len);
1963 SIVAL(p,0,0); /* Ensure any padding is null. */
1965 len = PTR_DIFF(p, pdata);
1966 len = (len + 3) & ~3;
1967 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1969 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1979 if (PTR_DIFF(p,pdata) > space_remaining) {
1980 /* Move the dirptr back to prev_dirpos */
1981 dptr_SeekDir(conn->dirptr, prev_dirpos);
1982 *out_of_space = True;
1983 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1984 return False; /* Not finished - just out of space */
1987 /* Setup the last entry pointer, as an offset from base_data */
1988 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1989 /* Advance the data pointer to the next slot */
1995 /****************************************************************************
1996 Reply to a TRANS2_FINDFIRST.
1997 ****************************************************************************/
1999 static void call_trans2findfirst(connection_struct *conn,
2000 struct smb_request *req,
2001 char **pparams, int total_params,
2002 char **ppdata, int total_data,
2003 unsigned int max_data_bytes)
2005 /* We must be careful here that we don't return more than the
2006 allowed number of data bytes. If this means returning fewer than
2007 maxentries then so be it. We assume that the redirector has
2008 enough room for the fixed number of parameter bytes it has
2010 struct smb_filename *smb_dname = NULL;
2011 char *params = *pparams;
2012 char *pdata = *ppdata;
2016 uint16 findfirst_flags;
2017 bool close_after_first;
2019 bool requires_resume_key;
2021 char *directory = NULL;
2024 int last_entry_off=0;
2028 bool finished = False;
2029 bool dont_descend = False;
2030 bool out_of_space = False;
2031 int space_remaining;
2032 bool mask_contains_wcard = False;
2033 struct ea_list *ea_list = NULL;
2034 NTSTATUS ntstatus = NT_STATUS_OK;
2035 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2036 TALLOC_CTX *ctx = talloc_tos();
2038 if (total_params < 13) {
2039 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2043 dirtype = SVAL(params,0);
2044 maxentries = SVAL(params,2);
2045 findfirst_flags = SVAL(params,4);
2046 close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
2047 close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2048 requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2049 info_level = SVAL(params,6);
2051 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2052 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
2053 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
2054 info_level, max_data_bytes));
2057 /* W2K3 seems to treat zero as 1. */
2061 switch (info_level) {
2062 case SMB_FIND_INFO_STANDARD:
2063 case SMB_FIND_EA_SIZE:
2064 case SMB_FIND_EA_LIST:
2065 case SMB_FIND_FILE_DIRECTORY_INFO:
2066 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2067 case SMB_FIND_FILE_NAMES_INFO:
2068 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2069 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2070 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2072 case SMB_FIND_FILE_UNIX:
2073 case SMB_FIND_FILE_UNIX_INFO2:
2074 /* Always use filesystem for UNIX mtime query. */
2075 ask_sharemode = false;
2076 if (!lp_unix_extensions()) {
2077 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2082 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2086 srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
2087 params+12, total_params - 12,
2088 STR_TERMINATE, &ntstatus, &mask_contains_wcard);
2089 if (!NT_STATUS_IS_OK(ntstatus)) {
2090 reply_nterror(req, ntstatus);
2094 ntstatus = filename_convert(ctx, conn,
2095 req->flags2 & FLAGS2_DFS_PATHNAMES,
2098 UCF_ALWAYS_ALLOW_WCARD_LCOMP),
2099 &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 mask = smb_dname->original_lcomp;
2113 directory = smb_dname->base_name;
2115 p = strrchr_m(directory,'/');
2117 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2118 if((directory[0] == '.') && (directory[1] == '\0')) {
2119 mask = talloc_strdup(ctx,"*");
2121 reply_nterror(req, NT_STATUS_NO_MEMORY);
2124 mask_contains_wcard = True;
2126 directory = talloc_strdup(talloc_tos(), "./");
2128 reply_nterror(req, NT_STATUS_NO_MEMORY);
2135 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2137 if (info_level == SMB_FIND_EA_LIST) {
2140 if (total_data < 4) {
2141 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2145 ea_size = IVAL(pdata,0);
2146 if (ea_size != total_data) {
2147 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2148 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2149 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2153 if (!lp_ea_support(SNUM(conn))) {
2154 reply_doserror(req, ERRDOS, ERReasnotsupported);
2158 /* Pull out the list of names. */
2159 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2161 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2166 *ppdata = (char *)SMB_REALLOC(
2167 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2168 if(*ppdata == NULL ) {
2169 reply_nterror(req, NT_STATUS_NO_MEMORY);
2173 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2175 /* Realloc the params space */
2176 *pparams = (char *)SMB_REALLOC(*pparams, 10);
2177 if (*pparams == NULL) {
2178 reply_nterror(req, NT_STATUS_NO_MEMORY);
2183 /* Save the wildcard match and attribs we are using on this directory -
2184 needed as lanman2 assumes these are being saved between calls */
2186 ntstatus = dptr_create(conn,
2192 mask_contains_wcard,
2196 if (!NT_STATUS_IS_OK(ntstatus)) {
2197 reply_nterror(req, ntstatus);
2201 dptr_num = dptr_dnum(conn->dirptr);
2202 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2204 /* Initialize per TRANS2_FIND_FIRST operation data */
2205 dptr_init_search_op(conn->dirptr);
2207 /* We don't need to check for VOL here as this is returned by
2208 a different TRANS2 call. */
2210 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
2211 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2212 dont_descend = True;
2215 space_remaining = max_data_bytes;
2216 out_of_space = False;
2218 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2219 bool got_exact_match = False;
2221 /* this is a heuristic to avoid seeking the dirptr except when
2222 absolutely necessary. It allows for a filename of about 40 chars */
2223 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2224 out_of_space = True;
2227 finished = !get_lanman2_dir_entry(ctx,
2230 mask,dirtype,info_level,
2231 requires_resume_key,dont_descend,
2234 space_remaining, &out_of_space,
2236 &last_entry_off, ea_list);
2239 if (finished && out_of_space)
2242 if (!finished && !out_of_space)
2246 * As an optimisation if we know we aren't looking
2247 * for a wildcard name (ie. the name matches the wildcard exactly)
2248 * then we can finish on any (first) match.
2249 * This speeds up large directory searches. JRA.
2255 /* Ensure space_remaining never goes -ve. */
2256 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2257 space_remaining = 0;
2258 out_of_space = true;
2260 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2264 /* Check if we can close the dirptr */
2265 if(close_after_first || (finished && close_if_end)) {
2266 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2267 dptr_close(&dptr_num);
2271 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2272 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2273 * the protocol level is less than NT1. Tested with smbclient. JRA.
2274 * This should fix the OS/2 client bug #2335.
2277 if(numentries == 0) {
2278 dptr_close(&dptr_num);
2279 if (Protocol < PROTOCOL_NT1) {
2280 reply_doserror(req, ERRDOS, ERRnofiles);
2283 reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2284 ERRDOS, ERRbadfile);
2289 /* At this point pdata points to numentries directory entries. */
2291 /* Set up the return parameter block */
2292 SSVAL(params,0,dptr_num);
2293 SSVAL(params,2,numentries);
2294 SSVAL(params,4,finished);
2295 SSVAL(params,6,0); /* Never an EA error */
2296 SSVAL(params,8,last_entry_off);
2298 send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
2301 if ((! *directory) && dptr_path(dptr_num)) {
2302 directory = talloc_strdup(talloc_tos(),dptr_path(dptr_num));
2304 reply_nterror(req, NT_STATUS_NO_MEMORY);
2308 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2309 smb_fn_name(req->cmd),
2310 mask, directory, dirtype, numentries ) );
2313 * Force a name mangle here to ensure that the
2314 * mask as an 8.3 name is top of the mangled cache.
2315 * The reasons for this are subtle. Don't remove
2316 * this code unless you know what you are doing
2317 * (see PR#13758). JRA.
2320 if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2321 char mangled_name[13];
2322 name_to_8_3(mask, mangled_name, True, conn->params);
2325 TALLOC_FREE(smb_dname);
2329 /****************************************************************************
2330 Reply to a TRANS2_FINDNEXT.
2331 ****************************************************************************/
2333 static void call_trans2findnext(connection_struct *conn,
2334 struct smb_request *req,
2335 char **pparams, int total_params,
2336 char **ppdata, int total_data,
2337 unsigned int max_data_bytes)
2339 /* We must be careful here that we don't return more than the
2340 allowed number of data bytes. If this means returning fewer than
2341 maxentries then so be it. We assume that the redirector has
2342 enough room for the fixed number of parameter bytes it has
2344 char *params = *pparams;
2345 char *pdata = *ppdata;
2351 uint16 findnext_flags;
2352 bool close_after_request;
2354 bool requires_resume_key;
2356 bool mask_contains_wcard = False;
2357 char *resume_name = NULL;
2358 const char *mask = NULL;
2359 const char *directory = NULL;
2363 int i, last_entry_off=0;
2364 bool finished = False;
2365 bool dont_descend = False;
2366 bool out_of_space = False;
2367 int space_remaining;
2368 struct ea_list *ea_list = NULL;
2369 NTSTATUS ntstatus = NT_STATUS_OK;
2370 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2371 TALLOC_CTX *ctx = talloc_tos();
2373 if (total_params < 13) {
2374 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2378 dptr_num = SVAL(params,0);
2379 maxentries = SVAL(params,2);
2380 info_level = SVAL(params,4);
2381 resume_key = IVAL(params,6);
2382 findnext_flags = SVAL(params,10);
2383 close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2384 close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2385 requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2386 continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2388 srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2390 total_params - 12, STR_TERMINATE, &ntstatus,
2391 &mask_contains_wcard);
2392 if (!NT_STATUS_IS_OK(ntstatus)) {
2393 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2394 complain (it thinks we're asking for the directory above the shared
2395 path or an invalid name). Catch this as the resume name is only compared, never used in
2396 a file access. JRA. */
2397 srvstr_pull_talloc(ctx, params, req->flags2,
2398 &resume_name, params+12,
2402 if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2403 reply_nterror(req, ntstatus);
2408 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2409 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2410 resume_key = %d resume name = %s continue=%d level = %d\n",
2411 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
2412 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
2415 /* W2K3 seems to treat zero as 1. */
2419 switch (info_level) {
2420 case SMB_FIND_INFO_STANDARD:
2421 case SMB_FIND_EA_SIZE:
2422 case SMB_FIND_EA_LIST:
2423 case SMB_FIND_FILE_DIRECTORY_INFO:
2424 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2425 case SMB_FIND_FILE_NAMES_INFO:
2426 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2427 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2428 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2430 case SMB_FIND_FILE_UNIX:
2431 case SMB_FIND_FILE_UNIX_INFO2:
2432 /* Always use filesystem for UNIX mtime query. */
2433 ask_sharemode = false;
2434 if (!lp_unix_extensions()) {
2435 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2440 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2444 if (info_level == SMB_FIND_EA_LIST) {
2447 if (total_data < 4) {
2448 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2452 ea_size = IVAL(pdata,0);
2453 if (ea_size != total_data) {
2454 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2455 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2456 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2460 if (!lp_ea_support(SNUM(conn))) {
2461 reply_doserror(req, ERRDOS, ERReasnotsupported);
2465 /* Pull out the list of names. */
2466 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2468 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2473 *ppdata = (char *)SMB_REALLOC(
2474 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2475 if(*ppdata == NULL) {
2476 reply_nterror(req, NT_STATUS_NO_MEMORY);
2481 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2483 /* Realloc the params space */
2484 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2485 if(*pparams == NULL ) {
2486 reply_nterror(req, NT_STATUS_NO_MEMORY);
2492 /* Check that the dptr is valid */
2493 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2494 reply_doserror(req, ERRDOS, ERRnofiles);
2498 string_set(&conn->dirpath,dptr_path(dptr_num));
2500 /* Get the wildcard mask from the dptr */
2501 if((p = dptr_wcard(dptr_num))== NULL) {
2502 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2503 reply_doserror(req, ERRDOS, ERRnofiles);
2508 directory = conn->dirpath;
2510 /* Get the attr mask from the dptr */
2511 dirtype = dptr_attr(dptr_num);
2513 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2514 dptr_num, mask, dirtype,
2516 dptr_TellDir(conn->dirptr)));
2518 /* Initialize per TRANS2_FIND_NEXT operation data */
2519 dptr_init_search_op(conn->dirptr);
2521 /* We don't need to check for VOL here as this is returned by
2522 a different TRANS2 call. */
2524 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2525 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2526 dont_descend = True;
2529 space_remaining = max_data_bytes;
2530 out_of_space = False;
2533 * Seek to the correct position. We no longer use the resume key but
2534 * depend on the last file name instead.
2537 if(*resume_name && !continue_bit) {
2540 long current_pos = 0;
2542 * Remember, name_to_8_3 is called by
2543 * get_lanman2_dir_entry(), so the resume name
2544 * could be mangled. Ensure we check the unmangled name.
2547 if (mangle_is_mangled(resume_name, conn->params)) {
2548 char *new_resume_name = NULL;
2549 mangle_lookup_name_from_8_3(ctx,
2553 if (new_resume_name) {
2554 resume_name = new_resume_name;
2559 * Fix for NT redirector problem triggered by resume key indexes
2560 * changing between directory scans. We now return a resume key of 0
2561 * and instead look for the filename to continue from (also given
2562 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2563 * findfirst/findnext (as is usual) then the directory pointer
2564 * should already be at the correct place.
2567 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
2568 } /* end if resume_name && !continue_bit */
2570 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2571 bool got_exact_match = False;
2573 /* this is a heuristic to avoid seeking the dirptr except when
2574 absolutely necessary. It allows for a filename of about 40 chars */
2575 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2576 out_of_space = True;
2579 finished = !get_lanman2_dir_entry(ctx,
2582 mask,dirtype,info_level,
2583 requires_resume_key,dont_descend,
2586 space_remaining, &out_of_space,
2588 &last_entry_off, ea_list);
2591 if (finished && out_of_space)
2594 if (!finished && !out_of_space)
2598 * As an optimisation if we know we aren't looking
2599 * for a wildcard name (ie. the name matches the wildcard exactly)
2600 * then we can finish on any (first) match.
2601 * This speeds up large directory searches. JRA.
2607 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2610 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2611 smb_fn_name(req->cmd),
2612 mask, directory, dirtype, numentries ) );
2614 /* Check if we can close the dirptr */
2615 if(close_after_request || (finished && close_if_end)) {
2616 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2617 dptr_close(&dptr_num); /* This frees up the saved mask */
2620 /* Set up the return parameter block */
2621 SSVAL(params,0,numentries);
2622 SSVAL(params,2,finished);
2623 SSVAL(params,4,0); /* Never an EA error */
2624 SSVAL(params,6,last_entry_off);
2626 send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
2632 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
2634 E_md4hash(lp_servicename(SNUM(conn)),objid);
2638 static void samba_extended_info_version(struct smb_extended_info *extended_info)
2640 SMB_ASSERT(extended_info != NULL);
2642 extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
2643 extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
2644 | ((SAMBA_VERSION_MINOR & 0xff) << 16)
2645 | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
2646 #ifdef SAMBA_VERSION_REVISION
2647 extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
2649 extended_info->samba_subversion = 0;
2650 #ifdef SAMBA_VERSION_RC_RELEASE
2651 extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
2653 #ifdef SAMBA_VERSION_PRE_RELEASE
2654 extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
2657 #ifdef SAMBA_VERSION_VENDOR_PATCH
2658 extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
2660 extended_info->samba_gitcommitdate = 0;
2661 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2662 unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
2665 memset(extended_info->samba_version_string, 0,
2666 sizeof(extended_info->samba_version_string));
2668 snprintf (extended_info->samba_version_string,
2669 sizeof(extended_info->samba_version_string),
2670 "%s", samba_version_string());
2673 NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
2674 TALLOC_CTX *mem_ctx,
2675 uint16_t info_level,
2677 unsigned int max_data_bytes,
2681 char *pdata, *end_data;
2682 int data_len = 0, len;
2683 const char *vname = volume_label(SNUM(conn));
2684 int snum = SNUM(conn);
2685 char *fstype = lp_fstype(SNUM(conn));
2686 uint32 additional_flags = 0;
2687 struct smb_filename *smb_fname_dot = NULL;
2692 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2693 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
2694 "info level (0x%x) on IPC$.\n",
2695 (unsigned int)info_level));
2696 return NT_STATUS_ACCESS_DENIED;
2700 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
2702 status = create_synthetic_smb_fname(talloc_tos(), ".", NULL, NULL,
2704 if (!NT_STATUS_IS_OK(status)) {
2708 if(SMB_VFS_STAT(conn, smb_fname_dot) != 0) {
2709 DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
2710 TALLOC_FREE(smb_fname_dot);
2711 return map_nt_error_from_unix(errno);
2714 st = smb_fname_dot->st;
2715 TALLOC_FREE(smb_fname_dot);
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 != sec_initial_uid()) {
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_ACCESS_DENIED;
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 map_nt_error_from_unix(errno);
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: