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"
30 extern enum protocol_types Protocol;
32 #define DIR_ENTRY_SAFETY_MARGIN 4096
34 static char *store_file_unix_basic(connection_struct *conn,
37 const SMB_STRUCT_STAT *psbuf);
39 static char *store_file_unix_basic_info2(connection_struct *conn,
42 const SMB_STRUCT_STAT *psbuf);
44 /********************************************************************
45 Roundup a value to the nearest allocation roundup size boundary.
46 Only do this for Windows clients.
47 ********************************************************************/
49 uint64_t smb_roundup(connection_struct *conn, uint64_t val)
51 uint64_t rval = lp_allocation_roundup_size(SNUM(conn));
53 /* Only roundup for Windows clients. */
54 enum remote_arch_types ra_type = get_remote_arch();
55 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
56 val = SMB_ROUNDUP(val,rval);
61 /****************************************************************************
62 Utility functions for dealing with extended attributes.
63 ****************************************************************************/
65 /****************************************************************************
66 Refuse to allow clients to overwrite our private xattrs.
67 ****************************************************************************/
69 static bool samba_private_attr_name(const char *unix_ea_name)
71 static const char * const prohibited_ea_names[] = {
72 SAMBA_POSIX_INHERITANCE_EA_NAME,
73 SAMBA_XATTR_DOS_ATTRIB,
79 for (i = 0; prohibited_ea_names[i]; i++) {
80 if (strequal( prohibited_ea_names[i], unix_ea_name))
83 if (StrnCaseCmp(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
84 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
90 /****************************************************************************
91 Get one EA value. Fill in a struct ea_struct.
92 ****************************************************************************/
94 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
95 files_struct *fsp, const char *fname,
96 const char *ea_name, struct ea_struct *pea)
98 /* Get the value of this xattr. Max size is 64k. */
99 size_t attr_size = 256;
105 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
107 return NT_STATUS_NO_MEMORY;
110 if (fsp && fsp->fh->fd != -1) {
111 sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
113 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
116 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
122 return map_nt_error_from_unix(errno);
125 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
126 dump_data(10, (uint8 *)val, sizeret);
129 if (strnequal(ea_name, "user.", 5)) {
130 pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
132 pea->name = talloc_strdup(mem_ctx, ea_name);
134 if (pea->name == NULL) {
136 return NT_STATUS_NO_MEMORY;
138 pea->value.data = (unsigned char *)val;
139 pea->value.length = (size_t)sizeret;
143 NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
144 files_struct *fsp, const char *fname,
145 char ***pnames, size_t *pnum_names)
147 /* Get a list of all xattrs. Max namesize is 64k. */
148 size_t ea_namelist_size = 1024;
149 char *ea_namelist = NULL;
154 ssize_t sizeret = -1;
156 if (!lp_ea_support(SNUM(conn))) {
163 * TALLOC the result early to get the talloc hierarchy right.
166 names = TALLOC_ARRAY(mem_ctx, char *, 1);
168 DEBUG(0, ("talloc failed\n"));
169 return NT_STATUS_NO_MEMORY;
172 while (ea_namelist_size <= 65536) {
174 ea_namelist = TALLOC_REALLOC_ARRAY(
175 names, ea_namelist, char, ea_namelist_size);
176 if (ea_namelist == NULL) {
177 DEBUG(0, ("talloc failed\n"));
179 return NT_STATUS_NO_MEMORY;
182 if (fsp && fsp->fh->fd != -1) {
183 sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
186 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist,
190 if ((sizeret == -1) && (errno == ERANGE)) {
191 ea_namelist_size *= 2;
200 return map_nt_error_from_unix(errno);
203 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
204 (unsigned int)sizeret));
214 * Ensure the result is 0-terminated
217 if (ea_namelist[sizeret-1] != '\0') {
219 return NT_STATUS_INTERNAL_ERROR;
227 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
231 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names);
233 DEBUG(0, ("talloc failed\n"));
235 return NT_STATUS_NO_MEMORY;
241 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
242 names[num_names++] = p;
246 *pnum_names = num_names;
250 /****************************************************************************
251 Return a linked list of the total EA's. Plus the total size
252 ****************************************************************************/
254 static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
255 const char *fname, size_t *pea_total_len)
257 /* Get a list of all xattrs. Max namesize is 64k. */
260 struct ea_list *ea_list_head = NULL;
265 if (!lp_ea_support(SNUM(conn))) {
269 status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
272 if (!NT_STATUS_IS_OK(status) || (num_names == 0)) {
276 for (i=0; i<num_names; i++) {
277 struct ea_list *listp;
280 if (strnequal(names[i], "system.", 7)
281 || samba_private_attr_name(names[i]))
284 listp = TALLOC_P(mem_ctx, struct ea_list);
289 if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx, conn, fsp,
295 push_ascii_fstring(dos_ea_name, listp->ea.name);
298 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
300 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
301 "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
302 (unsigned int)listp->ea.value.length));
304 DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
308 /* Add on 4 for total length. */
309 if (*pea_total_len) {
313 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
314 (unsigned int)*pea_total_len));
319 /****************************************************************************
320 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
322 ****************************************************************************/
324 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
325 connection_struct *conn, struct ea_list *ea_list)
327 unsigned int ret_data_size = 4;
330 SMB_ASSERT(total_data_size >= 4);
332 if (!lp_ea_support(SNUM(conn))) {
337 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
340 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
341 dos_namelen = strlen(dos_ea_name);
342 if (dos_namelen > 255 || dos_namelen == 0) {
345 if (ea_list->ea.value.length > 65535) {
348 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
352 /* We know we have room. */
353 SCVAL(p,0,ea_list->ea.flags);
354 SCVAL(p,1,dos_namelen);
355 SSVAL(p,2,ea_list->ea.value.length);
356 fstrcpy(p+4, dos_ea_name);
357 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
359 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
360 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
363 ret_data_size = PTR_DIFF(p, pdata);
364 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
365 SIVAL(pdata,0,ret_data_size);
366 return ret_data_size;
369 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
371 size_t total_ea_len = 0;
372 TALLOC_CTX *mem_ctx = NULL;
374 if (!lp_ea_support(SNUM(conn))) {
377 mem_ctx = talloc_tos();
378 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
382 /****************************************************************************
383 Ensure the EA name is case insensitive by matching any existing EA name.
384 ****************************************************************************/
386 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
389 TALLOC_CTX *mem_ctx = talloc_tos();
390 struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
392 for (; ea_list; ea_list = ea_list->next) {
393 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
394 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
395 &unix_ea_name[5], ea_list->ea.name));
396 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
402 /****************************************************************************
403 Set or delete an extended attribute.
404 ****************************************************************************/
406 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, struct ea_list *ea_list)
408 if (!lp_ea_support(SNUM(conn))) {
409 return NT_STATUS_EAS_NOT_SUPPORTED;
412 for (;ea_list; ea_list = ea_list->next) {
414 fstring unix_ea_name;
416 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
417 fstrcat(unix_ea_name, ea_list->ea.name);
419 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
421 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
423 if (samba_private_attr_name(unix_ea_name)) {
424 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
425 return NT_STATUS_ACCESS_DENIED;
428 if (ea_list->ea.value.length == 0) {
429 /* Remove the attribute. */
430 if (fsp && (fsp->fh->fd != -1)) {
431 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
432 unix_ea_name, fsp->fsp_name));
433 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
435 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
436 unix_ea_name, fname));
437 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
440 /* Removing a non existent attribute always succeeds. */
441 if (ret == -1 && errno == ENOATTR) {
442 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
448 if (fsp && (fsp->fh->fd != -1)) {
449 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
450 unix_ea_name, fsp->fsp_name));
451 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
452 ea_list->ea.value.data, ea_list->ea.value.length, 0);
454 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
455 unix_ea_name, fname));
456 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
457 ea_list->ea.value.data, ea_list->ea.value.length, 0);
463 if (errno == ENOTSUP) {
464 return NT_STATUS_EAS_NOT_SUPPORTED;
467 return map_nt_error_from_unix(errno);
473 /****************************************************************************
474 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
475 ****************************************************************************/
477 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
479 struct ea_list *ea_list_head = NULL;
480 size_t converted_size, offset = 0;
482 while (offset + 2 < data_size) {
483 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
484 unsigned int namelen = CVAL(pdata,offset);
486 offset++; /* Go past the namelen byte. */
488 /* integer wrap paranioa. */
489 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
490 (offset > data_size) || (namelen > data_size) ||
491 (offset + namelen >= data_size)) {
494 /* Ensure the name is null terminated. */
495 if (pdata[offset + namelen] != '\0') {
498 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
500 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
501 "failed: %s", strerror(errno)));
507 offset += (namelen + 1); /* Go past the name + terminating zero. */
508 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
509 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
515 /****************************************************************************
516 Read one EA list entry from the buffer.
517 ****************************************************************************/
519 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
521 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
523 unsigned int namelen;
524 size_t converted_size;
534 eal->ea.flags = CVAL(pdata,0);
535 namelen = CVAL(pdata,1);
536 val_len = SVAL(pdata,2);
538 if (4 + namelen + 1 + val_len > data_size) {
542 /* Ensure the name is null terminated. */
543 if (pdata[namelen + 4] != '\0') {
546 if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
547 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
554 eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
555 if (!eal->ea.value.data) {
559 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
561 /* Ensure we're null terminated just in case we print the value. */
562 eal->ea.value.data[val_len] = '\0';
563 /* But don't count the null. */
564 eal->ea.value.length--;
567 *pbytes_used = 4 + namelen + 1 + val_len;
570 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
571 dump_data(10, eal->ea.value.data, eal->ea.value.length);
576 /****************************************************************************
577 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
578 ****************************************************************************/
580 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
582 struct ea_list *ea_list_head = NULL;
584 size_t bytes_used = 0;
586 while (offset < data_size) {
587 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
593 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
594 offset += bytes_used;
600 /****************************************************************************
601 Count the total EA size needed.
602 ****************************************************************************/
604 static size_t ea_list_size(struct ea_list *ealist)
607 struct ea_list *listp;
610 for (listp = ealist; listp; listp = listp->next) {
611 push_ascii_fstring(dos_ea_name, listp->ea.name);
612 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
614 /* Add on 4 for total length. */
622 /****************************************************************************
623 Return a union of EA's from a file list and a list of names.
624 The TALLOC context for the two lists *MUST* be identical as we steal
625 memory from one list to add to another. JRA.
626 ****************************************************************************/
628 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
630 struct ea_list *nlistp, *flistp;
632 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
633 for (flistp = file_list; flistp; flistp = flistp->next) {
634 if (strequal(nlistp->ea.name, flistp->ea.name)) {
640 /* Copy the data from this entry. */
641 nlistp->ea.flags = flistp->ea.flags;
642 nlistp->ea.value = flistp->ea.value;
645 nlistp->ea.flags = 0;
646 ZERO_STRUCT(nlistp->ea.value);
650 *total_ea_len = ea_list_size(name_list);
654 /****************************************************************************
655 Send the required number of replies back.
656 We assume all fields other than the data fields are
657 set correctly for the type of call.
658 HACK ! Always assumes smb_setup field is zero.
659 ****************************************************************************/
661 void send_trans2_replies(connection_struct *conn,
662 struct smb_request *req,
669 /* As we are using a protocol > LANMAN1 then the max_send
670 variable must have been set in the sessetupX call.
671 This takes precedence over the max_xmit field in the
672 global struct. These different max_xmit variables should
673 be merged as this is now too confusing */
675 int data_to_send = datasize;
676 int params_to_send = paramsize;
678 const char *pp = params;
679 const char *pd = pdata;
680 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
681 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
682 int data_alignment_offset = 0;
683 bool overflow = False;
685 /* Modify the data_to_send and datasize and set the error if
686 we're trying to send more than max_data_bytes. We still send
687 the part of the packet(s) that fit. Strange, but needed
690 if (max_data_bytes > 0 && datasize > max_data_bytes) {
691 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
692 max_data_bytes, datasize ));
693 datasize = data_to_send = max_data_bytes;
697 /* If there genuinely are no parameters or data to send just send the empty packet */
699 if(params_to_send == 0 && data_to_send == 0) {
700 reply_outbuf(req, 10, 0);
701 show_msg((char *)req->outbuf);
705 /* When sending params and data ensure that both are nicely aligned */
706 /* Only do this alignment when there is also data to send - else
707 can cause NT redirector problems. */
709 if (((params_to_send % 4) != 0) && (data_to_send != 0))
710 data_alignment_offset = 4 - (params_to_send % 4);
712 /* Space is bufsize minus Netbios over TCP header minus SMB header */
713 /* The alignment_offset is to align the param bytes on an even byte
714 boundary. NT 4.0 Beta needs this to work correctly. */
716 useable_space = max_send - (smb_size
719 + data_alignment_offset);
721 if (useable_space < 0) {
722 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
723 "= %d!!!", useable_space));
724 exit_server_cleanly("send_trans2_replies: Not enough space");
727 while (params_to_send || data_to_send) {
728 /* Calculate whether we will totally or partially fill this packet */
730 total_sent_thistime = params_to_send + data_to_send;
732 /* We can never send more than useable_space */
734 * Note that 'useable_space' does not include the alignment offsets,
735 * but we must include the alignment offsets in the calculation of
736 * the length of the data we send over the wire, as the alignment offsets
737 * are sent here. Fix from Marc_Jacobsen@hp.com.
740 total_sent_thistime = MIN(total_sent_thistime, useable_space);
742 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
743 + data_alignment_offset);
746 * We might have SMBtrans2s in req which was transferred to
747 * the outbuf, fix that.
749 SCVAL(req->outbuf, smb_com, SMBtrans2);
751 /* Set total params and data to be sent */
752 SSVAL(req->outbuf,smb_tprcnt,paramsize);
753 SSVAL(req->outbuf,smb_tdrcnt,datasize);
755 /* Calculate how many parameters and data we can fit into
756 * this packet. Parameters get precedence
759 params_sent_thistime = MIN(params_to_send,useable_space);
760 data_sent_thistime = useable_space - params_sent_thistime;
761 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
763 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
765 /* smb_proff is the offset from the start of the SMB header to the
766 parameter bytes, however the first 4 bytes of outbuf are
767 the Netbios over TCP header. Thus use smb_base() to subtract
768 them from the calculation */
770 SSVAL(req->outbuf,smb_proff,
771 ((smb_buf(req->outbuf)+alignment_offset)
772 - smb_base(req->outbuf)));
774 if(params_sent_thistime == 0)
775 SSVAL(req->outbuf,smb_prdisp,0);
777 /* Absolute displacement of param bytes sent in this packet */
778 SSVAL(req->outbuf,smb_prdisp,pp - params);
780 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
781 if(data_sent_thistime == 0) {
782 SSVAL(req->outbuf,smb_droff,0);
783 SSVAL(req->outbuf,smb_drdisp, 0);
785 /* The offset of the data bytes is the offset of the
786 parameter bytes plus the number of parameters being sent this time */
787 SSVAL(req->outbuf, smb_droff,
788 ((smb_buf(req->outbuf)+alignment_offset)
789 - smb_base(req->outbuf))
790 + params_sent_thistime + data_alignment_offset);
791 SSVAL(req->outbuf,smb_drdisp, pd - pdata);
794 /* Initialize the padding for alignment */
796 if (alignment_offset != 0) {
797 memset(smb_buf(req->outbuf), 0, alignment_offset);
800 /* Copy the param bytes into the packet */
802 if(params_sent_thistime) {
803 memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
804 params_sent_thistime);
807 /* Copy in the data bytes */
808 if(data_sent_thistime) {
809 if (data_alignment_offset != 0) {
810 memset((smb_buf(req->outbuf)+alignment_offset+
811 params_sent_thistime), 0,
812 data_alignment_offset);
814 memcpy(smb_buf(req->outbuf)+alignment_offset
815 +params_sent_thistime+data_alignment_offset,
816 pd,data_sent_thistime);
819 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
820 params_sent_thistime, data_sent_thistime, useable_space));
821 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
822 params_to_send, data_to_send, paramsize, datasize));
825 error_packet_set((char *)req->outbuf,
826 ERRDOS,ERRbufferoverflow,
827 STATUS_BUFFER_OVERFLOW,
831 /* Send the packet */
832 show_msg((char *)req->outbuf);
833 if (!srv_send_smb(smbd_server_fd(),
835 IS_CONN_ENCRYPTED(conn),
837 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
839 TALLOC_FREE(req->outbuf);
841 pp += params_sent_thistime;
842 pd += data_sent_thistime;
844 params_to_send -= params_sent_thistime;
845 data_to_send -= data_sent_thistime;
848 if(params_to_send < 0 || data_to_send < 0) {
849 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
850 params_to_send, data_to_send));
858 /****************************************************************************
859 Reply to a TRANSACT2_OPEN.
860 ****************************************************************************/
862 static void call_trans2open(connection_struct *conn,
863 struct smb_request *req,
864 char **pparams, int total_params,
865 char **ppdata, int total_data,
866 unsigned int max_data_bytes)
868 char *params = *pparams;
869 char *pdata = *ppdata;
874 bool return_additional_info;
885 SMB_STRUCT_STAT sbuf;
888 struct ea_list *ea_list = NULL;
893 uint32 create_disposition;
894 uint32 create_options = 0;
895 TALLOC_CTX *ctx = talloc_tos();
898 * Ensure we have enough parameters to perform the operation.
901 if (total_params < 29) {
902 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
906 flags = SVAL(params, 0);
907 deny_mode = SVAL(params, 2);
908 open_attr = SVAL(params,6);
909 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
910 if (oplock_request) {
911 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
915 return_additional_info = BITSETW(params,0);
916 open_sattr = SVAL(params, 4);
917 open_time = make_unix_date3(params+8);
919 open_ofun = SVAL(params,12);
920 open_size = IVAL(params,14);
924 reply_doserror(req, ERRSRV, ERRaccess);
928 srvstr_get_path(ctx, params, req->flags2, &fname, pname,
929 total_params - 28, STR_TERMINATE,
931 if (!NT_STATUS_IS_OK(status)) {
932 reply_nterror(req, status);
936 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
937 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
938 (unsigned int)open_ofun, open_size));
940 if (open_ofun == 0) {
941 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
945 if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
950 reply_doserror(req, ERRDOS, ERRbadaccess);
954 /* Any data in this call is an EA list. */
955 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
956 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
960 if (total_data != 4) {
961 if (total_data < 10) {
962 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
966 if (IVAL(pdata,0) > total_data) {
967 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
968 IVAL(pdata,0), (unsigned int)total_data));
969 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
973 ea_list = read_ea_list(talloc_tos(), pdata + 4,
976 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
979 } else if (IVAL(pdata,0) != 4) {
980 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
984 status = SMB_VFS_CREATE_FILE(
987 0, /* root_dir_fid */
989 CFF_DOS_PATH, /* create_file_flags */
990 access_mask, /* access_mask */
991 share_mode, /* share_access */
992 create_disposition, /* create_disposition*/
993 create_options, /* create_options */
994 open_attr, /* file_attributes */
995 oplock_request, /* oplock_request */
996 open_size, /* allocation_size */
998 ea_list, /* ea_list */
1000 &smb_action, /* pinfo */
1003 if (!NT_STATUS_IS_OK(status)) {
1004 if (open_was_deferred(req->mid)) {
1005 /* We have re-scheduled this call. */
1008 reply_openerror(req, status);
1012 size = get_file_size_stat(&sbuf);
1013 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1014 mtime = sbuf.st_mtime;
1015 inode = sbuf.st_ino;
1017 close_file(req, fsp, ERROR_CLOSE);
1018 reply_doserror(req, ERRDOS,ERRnoaccess);
1022 /* Realloc the size of parameters and data we will return */
1023 *pparams = (char *)SMB_REALLOC(*pparams, 30);
1024 if(*pparams == NULL ) {
1025 reply_nterror(req, NT_STATUS_NO_MEMORY);
1030 SSVAL(params,0,fsp->fnum);
1031 SSVAL(params,2,fattr);
1032 srv_put_dos_date2(params,4, mtime);
1033 SIVAL(params,8, (uint32)size);
1034 SSVAL(params,12,deny_mode);
1035 SSVAL(params,14,0); /* open_type - file or directory. */
1036 SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1038 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1039 smb_action |= EXTENDED_OPLOCK_GRANTED;
1042 SSVAL(params,18,smb_action);
1045 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1047 SIVAL(params,20,inode);
1048 SSVAL(params,24,0); /* Padding. */
1050 uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
1051 SIVAL(params, 26, ea_size);
1053 SIVAL(params, 26, 0);
1056 /* Send the required number of replies */
1057 send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
1060 /*********************************************************
1061 Routine to check if a given string matches exactly.
1062 as a special case a mask of "." does NOT match. That
1063 is required for correct wildcard semantics
1064 Case can be significant or not.
1065 **********************************************************/
1067 static bool exact_match(connection_struct *conn,
1071 if (mask[0] == '.' && mask[1] == 0)
1073 if (dptr_has_wild(conn->dirptr)) {
1076 if (conn->case_sensitive)
1077 return strcmp(str,mask)==0;
1079 return StrCaseCmp(str,mask) == 0;
1082 /****************************************************************************
1083 Return the filetype for UNIX extensions.
1084 ****************************************************************************/
1086 static uint32 unix_filetype(mode_t mode)
1089 return UNIX_TYPE_FILE;
1090 else if(S_ISDIR(mode))
1091 return UNIX_TYPE_DIR;
1093 else if(S_ISLNK(mode))
1094 return UNIX_TYPE_SYMLINK;
1097 else if(S_ISCHR(mode))
1098 return UNIX_TYPE_CHARDEV;
1101 else if(S_ISBLK(mode))
1102 return UNIX_TYPE_BLKDEV;
1105 else if(S_ISFIFO(mode))
1106 return UNIX_TYPE_FIFO;
1109 else if(S_ISSOCK(mode))
1110 return UNIX_TYPE_SOCKET;
1113 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1114 return UNIX_TYPE_UNKNOWN;
1117 /****************************************************************************
1118 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1119 ****************************************************************************/
1121 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1123 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1124 SMB_STRUCT_STAT *psbuf,
1126 enum perm_type ptype,
1131 if (perms == SMB_MODE_NO_CHANGE) {
1132 if (!VALID_STAT(*psbuf)) {
1133 return NT_STATUS_INVALID_PARAMETER;
1135 *ret_perms = psbuf->st_mode;
1136 return NT_STATUS_OK;
1140 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1141 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1142 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1143 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1144 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1145 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1146 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1147 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1148 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1150 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1153 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1156 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1161 /* Apply mode mask */
1162 ret &= lp_create_mask(SNUM(conn));
1163 /* Add in force bits */
1164 ret |= lp_force_create_mode(SNUM(conn));
1167 ret &= lp_dir_mask(SNUM(conn));
1168 /* Add in force bits */
1169 ret |= lp_force_dir_mode(SNUM(conn));
1171 case PERM_EXISTING_FILE:
1172 /* Apply mode mask */
1173 ret &= lp_security_mask(SNUM(conn));
1174 /* Add in force bits */
1175 ret |= lp_force_security_mode(SNUM(conn));
1177 case PERM_EXISTING_DIR:
1178 /* Apply mode mask */
1179 ret &= lp_dir_security_mask(SNUM(conn));
1180 /* Add in force bits */
1181 ret |= lp_force_dir_security_mode(SNUM(conn));
1186 return NT_STATUS_OK;
1189 /****************************************************************************
1190 Needed to show the msdfs symlinks as directories. Modifies psbuf
1191 to be a directory if it's a msdfs link.
1192 ****************************************************************************/
1194 static bool check_msdfs_link(connection_struct *conn,
1195 const char *pathname,
1196 SMB_STRUCT_STAT *psbuf)
1198 int saved_errno = errno;
1199 if(lp_host_msdfs() &&
1200 lp_msdfs_root(SNUM(conn)) &&
1201 is_msdfs_link(conn, pathname, psbuf)) {
1203 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1206 psbuf->st_mode = (psbuf->st_mode & 0xFFF) | S_IFDIR;
1207 errno = saved_errno;
1210 errno = saved_errno;
1215 /****************************************************************************
1216 Get a level dependent lanman2 dir entry.
1217 ****************************************************************************/
1219 static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
1220 connection_struct *conn,
1222 const char *path_mask,
1225 int requires_resume_key,
1231 int space_remaining,
1233 bool *got_exact_match,
1234 int *last_entry_off,
1235 struct ea_list *name_list)
1239 SMB_STRUCT_STAT sbuf;
1240 const char *mask = NULL;
1241 char *pathreal = NULL;
1242 const char *fname = NULL;
1243 char *p, *q, *pdata = *ppdata;
1247 SMB_OFF_T file_size = 0;
1248 uint64_t allocation_size = 0;
1250 struct timespec mdate_ts, adate_ts, create_date_ts;
1251 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1253 char *last_entry_ptr;
1255 uint32 nt_extmode; /* Used for NT connections instead of mode */
1256 bool needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1257 bool check_mangled_names = lp_manglednames(conn->params);
1258 char mangled_name[13]; /* mangled 8.3 name. */
1260 *out_of_space = False;
1261 *got_exact_match = False;
1263 ZERO_STRUCT(mdate_ts);
1264 ZERO_STRUCT(adate_ts);
1265 ZERO_STRUCT(create_date_ts);
1267 if (!conn->dirptr) {
1271 p = strrchr_m(path_mask,'/');
1274 mask = talloc_strdup(ctx,"*.*");
1284 bool ms_dfs_link = False;
1286 /* Needed if we run out of space */
1287 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1288 dname = dptr_ReadDirName(ctx,conn->dirptr,&curr_dirpos,&sbuf);
1291 * Due to bugs in NT client redirectors we are not using
1292 * resume keys any more - set them to zero.
1293 * Check out the related comments in findfirst/findnext.
1299 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1300 (long)conn->dirptr,curr_dirpos));
1307 * fname may get mangled, dname is never mangled.
1308 * Whenever we're accessing the filesystem we use
1309 * pathreal which is composed from dname.
1315 /* Mangle fname if it's an illegal name. */
1316 if (mangle_must_mangle(dname,conn->params)) {
1317 if (!name_to_8_3(dname,mangled_name,True,conn->params)) {
1318 continue; /* Error - couldn't mangle. */
1320 fname = mangled_name;
1323 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
1324 got_match = mask_match(fname, mask, conn->case_sensitive);
1327 if(!got_match && check_mangled_names &&
1328 !mangle_is_8_3(fname, False, conn->params)) {
1330 * It turns out that NT matches wildcards against
1331 * both long *and* short names. This may explain some
1332 * of the wildcard wierdness from old DOS clients
1333 * that some people have been seeing.... JRA.
1335 /* Force the mangling into 8.3. */
1336 if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
1337 continue; /* Error - couldn't mangle. */
1340 if(!(got_match = *got_exact_match = exact_match(conn, mangled_name, mask))) {
1341 got_match = mask_match(mangled_name, mask, conn->case_sensitive);
1346 bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
1348 if (dont_descend && !isdots) {
1354 pathreal = talloc_asprintf(ctx,
1359 pathreal = talloc_asprintf(ctx,
1369 if (INFO_LEVEL_IS_UNIX(info_level)) {
1370 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1371 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1372 pathreal,strerror(errno)));
1373 TALLOC_FREE(pathreal);
1376 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1377 /* Needed to show the msdfs symlinks as
1380 ms_dfs_link = check_msdfs_link(conn, pathreal, &sbuf);
1382 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1383 pathreal,strerror(errno)));
1384 TALLOC_FREE(pathreal);
1390 mode = dos_mode_msdfs(conn,pathreal,&sbuf);
1392 mode = dos_mode(conn,pathreal,&sbuf);
1395 if (!dir_check_ftype(conn,mode,dirtype)) {
1396 DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
1397 TALLOC_FREE(pathreal);
1401 if (!(mode & aDIR)) {
1402 file_size = get_file_size_stat(&sbuf);
1404 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf);
1406 mdate_ts = get_mtimespec(&sbuf);
1407 adate_ts = get_atimespec(&sbuf);
1408 create_date_ts = get_create_timespec(&sbuf,
1409 lp_fake_dir_create_times(SNUM(conn)));
1411 if (ask_sharemode) {
1412 struct timespec write_time_ts;
1413 struct file_id fileid;
1415 fileid = vfs_file_id_from_sbuf(conn, &sbuf);
1416 get_file_infos(fileid, NULL, &write_time_ts);
1417 if (!null_timespec(write_time_ts)) {
1418 mdate_ts = write_time_ts;
1422 if (lp_dos_filetime_resolution(SNUM(conn))) {
1423 dos_filetime_timespec(&create_date_ts);
1424 dos_filetime_timespec(&mdate_ts);
1425 dos_filetime_timespec(&adate_ts);
1428 create_date = convert_timespec_to_time_t(create_date_ts);
1429 mdate = convert_timespec_to_time_t(mdate_ts);
1430 adate = convert_timespec_to_time_t(adate_ts);
1432 DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",
1437 dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1444 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1446 switch (info_level) {
1447 case SMB_FIND_INFO_STANDARD:
1448 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1449 if(requires_resume_key) {
1453 srv_put_dos_date2(p,0,create_date);
1454 srv_put_dos_date2(p,4,adate);
1455 srv_put_dos_date2(p,8,mdate);
1456 SIVAL(p,12,(uint32)file_size);
1457 SIVAL(p,16,(uint32)allocation_size);
1461 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1462 p += ucs2_align(base_data, p, 0);
1464 len = srvstr_push(base_data, flags2, p,
1465 fname, PTR_DIFF(end_data, p),
1467 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1469 SCVAL(nameptr, -1, len - 2);
1471 SCVAL(nameptr, -1, 0);
1475 SCVAL(nameptr, -1, len - 1);
1477 SCVAL(nameptr, -1, 0);
1483 case SMB_FIND_EA_SIZE:
1484 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1485 if(requires_resume_key) {
1489 srv_put_dos_date2(p,0,create_date);
1490 srv_put_dos_date2(p,4,adate);
1491 srv_put_dos_date2(p,8,mdate);
1492 SIVAL(p,12,(uint32)file_size);
1493 SIVAL(p,16,(uint32)allocation_size);
1496 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1497 SIVAL(p,22,ea_size); /* Extended attributes */
1501 len = srvstr_push(base_data, flags2,
1502 p, fname, PTR_DIFF(end_data, p),
1503 STR_TERMINATE | STR_NOALIGN);
1504 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1517 SCVAL(nameptr,0,len);
1519 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1522 case SMB_FIND_EA_LIST:
1524 struct ea_list *file_list = NULL;
1527 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1531 if(requires_resume_key) {
1535 srv_put_dos_date2(p,0,create_date);
1536 srv_put_dos_date2(p,4,adate);
1537 srv_put_dos_date2(p,8,mdate);
1538 SIVAL(p,12,(uint32)file_size);
1539 SIVAL(p,16,(uint32)allocation_size);
1541 p += 22; /* p now points to the EA area. */
1543 file_list = get_ea_list_from_file(ctx, conn, NULL, pathreal, &ea_len);
1544 name_list = ea_list_union(name_list, file_list, &ea_len);
1546 /* We need to determine if this entry will fit in the space available. */
1547 /* Max string size is 255 bytes. */
1548 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1549 /* Move the dirptr back to prev_dirpos */
1550 dptr_SeekDir(conn->dirptr, prev_dirpos);
1551 *out_of_space = True;
1552 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1553 return False; /* Not finished - just out of space */
1556 /* Push the ea_data followed by the name. */
1557 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1559 len = srvstr_push(base_data, flags2,
1560 p + 1, fname, PTR_DIFF(end_data, p+1),
1561 STR_TERMINATE | STR_NOALIGN);
1562 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1575 SCVAL(nameptr,0,len);
1577 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1581 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1582 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1583 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1585 SIVAL(p,0,reskey); p += 4;
1586 put_long_date_timespec(p,create_date_ts); p += 8;
1587 put_long_date_timespec(p,adate_ts); p += 8;
1588 put_long_date_timespec(p,mdate_ts); p += 8;
1589 put_long_date_timespec(p,mdate_ts); p += 8;
1590 SOFF_T(p,0,file_size); p += 8;
1591 SOFF_T(p,0,allocation_size); p += 8;
1592 SIVAL(p,0,nt_extmode); p += 4;
1593 q = p; p += 4; /* q is placeholder for name length. */
1595 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1596 SIVAL(p,0,ea_size); /* Extended attributes */
1599 /* Clear the short name buffer. This is
1600 * IMPORTANT as not doing so will trigger
1601 * a Win2k client bug. JRA.
1603 if (!was_8_3 && check_mangled_names) {
1604 if (!name_to_8_3(fname,mangled_name,True,
1606 /* Error - mangle failed ! */
1607 memset(mangled_name,'\0',12);
1609 mangled_name[12] = 0;
1610 len = srvstr_push(base_data, flags2,
1611 p+2, mangled_name, 24,
1612 STR_UPPER|STR_UNICODE);
1614 memset(p + 2 + len,'\0',24 - len);
1621 len = srvstr_push(base_data, flags2, p,
1622 fname, PTR_DIFF(end_data, p),
1623 STR_TERMINATE_ASCII);
1626 SIVAL(p,0,0); /* Ensure any padding is null. */
1627 len = PTR_DIFF(p, pdata);
1628 len = (len + 3) & ~3;
1633 case SMB_FIND_FILE_DIRECTORY_INFO:
1634 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1636 SIVAL(p,0,reskey); p += 4;
1637 put_long_date_timespec(p,create_date_ts); p += 8;
1638 put_long_date_timespec(p,adate_ts); p += 8;
1639 put_long_date_timespec(p,mdate_ts); p += 8;
1640 put_long_date_timespec(p,mdate_ts); p += 8;
1641 SOFF_T(p,0,file_size); p += 8;
1642 SOFF_T(p,0,allocation_size); p += 8;
1643 SIVAL(p,0,nt_extmode); p += 4;
1644 len = srvstr_push(base_data, flags2,
1645 p + 4, fname, PTR_DIFF(end_data, p+4),
1646 STR_TERMINATE_ASCII);
1649 SIVAL(p,0,0); /* Ensure any padding is null. */
1650 len = PTR_DIFF(p, pdata);
1651 len = (len + 3) & ~3;
1656 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1657 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1659 SIVAL(p,0,reskey); p += 4;
1660 put_long_date_timespec(p,create_date_ts); p += 8;
1661 put_long_date_timespec(p,adate_ts); p += 8;
1662 put_long_date_timespec(p,mdate_ts); p += 8;
1663 put_long_date_timespec(p,mdate_ts); p += 8;
1664 SOFF_T(p,0,file_size); p += 8;
1665 SOFF_T(p,0,allocation_size); p += 8;
1666 SIVAL(p,0,nt_extmode); p += 4;
1667 q = p; p += 4; /* q is placeholder for name length. */
1669 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1670 SIVAL(p,0,ea_size); /* Extended attributes */
1673 len = srvstr_push(base_data, flags2, p,
1674 fname, PTR_DIFF(end_data, p),
1675 STR_TERMINATE_ASCII);
1679 SIVAL(p,0,0); /* Ensure any padding is null. */
1680 len = PTR_DIFF(p, pdata);
1681 len = (len + 3) & ~3;
1686 case SMB_FIND_FILE_NAMES_INFO:
1687 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1689 SIVAL(p,0,reskey); p += 4;
1691 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1692 acl on a dir (tridge) */
1693 len = srvstr_push(base_data, flags2, p,
1694 fname, PTR_DIFF(end_data, p),
1695 STR_TERMINATE_ASCII);
1698 SIVAL(p,0,0); /* Ensure any padding is null. */
1699 len = PTR_DIFF(p, pdata);
1700 len = (len + 3) & ~3;
1705 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1706 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1708 SIVAL(p,0,reskey); p += 4;
1709 put_long_date_timespec(p,create_date_ts); p += 8;
1710 put_long_date_timespec(p,adate_ts); p += 8;
1711 put_long_date_timespec(p,mdate_ts); p += 8;
1712 put_long_date_timespec(p,mdate_ts); p += 8;
1713 SOFF_T(p,0,file_size); p += 8;
1714 SOFF_T(p,0,allocation_size); p += 8;
1715 SIVAL(p,0,nt_extmode); p += 4;
1716 q = p; p += 4; /* q is placeholder for name length. */
1718 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1719 SIVAL(p,0,ea_size); /* Extended attributes */
1722 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1723 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1724 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1725 len = srvstr_push(base_data, flags2, p,
1726 fname, PTR_DIFF(end_data, p),
1727 STR_TERMINATE_ASCII);
1730 SIVAL(p,0,0); /* Ensure any padding is null. */
1731 len = PTR_DIFF(p, pdata);
1732 len = (len + 3) & ~3;
1737 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1738 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1739 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1741 SIVAL(p,0,reskey); p += 4;
1742 put_long_date_timespec(p,create_date_ts); p += 8;
1743 put_long_date_timespec(p,adate_ts); p += 8;
1744 put_long_date_timespec(p,mdate_ts); p += 8;
1745 put_long_date_timespec(p,mdate_ts); p += 8;
1746 SOFF_T(p,0,file_size); p += 8;
1747 SOFF_T(p,0,allocation_size); p += 8;
1748 SIVAL(p,0,nt_extmode); p += 4;
1749 q = p; p += 4; /* q is placeholder for name length */
1751 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1752 SIVAL(p,0,ea_size); /* Extended attributes */
1755 /* Clear the short name buffer. This is
1756 * IMPORTANT as not doing so will trigger
1757 * a Win2k client bug. JRA.
1759 if (!was_8_3 && check_mangled_names) {
1760 if (!name_to_8_3(fname,mangled_name,True,
1762 /* Error - mangle failed ! */
1763 memset(mangled_name,'\0',12);
1765 mangled_name[12] = 0;
1766 len = srvstr_push(base_data, flags2,
1767 p+2, mangled_name, 24,
1768 STR_UPPER|STR_UNICODE);
1771 memset(p + 2 + len,'\0',24 - len);
1778 SSVAL(p,0,0); p += 2; /* Reserved ? */
1779 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1780 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1781 len = srvstr_push(base_data, flags2, p,
1782 fname, PTR_DIFF(end_data, p),
1783 STR_TERMINATE_ASCII);
1786 SIVAL(p,0,0); /* Ensure any padding is null. */
1787 len = PTR_DIFF(p, pdata);
1788 len = (len + 3) & ~3;
1793 /* CIFS UNIX Extension. */
1795 case SMB_FIND_FILE_UNIX:
1796 case SMB_FIND_FILE_UNIX_INFO2:
1798 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1800 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1802 if (info_level == SMB_FIND_FILE_UNIX) {
1803 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1804 p = store_file_unix_basic(conn, p,
1806 len = srvstr_push(base_data, flags2, p,
1807 fname, PTR_DIFF(end_data, p),
1810 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1811 p = store_file_unix_basic_info2(conn, p,
1815 len = srvstr_push(base_data, flags2, p, fname,
1816 PTR_DIFF(end_data, p), 0);
1817 SIVAL(nameptr, 0, len);
1821 SIVAL(p,0,0); /* Ensure any padding is null. */
1823 len = PTR_DIFF(p, pdata);
1824 len = (len + 3) & ~3;
1825 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1827 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1836 if (PTR_DIFF(p,pdata) > space_remaining) {
1837 /* Move the dirptr back to prev_dirpos */
1838 dptr_SeekDir(conn->dirptr, prev_dirpos);
1839 *out_of_space = True;
1840 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1841 return False; /* Not finished - just out of space */
1844 /* Setup the last entry pointer, as an offset from base_data */
1845 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1846 /* Advance the data pointer to the next slot */
1852 /****************************************************************************
1853 Reply to a TRANS2_FINDFIRST.
1854 ****************************************************************************/
1856 static void call_trans2findfirst(connection_struct *conn,
1857 struct smb_request *req,
1858 char **pparams, int total_params,
1859 char **ppdata, int total_data,
1860 unsigned int max_data_bytes)
1862 /* We must be careful here that we don't return more than the
1863 allowed number of data bytes. If this means returning fewer than
1864 maxentries then so be it. We assume that the redirector has
1865 enough room for the fixed number of parameter bytes it has
1867 char *params = *pparams;
1868 char *pdata = *ppdata;
1872 uint16 findfirst_flags;
1873 bool close_after_first;
1875 bool requires_resume_key;
1877 char *directory = NULL;
1880 int last_entry_off=0;
1884 bool finished = False;
1885 bool dont_descend = False;
1886 bool out_of_space = False;
1887 int space_remaining;
1888 bool mask_contains_wcard = False;
1889 SMB_STRUCT_STAT sbuf;
1890 struct ea_list *ea_list = NULL;
1891 NTSTATUS ntstatus = NT_STATUS_OK;
1892 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1893 TALLOC_CTX *ctx = talloc_tos();
1895 if (total_params < 13) {
1896 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1900 dirtype = SVAL(params,0);
1901 maxentries = SVAL(params,2);
1902 findfirst_flags = SVAL(params,4);
1903 close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1904 close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1905 requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1906 info_level = SVAL(params,6);
1908 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
1909 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1910 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1911 info_level, max_data_bytes));
1914 /* W2K3 seems to treat zero as 1. */
1918 switch (info_level) {
1919 case SMB_FIND_INFO_STANDARD:
1920 case SMB_FIND_EA_SIZE:
1921 case SMB_FIND_EA_LIST:
1922 case SMB_FIND_FILE_DIRECTORY_INFO:
1923 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1924 case SMB_FIND_FILE_NAMES_INFO:
1925 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1926 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1927 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1929 case SMB_FIND_FILE_UNIX:
1930 case SMB_FIND_FILE_UNIX_INFO2:
1931 /* Always use filesystem for UNIX mtime query. */
1932 ask_sharemode = false;
1933 if (!lp_unix_extensions()) {
1934 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1939 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1943 srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
1944 params+12, total_params - 12,
1945 STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1946 if (!NT_STATUS_IS_OK(ntstatus)) {
1947 reply_nterror(req, ntstatus);
1951 ntstatus = resolve_dfspath_wcard(ctx, conn,
1952 req->flags2 & FLAGS2_DFS_PATHNAMES,
1955 &mask_contains_wcard);
1956 if (!NT_STATUS_IS_OK(ntstatus)) {
1957 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
1958 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1959 ERRSRV, ERRbadpath);
1962 reply_nterror(req, ntstatus);
1966 ntstatus = unix_convert(ctx, conn, directory, True, &directory, &mask, &sbuf);
1967 if (!NT_STATUS_IS_OK(ntstatus)) {
1968 reply_nterror(req, ntstatus);
1972 ntstatus = check_name(conn, directory);
1973 if (!NT_STATUS_IS_OK(ntstatus)) {
1974 reply_nterror(req, ntstatus);
1978 p = strrchr_m(directory,'/');
1980 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1981 if((directory[0] == '.') && (directory[1] == '\0')) {
1982 mask = talloc_strdup(ctx,"*");
1984 reply_nterror(req, NT_STATUS_NO_MEMORY);
1987 mask_contains_wcard = True;
1989 directory = talloc_strdup(talloc_tos(), "./");
1991 reply_nterror(req, NT_STATUS_NO_MEMORY);
1998 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2000 if (info_level == SMB_FIND_EA_LIST) {
2003 if (total_data < 4) {
2004 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2008 ea_size = IVAL(pdata,0);
2009 if (ea_size != total_data) {
2010 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2011 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2012 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2016 if (!lp_ea_support(SNUM(conn))) {
2017 reply_doserror(req, ERRDOS, ERReasnotsupported);
2021 /* Pull out the list of names. */
2022 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2024 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2029 *ppdata = (char *)SMB_REALLOC(
2030 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2031 if(*ppdata == NULL ) {
2032 reply_nterror(req, NT_STATUS_NO_MEMORY);
2036 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2038 /* Realloc the params space */
2039 *pparams = (char *)SMB_REALLOC(*pparams, 10);
2040 if (*pparams == NULL) {
2041 reply_nterror(req, NT_STATUS_NO_MEMORY);
2046 /* Save the wildcard match and attribs we are using on this directory -
2047 needed as lanman2 assumes these are being saved between calls */
2049 ntstatus = dptr_create(conn,
2055 mask_contains_wcard,
2059 if (!NT_STATUS_IS_OK(ntstatus)) {
2060 reply_nterror(req, ntstatus);
2064 dptr_num = dptr_dnum(conn->dirptr);
2065 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2067 /* Initialize per TRANS2_FIND_FIRST operation data */
2068 dptr_init_search_op(conn->dirptr);
2070 /* We don't need to check for VOL here as this is returned by
2071 a different TRANS2 call. */
2073 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
2074 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2075 dont_descend = True;
2078 space_remaining = max_data_bytes;
2079 out_of_space = False;
2081 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2082 bool got_exact_match = False;
2084 /* this is a heuristic to avoid seeking the dirptr except when
2085 absolutely necessary. It allows for a filename of about 40 chars */
2086 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2087 out_of_space = True;
2090 finished = !get_lanman2_dir_entry(ctx,
2093 mask,dirtype,info_level,
2094 requires_resume_key,dont_descend,
2097 space_remaining, &out_of_space,
2099 &last_entry_off, ea_list);
2102 if (finished && out_of_space)
2105 if (!finished && !out_of_space)
2109 * As an optimisation if we know we aren't looking
2110 * for a wildcard name (ie. the name matches the wildcard exactly)
2111 * then we can finish on any (first) match.
2112 * This speeds up large directory searches. JRA.
2118 /* Ensure space_remaining never goes -ve. */
2119 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2120 space_remaining = 0;
2121 out_of_space = true;
2123 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2127 /* Check if we can close the dirptr */
2128 if(close_after_first || (finished && close_if_end)) {
2129 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2130 dptr_close(&dptr_num);
2134 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2135 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2136 * the protocol level is less than NT1. Tested with smbclient. JRA.
2137 * This should fix the OS/2 client bug #2335.
2140 if(numentries == 0) {
2141 dptr_close(&dptr_num);
2142 if (Protocol < PROTOCOL_NT1) {
2143 reply_doserror(req, ERRDOS, ERRnofiles);
2146 reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2147 ERRDOS, ERRbadfile);
2152 /* At this point pdata points to numentries directory entries. */
2154 /* Set up the return parameter block */
2155 SSVAL(params,0,dptr_num);
2156 SSVAL(params,2,numentries);
2157 SSVAL(params,4,finished);
2158 SSVAL(params,6,0); /* Never an EA error */
2159 SSVAL(params,8,last_entry_off);
2161 send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
2164 if ((! *directory) && dptr_path(dptr_num)) {
2165 directory = talloc_strdup(talloc_tos(),dptr_path(dptr_num));
2167 reply_nterror(req, NT_STATUS_NO_MEMORY);
2171 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2172 smb_fn_name(req->cmd),
2173 mask, directory, dirtype, numentries ) );
2176 * Force a name mangle here to ensure that the
2177 * mask as an 8.3 name is top of the mangled cache.
2178 * The reasons for this are subtle. Don't remove
2179 * this code unless you know what you are doing
2180 * (see PR#13758). JRA.
2183 if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2184 char mangled_name[13];
2185 name_to_8_3(mask, mangled_name, True, conn->params);
2191 /****************************************************************************
2192 Reply to a TRANS2_FINDNEXT.
2193 ****************************************************************************/
2195 static void call_trans2findnext(connection_struct *conn,
2196 struct smb_request *req,
2197 char **pparams, int total_params,
2198 char **ppdata, int total_data,
2199 unsigned int max_data_bytes)
2201 /* We must be careful here that we don't return more than the
2202 allowed number of data bytes. If this means returning fewer than
2203 maxentries then so be it. We assume that the redirector has
2204 enough room for the fixed number of parameter bytes it has
2206 char *params = *pparams;
2207 char *pdata = *ppdata;
2213 uint16 findnext_flags;
2214 bool close_after_request;
2216 bool requires_resume_key;
2218 bool mask_contains_wcard = False;
2219 char *resume_name = NULL;
2220 const char *mask = NULL;
2221 const char *directory = NULL;
2225 int i, last_entry_off=0;
2226 bool finished = False;
2227 bool dont_descend = False;
2228 bool out_of_space = False;
2229 int space_remaining;
2230 struct ea_list *ea_list = NULL;
2231 NTSTATUS ntstatus = NT_STATUS_OK;
2232 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2233 TALLOC_CTX *ctx = talloc_tos();
2235 if (total_params < 13) {
2236 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2240 dptr_num = SVAL(params,0);
2241 maxentries = SVAL(params,2);
2242 info_level = SVAL(params,4);
2243 resume_key = IVAL(params,6);
2244 findnext_flags = SVAL(params,10);
2245 close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2246 close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2247 requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2248 continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2250 srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2252 total_params - 12, STR_TERMINATE, &ntstatus,
2253 &mask_contains_wcard);
2254 if (!NT_STATUS_IS_OK(ntstatus)) {
2255 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2256 complain (it thinks we're asking for the directory above the shared
2257 path or an invalid name). Catch this as the resume name is only compared, never used in
2258 a file access. JRA. */
2259 srvstr_pull_talloc(ctx, params, req->flags2,
2260 &resume_name, params+12,
2264 if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2265 reply_nterror(req, ntstatus);
2270 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2271 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2272 resume_key = %d resume name = %s continue=%d level = %d\n",
2273 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
2274 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
2277 /* W2K3 seems to treat zero as 1. */
2281 switch (info_level) {
2282 case SMB_FIND_INFO_STANDARD:
2283 case SMB_FIND_EA_SIZE:
2284 case SMB_FIND_EA_LIST:
2285 case SMB_FIND_FILE_DIRECTORY_INFO:
2286 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2287 case SMB_FIND_FILE_NAMES_INFO:
2288 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2289 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2290 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2292 case SMB_FIND_FILE_UNIX:
2293 case SMB_FIND_FILE_UNIX_INFO2:
2294 /* Always use filesystem for UNIX mtime query. */
2295 ask_sharemode = false;
2296 if (!lp_unix_extensions()) {
2297 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2302 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2306 if (info_level == SMB_FIND_EA_LIST) {
2309 if (total_data < 4) {
2310 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2314 ea_size = IVAL(pdata,0);
2315 if (ea_size != total_data) {
2316 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2317 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2318 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2322 if (!lp_ea_support(SNUM(conn))) {
2323 reply_doserror(req, ERRDOS, ERReasnotsupported);
2327 /* Pull out the list of names. */
2328 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2330 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2335 *ppdata = (char *)SMB_REALLOC(
2336 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2337 if(*ppdata == NULL) {
2338 reply_nterror(req, NT_STATUS_NO_MEMORY);
2343 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2345 /* Realloc the params space */
2346 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2347 if(*pparams == NULL ) {
2348 reply_nterror(req, NT_STATUS_NO_MEMORY);
2354 /* Check that the dptr is valid */
2355 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2356 reply_doserror(req, ERRDOS, ERRnofiles);
2360 string_set(&conn->dirpath,dptr_path(dptr_num));
2362 /* Get the wildcard mask from the dptr */
2363 if((p = dptr_wcard(dptr_num))== NULL) {
2364 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2365 reply_doserror(req, ERRDOS, ERRnofiles);
2370 directory = conn->dirpath;
2372 /* Get the attr mask from the dptr */
2373 dirtype = dptr_attr(dptr_num);
2375 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2376 dptr_num, mask, dirtype,
2378 dptr_TellDir(conn->dirptr)));
2380 /* Initialize per TRANS2_FIND_NEXT operation data */
2381 dptr_init_search_op(conn->dirptr);
2383 /* We don't need to check for VOL here as this is returned by
2384 a different TRANS2 call. */
2386 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2387 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2388 dont_descend = True;
2391 space_remaining = max_data_bytes;
2392 out_of_space = False;
2395 * Seek to the correct position. We no longer use the resume key but
2396 * depend on the last file name instead.
2399 if(*resume_name && !continue_bit) {
2402 long current_pos = 0;
2404 * Remember, name_to_8_3 is called by
2405 * get_lanman2_dir_entry(), so the resume name
2406 * could be mangled. Ensure we check the unmangled name.
2409 if (mangle_is_mangled(resume_name, conn->params)) {
2410 char *new_resume_name = NULL;
2411 mangle_lookup_name_from_8_3(ctx,
2415 if (new_resume_name) {
2416 resume_name = new_resume_name;
2421 * Fix for NT redirector problem triggered by resume key indexes
2422 * changing between directory scans. We now return a resume key of 0
2423 * and instead look for the filename to continue from (also given
2424 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2425 * findfirst/findnext (as is usual) then the directory pointer
2426 * should already be at the correct place.
2429 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
2430 } /* end if resume_name && !continue_bit */
2432 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2433 bool got_exact_match = False;
2435 /* this is a heuristic to avoid seeking the dirptr except when
2436 absolutely necessary. It allows for a filename of about 40 chars */
2437 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2438 out_of_space = True;
2441 finished = !get_lanman2_dir_entry(ctx,
2444 mask,dirtype,info_level,
2445 requires_resume_key,dont_descend,
2448 space_remaining, &out_of_space,
2450 &last_entry_off, ea_list);
2453 if (finished && out_of_space)
2456 if (!finished && !out_of_space)
2460 * As an optimisation if we know we aren't looking
2461 * for a wildcard name (ie. the name matches the wildcard exactly)
2462 * then we can finish on any (first) match.
2463 * This speeds up large directory searches. JRA.
2469 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2472 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2473 smb_fn_name(req->cmd),
2474 mask, directory, dirtype, numentries ) );
2476 /* Check if we can close the dirptr */
2477 if(close_after_request || (finished && close_if_end)) {
2478 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2479 dptr_close(&dptr_num); /* This frees up the saved mask */
2482 /* Set up the return parameter block */
2483 SSVAL(params,0,numentries);
2484 SSVAL(params,2,finished);
2485 SSVAL(params,4,0); /* Never an EA error */
2486 SSVAL(params,6,last_entry_off);
2488 send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
2494 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
2496 E_md4hash(lp_servicename(SNUM(conn)),objid);
2500 static void samba_extended_info_version(struct smb_extended_info *extended_info)
2502 SMB_ASSERT(extended_info != NULL);
2504 extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
2505 extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
2506 | ((SAMBA_VERSION_MINOR & 0xff) << 16)
2507 | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
2508 #ifdef SAMBA_VERSION_REVISION
2509 extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
2511 extended_info->samba_subversion = 0;
2512 #ifdef SAMBA_VERSION_RC_RELEASE
2513 extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
2515 #ifdef SAMBA_VERSION_PRE_RELEASE
2516 extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
2519 #ifdef SAMBA_VERSION_VENDOR_PATCH
2520 extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
2522 extended_info->samba_gitcommitdate = 0;
2523 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2524 unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
2527 memset(extended_info->samba_version_string, 0,
2528 sizeof(extended_info->samba_version_string));
2530 snprintf (extended_info->samba_version_string,
2531 sizeof(extended_info->samba_version_string),
2532 "%s", samba_version_string());
2535 /****************************************************************************
2536 Reply to a TRANS2_QFSINFO (query filesystem info).
2537 ****************************************************************************/
2539 static void call_trans2qfsinfo(connection_struct *conn,
2540 struct smb_request *req,
2541 char **pparams, int total_params,
2542 char **ppdata, int total_data,
2543 unsigned int max_data_bytes)
2545 char *pdata, *end_data;
2546 char *params = *pparams;
2550 const char *vname = volume_label(SNUM(conn));
2551 int snum = SNUM(conn);
2552 char *fstype = lp_fstype(SNUM(conn));
2553 uint32 additional_flags = 0;
2555 if (total_params < 2) {
2556 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2560 info_level = SVAL(params,0);
2563 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2564 DEBUG(0,("call_trans2qfsinfo: not an allowed "
2565 "info level (0x%x) on IPC$.\n",
2566 (unsigned int)info_level));
2567 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2572 if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
2573 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2574 DEBUG(0,("call_trans2qfsinfo: encryption required "
2575 "and info level 0x%x sent.\n",
2576 (unsigned int)info_level));
2577 exit_server_cleanly("encryption required "
2583 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2585 if(SMB_VFS_STAT(conn,".",&st)!=0) {
2586 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2587 reply_doserror(req, ERRSRV, ERRinvdevice);
2591 *ppdata = (char *)SMB_REALLOC(
2592 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2593 if (*ppdata == NULL ) {
2594 reply_nterror(req, NT_STATUS_NO_MEMORY);
2599 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2600 end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2602 switch (info_level) {
2603 case SMB_INFO_ALLOCATION:
2605 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2607 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2608 reply_unixerror(req, ERRHRD, ERRgeneral);
2612 block_size = lp_block_size(snum);
2613 if (bsize < block_size) {
2614 uint64_t factor = block_size/bsize;
2619 if (bsize > block_size) {
2620 uint64_t factor = bsize/block_size;
2625 bytes_per_sector = 512;
2626 sectors_per_unit = bsize/bytes_per_sector;
2628 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2629 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2630 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2632 SIVAL(pdata,l1_idFileSystem,st.st_dev);
2633 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2634 SIVAL(pdata,l1_cUnit,dsize);
2635 SIVAL(pdata,l1_cUnitAvail,dfree);
2636 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2640 case SMB_INFO_VOLUME:
2641 /* Return volume name */
2643 * Add volume serial number - hash of a combination of
2644 * the called hostname and the service name.
2646 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2648 * Win2k3 and previous mess this up by sending a name length
2649 * one byte short. I believe only older clients (OS/2 Win9x) use
2650 * this call so try fixing this by adding a terminating null to
2651 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2655 pdata+l2_vol_szVolLabel, vname,
2656 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
2657 STR_NOALIGN|STR_TERMINATE);
2658 SCVAL(pdata,l2_vol_cch,len);
2659 data_len = l2_vol_szVolLabel + len;
2660 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2661 (unsigned)st.st_ctime, len, vname));
2664 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2665 case SMB_FS_ATTRIBUTE_INFORMATION:
2667 additional_flags = 0;
2668 #if defined(HAVE_SYS_QUOTAS)
2669 additional_flags |= FILE_VOLUME_QUOTAS;
2672 if(lp_nt_acl_support(SNUM(conn))) {
2673 additional_flags |= FILE_PERSISTENT_ACLS;
2676 /* Capabilities are filled in at connection time through STATVFS call */
2677 additional_flags |= conn->fs_capabilities;
2679 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2680 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
2681 additional_flags); /* FS ATTRIBUTES */
2683 SIVAL(pdata,4,255); /* Max filename component length */
2684 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2685 and will think we can't do long filenames */
2686 len = srvstr_push(pdata, req->flags2, pdata+12, fstype,
2687 PTR_DIFF(end_data, pdata+12),
2690 data_len = 12 + len;
2693 case SMB_QUERY_FS_LABEL_INFO:
2694 case SMB_FS_LABEL_INFORMATION:
2695 len = srvstr_push(pdata, req->flags2, pdata+4, vname,
2696 PTR_DIFF(end_data, pdata+4), 0);
2701 case SMB_QUERY_FS_VOLUME_INFO:
2702 case SMB_FS_VOLUME_INFORMATION:
2705 * Add volume serial number - hash of a combination of
2706 * the called hostname and the service name.
2708 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2709 (str_checksum(get_local_machine_name())<<16));
2711 /* Max label len is 32 characters. */
2712 len = srvstr_push(pdata, req->flags2, pdata+18, vname,
2713 PTR_DIFF(end_data, pdata+18),
2715 SIVAL(pdata,12,len);
2718 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2719 (int)strlen(vname),vname, lp_servicename(snum)));
2722 case SMB_QUERY_FS_SIZE_INFO:
2723 case SMB_FS_SIZE_INFORMATION:
2725 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2727 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2728 reply_unixerror(req, ERRHRD, ERRgeneral);
2731 block_size = lp_block_size(snum);
2732 if (bsize < block_size) {
2733 uint64_t factor = block_size/bsize;
2738 if (bsize > block_size) {
2739 uint64_t factor = bsize/block_size;
2744 bytes_per_sector = 512;
2745 sectors_per_unit = bsize/bytes_per_sector;
2746 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2747 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2748 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2749 SBIG_UINT(pdata,0,dsize);
2750 SBIG_UINT(pdata,8,dfree);
2751 SIVAL(pdata,16,sectors_per_unit);
2752 SIVAL(pdata,20,bytes_per_sector);
2756 case SMB_FS_FULL_SIZE_INFORMATION:
2758 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2760 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2761 reply_unixerror(req, ERRHRD, ERRgeneral);
2764 block_size = lp_block_size(snum);
2765 if (bsize < block_size) {
2766 uint64_t factor = block_size/bsize;
2771 if (bsize > block_size) {
2772 uint64_t factor = bsize/block_size;
2777 bytes_per_sector = 512;
2778 sectors_per_unit = bsize/bytes_per_sector;
2779 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2780 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2781 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2782 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2783 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2784 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2785 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2786 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2790 case SMB_QUERY_FS_DEVICE_INFO:
2791 case SMB_FS_DEVICE_INFORMATION:
2793 SIVAL(pdata,0,0); /* dev type */
2794 SIVAL(pdata,4,0); /* characteristics */
2797 #ifdef HAVE_SYS_QUOTAS
2798 case SMB_FS_QUOTA_INFORMATION:
2800 * what we have to send --metze:
2802 * Unknown1: 24 NULL bytes
2803 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
2804 * Hard Quota Limit: 8 bytes seems like uint64_t or so
2805 * Quota Flags: 2 byte :
2806 * Unknown3: 6 NULL bytes
2810 * details for Quota Flags:
2812 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2813 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2814 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2815 * 0x0001 Enable Quotas: enable quota for this fs
2819 /* we need to fake up a fsp here,
2820 * because its not send in this call
2823 SMB_NTQUOTA_STRUCT quotas;
2826 ZERO_STRUCT(quotas);
2832 if (conn->server_info->utok.uid != 0) {
2833 DEBUG(0,("set_user_quota: access_denied "
2834 "service [%s] user [%s]\n",
2835 lp_servicename(SNUM(conn)),
2836 conn->server_info->unix_name));
2837 reply_doserror(req, ERRDOS, ERRnoaccess);
2841 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2842 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2843 reply_doserror(req, ERRSRV, ERRerror);
2849 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2851 /* Unknown1 24 NULL bytes*/
2852 SBIG_UINT(pdata,0,(uint64_t)0);
2853 SBIG_UINT(pdata,8,(uint64_t)0);
2854 SBIG_UINT(pdata,16,(uint64_t)0);
2856 /* Default Soft Quota 8 bytes */
2857 SBIG_UINT(pdata,24,quotas.softlim);
2859 /* Default Hard Quota 8 bytes */
2860 SBIG_UINT(pdata,32,quotas.hardlim);
2862 /* Quota flag 2 bytes */
2863 SSVAL(pdata,40,quotas.qflags);
2865 /* Unknown3 6 NULL bytes */
2871 #endif /* HAVE_SYS_QUOTAS */
2872 case SMB_FS_OBJECTID_INFORMATION:
2874 unsigned char objid[16];
2875 struct smb_extended_info extended_info;
2876 memcpy(pdata,create_volume_objectid(conn, objid),16);
2877 samba_extended_info_version (&extended_info);
2878 SIVAL(pdata,16,extended_info.samba_magic);
2879 SIVAL(pdata,20,extended_info.samba_version);
2880 SIVAL(pdata,24,extended_info.samba_subversion);
2881 SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
2882 memcpy(pdata+36,extended_info.samba_version_string,28);
2888 * Query the version and capabilities of the CIFS UNIX extensions
2892 case SMB_QUERY_CIFS_UNIX_INFO:
2894 bool large_write = lp_min_receive_file_size() &&
2895 !srv_is_signing_active();
2896 bool large_read = !srv_is_signing_active();
2897 int encrypt_caps = 0;
2899 if (!lp_unix_extensions()) {
2900 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2904 switch (conn->encrypt_level) {
2910 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
2913 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
2914 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
2915 large_write = false;
2921 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2922 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2924 /* We have POSIX ACLs, pathname, encryption,
2925 * large read/write, and locking capability. */
2927 SBIG_UINT(pdata,4,((uint64_t)(
2928 CIFS_UNIX_POSIX_ACLS_CAP|
2929 CIFS_UNIX_POSIX_PATHNAMES_CAP|
2930 CIFS_UNIX_FCNTL_LOCKS_CAP|
2931 CIFS_UNIX_EXTATTR_CAP|
2932 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
2934 (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
2936 CIFS_UNIX_LARGE_WRITE_CAP : 0))));
2940 case SMB_QUERY_POSIX_FS_INFO:
2943 vfs_statvfs_struct svfs;
2945 if (!lp_unix_extensions()) {
2946 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2950 rc = SMB_VFS_STATVFS(conn, ".", &svfs);
2954 SIVAL(pdata,0,svfs.OptimalTransferSize);
2955 SIVAL(pdata,4,svfs.BlockSize);
2956 SBIG_UINT(pdata,8,svfs.TotalBlocks);
2957 SBIG_UINT(pdata,16,svfs.BlocksAvail);
2958 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
2959 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
2960 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
2961 SBIG_UINT(pdata,48,svfs.FsIdentifier);
2962 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2964 } else if (rc == EOPNOTSUPP) {
2965 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2967 #endif /* EOPNOTSUPP */
2969 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2970 reply_doserror(req, ERRSRV, ERRerror);
2976 case SMB_QUERY_POSIX_WHOAMI:
2982 if (!lp_unix_extensions()) {
2983 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2987 if (max_data_bytes < 40) {
2988 reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);