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 get_file_size(sbuf) ((sbuf).st_size)
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 Given a stat buffer return the allocated size on disk, taking into
65 ********************************************************************/
67 uint64_t get_allocation_size(connection_struct *conn, files_struct *fsp, const SMB_STRUCT_STAT *sbuf)
71 if(S_ISDIR(sbuf->st_mode)) {
75 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
76 ret = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks;
78 ret = (uint64_t)get_file_size(*sbuf);
81 if (fsp && fsp->initial_allocation_size)
82 ret = MAX(ret,fsp->initial_allocation_size);
84 return smb_roundup(conn, ret);
87 /****************************************************************************
88 Utility functions for dealing with extended attributes.
89 ****************************************************************************/
91 /****************************************************************************
92 Refuse to allow clients to overwrite our private xattrs.
93 ****************************************************************************/
95 static bool samba_private_attr_name(const char *unix_ea_name)
97 static const char * const prohibited_ea_names[] = {
98 SAMBA_POSIX_INHERITANCE_EA_NAME,
99 SAMBA_XATTR_DOS_ATTRIB,
105 for (i = 0; prohibited_ea_names[i]; i++) {
106 if (strequal( prohibited_ea_names[i], unix_ea_name))
109 if (StrnCaseCmp(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
110 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
116 /****************************************************************************
117 Get one EA value. Fill in a struct ea_struct.
118 ****************************************************************************/
120 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
121 files_struct *fsp, const char *fname,
122 const char *ea_name, struct ea_struct *pea)
124 /* Get the value of this xattr. Max size is 64k. */
125 size_t attr_size = 256;
131 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
133 return NT_STATUS_NO_MEMORY;
136 if (fsp && fsp->fh->fd != -1) {
137 sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
139 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
142 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
148 return map_nt_error_from_unix(errno);
151 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
152 dump_data(10, (uint8 *)val, sizeret);
155 if (strnequal(ea_name, "user.", 5)) {
156 pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
158 pea->name = talloc_strdup(mem_ctx, ea_name);
160 if (pea->name == NULL) {
162 return NT_STATUS_NO_MEMORY;
164 pea->value.data = (unsigned char *)val;
165 pea->value.length = (size_t)sizeret;
169 NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
170 files_struct *fsp, const char *fname,
171 char ***pnames, size_t *pnum_names)
173 /* Get a list of all xattrs. Max namesize is 64k. */
174 size_t ea_namelist_size = 1024;
175 char *ea_namelist = NULL;
180 ssize_t sizeret = -1;
182 if (!lp_ea_support(SNUM(conn))) {
189 * TALLOC the result early to get the talloc hierarchy right.
192 names = TALLOC_ARRAY(mem_ctx, char *, 1);
194 DEBUG(0, ("talloc failed\n"));
195 return NT_STATUS_NO_MEMORY;
198 while (ea_namelist_size <= 65536) {
200 ea_namelist = TALLOC_REALLOC_ARRAY(
201 names, ea_namelist, char, ea_namelist_size);
202 if (ea_namelist == NULL) {
203 DEBUG(0, ("talloc failed\n"));
205 return NT_STATUS_NO_MEMORY;
208 if (fsp && fsp->fh->fd != -1) {
209 sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
212 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist,
216 if ((sizeret == -1) && (errno == ERANGE)) {
217 ea_namelist_size *= 2;
226 return map_nt_error_from_unix(errno);
229 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
230 (unsigned int)sizeret));
240 * Ensure the result is 0-terminated
243 if (ea_namelist[sizeret-1] != '\0') {
245 return NT_STATUS_INTERNAL_ERROR;
253 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
257 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names);
259 DEBUG(0, ("talloc failed\n"));
261 return NT_STATUS_NO_MEMORY;
267 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
268 names[num_names++] = p;
272 *pnum_names = num_names;
276 /****************************************************************************
277 Return a linked list of the total EA's. Plus the total size
278 ****************************************************************************/
280 static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
281 const char *fname, size_t *pea_total_len)
283 /* Get a list of all xattrs. Max namesize is 64k. */
286 struct ea_list *ea_list_head = NULL;
291 if (!lp_ea_support(SNUM(conn))) {
295 status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
298 if (!NT_STATUS_IS_OK(status) || (num_names == 0)) {
302 for (i=0; i<num_names; i++) {
303 struct ea_list *listp;
306 if (strnequal(names[i], "system.", 7)
307 || samba_private_attr_name(names[i]))
310 listp = TALLOC_P(mem_ctx, struct ea_list);
315 if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx, conn, fsp,
321 push_ascii_fstring(dos_ea_name, listp->ea.name);
324 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
326 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
327 "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
328 (unsigned int)listp->ea.value.length));
330 DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
334 /* Add on 4 for total length. */
335 if (*pea_total_len) {
339 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
340 (unsigned int)*pea_total_len));
345 /****************************************************************************
346 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
348 ****************************************************************************/
350 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
351 connection_struct *conn, struct ea_list *ea_list)
353 unsigned int ret_data_size = 4;
356 SMB_ASSERT(total_data_size >= 4);
358 if (!lp_ea_support(SNUM(conn))) {
363 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
366 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
367 dos_namelen = strlen(dos_ea_name);
368 if (dos_namelen > 255 || dos_namelen == 0) {
371 if (ea_list->ea.value.length > 65535) {
374 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
378 /* We know we have room. */
379 SCVAL(p,0,ea_list->ea.flags);
380 SCVAL(p,1,dos_namelen);
381 SSVAL(p,2,ea_list->ea.value.length);
382 fstrcpy(p+4, dos_ea_name);
383 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
385 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
386 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
389 ret_data_size = PTR_DIFF(p, pdata);
390 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
391 SIVAL(pdata,0,ret_data_size);
392 return ret_data_size;
395 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
397 size_t total_ea_len = 0;
398 TALLOC_CTX *mem_ctx = NULL;
400 if (!lp_ea_support(SNUM(conn))) {
403 mem_ctx = talloc_tos();
404 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
408 /****************************************************************************
409 Ensure the EA name is case insensitive by matching any existing EA name.
410 ****************************************************************************/
412 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
415 TALLOC_CTX *mem_ctx = talloc_tos();
416 struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
418 for (; ea_list; ea_list = ea_list->next) {
419 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
420 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
421 &unix_ea_name[5], ea_list->ea.name));
422 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
428 /****************************************************************************
429 Set or delete an extended attribute.
430 ****************************************************************************/
432 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, struct ea_list *ea_list)
434 if (!lp_ea_support(SNUM(conn))) {
435 return NT_STATUS_EAS_NOT_SUPPORTED;
438 for (;ea_list; ea_list = ea_list->next) {
440 fstring unix_ea_name;
442 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
443 fstrcat(unix_ea_name, ea_list->ea.name);
445 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
447 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
449 if (samba_private_attr_name(unix_ea_name)) {
450 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
451 return NT_STATUS_ACCESS_DENIED;
454 if (ea_list->ea.value.length == 0) {
455 /* Remove the attribute. */
456 if (fsp && (fsp->fh->fd != -1)) {
457 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
458 unix_ea_name, fsp->fsp_name));
459 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
461 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
462 unix_ea_name, fname));
463 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
466 /* Removing a non existent attribute always succeeds. */
467 if (ret == -1 && errno == ENOATTR) {
468 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
474 if (fsp && (fsp->fh->fd != -1)) {
475 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
476 unix_ea_name, fsp->fsp_name));
477 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
478 ea_list->ea.value.data, ea_list->ea.value.length, 0);
480 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
481 unix_ea_name, fname));
482 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
483 ea_list->ea.value.data, ea_list->ea.value.length, 0);
489 if (errno == ENOTSUP) {
490 return NT_STATUS_EAS_NOT_SUPPORTED;
493 return map_nt_error_from_unix(errno);
499 /****************************************************************************
500 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
501 ****************************************************************************/
503 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
505 struct ea_list *ea_list_head = NULL;
506 size_t converted_size, offset = 0;
508 while (offset + 2 < data_size) {
509 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
510 unsigned int namelen = CVAL(pdata,offset);
512 offset++; /* Go past the namelen byte. */
514 /* integer wrap paranioa. */
515 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
516 (offset > data_size) || (namelen > data_size) ||
517 (offset + namelen >= data_size)) {
520 /* Ensure the name is null terminated. */
521 if (pdata[offset + namelen] != '\0') {
524 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
526 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
527 "failed: %s", strerror(errno)));
533 offset += (namelen + 1); /* Go past the name + terminating zero. */
534 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
535 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
541 /****************************************************************************
542 Read one EA list entry from the buffer.
543 ****************************************************************************/
545 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
547 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
549 unsigned int namelen;
550 size_t converted_size;
560 eal->ea.flags = CVAL(pdata,0);
561 namelen = CVAL(pdata,1);
562 val_len = SVAL(pdata,2);
564 if (4 + namelen + 1 + val_len > data_size) {
568 /* Ensure the name is null terminated. */
569 if (pdata[namelen + 4] != '\0') {
572 if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
573 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
580 eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
581 if (!eal->ea.value.data) {
585 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
587 /* Ensure we're null terminated just in case we print the value. */
588 eal->ea.value.data[val_len] = '\0';
589 /* But don't count the null. */
590 eal->ea.value.length--;
593 *pbytes_used = 4 + namelen + 1 + val_len;
596 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
597 dump_data(10, eal->ea.value.data, eal->ea.value.length);
602 /****************************************************************************
603 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
604 ****************************************************************************/
606 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
608 struct ea_list *ea_list_head = NULL;
610 size_t bytes_used = 0;
612 while (offset < data_size) {
613 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
619 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
620 offset += bytes_used;
626 /****************************************************************************
627 Count the total EA size needed.
628 ****************************************************************************/
630 static size_t ea_list_size(struct ea_list *ealist)
633 struct ea_list *listp;
636 for (listp = ealist; listp; listp = listp->next) {
637 push_ascii_fstring(dos_ea_name, listp->ea.name);
638 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
640 /* Add on 4 for total length. */
648 /****************************************************************************
649 Return a union of EA's from a file list and a list of names.
650 The TALLOC context for the two lists *MUST* be identical as we steal
651 memory from one list to add to another. JRA.
652 ****************************************************************************/
654 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
656 struct ea_list *nlistp, *flistp;
658 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
659 for (flistp = file_list; flistp; flistp = flistp->next) {
660 if (strequal(nlistp->ea.name, flistp->ea.name)) {
666 /* Copy the data from this entry. */
667 nlistp->ea.flags = flistp->ea.flags;
668 nlistp->ea.value = flistp->ea.value;
671 nlistp->ea.flags = 0;
672 ZERO_STRUCT(nlistp->ea.value);
676 *total_ea_len = ea_list_size(name_list);
680 /****************************************************************************
681 Send the required number of replies back.
682 We assume all fields other than the data fields are
683 set correctly for the type of call.
684 HACK ! Always assumes smb_setup field is zero.
685 ****************************************************************************/
687 void send_trans2_replies(connection_struct *conn,
688 struct smb_request *req,
695 /* As we are using a protocol > LANMAN1 then the max_send
696 variable must have been set in the sessetupX call.
697 This takes precedence over the max_xmit field in the
698 global struct. These different max_xmit variables should
699 be merged as this is now too confusing */
701 int data_to_send = datasize;
702 int params_to_send = paramsize;
704 const char *pp = params;
705 const char *pd = pdata;
706 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
707 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
708 int data_alignment_offset = 0;
709 bool overflow = False;
711 /* Modify the data_to_send and datasize and set the error if
712 we're trying to send more than max_data_bytes. We still send
713 the part of the packet(s) that fit. Strange, but needed
716 if (max_data_bytes > 0 && datasize > max_data_bytes) {
717 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
718 max_data_bytes, datasize ));
719 datasize = data_to_send = max_data_bytes;
723 /* If there genuinely are no parameters or data to send just send the empty packet */
725 if(params_to_send == 0 && data_to_send == 0) {
726 reply_outbuf(req, 10, 0);
727 show_msg((char *)req->outbuf);
731 /* When sending params and data ensure that both are nicely aligned */
732 /* Only do this alignment when there is also data to send - else
733 can cause NT redirector problems. */
735 if (((params_to_send % 4) != 0) && (data_to_send != 0))
736 data_alignment_offset = 4 - (params_to_send % 4);
738 /* Space is bufsize minus Netbios over TCP header minus SMB header */
739 /* The alignment_offset is to align the param bytes on an even byte
740 boundary. NT 4.0 Beta needs this to work correctly. */
742 useable_space = max_send - (smb_size
745 + data_alignment_offset);
747 if (useable_space < 0) {
748 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
749 "= %d!!!", useable_space));
750 exit_server_cleanly("send_trans2_replies: Not enough space");
753 while (params_to_send || data_to_send) {
754 /* Calculate whether we will totally or partially fill this packet */
756 total_sent_thistime = params_to_send + data_to_send;
758 /* We can never send more than useable_space */
760 * Note that 'useable_space' does not include the alignment offsets,
761 * but we must include the alignment offsets in the calculation of
762 * the length of the data we send over the wire, as the alignment offsets
763 * are sent here. Fix from Marc_Jacobsen@hp.com.
766 total_sent_thistime = MIN(total_sent_thistime, useable_space);
768 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
769 + data_alignment_offset);
772 * We might have SMBtrans2s in req which was transferred to
773 * the outbuf, fix that.
775 SCVAL(req->outbuf, smb_com, SMBtrans2);
777 /* Set total params and data to be sent */
778 SSVAL(req->outbuf,smb_tprcnt,paramsize);
779 SSVAL(req->outbuf,smb_tdrcnt,datasize);
781 /* Calculate how many parameters and data we can fit into
782 * this packet. Parameters get precedence
785 params_sent_thistime = MIN(params_to_send,useable_space);
786 data_sent_thistime = useable_space - params_sent_thistime;
787 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
789 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
791 /* smb_proff is the offset from the start of the SMB header to the
792 parameter bytes, however the first 4 bytes of outbuf are
793 the Netbios over TCP header. Thus use smb_base() to subtract
794 them from the calculation */
796 SSVAL(req->outbuf,smb_proff,
797 ((smb_buf(req->outbuf)+alignment_offset)
798 - smb_base(req->outbuf)));
800 if(params_sent_thistime == 0)
801 SSVAL(req->outbuf,smb_prdisp,0);
803 /* Absolute displacement of param bytes sent in this packet */
804 SSVAL(req->outbuf,smb_prdisp,pp - params);
806 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
807 if(data_sent_thistime == 0) {
808 SSVAL(req->outbuf,smb_droff,0);
809 SSVAL(req->outbuf,smb_drdisp, 0);
811 /* The offset of the data bytes is the offset of the
812 parameter bytes plus the number of parameters being sent this time */
813 SSVAL(req->outbuf, smb_droff,
814 ((smb_buf(req->outbuf)+alignment_offset)
815 - smb_base(req->outbuf))
816 + params_sent_thistime + data_alignment_offset);
817 SSVAL(req->outbuf,smb_drdisp, pd - pdata);
820 /* Initialize the padding for alignment */
822 if (alignment_offset != 0) {
823 memset(smb_buf(req->outbuf), 0, alignment_offset);
826 /* Copy the param bytes into the packet */
828 if(params_sent_thistime) {
829 memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
830 params_sent_thistime);
833 /* Copy in the data bytes */
834 if(data_sent_thistime) {
835 if (data_alignment_offset != 0) {
836 memset((smb_buf(req->outbuf)+alignment_offset+
837 params_sent_thistime), 0,
838 data_alignment_offset);
840 memcpy(smb_buf(req->outbuf)+alignment_offset
841 +params_sent_thistime+data_alignment_offset,
842 pd,data_sent_thistime);
845 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
846 params_sent_thistime, data_sent_thistime, useable_space));
847 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
848 params_to_send, data_to_send, paramsize, datasize));
851 error_packet_set((char *)req->outbuf,
852 ERRDOS,ERRbufferoverflow,
853 STATUS_BUFFER_OVERFLOW,
857 /* Send the packet */
858 show_msg((char *)req->outbuf);
859 if (!srv_send_smb(smbd_server_fd(),
861 IS_CONN_ENCRYPTED(conn)))
862 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
864 TALLOC_FREE(req->outbuf);
866 pp += params_sent_thistime;
867 pd += data_sent_thistime;
869 params_to_send -= params_sent_thistime;
870 data_to_send -= data_sent_thistime;
873 if(params_to_send < 0 || data_to_send < 0) {
874 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
875 params_to_send, data_to_send));
883 /****************************************************************************
884 Reply to a TRANSACT2_OPEN.
885 ****************************************************************************/
887 static void call_trans2open(connection_struct *conn,
888 struct smb_request *req,
889 char **pparams, int total_params,
890 char **ppdata, int total_data,
891 unsigned int max_data_bytes)
893 char *params = *pparams;
894 char *pdata = *ppdata;
899 bool return_additional_info;
910 SMB_STRUCT_STAT sbuf;
913 struct ea_list *ea_list = NULL;
918 uint32 create_disposition;
919 uint32 create_options = 0;
920 TALLOC_CTX *ctx = talloc_tos();
923 * Ensure we have enough parameters to perform the operation.
926 if (total_params < 29) {
927 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
931 flags = SVAL(params, 0);
932 deny_mode = SVAL(params, 2);
933 open_attr = SVAL(params,6);
934 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
935 if (oplock_request) {
936 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
940 return_additional_info = BITSETW(params,0);
941 open_sattr = SVAL(params, 4);
942 open_time = make_unix_date3(params+8);
944 open_ofun = SVAL(params,12);
945 open_size = IVAL(params,14);
949 reply_doserror(req, ERRSRV, ERRaccess);
953 srvstr_get_path(ctx, params, req->flags2, &fname, pname,
954 total_params - 28, STR_TERMINATE,
956 if (!NT_STATUS_IS_OK(status)) {
957 reply_nterror(req, status);
961 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
962 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
963 (unsigned int)open_ofun, open_size));
965 if (open_ofun == 0) {
966 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
970 if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
975 reply_doserror(req, ERRDOS, ERRbadaccess);
979 /* Any data in this call is an EA list. */
980 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
981 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
985 if (total_data != 4) {
986 if (total_data < 10) {
987 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
991 if (IVAL(pdata,0) > total_data) {
992 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
993 IVAL(pdata,0), (unsigned int)total_data));
994 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
998 ea_list = read_ea_list(talloc_tos(), pdata + 4,
1001 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1004 } else if (IVAL(pdata,0) != 4) {
1005 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1009 status = SMB_VFS_CREATE_FILE(
1012 0, /* root_dir_fid */
1014 CFF_DOS_PATH, /* create_file_flags */
1015 access_mask, /* access_mask */
1016 share_mode, /* share_access */
1017 create_disposition, /* create_disposition*/
1018 create_options, /* create_options */
1019 open_attr, /* file_attributes */
1020 oplock_request, /* oplock_request */
1021 open_size, /* allocation_size */
1023 ea_list, /* ea_list */
1025 &smb_action, /* pinfo */
1028 if (!NT_STATUS_IS_OK(status)) {
1029 if (open_was_deferred(req->mid)) {
1030 /* We have re-scheduled this call. */
1033 reply_openerror(req, status);
1037 size = get_file_size(sbuf);
1038 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1039 mtime = sbuf.st_mtime;
1040 inode = sbuf.st_ino;
1042 close_file(req, fsp, ERROR_CLOSE);
1043 reply_doserror(req, ERRDOS,ERRnoaccess);
1047 /* Realloc the size of parameters and data we will return */
1048 *pparams = (char *)SMB_REALLOC(*pparams, 30);
1049 if(*pparams == NULL ) {
1050 reply_nterror(req, NT_STATUS_NO_MEMORY);
1055 SSVAL(params,0,fsp->fnum);
1056 SSVAL(params,2,fattr);
1057 srv_put_dos_date2(params,4, mtime);
1058 SIVAL(params,8, (uint32)size);
1059 SSVAL(params,12,deny_mode);
1060 SSVAL(params,14,0); /* open_type - file or directory. */
1061 SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1063 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1064 smb_action |= EXTENDED_OPLOCK_GRANTED;
1067 SSVAL(params,18,smb_action);
1070 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1072 SIVAL(params,20,inode);
1073 SSVAL(params,24,0); /* Padding. */
1075 uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
1076 SIVAL(params, 26, ea_size);
1078 SIVAL(params, 26, 0);
1081 /* Send the required number of replies */
1082 send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
1085 /*********************************************************
1086 Routine to check if a given string matches exactly.
1087 as a special case a mask of "." does NOT match. That
1088 is required for correct wildcard semantics
1089 Case can be significant or not.
1090 **********************************************************/
1092 static bool exact_match(connection_struct *conn,
1096 if (mask[0] == '.' && mask[1] == 0)
1098 if (dptr_has_wild(conn->dirptr)) {
1101 if (conn->case_sensitive)
1102 return strcmp(str,mask)==0;
1104 return StrCaseCmp(str,mask) == 0;
1107 /****************************************************************************
1108 Return the filetype for UNIX extensions.
1109 ****************************************************************************/
1111 static uint32 unix_filetype(mode_t mode)
1114 return UNIX_TYPE_FILE;
1115 else if(S_ISDIR(mode))
1116 return UNIX_TYPE_DIR;
1118 else if(S_ISLNK(mode))
1119 return UNIX_TYPE_SYMLINK;
1122 else if(S_ISCHR(mode))
1123 return UNIX_TYPE_CHARDEV;
1126 else if(S_ISBLK(mode))
1127 return UNIX_TYPE_BLKDEV;
1130 else if(S_ISFIFO(mode))
1131 return UNIX_TYPE_FIFO;
1134 else if(S_ISSOCK(mode))
1135 return UNIX_TYPE_SOCKET;
1138 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1139 return UNIX_TYPE_UNKNOWN;
1142 /****************************************************************************
1143 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1144 ****************************************************************************/
1146 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1148 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1149 SMB_STRUCT_STAT *psbuf,
1151 enum perm_type ptype,
1156 if (perms == SMB_MODE_NO_CHANGE) {
1157 if (!VALID_STAT(*psbuf)) {
1158 return NT_STATUS_INVALID_PARAMETER;
1160 *ret_perms = psbuf->st_mode;
1161 return NT_STATUS_OK;
1165 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1166 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1167 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1168 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1169 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1170 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1171 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1172 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1173 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1175 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1178 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1181 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1186 /* Apply mode mask */
1187 ret &= lp_create_mask(SNUM(conn));
1188 /* Add in force bits */
1189 ret |= lp_force_create_mode(SNUM(conn));
1192 ret &= lp_dir_mask(SNUM(conn));
1193 /* Add in force bits */
1194 ret |= lp_force_dir_mode(SNUM(conn));
1196 case PERM_EXISTING_FILE:
1197 /* Apply mode mask */
1198 ret &= lp_security_mask(SNUM(conn));
1199 /* Add in force bits */
1200 ret |= lp_force_security_mode(SNUM(conn));
1202 case PERM_EXISTING_DIR:
1203 /* Apply mode mask */
1204 ret &= lp_dir_security_mask(SNUM(conn));
1205 /* Add in force bits */
1206 ret |= lp_force_dir_security_mode(SNUM(conn));
1211 return NT_STATUS_OK;
1214 /****************************************************************************
1215 Needed to show the msdfs symlinks as directories. Modifies psbuf
1216 to be a directory if it's a msdfs link.
1217 ****************************************************************************/
1219 static bool check_msdfs_link(connection_struct *conn,
1220 const char *pathname,
1221 SMB_STRUCT_STAT *psbuf)
1223 int saved_errno = errno;
1224 if(lp_host_msdfs() &&
1225 lp_msdfs_root(SNUM(conn)) &&
1226 is_msdfs_link(conn, pathname, psbuf)) {
1228 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1231 psbuf->st_mode = (psbuf->st_mode & 0xFFF) | S_IFDIR;
1232 errno = saved_errno;
1235 errno = saved_errno;
1240 /****************************************************************************
1241 Get a level dependent lanman2 dir entry.
1242 ****************************************************************************/
1244 static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
1245 connection_struct *conn,
1247 const char *path_mask,
1250 int requires_resume_key,
1256 int space_remaining,
1258 bool *got_exact_match,
1259 int *last_entry_off,
1260 struct ea_list *name_list)
1264 SMB_STRUCT_STAT sbuf;
1265 const char *mask = NULL;
1266 char *pathreal = NULL;
1267 const char *fname = NULL;
1268 char *p, *q, *pdata = *ppdata;
1272 SMB_OFF_T file_size = 0;
1273 uint64_t allocation_size = 0;
1275 struct timespec mdate_ts, adate_ts, create_date_ts;
1276 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1278 char *last_entry_ptr;
1280 uint32 nt_extmode; /* Used for NT connections instead of mode */
1281 bool needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1282 bool check_mangled_names = lp_manglednames(conn->params);
1283 char mangled_name[13]; /* mangled 8.3 name. */
1285 *out_of_space = False;
1286 *got_exact_match = False;
1288 ZERO_STRUCT(mdate_ts);
1289 ZERO_STRUCT(adate_ts);
1290 ZERO_STRUCT(create_date_ts);
1292 if (!conn->dirptr) {
1296 p = strrchr_m(path_mask,'/');
1299 mask = talloc_strdup(ctx,"*.*");
1309 bool ms_dfs_link = False;
1311 /* Needed if we run out of space */
1312 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1313 dname = dptr_ReadDirName(ctx,conn->dirptr,&curr_dirpos,&sbuf);
1316 * Due to bugs in NT client redirectors we are not using
1317 * resume keys any more - set them to zero.
1318 * Check out the related comments in findfirst/findnext.
1324 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1325 (long)conn->dirptr,curr_dirpos));
1332 * fname may get mangled, dname is never mangled.
1333 * Whenever we're accessing the filesystem we use
1334 * pathreal which is composed from dname.
1340 /* Mangle fname if it's an illegal name. */
1341 if (mangle_must_mangle(dname,conn->params)) {
1342 if (!name_to_8_3(dname,mangled_name,True,conn->params)) {
1343 continue; /* Error - couldn't mangle. */
1345 fname = mangled_name;
1348 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
1349 got_match = mask_match(fname, mask, conn->case_sensitive);
1352 if(!got_match && check_mangled_names &&
1353 !mangle_is_8_3(fname, False, conn->params)) {
1355 * It turns out that NT matches wildcards against
1356 * both long *and* short names. This may explain some
1357 * of the wildcard wierdness from old DOS clients
1358 * that some people have been seeing.... JRA.
1360 /* Force the mangling into 8.3. */
1361 if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
1362 continue; /* Error - couldn't mangle. */
1365 if(!(got_match = *got_exact_match = exact_match(conn, mangled_name, mask))) {
1366 got_match = mask_match(mangled_name, mask, conn->case_sensitive);
1371 bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
1373 if (dont_descend && !isdots) {
1379 pathreal = talloc_asprintf(ctx,
1384 pathreal = talloc_asprintf(ctx,
1394 if (INFO_LEVEL_IS_UNIX(info_level)) {
1395 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1396 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1397 pathreal,strerror(errno)));
1398 TALLOC_FREE(pathreal);
1401 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1402 /* Needed to show the msdfs symlinks as
1405 ms_dfs_link = check_msdfs_link(conn, pathreal, &sbuf);
1407 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1408 pathreal,strerror(errno)));
1409 TALLOC_FREE(pathreal);
1415 mode = dos_mode_msdfs(conn,pathreal,&sbuf);
1417 mode = dos_mode(conn,pathreal,&sbuf);
1420 if (!dir_check_ftype(conn,mode,dirtype)) {
1421 DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
1422 TALLOC_FREE(pathreal);
1426 if (!(mode & aDIR)) {
1427 file_size = get_file_size(sbuf);
1429 allocation_size = get_allocation_size(conn,NULL,&sbuf);
1431 mdate_ts = get_mtimespec(&sbuf);
1432 adate_ts = get_atimespec(&sbuf);
1433 create_date_ts = get_create_timespec(&sbuf,
1434 lp_fake_dir_create_times(SNUM(conn)));
1436 if (ask_sharemode) {
1437 struct timespec write_time_ts;
1438 struct file_id fileid;
1440 fileid = vfs_file_id_from_sbuf(conn, &sbuf);
1441 get_file_infos(fileid, NULL, &write_time_ts);
1442 if (!null_timespec(write_time_ts)) {
1443 mdate_ts = write_time_ts;
1447 if (lp_dos_filetime_resolution(SNUM(conn))) {
1448 dos_filetime_timespec(&create_date_ts);
1449 dos_filetime_timespec(&mdate_ts);
1450 dos_filetime_timespec(&adate_ts);
1453 create_date = convert_timespec_to_time_t(create_date_ts);
1454 mdate = convert_timespec_to_time_t(mdate_ts);
1455 adate = convert_timespec_to_time_t(adate_ts);
1457 DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",
1462 dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1469 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1471 switch (info_level) {
1472 case SMB_FIND_INFO_STANDARD:
1473 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1474 if(requires_resume_key) {
1478 srv_put_dos_date2(p,0,create_date);
1479 srv_put_dos_date2(p,4,adate);
1480 srv_put_dos_date2(p,8,mdate);
1481 SIVAL(p,12,(uint32)file_size);
1482 SIVAL(p,16,(uint32)allocation_size);
1486 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1487 p += ucs2_align(base_data, p, 0);
1489 len = srvstr_push(base_data, flags2, p,
1490 fname, PTR_DIFF(end_data, p),
1492 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1494 SCVAL(nameptr, -1, len - 2);
1496 SCVAL(nameptr, -1, 0);
1500 SCVAL(nameptr, -1, len - 1);
1502 SCVAL(nameptr, -1, 0);
1508 case SMB_FIND_EA_SIZE:
1509 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1510 if(requires_resume_key) {
1514 srv_put_dos_date2(p,0,create_date);
1515 srv_put_dos_date2(p,4,adate);
1516 srv_put_dos_date2(p,8,mdate);
1517 SIVAL(p,12,(uint32)file_size);
1518 SIVAL(p,16,(uint32)allocation_size);
1521 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1522 SIVAL(p,22,ea_size); /* Extended attributes */
1526 len = srvstr_push(base_data, flags2,
1527 p, fname, PTR_DIFF(end_data, p),
1528 STR_TERMINATE | STR_NOALIGN);
1529 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1542 SCVAL(nameptr,0,len);
1544 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1547 case SMB_FIND_EA_LIST:
1549 struct ea_list *file_list = NULL;
1552 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1556 if(requires_resume_key) {
1560 srv_put_dos_date2(p,0,create_date);
1561 srv_put_dos_date2(p,4,adate);
1562 srv_put_dos_date2(p,8,mdate);
1563 SIVAL(p,12,(uint32)file_size);
1564 SIVAL(p,16,(uint32)allocation_size);
1566 p += 22; /* p now points to the EA area. */
1568 file_list = get_ea_list_from_file(ctx, conn, NULL, pathreal, &ea_len);
1569 name_list = ea_list_union(name_list, file_list, &ea_len);
1571 /* We need to determine if this entry will fit in the space available. */
1572 /* Max string size is 255 bytes. */
1573 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1574 /* Move the dirptr back to prev_dirpos */
1575 dptr_SeekDir(conn->dirptr, prev_dirpos);
1576 *out_of_space = True;
1577 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1578 return False; /* Not finished - just out of space */
1581 /* Push the ea_data followed by the name. */
1582 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1584 len = srvstr_push(base_data, flags2,
1585 p + 1, fname, PTR_DIFF(end_data, p+1),
1586 STR_TERMINATE | STR_NOALIGN);
1587 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1600 SCVAL(nameptr,0,len);
1602 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1606 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1607 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1608 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1610 SIVAL(p,0,reskey); p += 4;
1611 put_long_date_timespec(p,create_date_ts); p += 8;
1612 put_long_date_timespec(p,adate_ts); p += 8;
1613 put_long_date_timespec(p,mdate_ts); p += 8;
1614 put_long_date_timespec(p,mdate_ts); p += 8;
1615 SOFF_T(p,0,file_size); p += 8;
1616 SOFF_T(p,0,allocation_size); p += 8;
1617 SIVAL(p,0,nt_extmode); p += 4;
1618 q = p; p += 4; /* q is placeholder for name length. */
1620 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1621 SIVAL(p,0,ea_size); /* Extended attributes */
1624 /* Clear the short name buffer. This is
1625 * IMPORTANT as not doing so will trigger
1626 * a Win2k client bug. JRA.
1628 if (!was_8_3 && check_mangled_names) {
1629 if (!name_to_8_3(fname,mangled_name,True,
1631 /* Error - mangle failed ! */
1632 memset(mangled_name,'\0',12);
1634 mangled_name[12] = 0;
1635 len = srvstr_push(base_data, flags2,
1636 p+2, mangled_name, 24,
1637 STR_UPPER|STR_UNICODE);
1639 memset(p + 2 + len,'\0',24 - len);
1646 len = srvstr_push(base_data, flags2, p,
1647 fname, PTR_DIFF(end_data, p),
1648 STR_TERMINATE_ASCII);
1651 SIVAL(p,0,0); /* Ensure any padding is null. */
1652 len = PTR_DIFF(p, pdata);
1653 len = (len + 3) & ~3;
1658 case SMB_FIND_FILE_DIRECTORY_INFO:
1659 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1661 SIVAL(p,0,reskey); p += 4;
1662 put_long_date_timespec(p,create_date_ts); p += 8;
1663 put_long_date_timespec(p,adate_ts); p += 8;
1664 put_long_date_timespec(p,mdate_ts); p += 8;
1665 put_long_date_timespec(p,mdate_ts); p += 8;
1666 SOFF_T(p,0,file_size); p += 8;
1667 SOFF_T(p,0,allocation_size); p += 8;
1668 SIVAL(p,0,nt_extmode); p += 4;
1669 len = srvstr_push(base_data, flags2,
1670 p + 4, fname, PTR_DIFF(end_data, p+4),
1671 STR_TERMINATE_ASCII);
1674 SIVAL(p,0,0); /* Ensure any padding is null. */
1675 len = PTR_DIFF(p, pdata);
1676 len = (len + 3) & ~3;
1681 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1682 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1684 SIVAL(p,0,reskey); p += 4;
1685 put_long_date_timespec(p,create_date_ts); p += 8;
1686 put_long_date_timespec(p,adate_ts); p += 8;
1687 put_long_date_timespec(p,mdate_ts); p += 8;
1688 put_long_date_timespec(p,mdate_ts); p += 8;
1689 SOFF_T(p,0,file_size); p += 8;
1690 SOFF_T(p,0,allocation_size); p += 8;
1691 SIVAL(p,0,nt_extmode); p += 4;
1692 q = p; p += 4; /* q is placeholder for name length. */
1694 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1695 SIVAL(p,0,ea_size); /* Extended attributes */
1698 len = srvstr_push(base_data, flags2, p,
1699 fname, PTR_DIFF(end_data, p),
1700 STR_TERMINATE_ASCII);
1704 SIVAL(p,0,0); /* Ensure any padding is null. */
1705 len = PTR_DIFF(p, pdata);
1706 len = (len + 3) & ~3;
1711 case SMB_FIND_FILE_NAMES_INFO:
1712 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1714 SIVAL(p,0,reskey); p += 4;
1716 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1717 acl on a dir (tridge) */
1718 len = srvstr_push(base_data, flags2, p,
1719 fname, PTR_DIFF(end_data, p),
1720 STR_TERMINATE_ASCII);
1723 SIVAL(p,0,0); /* Ensure any padding is null. */
1724 len = PTR_DIFF(p, pdata);
1725 len = (len + 3) & ~3;
1730 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1731 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1733 SIVAL(p,0,reskey); p += 4;
1734 put_long_date_timespec(p,create_date_ts); p += 8;
1735 put_long_date_timespec(p,adate_ts); p += 8;
1736 put_long_date_timespec(p,mdate_ts); p += 8;
1737 put_long_date_timespec(p,mdate_ts); p += 8;
1738 SOFF_T(p,0,file_size); p += 8;
1739 SOFF_T(p,0,allocation_size); p += 8;
1740 SIVAL(p,0,nt_extmode); p += 4;
1741 q = p; p += 4; /* q is placeholder for name length. */
1743 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1744 SIVAL(p,0,ea_size); /* Extended attributes */
1747 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1748 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1749 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1750 len = srvstr_push(base_data, flags2, p,
1751 fname, PTR_DIFF(end_data, p),
1752 STR_TERMINATE_ASCII);
1755 SIVAL(p,0,0); /* Ensure any padding is null. */
1756 len = PTR_DIFF(p, pdata);
1757 len = (len + 3) & ~3;
1762 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1763 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1764 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1766 SIVAL(p,0,reskey); p += 4;
1767 put_long_date_timespec(p,create_date_ts); p += 8;
1768 put_long_date_timespec(p,adate_ts); p += 8;
1769 put_long_date_timespec(p,mdate_ts); p += 8;
1770 put_long_date_timespec(p,mdate_ts); p += 8;
1771 SOFF_T(p,0,file_size); p += 8;
1772 SOFF_T(p,0,allocation_size); p += 8;
1773 SIVAL(p,0,nt_extmode); p += 4;
1774 q = p; p += 4; /* q is placeholder for name length */
1776 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1777 SIVAL(p,0,ea_size); /* Extended attributes */
1780 /* Clear the short name buffer. This is
1781 * IMPORTANT as not doing so will trigger
1782 * a Win2k client bug. JRA.
1784 if (!was_8_3 && check_mangled_names) {
1785 if (!name_to_8_3(fname,mangled_name,True,
1787 /* Error - mangle failed ! */
1788 memset(mangled_name,'\0',12);
1790 mangled_name[12] = 0;
1791 len = srvstr_push(base_data, flags2,
1792 p+2, mangled_name, 24,
1793 STR_UPPER|STR_UNICODE);
1796 memset(p + 2 + len,'\0',24 - len);
1803 SSVAL(p,0,0); p += 2; /* Reserved ? */
1804 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1805 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1806 len = srvstr_push(base_data, flags2, p,
1807 fname, PTR_DIFF(end_data, p),
1808 STR_TERMINATE_ASCII);
1811 SIVAL(p,0,0); /* Ensure any padding is null. */
1812 len = PTR_DIFF(p, pdata);
1813 len = (len + 3) & ~3;
1818 /* CIFS UNIX Extension. */
1820 case SMB_FIND_FILE_UNIX:
1821 case SMB_FIND_FILE_UNIX_INFO2:
1823 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1825 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1827 if (info_level == SMB_FIND_FILE_UNIX) {
1828 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1829 p = store_file_unix_basic(conn, p,
1831 len = srvstr_push(base_data, flags2, p,
1832 fname, PTR_DIFF(end_data, p),
1835 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1836 p = store_file_unix_basic_info2(conn, p,
1840 len = srvstr_push(base_data, flags2, p, fname,
1841 PTR_DIFF(end_data, p), 0);
1842 SIVAL(nameptr, 0, len);
1846 SIVAL(p,0,0); /* Ensure any padding is null. */
1848 len = PTR_DIFF(p, pdata);
1849 len = (len + 3) & ~3;
1850 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1852 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1861 if (PTR_DIFF(p,pdata) > space_remaining) {
1862 /* Move the dirptr back to prev_dirpos */
1863 dptr_SeekDir(conn->dirptr, prev_dirpos);
1864 *out_of_space = True;
1865 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1866 return False; /* Not finished - just out of space */
1869 /* Setup the last entry pointer, as an offset from base_data */
1870 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1871 /* Advance the data pointer to the next slot */
1877 /****************************************************************************
1878 Reply to a TRANS2_FINDFIRST.
1879 ****************************************************************************/
1881 static void call_trans2findfirst(connection_struct *conn,
1882 struct smb_request *req,
1883 char **pparams, int total_params,
1884 char **ppdata, int total_data,
1885 unsigned int max_data_bytes)
1887 /* We must be careful here that we don't return more than the
1888 allowed number of data bytes. If this means returning fewer than
1889 maxentries then so be it. We assume that the redirector has
1890 enough room for the fixed number of parameter bytes it has
1892 char *params = *pparams;
1893 char *pdata = *ppdata;
1897 uint16 findfirst_flags;
1898 bool close_after_first;
1900 bool requires_resume_key;
1902 char *directory = NULL;
1905 int last_entry_off=0;
1909 bool finished = False;
1910 bool dont_descend = False;
1911 bool out_of_space = False;
1912 int space_remaining;
1913 bool mask_contains_wcard = False;
1914 SMB_STRUCT_STAT sbuf;
1915 struct ea_list *ea_list = NULL;
1916 NTSTATUS ntstatus = NT_STATUS_OK;
1917 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1918 TALLOC_CTX *ctx = talloc_tos();
1920 if (total_params < 13) {
1921 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1925 dirtype = SVAL(params,0);
1926 maxentries = SVAL(params,2);
1927 findfirst_flags = SVAL(params,4);
1928 close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1929 close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1930 requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1931 info_level = SVAL(params,6);
1933 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
1934 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1935 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1936 info_level, max_data_bytes));
1939 /* W2K3 seems to treat zero as 1. */
1943 switch (info_level) {
1944 case SMB_FIND_INFO_STANDARD:
1945 case SMB_FIND_EA_SIZE:
1946 case SMB_FIND_EA_LIST:
1947 case SMB_FIND_FILE_DIRECTORY_INFO:
1948 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1949 case SMB_FIND_FILE_NAMES_INFO:
1950 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1951 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1952 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1954 case SMB_FIND_FILE_UNIX:
1955 case SMB_FIND_FILE_UNIX_INFO2:
1956 /* Always use filesystem for UNIX mtime query. */
1957 ask_sharemode = false;
1958 if (!lp_unix_extensions()) {
1959 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1964 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
1968 srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
1969 params+12, total_params - 12,
1970 STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1971 if (!NT_STATUS_IS_OK(ntstatus)) {
1972 reply_nterror(req, ntstatus);
1976 ntstatus = resolve_dfspath_wcard(ctx, conn,
1977 req->flags2 & FLAGS2_DFS_PATHNAMES,
1980 &mask_contains_wcard);
1981 if (!NT_STATUS_IS_OK(ntstatus)) {
1982 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
1983 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1984 ERRSRV, ERRbadpath);
1987 reply_nterror(req, ntstatus);
1991 ntstatus = unix_convert(ctx, conn, directory, True, &directory, &mask, &sbuf);
1992 if (!NT_STATUS_IS_OK(ntstatus)) {
1993 reply_nterror(req, ntstatus);
1997 ntstatus = check_name(conn, directory);
1998 if (!NT_STATUS_IS_OK(ntstatus)) {
1999 reply_nterror(req, ntstatus);
2003 p = strrchr_m(directory,'/');
2005 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2006 if((directory[0] == '.') && (directory[1] == '\0')) {
2007 mask = talloc_strdup(ctx,"*");
2009 reply_nterror(req, NT_STATUS_NO_MEMORY);
2012 mask_contains_wcard = True;
2014 directory = talloc_strdup(talloc_tos(), "./");
2016 reply_nterror(req, NT_STATUS_NO_MEMORY);
2023 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2025 if (info_level == SMB_FIND_EA_LIST) {
2028 if (total_data < 4) {
2029 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2033 ea_size = IVAL(pdata,0);
2034 if (ea_size != total_data) {
2035 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2036 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2037 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2041 if (!lp_ea_support(SNUM(conn))) {
2042 reply_doserror(req, ERRDOS, ERReasnotsupported);
2046 /* Pull out the list of names. */
2047 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2049 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2054 *ppdata = (char *)SMB_REALLOC(
2055 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2056 if(*ppdata == NULL ) {
2057 reply_nterror(req, NT_STATUS_NO_MEMORY);
2061 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2063 /* Realloc the params space */
2064 *pparams = (char *)SMB_REALLOC(*pparams, 10);
2065 if (*pparams == NULL) {
2066 reply_nterror(req, NT_STATUS_NO_MEMORY);
2071 /* Save the wildcard match and attribs we are using on this directory -
2072 needed as lanman2 assumes these are being saved between calls */
2074 ntstatus = dptr_create(conn,
2080 mask_contains_wcard,
2084 if (!NT_STATUS_IS_OK(ntstatus)) {
2085 reply_nterror(req, ntstatus);
2089 dptr_num = dptr_dnum(conn->dirptr);
2090 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2092 /* We don't need to check for VOL here as this is returned by
2093 a different TRANS2 call. */
2095 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
2096 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2097 dont_descend = True;
2100 space_remaining = max_data_bytes;
2101 out_of_space = False;
2103 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2104 bool got_exact_match = False;
2106 /* this is a heuristic to avoid seeking the dirptr except when
2107 absolutely necessary. It allows for a filename of about 40 chars */
2108 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2109 out_of_space = True;
2112 finished = !get_lanman2_dir_entry(ctx,
2115 mask,dirtype,info_level,
2116 requires_resume_key,dont_descend,
2119 space_remaining, &out_of_space,
2121 &last_entry_off, ea_list);
2124 if (finished && out_of_space)
2127 if (!finished && !out_of_space)
2131 * As an optimisation if we know we aren't looking
2132 * for a wildcard name (ie. the name matches the wildcard exactly)
2133 * then we can finish on any (first) match.
2134 * This speeds up large directory searches. JRA.
2140 /* Ensure space_remaining never goes -ve. */
2141 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2142 space_remaining = 0;
2143 out_of_space = true;
2145 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2149 /* Check if we can close the dirptr */
2150 if(close_after_first || (finished && close_if_end)) {
2151 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2152 dptr_close(&dptr_num);
2156 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2157 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2158 * the protocol level is less than NT1. Tested with smbclient. JRA.
2159 * This should fix the OS/2 client bug #2335.
2162 if(numentries == 0) {
2163 dptr_close(&dptr_num);
2164 if (Protocol < PROTOCOL_NT1) {
2165 reply_doserror(req, ERRDOS, ERRnofiles);
2168 reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2169 ERRDOS, ERRbadfile);
2174 /* At this point pdata points to numentries directory entries. */
2176 /* Set up the return parameter block */
2177 SSVAL(params,0,dptr_num);
2178 SSVAL(params,2,numentries);
2179 SSVAL(params,4,finished);
2180 SSVAL(params,6,0); /* Never an EA error */
2181 SSVAL(params,8,last_entry_off);
2183 send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
2186 if ((! *directory) && dptr_path(dptr_num)) {
2187 directory = talloc_strdup(talloc_tos(),dptr_path(dptr_num));
2189 reply_nterror(req, NT_STATUS_NO_MEMORY);
2193 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2194 smb_fn_name(req->cmd),
2195 mask, directory, dirtype, numentries ) );
2198 * Force a name mangle here to ensure that the
2199 * mask as an 8.3 name is top of the mangled cache.
2200 * The reasons for this are subtle. Don't remove
2201 * this code unless you know what you are doing
2202 * (see PR#13758). JRA.
2205 if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2206 char mangled_name[13];
2207 name_to_8_3(mask, mangled_name, True, conn->params);
2213 /****************************************************************************
2214 Reply to a TRANS2_FINDNEXT.
2215 ****************************************************************************/
2217 static void call_trans2findnext(connection_struct *conn,
2218 struct smb_request *req,
2219 char **pparams, int total_params,
2220 char **ppdata, int total_data,
2221 unsigned int max_data_bytes)
2223 /* We must be careful here that we don't return more than the
2224 allowed number of data bytes. If this means returning fewer than
2225 maxentries then so be it. We assume that the redirector has
2226 enough room for the fixed number of parameter bytes it has
2228 char *params = *pparams;
2229 char *pdata = *ppdata;
2235 uint16 findnext_flags;
2236 bool close_after_request;
2238 bool requires_resume_key;
2240 bool mask_contains_wcard = False;
2241 char *resume_name = NULL;
2242 const char *mask = NULL;
2243 const char *directory = NULL;
2247 int i, last_entry_off=0;
2248 bool finished = False;
2249 bool dont_descend = False;
2250 bool out_of_space = False;
2251 int space_remaining;
2252 struct ea_list *ea_list = NULL;
2253 NTSTATUS ntstatus = NT_STATUS_OK;
2254 bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2255 TALLOC_CTX *ctx = talloc_tos();
2257 if (total_params < 13) {
2258 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2262 dptr_num = SVAL(params,0);
2263 maxentries = SVAL(params,2);
2264 info_level = SVAL(params,4);
2265 resume_key = IVAL(params,6);
2266 findnext_flags = SVAL(params,10);
2267 close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2268 close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2269 requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2270 continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2272 srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2274 total_params - 12, STR_TERMINATE, &ntstatus,
2275 &mask_contains_wcard);
2276 if (!NT_STATUS_IS_OK(ntstatus)) {
2277 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2278 complain (it thinks we're asking for the directory above the shared
2279 path or an invalid name). Catch this as the resume name is only compared, never used in
2280 a file access. JRA. */
2281 srvstr_pull_talloc(ctx, params, req->flags2,
2282 &resume_name, params+12,
2286 if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2287 reply_nterror(req, ntstatus);
2292 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2293 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2294 resume_key = %d resume name = %s continue=%d level = %d\n",
2295 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
2296 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
2299 /* W2K3 seems to treat zero as 1. */
2303 switch (info_level) {
2304 case SMB_FIND_INFO_STANDARD:
2305 case SMB_FIND_EA_SIZE:
2306 case SMB_FIND_EA_LIST:
2307 case SMB_FIND_FILE_DIRECTORY_INFO:
2308 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2309 case SMB_FIND_FILE_NAMES_INFO:
2310 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2311 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2312 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2314 case SMB_FIND_FILE_UNIX:
2315 case SMB_FIND_FILE_UNIX_INFO2:
2316 /* Always use filesystem for UNIX mtime query. */
2317 ask_sharemode = false;
2318 if (!lp_unix_extensions()) {
2319 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2324 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2328 if (info_level == SMB_FIND_EA_LIST) {
2331 if (total_data < 4) {
2332 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2336 ea_size = IVAL(pdata,0);
2337 if (ea_size != total_data) {
2338 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2339 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2340 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2344 if (!lp_ea_support(SNUM(conn))) {
2345 reply_doserror(req, ERRDOS, ERReasnotsupported);
2349 /* Pull out the list of names. */
2350 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2352 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2357 *ppdata = (char *)SMB_REALLOC(
2358 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2359 if(*ppdata == NULL) {
2360 reply_nterror(req, NT_STATUS_NO_MEMORY);
2365 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2367 /* Realloc the params space */
2368 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2369 if(*pparams == NULL ) {
2370 reply_nterror(req, NT_STATUS_NO_MEMORY);
2376 /* Check that the dptr is valid */
2377 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2378 reply_doserror(req, ERRDOS, ERRnofiles);
2382 string_set(&conn->dirpath,dptr_path(dptr_num));
2384 /* Get the wildcard mask from the dptr */
2385 if((p = dptr_wcard(dptr_num))== NULL) {
2386 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2387 reply_doserror(req, ERRDOS, ERRnofiles);
2392 directory = conn->dirpath;
2394 /* Get the attr mask from the dptr */
2395 dirtype = dptr_attr(dptr_num);
2397 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2398 dptr_num, mask, dirtype,
2400 dptr_TellDir(conn->dirptr)));
2402 /* We don't need to check for VOL here as this is returned by
2403 a different TRANS2 call. */
2405 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2406 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2407 dont_descend = True;
2410 space_remaining = max_data_bytes;
2411 out_of_space = False;
2414 * Seek to the correct position. We no longer use the resume key but
2415 * depend on the last file name instead.
2418 if(*resume_name && !continue_bit) {
2421 long current_pos = 0;
2423 * Remember, name_to_8_3 is called by
2424 * get_lanman2_dir_entry(), so the resume name
2425 * could be mangled. Ensure we check the unmangled name.
2428 if (mangle_is_mangled(resume_name, conn->params)) {
2429 char *new_resume_name = NULL;
2430 mangle_lookup_name_from_8_3(ctx,
2434 if (new_resume_name) {
2435 resume_name = new_resume_name;
2440 * Fix for NT redirector problem triggered by resume key indexes
2441 * changing between directory scans. We now return a resume key of 0
2442 * and instead look for the filename to continue from (also given
2443 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2444 * findfirst/findnext (as is usual) then the directory pointer
2445 * should already be at the correct place.
2448 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
2449 } /* end if resume_name && !continue_bit */
2451 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2452 bool got_exact_match = False;
2454 /* this is a heuristic to avoid seeking the dirptr except when
2455 absolutely necessary. It allows for a filename of about 40 chars */
2456 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2457 out_of_space = True;
2460 finished = !get_lanman2_dir_entry(ctx,
2463 mask,dirtype,info_level,
2464 requires_resume_key,dont_descend,
2467 space_remaining, &out_of_space,
2469 &last_entry_off, ea_list);
2472 if (finished && out_of_space)
2475 if (!finished && !out_of_space)
2479 * As an optimisation if we know we aren't looking
2480 * for a wildcard name (ie. the name matches the wildcard exactly)
2481 * then we can finish on any (first) match.
2482 * This speeds up large directory searches. JRA.
2488 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2491 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2492 smb_fn_name(req->cmd),
2493 mask, directory, dirtype, numentries ) );
2495 /* Check if we can close the dirptr */
2496 if(close_after_request || (finished && close_if_end)) {
2497 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2498 dptr_close(&dptr_num); /* This frees up the saved mask */
2501 /* Set up the return parameter block */
2502 SSVAL(params,0,numentries);
2503 SSVAL(params,2,finished);
2504 SSVAL(params,4,0); /* Never an EA error */
2505 SSVAL(params,6,last_entry_off);
2507 send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
2513 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
2515 E_md4hash(lp_servicename(SNUM(conn)),objid);
2519 static void samba_extended_info_version(struct smb_extended_info *extended_info)
2521 SMB_ASSERT(extended_info != NULL);
2523 extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
2524 extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
2525 | ((SAMBA_VERSION_MINOR & 0xff) << 16)
2526 | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
2527 #ifdef SAMBA_VERSION_REVISION
2528 extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
2530 extended_info->samba_subversion = 0;
2531 #ifdef SAMBA_VERSION_RC_RELEASE
2532 extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
2534 #ifdef SAMBA_VERSION_PRE_RELEASE
2535 extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
2538 #ifdef SAMBA_VERSION_VENDOR_PATCH
2539 extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
2541 extended_info->samba_gitcommitdate = 0;
2542 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2543 unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
2546 memset(extended_info->samba_version_string, 0,
2547 sizeof(extended_info->samba_version_string));
2549 snprintf (extended_info->samba_version_string,
2550 sizeof(extended_info->samba_version_string),
2551 "%s", samba_version_string());
2554 /****************************************************************************
2555 Reply to a TRANS2_QFSINFO (query filesystem info).
2556 ****************************************************************************/
2558 static void call_trans2qfsinfo(connection_struct *conn,
2559 struct smb_request *req,
2560 char **pparams, int total_params,
2561 char **ppdata, int total_data,
2562 unsigned int max_data_bytes)
2564 char *pdata, *end_data;
2565 char *params = *pparams;
2569 const char *vname = volume_label(SNUM(conn));
2570 int snum = SNUM(conn);
2571 char *fstype = lp_fstype(SNUM(conn));
2572 uint32 additional_flags = 0;
2574 if (total_params < 2) {
2575 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2579 info_level = SVAL(params,0);
2582 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2583 DEBUG(0,("call_trans2qfsinfo: not an allowed "
2584 "info level (0x%x) on IPC$.\n",
2585 (unsigned int)info_level));
2586 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2591 if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
2592 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2593 DEBUG(0,("call_trans2qfsinfo: encryption required "
2594 "and info level 0x%x sent.\n",
2595 (unsigned int)info_level));
2596 exit_server_cleanly("encryption required "
2602 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2604 if(SMB_VFS_STAT(conn,".",&st)!=0) {
2605 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2606 reply_doserror(req, ERRSRV, ERRinvdevice);
2610 *ppdata = (char *)SMB_REALLOC(
2611 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2612 if (*ppdata == NULL ) {
2613 reply_nterror(req, NT_STATUS_NO_MEMORY);
2618 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2619 end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2621 switch (info_level) {
2622 case SMB_INFO_ALLOCATION:
2624 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2626 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2627 reply_unixerror(req, ERRHRD, ERRgeneral);
2631 block_size = lp_block_size(snum);
2632 if (bsize < block_size) {
2633 uint64_t factor = block_size/bsize;
2638 if (bsize > block_size) {
2639 uint64_t factor = bsize/block_size;
2644 bytes_per_sector = 512;
2645 sectors_per_unit = bsize/bytes_per_sector;
2647 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2648 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2649 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2651 SIVAL(pdata,l1_idFileSystem,st.st_dev);
2652 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2653 SIVAL(pdata,l1_cUnit,dsize);
2654 SIVAL(pdata,l1_cUnitAvail,dfree);
2655 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2659 case SMB_INFO_VOLUME:
2660 /* Return volume name */
2662 * Add volume serial number - hash of a combination of
2663 * the called hostname and the service name.
2665 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2667 * Win2k3 and previous mess this up by sending a name length
2668 * one byte short. I believe only older clients (OS/2 Win9x) use
2669 * this call so try fixing this by adding a terminating null to
2670 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2674 pdata+l2_vol_szVolLabel, vname,
2675 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
2676 STR_NOALIGN|STR_TERMINATE);
2677 SCVAL(pdata,l2_vol_cch,len);
2678 data_len = l2_vol_szVolLabel + len;
2679 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2680 (unsigned)st.st_ctime, len, vname));
2683 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2684 case SMB_FS_ATTRIBUTE_INFORMATION:
2686 additional_flags = 0;
2687 #if defined(HAVE_SYS_QUOTAS)
2688 additional_flags |= FILE_VOLUME_QUOTAS;
2691 if(lp_nt_acl_support(SNUM(conn))) {
2692 additional_flags |= FILE_PERSISTENT_ACLS;
2695 /* Capabilities are filled in at connection time through STATVFS call */
2696 additional_flags |= conn->fs_capabilities;
2698 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2699 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
2700 additional_flags); /* FS ATTRIBUTES */
2702 SIVAL(pdata,4,255); /* Max filename component length */
2703 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2704 and will think we can't do long filenames */
2705 len = srvstr_push(pdata, req->flags2, pdata+12, fstype,
2706 PTR_DIFF(end_data, pdata+12),
2709 data_len = 12 + len;
2712 case SMB_QUERY_FS_LABEL_INFO:
2713 case SMB_FS_LABEL_INFORMATION:
2714 len = srvstr_push(pdata, req->flags2, pdata+4, vname,
2715 PTR_DIFF(end_data, pdata+4), 0);
2720 case SMB_QUERY_FS_VOLUME_INFO:
2721 case SMB_FS_VOLUME_INFORMATION:
2724 * Add volume serial number - hash of a combination of
2725 * the called hostname and the service name.
2727 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2728 (str_checksum(get_local_machine_name())<<16));
2730 /* Max label len is 32 characters. */
2731 len = srvstr_push(pdata, req->flags2, pdata+18, vname,
2732 PTR_DIFF(end_data, pdata+18),
2734 SIVAL(pdata,12,len);
2737 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2738 (int)strlen(vname),vname, lp_servicename(snum)));
2741 case SMB_QUERY_FS_SIZE_INFO:
2742 case SMB_FS_SIZE_INFORMATION:
2744 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2746 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2747 reply_unixerror(req, ERRHRD, ERRgeneral);
2750 block_size = lp_block_size(snum);
2751 if (bsize < block_size) {
2752 uint64_t factor = block_size/bsize;
2757 if (bsize > block_size) {
2758 uint64_t factor = bsize/block_size;
2763 bytes_per_sector = 512;
2764 sectors_per_unit = bsize/bytes_per_sector;
2765 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2766 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2767 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2768 SBIG_UINT(pdata,0,dsize);
2769 SBIG_UINT(pdata,8,dfree);
2770 SIVAL(pdata,16,sectors_per_unit);
2771 SIVAL(pdata,20,bytes_per_sector);
2775 case SMB_FS_FULL_SIZE_INFORMATION:
2777 uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2779 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2780 reply_unixerror(req, ERRHRD, ERRgeneral);
2783 block_size = lp_block_size(snum);
2784 if (bsize < block_size) {
2785 uint64_t factor = block_size/bsize;
2790 if (bsize > block_size) {
2791 uint64_t factor = bsize/block_size;
2796 bytes_per_sector = 512;
2797 sectors_per_unit = bsize/bytes_per_sector;
2798 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2799 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2800 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2801 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2802 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2803 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2804 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2805 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2809 case SMB_QUERY_FS_DEVICE_INFO:
2810 case SMB_FS_DEVICE_INFORMATION:
2812 SIVAL(pdata,0,0); /* dev type */
2813 SIVAL(pdata,4,0); /* characteristics */
2816 #ifdef HAVE_SYS_QUOTAS
2817 case SMB_FS_QUOTA_INFORMATION:
2819 * what we have to send --metze:
2821 * Unknown1: 24 NULL bytes
2822 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
2823 * Hard Quota Limit: 8 bytes seems like uint64_t or so
2824 * Quota Flags: 2 byte :
2825 * Unknown3: 6 NULL bytes
2829 * details for Quota Flags:
2831 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2832 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2833 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2834 * 0x0001 Enable Quotas: enable quota for this fs
2838 /* we need to fake up a fsp here,
2839 * because its not send in this call
2842 SMB_NTQUOTA_STRUCT quotas;
2845 ZERO_STRUCT(quotas);
2851 if (conn->server_info->utok.uid != 0) {
2852 DEBUG(0,("set_user_quota: access_denied "
2853 "service [%s] user [%s]\n",
2854 lp_servicename(SNUM(conn)),
2855 conn->server_info->unix_name));
2856 reply_doserror(req, ERRDOS, ERRnoaccess);
2860 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2861 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2862 reply_doserror(req, ERRSRV, ERRerror);
2868 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2870 /* Unknown1 24 NULL bytes*/
2871 SBIG_UINT(pdata,0,(uint64_t)0);
2872 SBIG_UINT(pdata,8,(uint64_t)0);
2873 SBIG_UINT(pdata,16,(uint64_t)0);
2875 /* Default Soft Quota 8 bytes */
2876 SBIG_UINT(pdata,24,quotas.softlim);
2878 /* Default Hard Quota 8 bytes */
2879 SBIG_UINT(pdata,32,quotas.hardlim);
2881 /* Quota flag 2 bytes */
2882 SSVAL(pdata,40,quotas.qflags);
2884 /* Unknown3 6 NULL bytes */
2890 #endif /* HAVE_SYS_QUOTAS */
2891 case SMB_FS_OBJECTID_INFORMATION:
2893 unsigned char objid[16];
2894 struct smb_extended_info extended_info;
2895 memcpy(pdata,create_volume_objectid(conn, objid),16);
2896 samba_extended_info_version (&extended_info);
2897 SIVAL(pdata,16,extended_info.samba_magic);
2898 SIVAL(pdata,20,extended_info.samba_version);
2899 SIVAL(pdata,24,extended_info.samba_subversion);
2900 SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
2901 memcpy(pdata+36,extended_info.samba_version_string,28);
2907 * Query the version and capabilities of the CIFS UNIX extensions
2911 case SMB_QUERY_CIFS_UNIX_INFO:
2913 bool large_write = lp_min_receive_file_size() &&
2914 !srv_is_signing_active();
2915 bool large_read = !srv_is_signing_active();
2916 int encrypt_caps = 0;
2918 if (!lp_unix_extensions()) {
2919 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2923 switch (conn->encrypt_level) {
2929 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
2932 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
2933 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
2934 large_write = false;
2940 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2941 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2943 /* We have POSIX ACLs, pathname, encryption,
2944 * large read/write, and locking capability. */
2946 SBIG_UINT(pdata,4,((uint64_t)(
2947 CIFS_UNIX_POSIX_ACLS_CAP|
2948 CIFS_UNIX_POSIX_PATHNAMES_CAP|
2949 CIFS_UNIX_FCNTL_LOCKS_CAP|
2950 CIFS_UNIX_EXTATTR_CAP|
2951 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
2953 (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
2955 CIFS_UNIX_LARGE_WRITE_CAP : 0))));
2959 case SMB_QUERY_POSIX_FS_INFO:
2962 vfs_statvfs_struct svfs;
2964 if (!lp_unix_extensions()) {
2965 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2969 rc = SMB_VFS_STATVFS(conn, ".", &svfs);
2973 SIVAL(pdata,0,svfs.OptimalTransferSize);
2974 SIVAL(pdata,4,svfs.BlockSize);
2975 SBIG_UINT(pdata,8,svfs.TotalBlocks);
2976 SBIG_UINT(pdata,16,svfs.BlocksAvail);
2977 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
2978 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
2979 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
2980 SBIG_UINT(pdata,48,svfs.FsIdentifier);
2981 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2983 } else if (rc == EOPNOTSUPP) {
2984 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2986 #endif /* EOPNOTSUPP */
2988 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2989 reply_doserror(req, ERRSRV, ERRerror);
2995 case SMB_QUERY_POSIX_WHOAMI:
3001 if (!lp_unix_extensions()) {
3002 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3006 if (max_data_bytes < 40) {
3007 reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3011 /* We ARE guest if global_sid_Builtin_Guests is
3012 * in our list of SIDs.
3014 if (nt_token_check_sid(&global_sid_Builtin_Guests,
3015 conn->server_info->ptok)) {
3016 flags |= SMB_WHOAMI_GUEST;
3019 /* We are NOT guest if global_sid_Authenticated_Users
3020 * is in our list of SIDs.
3022 if (nt_token_check_sid(&global_sid_Authenticated_Users,
3023 conn->server_info->ptok)) {
3024 flags &= ~SMB_WHOAMI_GUEST;
3027 /* NOTE: 8 bytes for UID/GID, irrespective of native
3028 * platform size. This matches
3029 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3031 data_len = 4 /* flags */
3038 + 4 /* pad/reserved */
3039 + (conn->server_info->utok.ngroups * 8)
3041 + (conn->server_info->ptok->num_sids *
3045 SIVAL(pdata, 0, flags);
3046 SIVAL(pdata, 4, SMB_WHOAMI_MASK);
3048 (uint64_t)conn->server_info->utok.uid);
3049 SBIG_UINT(pdata, 16,
3050 (uint64_t)conn->server_info->utok.gid);
3053 if (data_len >= max_data_bytes) {
3054 /* Potential overflow, skip the GIDs and SIDs. */
3056 SIVAL(pdata, 24, 0); /* num_groups */
3057 SIVAL(pdata, 28, 0); /* num_sids */
3058 SIVAL(pdata, 32, 0); /* num_sid_bytes */
3059 SIVAL(pdata, 36, 0); /* reserved */
3065 SIVAL(pdata, 24, conn->server_info->utok.ngroups);
3066 SIVAL(pdata, 28, conn->server_info->num_sids);
3068 /* We walk the SID list twice, but this call is fairly
3069 * infrequent, and I don't expect that it's performance
3070 * sensitive -- jpeach
3072 for (i = 0, sid_bytes = 0;
3073 i < conn->server_info->ptok->num_sids; ++i) {
3074 sid_bytes += ndr_size_dom_sid(
3075 &conn->server_info->ptok->user_sids[i],
3080 /* SID list byte count */
3081 SIVAL(pdata, 32, sid_bytes);
3083 /* 4 bytes pad/reserved - must be zero */
3084 SIVAL(pdata, 36, 0);
3088 for (i = 0; i < conn->server_info->utok.ngroups; ++i) {
3089 SBIG_UINT(pdata, data_len,
3090 (uint64_t)conn->server_info->utok.groups[i]);
3096 i < conn->server_info->ptok->num_sids; ++i) {
3097 int sid_len = ndr_size_dom_sid(
3098 &conn->server_info->ptok->user_sids[i],
3102 sid_linearize(pdata + data_len, sid_len,
3103 &conn->server_info->ptok->user_sids[i]);
3104 data_len += sid_len;
3110 case SMB_MAC_QUERY_FS_INFO:
3112 * Thursby MAC extension... ONLY on NTFS filesystems
3113 * once we do streams then we don't need this
3115 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
3117 SIVAL(pdata,84,0x100); /* Don't support mac... */
3122 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3127 send_trans2_replies(conn, req, params, 0, pdata, data_len,
3130 DEBUG( 4, ( "%s info_level = %d\n",
3131 smb_fn_name(req->cmd), info_level) );
3136 /****************************************************************************
3137 Reply to a TRANS2_SETFSINFO (set filesystem info).
3138 ****************************************************************************/
3140 static void call_trans2setfsinfo(connection_struct *conn,
3141 struct smb_request *req,
3142 char **pparams, int total_params,
3143 char **ppdata, int total_data,
3144 unsigned int max_data_bytes)
3146 char *pdata = *ppdata;
3147 char *params = *pparams;
3150 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
3153 if (total_params < 4) {
3154 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3156 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3160 info_level = SVAL(params,2);
3163 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
3164 info_level != SMB_SET_CIFS_UNIX_INFO) {
3165 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3166 "info level (0x%x) on IPC$.\n",
3167 (unsigned int)info_level));
3168 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3173 if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
3174 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
3175 DEBUG(0,("call_trans2setfsinfo: encryption required "
3176 "and info level 0x%x sent.\n",
3177 (unsigned int)info_level));
3178 exit_server_cleanly("encryption required "
3184 switch(info_level) {
3185 case SMB_SET_CIFS_UNIX_INFO:
3187 uint16 client_unix_major;
3188 uint16 client_unix_minor;
3189 uint32 client_unix_cap_low;
3190 uint32 client_unix_cap_high;
3192 if (!lp_unix_extensions()) {
3194 NT_STATUS_INVALID_LEVEL);
3198 /* There should be 12 bytes of capabilities set. */
3199 if (total_data < 8) {
3202 NT_STATUS_INVALID_PARAMETER);
3205 client_unix_major = SVAL(pdata,0);
3206 client_unix_minor = SVAL(pdata,2);
3207 client_unix_cap_low = IVAL(pdata,4);
3208 client_unix_cap_high = IVAL(pdata,8);
3209 /* Just print these values for now. */
3210 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
3211 cap_low = 0x%x, cap_high = 0x%x\n",
3212 (unsigned int)client_unix_major,
3213 (unsigned int)client_unix_minor,
3214 (unsigned int)client_unix_cap_low,
3215 (unsigned int)client_unix_cap_high ));
3217 /* Here is where we must switch to posix pathname processing... */
3218 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
3219 lp_set_posix_pathnames();
3220 mangle_change_to_posix();
3223 if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
3224 !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
3225 /* Client that knows how to do posix locks,
3226 * but not posix open/mkdir operations. Set a
3227 * default type for read/write checks. */
3229 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
3235 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
3238 size_t param_len = 0;
3239 size_t data_len = total_data;
3241 if (!lp_unix_extensions()) {
3244 NT_STATUS_INVALID_LEVEL);
3248 if (lp_smb_encrypt(SNUM(conn)) == false) {
3251 NT_STATUS_NOT_SUPPORTED);
3255 DEBUG( 4,("call_trans2setfsinfo: "
3256 "request transport encryption.\n"));
3258 status = srv_request_encryption_setup(conn,
3259 (unsigned char **)ppdata,
3261 (unsigned char **)pparams,
3264 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
3265 !NT_STATUS_IS_OK(status)) {
3266 reply_nterror(req, status);
3270 send_trans2_replies(conn, req,
3277 if (NT_STATUS_IS_OK(status)) {
3278 /* Server-side transport
3279 * encryption is now *on*. */
3280 status = srv_encryption_start(conn);
3281 if (!NT_STATUS_IS_OK(status)) {
3282 exit_server_cleanly(
3283 "Failure in setting "
3284 "up encrypted transport");
3290 case SMB_FS_QUOTA_INFORMATION:
3292 files_struct *fsp = NULL;
3293 SMB_NTQUOTA_STRUCT quotas;
3295 ZERO_STRUCT(quotas);
3298 if ((conn->server_info->utok.uid != 0)
3299 ||!CAN_WRITE(conn)) {
3300 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3301 lp_servicename(SNUM(conn)),
3302 conn->server_info->unix_name));
3303 reply_doserror(req, ERRSRV, ERRaccess);
3307 /* note: normaly there're 48 bytes,
3308 * but we didn't use the last 6 bytes for now
3311 fsp = file_fsp(req, SVAL(params,0));
3313 if (!check_fsp_ntquota_handle(conn, req,
3315 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3317 req, NT_STATUS_INVALID_HANDLE);
3321 if (total_data < 42) {
3322 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3326 NT_STATUS_INVALID_PARAMETER);
3330 /* unknown_1 24 NULL bytes in pdata*/
3332 /* the soft quotas 8 bytes (uint64_t)*/
3333 quotas.softlim = (uint64_t)IVAL(pdata,24);
3334 #ifdef LARGE_SMB_OFF_T
3335 quotas.softlim |= (((uint64_t)IVAL(pdata,28)) << 32);
3336 #else /* LARGE_SMB_OFF_T */
3337 if ((IVAL(pdata,28) != 0)&&
3338 ((quotas.softlim != 0xFFFFFFFF)||
3339 (IVAL(pdata,28)!=0xFFFFFFFF))) {
3340 /* more than 32 bits? */
3343 NT_STATUS_INVALID_PARAMETER);
3346 #endif /* LARGE_SMB_OFF_T */
3348 /* the hard quotas 8 bytes (uint64_t)*/
3349 quotas.hardlim = (uint64_t)IVAL(pdata,32);
3350 #ifdef LARGE_SMB_OFF_T
3351 quotas.hardlim |= (((uint64_t)IVAL(pdata,36)) << 32);
3352 #else /* LARGE_SMB_OFF_T */
3353 if ((IVAL(pdata,36) != 0)&&
3354 ((quotas.hardlim != 0xFFFFFFFF)||
3355 (IVAL(pdata,36)!=0xFFFFFFFF))) {
3356 /* more than 32 bits? */
3359 NT_STATUS_INVALID_PARAMETER);
3362 #endif /* LARGE_SMB_OFF_T */
3364 /* quota_flags 2 bytes **/
3365 quotas.qflags = SVAL(pdata,40);
3367 /* unknown_2 6 NULL bytes follow*/
3369 /* now set the quotas */
3370 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
3371 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
3372 reply_doserror(req, ERRSRV, ERRerror);
3379 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3381 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3387 * sending this reply works fine,
3388 * but I'm not sure it's the same
3389 * like windows do...
3392 reply_outbuf(req, 10, 0);
3395 #if defined(HAVE_POSIX_ACLS)
3396 /****************************************************************************
3397 Utility function to count the number of entries in a POSIX acl.
3398 ****************************************************************************/
3400 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
3402 unsigned int ace_count = 0;
3403 int entry_id = SMB_ACL_FIRST_ENTRY;
3404 SMB_ACL_ENTRY_T entry;
3406 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
3408 if (entry_id == SMB_ACL_FIRST_ENTRY) {
3409 entry_id = SMB_ACL_NEXT_ENTRY;
3416 /****************************************************************************
3417 Utility function to marshall a POSIX acl into wire format.
3418 ****************************************************************************/
3420 static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
3422 int entry_id = SMB_ACL_FIRST_ENTRY;
3423 SMB_ACL_ENTRY_T entry;
3425 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
3426 SMB_ACL_TAG_T tagtype;
3427 SMB_ACL_PERMSET_T permset;
3428 unsigned char perms = 0;
3429 unsigned int own_grp;
3432 if (entry_id == SMB_ACL_FIRST_ENTRY) {
3433 entry_id = SMB_ACL_NEXT_ENTRY;
3436 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
3437 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3441 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
3442 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3446 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
3447 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
3448 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
3450 SCVAL(pdata,1,perms);
3453 case SMB_ACL_USER_OBJ:
3454 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
3455 own_grp = (unsigned int)pst->st_uid;
3456 SIVAL(pdata,2,own_grp);
3461 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
3463 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3466 own_grp = (unsigned int)*puid;
3467 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
3468 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
3469 SIVAL(pdata,2,own_grp);
3473 case SMB_ACL_GROUP_OBJ:
3474 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
3475 own_grp = (unsigned int)pst->st_gid;
3476 SIVAL(pdata,2,own_grp);
3481 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
3483 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3486 own_grp = (unsigned int)*pgid;
3487 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
3488 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
3489 SIVAL(pdata,2,own_grp);
3494 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
3495 SIVAL(pdata,2,0xFFFFFFFF);
3496 SIVAL(pdata,6,0xFFFFFFFF);
3499 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
3500 SIVAL(pdata,2,0xFFFFFFFF);
3501 SIVAL(pdata,6,0xFFFFFFFF);
3504 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
3507 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
3514 /****************************************************************************
3515 Store the FILE_UNIX_BASIC info.
3516 ****************************************************************************/
3518 static char *store_file_unix_basic(connection_struct *conn,
3521 const SMB_STRUCT_STAT *psbuf)
3523 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
3524 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_mode));
3526 SOFF_T(pdata,0,get_file_size(*psbuf)); /* File size 64 Bit */
3529 SOFF_T(pdata,0,get_allocation_size(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
3532 put_long_date_timespec(pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */
3533 put_long_date_timespec(pdata+8,get_atimespec(psbuf)); /* Last access time 64 Bit */
3534 put_long_date_timespec(pdata+16,get_mtimespec(psbuf)); /* Last modification time 64 Bit */
3537 SIVAL(pdata,0,psbuf->st_uid); /* user id for the owner */
3541 SIVAL(pdata,0,psbuf->st_gid); /* group id of owner */
3545 SIVAL(pdata,0,unix_filetype(psbuf->st_mode));
3548 SIVAL(pdata,0,unix_dev_major(psbuf->st_rdev)); /* Major device number if type is device */
3552 SIVAL(pdata,0,unix_dev_minor(psbuf->st_rdev)); /* Minor device number if type is device */
3556 SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ino); /* inode number */
3559 SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_mode)); /* Standard UNIX file permissions */
3563 SIVAL(pdata,0,psbuf->st_nlink); /* number of hard links */
3570 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
3571 * the chflags(2) (or equivalent) flags.
3573 * XXX: this really should be behind the VFS interface. To do this, we would
3574 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
3575 * Each VFS module could then implement its own mapping as appropriate for the
3576 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
3578 static const struct {unsigned stat_fflag; unsigned smb_fflag;}
3582 { UF_NODUMP, EXT_DO_NOT_BACKUP },
3586 { UF_IMMUTABLE, EXT_IMMUTABLE },
3590 { UF_APPEND, EXT_OPEN_APPEND_ONLY },
3594 { UF_HIDDEN, EXT_HIDDEN },
3597 /* Do not remove. We need to guarantee that this array has at least one
3598 * entry to build on HP-UX.
3604 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
3605 uint32 *smb_fflags, uint32 *smb_fmask)
3607 #ifdef HAVE_STAT_ST_FLAGS
3610 for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
3611 *smb_fmask |= info2_flags_map[i].smb_fflag;
3612 if (psbuf->st_flags & info2_flags_map[i].stat_fflag) {
3613 *smb_fflags |= info2_flags_map[i].smb_fflag;
3616 #endif /* HAVE_STAT_ST_FLAGS */
3619 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
3620 const uint32 smb_fflags,
3621 const uint32 smb_fmask,
3624 #ifdef HAVE_STAT_ST_FLAGS
3625 uint32 max_fmask = 0;
3628 *stat_fflags = psbuf->st_flags;
3630 /* For each flags requested in smb_fmask, check the state of the
3631 * corresponding flag in smb_fflags and set or clear the matching
3635 for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
3636 max_fmask |= info2_flags_map[i].smb_fflag;
3637 if (smb_fmask & info2_flags_map[i].smb_fflag) {
3638 if (smb_fflags & info2_flags_map[i].smb_fflag) {
3639 *stat_fflags |= info2_flags_map[i].stat_fflag;
3641 *stat_fflags &= ~info2_flags_map[i].stat_fflag;
3646 /* If smb_fmask is asking to set any bits that are not supported by
3647 * our flag mappings, we should fail.
3649 if ((smb_fmask & max_fmask) != smb_fmask) {
3656 #endif /* HAVE_STAT_ST_FLAGS */
3660 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
3661 * of file flags and birth (create) time.
3663 static char *store_file_unix_basic_info2(connection_struct *conn,
3666 const SMB_STRUCT_STAT *psbuf)
3668 uint32 file_flags = 0;
3669 uint32 flags_mask = 0;
3671 pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
3673 /* Create (birth) time 64 bit */
3674 put_long_date_timespec(pdata, get_create_timespec(psbuf, False));
3677 map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
3678 SIVAL(pdata, 0, file_flags); /* flags */
3679 SIVAL(pdata, 4, flags_mask); /* mask */
3685 static NTSTATUS marshall_stream_info(unsigned int num_streams,
3686 const struct stream_struct *streams,
3688 unsigned int max_data_bytes,
3689 unsigned int *data_size)
3692 unsigned int ofs = 0;
3694 for (i = 0; i < num_streams && ofs <= max_data_bytes; i++) {
3695 unsigned int next_offset;
3697 smb_ucs2_t *namebuf;
3699 if (!push_ucs2_talloc(talloc_tos(), &namebuf,
3700 streams[i].name, &namelen) ||
3703 return NT_STATUS_INVALID_PARAMETER;
3707 * name_buf is now null-terminated, we need to marshall as not
3713 SIVAL(data, ofs+4, namelen);
3714 SOFF_T(data, ofs+8, streams[i].size);
3715 SOFF_T(data, ofs+16, streams[i].alloc_size);
3716 memcpy(data+ofs+24, namebuf, namelen);
3717 TALLOC_FREE(namebuf);
3719 next_offset = ofs + 24 + namelen;
3721 if (i == num_streams-1) {
3722 SIVAL(data, ofs, 0);
3725 unsigned int align = ndr_align_size(next_offset, 8);
3727 memset(data+next_offset, 0, align);
3728 next_offset += align;
3730 SIVAL(data, ofs, next_offset - ofs);
3739 return NT_STATUS_OK;
3742 /****************************************************************************
3743 Reply to a TRANSACT2_QFILEINFO on a PIPE !
3744 ****************************************************************************/
3746 static void call_trans2qpipeinfo(connection_struct *conn,
3747 struct smb_request *req,
3748 unsigned int tran_call,
3749 char **pparams, int total_params,
3750 char **ppdata, int total_data,
3751 unsigned int max_data_bytes)
3753 char *params = *pparams;
3754 char *pdata = *ppdata;
3755 unsigned int data_size = 0;
3756 unsigned int param_size = 2;
3761 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3765 if (total_params < 4) {
3766 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3770 fsp = file_fsp(req, SVAL(params,0));
3771 if (!fsp_is_np(fsp)) {
3772 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
3776 info_level = SVAL(params,2);
3778 *pparams = (char *)SMB_REALLOC(*pparams,2);
3779 if (*pparams == NULL) {
3780 reply_nterror(req, NT_STATUS_NO_MEMORY);
3785 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
3786 *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
3787 if (*ppdata == NULL ) {
3788 reply_nterror(req, NT_STATUS_NO_MEMORY);
3793 switch (info_level) {
3794 case SMB_FILE_STANDARD_INFORMATION:
3796 SOFF_T(pdata,0,4096LL);
3803 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3807 send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
3813 /****************************************************************************
3814 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
3815 file name or file id).
3816 ****************************************************************************/
3818 static void call_trans2qfilepathinfo(connection_struct *conn,
3819 struct smb_request *req,
3820 unsigned int tran_call,
3821 char **pparams, int total_params,
3822 char **ppdata, int total_data,
3823 unsigned int max_data_bytes)
3825 char *params = *pparams;
3826 char *pdata = *ppdata;
3827 char *dstart, *dend;
3831 SMB_OFF_T file_size=0;
3832 uint64_t allocation_size=0;
3833 unsigned int data_size = 0;
3834 unsigned int param_size = 2;
3835 SMB_STRUCT_STAT sbuf;
3836 char *dos_fname = NULL;
3842 bool delete_pending = False;
3844 time_t create_time, mtime, atime;
3845 struct timespec create_time_ts, mtime_ts, atime_ts;
3846 struct timespec write_time_ts;
3847 files_struct *fsp = NULL;
3848 struct file_id fileid;
3849 struct ea_list *ea_list = NULL;
3850 char *lock_data = NULL;
3851 bool ms_dfs_link = false;
3852 TALLOC_CTX *ctx = talloc_tos();
3855 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3860 ZERO_STRUCT(write_time_ts);
3862 if (tran_call == TRANSACT2_QFILEINFO) {
3863 if (total_params < 4) {
3864 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3869 call_trans2qpipeinfo(conn, req, tran_call,
3870 pparams, total_params,
3876 fsp = file_fsp(req, SVAL(params,0));
3877 info_level = SVAL(params,2);
3879 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
3881 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
3882 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3886 /* Initial check for valid fsp ptr. */
3887 if (!check_fsp_open(conn, req, fsp)) {
3891 fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
3893 reply_nterror(req, NT_STATUS_NO_MEMORY);
3897 if(fsp->fake_file_handle) {
3899 * This is actually for the QUOTA_FAKE_FILE --metze
3902 /* We know this name is ok, it's already passed the checks. */
3904 } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
3906 * This is actually a QFILEINFO on a directory
3907 * handle (returned from an NT SMB). NT5.0 seems
3908 * to do this call. JRA.
3911 if (INFO_LEVEL_IS_UNIX(info_level)) {
3912 /* Always do lstat for UNIX calls. */
3913 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
3914 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
3915 reply_unixerror(req,ERRDOS,ERRbadpath);
3918 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
3919 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
3920 reply_unixerror(req, ERRDOS, ERRbadpath);
3924 fileid = vfs_file_id_from_sbuf(conn, &sbuf);
3925 get_file_infos(fileid, &delete_pending, &write_time_ts);
3928 * Original code - this is an open file.
3930 if (!check_fsp(conn, req, fsp)) {
3934 if (SMB_VFS_FSTAT(fsp, &sbuf) != 0) {
3935 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
3936 reply_unixerror(req, ERRDOS, ERRbadfid);
3939 pos = fsp->fh->position_information;
3940 fileid = vfs_file_id_from_sbuf(conn, &sbuf);
3941 get_file_infos(fileid, &delete_pending, &write_time_ts);
3945 NTSTATUS status = NT_STATUS_OK;
3948 if (total_params < 7) {
3949 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3953 info_level = SVAL(params,0);
3955 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
3957 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
3958 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3962 srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6],
3964 STR_TERMINATE, &status);
3965 if (!NT_STATUS_IS_OK(status)) {
3966 reply_nterror(req, status);
3970 status = resolve_dfspath(ctx,
3972 req->flags2 & FLAGS2_DFS_PATHNAMES,
3975 if (!NT_STATUS_IS_OK(status)) {
3976 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
3977 reply_botherror(req,
3978 NT_STATUS_PATH_NOT_COVERED,
3979 ERRSRV, ERRbadpath);
3981 reply_nterror(req, status);
3985 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
3986 if (!NT_STATUS_IS_OK(status)) {
3987 reply_nterror(req, status);
3990 status = check_name(conn, fname);
3991 if (!NT_STATUS_IS_OK(status)) {
3992 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,nt_errstr(status)));
3993 reply_nterror(req, status);
3997 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
3998 && is_ntfs_stream_name(fname)) {
4000 SMB_STRUCT_STAT bsbuf;
4002 status = split_ntfs_stream_name(talloc_tos(), fname,
4004 if (!NT_STATUS_IS_OK(status)) {
4005 DEBUG(10, ("create_file_unixpath: "
4006 "split_ntfs_stream_name failed: %s\n",
4007 nt_errstr(status)));
4008 reply_nterror(req, status);
4012 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
4014 if (INFO_LEVEL_IS_UNIX(info_level)) {
4015 /* Always do lstat for UNIX calls. */
4016 if (SMB_VFS_LSTAT(conn,base,&bsbuf)) {
4017 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",base,strerror(errno)));
4018 reply_unixerror(req,ERRDOS,ERRbadpath);
4022 if (SMB_VFS_STAT(conn,base,&bsbuf) != 0) {
4023 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",base,strerror(errno)));
4024 reply_unixerror(req,ERRDOS,ERRbadpath);
4029 fileid = vfs_file_id_from_sbuf(conn, &bsbuf);
4030 get_file_infos(fileid, &delete_pending, NULL);
4031 if (delete_pending) {
4032 reply_nterror(req, NT_STATUS_DELETE_PENDING);
4037 if (INFO_LEVEL_IS_UNIX(info_level)) {
4038 /* Always do lstat for UNIX calls. */
4039 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
4040 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
4041 reply_unixerror(req, ERRDOS, ERRbadpath);
4045 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
4046 ms_dfs_link = check_msdfs_link(conn,fname,&sbuf);
4049 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
4050 reply_unixerror(req, ERRDOS, ERRbadpath);
4055 fileid = vfs_file_id_from_sbuf(conn, &sbuf);
4056 get_file_infos(fileid, &delete_pending, &write_time_ts);
4057 if (delete_pending) {
4058 reply_nterror(req, NT_STATUS_DELETE_PENDING);
4063 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
4064 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4068 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
4069 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
4071 p = strrchr_m(fname,'/');
4078 mode = dos_mode_msdfs(conn,fname,&sbuf);
4080 mode = dos_mode(conn,fname,&sbuf);
4083 mode = FILE_ATTRIBUTE_NORMAL;
4085 nlink = sbuf.st_nlink;
4087 if (nlink && (mode&aDIR)) {
4091 if ((nlink > 0) && delete_pending) {
4095 fullpathname = fname;
4097 file_size = get_file_size(sbuf);
4099 /* Pull out any data sent here before we realloc. */
4100 switch (info_level) {
4101 case SMB_INFO_QUERY_EAS_FROM_LIST:
4103 /* Pull any EA list from the data portion. */
4106 if (total_data < 4) {
4108 req, NT_STATUS_INVALID_PARAMETER);
4111 ea_size = IVAL(pdata,0);
4113 if (total_data > 0 && ea_size != total_data) {
4114 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
4115 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
4117 req, NT_STATUS_INVALID_PARAMETER);
4121 if (!lp_ea_support(SNUM(conn))) {
4122 reply_doserror(req, ERRDOS,
4123 ERReasnotsupported);
4127 /* Pull out the list of names. */
4128 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
4131 req, NT_STATUS_INVALID_PARAMETER);
4137 case SMB_QUERY_POSIX_LOCK:
4139 if (fsp == NULL || fsp->fh->fd == -1) {
4140 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
4144 if (total_data != POSIX_LOCK_DATA_SIZE) {
4146 req, NT_STATUS_INVALID_PARAMETER);
4150 /* Copy the lock range data. */
4151 lock_data = (char *)TALLOC_MEMDUP(
4152 ctx, pdata, total_data);
4154 reply_nterror(req, NT_STATUS_NO_MEMORY);
4162 *pparams = (char *)SMB_REALLOC(*pparams,2);
4163 if (*pparams == NULL) {
4164 reply_nterror(req, NT_STATUS_NO_MEMORY);
4169 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
4170 *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
4171 if (*ppdata == NULL ) {
4172 reply_nterror(req, NT_STATUS_NO_MEMORY);
4177 dend = dstart + data_size - 1;
4179 create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
4180 mtime_ts = get_mtimespec(&sbuf);
4181 atime_ts = get_atimespec(&sbuf);
4183 allocation_size = get_allocation_size(conn,fsp,&sbuf);
4186 /* Do we have this path open ? */
4188 fileid = vfs_file_id_from_sbuf(conn, &sbuf);
4189 fsp1 = file_find_di_first(fileid);
4190 if (fsp1 && fsp1->initial_allocation_size) {
4191 allocation_size = get_allocation_size(conn, fsp1, &sbuf);
4195 if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
4196 mtime_ts = write_time_ts;
4199 if (lp_dos_filetime_resolution(SNUM(conn))) {
4200 dos_filetime_timespec(&create_time_ts);
4201 dos_filetime_timespec(&mtime_ts);
4202 dos_filetime_timespec(&atime_ts);
4205 create_time = convert_timespec_to_time_t(create_time_ts);
4206 mtime = convert_timespec_to_time_t(mtime_ts);
4207 atime = convert_timespec_to_time_t(atime_ts);
4209 /* NT expects the name to be in an exact form of the *full*
4210 filename. See the trans2 torture test */
4211 if (ISDOT(base_name)) {
4212 dos_fname = talloc_strdup(ctx, "\\");
4214 reply_nterror(req, NT_STATUS_NO_MEMORY);
4218 dos_fname = talloc_asprintf(ctx,
4222 reply_nterror(req, NT_STATUS_NO_MEMORY);
4225 string_replace(dos_fname, '/', '\\');
4228 switch (info_level) {
4229 case SMB_INFO_STANDARD:
4230 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
4232 srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
4233 srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
4234 srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
4235 SIVAL(pdata,l1_cbFile,(uint32)file_size);
4236 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
4237 SSVAL(pdata,l1_attrFile,mode);
4240 case SMB_INFO_QUERY_EA_SIZE:
4242 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
4243 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4245 srv_put_dos_date2(pdata,0,create_time);
4246 srv_put_dos_date2(pdata,4,atime);
4247 srv_put_dos_date2(pdata,8,mtime); /* write time */
4248 SIVAL(pdata,12,(uint32)file_size);
4249 SIVAL(pdata,16,(uint32)allocation_size);
4250 SSVAL(pdata,20,mode);
4251 SIVAL(pdata,22,ea_size);
4255 case SMB_INFO_IS_NAME_VALID:
4256 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4257 if (tran_call == TRANSACT2_QFILEINFO) {
4258 /* os/2 needs this ? really ?*/
4259 reply_doserror(req, ERRDOS, ERRbadfunc);
4266 case SMB_INFO_QUERY_EAS_FROM_LIST:
4268 size_t total_ea_len = 0;
4269 struct ea_list *ea_file_list = NULL;
4271 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4273 ea_file_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
4274 ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
4276 if (!ea_list || (total_ea_len > data_size)) {
4278 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
4282 data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
4286 case SMB_INFO_QUERY_ALL_EAS:
4288 /* We have data_size bytes to put EA's into. */
4289 size_t total_ea_len = 0;
4291 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4293 ea_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
4294 if (!ea_list || (total_ea_len > data_size)) {
4296 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
4300 data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
4304 case SMB_FILE_BASIC_INFORMATION:
4305 case SMB_QUERY_FILE_BASIC_INFO:
4307 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
4308 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4309 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
4311 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4315 put_long_date_timespec(pdata,create_time_ts);
4316 put_long_date_timespec(pdata+8,atime_ts);
4317 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
4318 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
4319 SIVAL(pdata,32,mode);
4321 DEBUG(5,("SMB_QFBI - "));
4322 DEBUG(5,("create: %s ", ctime(&create_time)));
4323 DEBUG(5,("access: %s ", ctime(&atime)));
4324 DEBUG(5,("write: %s ", ctime(&mtime)));
4325 DEBUG(5,("change: %s ", ctime(&mtime)));
4326 DEBUG(5,("mode: %x\n", mode));
4329 case SMB_FILE_STANDARD_INFORMATION:
4330 case SMB_QUERY_FILE_STANDARD_INFO:
4332 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4334 SOFF_T(pdata,0,allocation_size);
4335 SOFF_T(pdata,8,file_size);
4336 SIVAL(pdata,16,nlink);
4337 SCVAL(pdata,20,delete_pending?1:0);
4338 SCVAL(pdata,21,(mode&aDIR)?1:0);
4339 SSVAL(pdata,22,0); /* Padding. */
4342 case SMB_FILE_EA_INFORMATION:
4343 case SMB_QUERY_FILE_EA_INFO:
4345 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
4346 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4348 SIVAL(pdata,0,ea_size);
4352 /* Get the 8.3 name - used if NT SMB was negotiated. */
4353 case SMB_QUERY_FILE_ALT_NAME_INFO:
4354 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
4356 char mangled_name[13];
4357 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4358 if (!name_to_8_3(base_name,mangled_name,
4359 True,conn->params)) {
4362 NT_STATUS_NO_MEMORY);
4364 len = srvstr_push(dstart, req->flags2,
4365 pdata+4, mangled_name,
4366 PTR_DIFF(dend, pdata+4),
4368 data_size = 4 + len;
4373 case SMB_QUERY_FILE_NAME_INFO:
4375 this must be *exactly* right for ACLs on mapped drives to work
4377 len = srvstr_push(dstart, req->flags2,
4379 PTR_DIFF(dend, pdata+4),
4381 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4382 data_size = 4 + len;
4386 case SMB_FILE_ALLOCATION_INFORMATION:
4387 case SMB_QUERY_FILE_ALLOCATION_INFO:
4388 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4390 SOFF_T(pdata,0,allocation_size);
4393 case SMB_FILE_END_OF_FILE_INFORMATION:
4394 case SMB_QUERY_FILE_END_OF_FILEINFO:
4395 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4397 SOFF_T(pdata,0,file_size);
4400 case SMB_QUERY_FILE_ALL_INFO:
4401 case SMB_FILE_ALL_INFORMATION:
4403 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
4404 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4405 put_long_date_timespec(pdata,create_time_ts);
4406 put_long_date_timespec(pdata+8,atime_ts);
4407 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
4408 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
4409 SIVAL(pdata,32,mode);
4410 SIVAL(pdata,36,0); /* padding. */
4412 SOFF_T(pdata,0,allocation_size);
4413 SOFF_T(pdata,8,file_size);
4414 SIVAL(pdata,16,nlink);
4415 SCVAL(pdata,20,delete_pending);
4416 SCVAL(pdata,21,(mode&aDIR)?1:0);
4419 SIVAL(pdata,0,ea_size);
4420 pdata += 4; /* EA info */
4421 len = srvstr_push(dstart, req->flags2,
4423 PTR_DIFF(dend, pdata+4),
4427 data_size = PTR_DIFF(pdata,(*ppdata));
4430 case SMB_FILE_INTERNAL_INFORMATION:
4431 /* This should be an index number - looks like
4434 I think this causes us to fail the IFSKIT
4435 BasicFileInformationTest. -tpot */
4437 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4438 SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
4439 SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
4443 case SMB_FILE_ACCESS_INFORMATION:
4444 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4446 SIVAL(pdata,0,fsp->access_mask);
4448 /* GENERIC_EXECUTE mapping from Windows */
4449 SIVAL(pdata,0,0x12019F);
4454 case SMB_FILE_NAME_INFORMATION:
4455 /* Pathname with leading '\'. */
4458 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
4459 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4460 SIVAL(pdata,0,byte_len);
4461 data_size = 4 + byte_len;
4465 case SMB_FILE_DISPOSITION_INFORMATION:
4466 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4468 SCVAL(pdata,0,delete_pending);
4471 case SMB_FILE_POSITION_INFORMATION:
4472 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4474 SOFF_T(pdata,0,pos);
4477 case SMB_FILE_MODE_INFORMATION:
4478 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4479 SIVAL(pdata,0,mode);
4483 case SMB_FILE_ALIGNMENT_INFORMATION:
4484 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4485 SIVAL(pdata,0,0); /* No alignment needed. */
4490 * NT4 server just returns "invalid query" to this - if we try
4491 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4494 /* The first statement above is false - verified using Thursby
4495 * client against NT4 -- gcolley.
4497 case SMB_QUERY_FILE_STREAM_INFO:
4498 case SMB_FILE_STREAM_INFORMATION: {
4499 unsigned int num_streams;
4500 struct stream_struct *streams;
4503 DEBUG(10,("call_trans2qfilepathinfo: "
4504 "SMB_FILE_STREAM_INFORMATION\n"));
4506 status = SMB_VFS_STREAMINFO(
4507 conn, fsp, fname, talloc_tos(),
4508 &num_streams, &streams);
4510 if (!NT_STATUS_IS_OK(status)) {
4511 DEBUG(10, ("could not get stream info: %s\n",
4512 nt_errstr(status)));
4513 reply_nterror(req, status);
4517 status = marshall_stream_info(num_streams, streams,
4518 pdata, max_data_bytes,
4521 if (!NT_STATUS_IS_OK(status)) {
4522 DEBUG(10, ("marshall_stream_info failed: %s\n",
4523 nt_errstr(status)));
4524 reply_nterror(req, status);
4528 TALLOC_FREE(streams);
4532 case SMB_QUERY_COMPRESSION_INFO:
4533 case SMB_FILE_COMPRESSION_INFORMATION:
4534 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4535 SOFF_T(pdata,0,file_size);
4536 SIVAL(pdata,8,0); /* ??? */
4537 SIVAL(pdata,12,0); /* ??? */
4541 case SMB_FILE_NETWORK_OPEN_INFORMATION:
4542 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4543 put_long_date_timespec(pdata,create_time_ts);
4544 put_long_date_timespec(pdata+8,atime_ts);
4545 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
4546 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
4547 SOFF_T(pdata,32,allocation_size);
4548 SOFF_T(pdata,40,file_size);
4549 SIVAL(pdata,48,mode);
4550 SIVAL(pdata,52,0); /* ??? */
4554 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
4555 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4556 SIVAL(pdata,0,mode);
4562 * CIFS UNIX Extensions.
4565 case SMB_QUERY_FILE_UNIX_BASIC:
4567 pdata = store_file_unix_basic(conn, pdata, fsp, &sbuf);
4568 data_size = PTR_DIFF(pdata,(*ppdata));
4572 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
4574 for (i=0; i<100; i++)
4575 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
4581 case SMB_QUERY_FILE_UNIX_INFO2:
4583 pdata = store_file_unix_basic_info2(conn, pdata, fsp, &sbuf);
4584 data_size = PTR_DIFF(pdata,(*ppdata));
4588 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4590 for (i=0; i<100; i++)
4591 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
4597 case SMB_QUERY_FILE_UNIX_LINK:
4599 char *buffer = TALLOC_ARRAY(ctx, char, PATH_MAX+1);
4602 reply_nterror(req, NT_STATUS_NO_MEMORY);
4606 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4608 if(!S_ISLNK(sbuf.st_mode)) {
4609 reply_unixerror(req, ERRSRV,
4614 reply_unixerror(req, ERRDOS, ERRbadlink);
4617 len = SMB_VFS_READLINK(conn,fullpathname,
4620 reply_unixerror(req, ERRDOS,
4625 len = srvstr_push(dstart, req->flags2,
4627 PTR_DIFF(dend, pdata),
4630 data_size = PTR_DIFF(pdata,(*ppdata));
4635 #if defined(HAVE_POSIX_ACLS)
4636 case SMB_QUERY_POSIX_ACL:
4638 SMB_ACL_T file_acl = NULL;
4639 SMB_ACL_T def_acl = NULL;
4640 uint16 num_file_acls = 0;
4641 uint16 num_def_acls = 0;
4643 if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
4644 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
4646 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
4649 if (file_acl == NULL && no_acl_syscall_error(errno)) {
4650 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
4654 NT_STATUS_NOT_IMPLEMENTED);
4658 if (S_ISDIR(sbuf.st_mode)) {
4659 if (fsp && fsp->is_directory) {
4660 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
4662 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
4664 def_acl = free_empty_sys_acl(conn, def_acl);
4667 num_file_acls = count_acl_entries(conn, file_acl);
4668 num_def_acls = count_acl_entries(conn, def_acl);
4670 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
4671 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
4673 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
4674 SMB_POSIX_ACL_HEADER_SIZE) ));
4676 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4679 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4683 NT_STATUS_BUFFER_TOO_SMALL);
4687 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
4688 SSVAL(pdata,2,num_file_acls);
4689 SSVAL(pdata,4,num_def_acls);
4690 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
4692 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4695 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4698 req, NT_STATUS_INTERNAL_ERROR);
4701 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
4703 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4706 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4710 NT_STATUS_INTERNAL_ERROR);
4715 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4718 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4720 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
4726 case SMB_QUERY_POSIX_LOCK:
4728 NTSTATUS status = NT_STATUS_INVALID_LEVEL;
4732 enum brl_type lock_type;
4734 if (total_data != POSIX_LOCK_DATA_SIZE) {
4736 req, NT_STATUS_INVALID_PARAMETER);
4740 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
4741 case POSIX_LOCK_TYPE_READ:
4742 lock_type = READ_LOCK;
4744 case POSIX_LOCK_TYPE_WRITE:
4745 lock_type = WRITE_LOCK;
4747 case POSIX_LOCK_TYPE_UNLOCK:
4749 /* There's no point in asking for an unlock... */
4752 NT_STATUS_INVALID_PARAMETER);
4756 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
4757 #if defined(HAVE_LONGLONG)
4758 offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
4759 ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
4760 count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
4761 ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
4762 #else /* HAVE_LONGLONG */
4763 offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
4764 count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
4765 #endif /* HAVE_LONGLONG */
4767 status = query_lock(fsp,
4774 if (ERROR_WAS_LOCK_DENIED(status)) {
4775 /* Here we need to report who has it locked... */
4776 data_size = POSIX_LOCK_DATA_SIZE;
4778 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
4779 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
4780 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid);
4781 #if defined(HAVE_LONGLONG)
4782 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
4783 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
4784 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
4785 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
4786 #else /* HAVE_LONGLONG */
4787 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
4788 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
4789 #endif /* HAVE_LONGLONG */
4791 } else if (NT_STATUS_IS_OK(status)) {
4792 /* For success we just return a copy of what we sent
4793 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
4794 data_size = POSIX_LOCK_DATA_SIZE;
4795 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
4796 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
4798 reply_nterror(req, status);
4805 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4809 send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
4815 /****************************************************************************
4816 Set a hard link (called by UNIX extensions and by NT rename with HARD link
4818 ****************************************************************************/
4820 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
4821 connection_struct *conn,
4822 const char *oldname_in,
4823 const char *newname_in)
4825 SMB_STRUCT_STAT sbuf1, sbuf2;
4826 char *last_component_oldname = NULL;
4827 char *last_component_newname = NULL;
4828 char *oldname = NULL;
4829 char *newname = NULL;
4830 NTSTATUS status = NT_STATUS_OK;
4835 status = unix_convert(ctx, conn, oldname_in, False, &oldname,
4836 &last_component_oldname, &sbuf1);
4837 if (!NT_STATUS_IS_OK(status)) {
4841 status = check_name(conn, oldname);
4842 if (!NT_STATUS_IS_OK(status)) {
4846 /* source must already exist. */
4847 if (!VALID_STAT(sbuf1)) {
4848 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4851 status = unix_convert(ctx, conn, newname_in, False, &newname,
4852 &last_component_newname, &sbuf2);
4853 if (!NT_STATUS_IS_OK(status)) {
4857 status = check_name(conn, newname);
4858 if (!NT_STATUS_IS_OK(status)) {
4862 /* Disallow if newname already exists. */
4863 if (VALID_STAT(sbuf2)) {
4864 return NT_STATUS_OBJECT_NAME_COLLISION;
4867 /* No links from a directory. */
4868 if (S_ISDIR(sbuf1.st_mode)) {
4869 return NT_STATUS_FILE_IS_A_DIRECTORY;
4872 /* Ensure this is within the share. */
4873 status = check_reduced_name(conn, oldname);
4874 if (!NT_STATUS_IS_OK(status)) {
4878 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
4880 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
4881 status = map_nt_error_from_unix(errno);
4882 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
4883 nt_errstr(status), newname, oldname));
4889 /****************************************************************************
4890 Deal with setting the time from any of the setfilepathinfo functions.
4891 ****************************************************************************/
4893 NTSTATUS smb_set_file_time(connection_struct *conn,
4896 const SMB_STRUCT_STAT *psbuf,
4897 struct smb_file_time *ft,
4898 bool setting_write_time)
4901 FILE_NOTIFY_CHANGE_LAST_ACCESS
4902 |FILE_NOTIFY_CHANGE_LAST_WRITE;
4904 if (!VALID_STAT(*psbuf)) {
4905 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4908 /* get some defaults (no modifications) if any info is zero or -1. */
4909 if (null_timespec(ft->atime)) {
4910 ft->atime= get_atimespec(psbuf);
4911 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
4914 if (null_timespec(ft->mtime)) {
4915 ft->mtime = get_mtimespec(psbuf);
4916 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
4919 if (!setting_write_time) {
4920 /* ft->mtime comes from change time, not write time. */
4921 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
4924 DEBUG(5,("smb_set_filetime: actime: %s\n ",
4925 time_to_asc(convert_timespec_to_time_t(ft->atime))));
4926 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
4927 time_to_asc(convert_timespec_to_time_t(ft->mtime))));
4928 if (!null_timespec(ft->create_time)) {
4929 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
4930 time_to_asc(convert_timespec_to_time_t(ft->create_time))));
4934 * Try and set the times of this file if
4935 * they are different from the current values.
4939 struct timespec mts = get_mtimespec(psbuf);
4940 struct timespec ats = get_atimespec(psbuf);
4941 if ((timespec_compare(&ft->atime, &ats) == 0) &&
4942 (timespec_compare(&ft->mtime, &mts) == 0)) {
4943 return NT_STATUS_OK;
4947 if (setting_write_time) {
4949 * This was a setfileinfo on an open file.
4950 * NT does this a lot. We also need to
4951 * set the time here, as it can be read by
4952 * FindFirst/FindNext and with the patch for bug #2045
4953 * in smbd/fileio.c it ensures that this timestamp is
4954 * kept sticky even after a write. We save the request
4955 * away and will set it on file close and after a write. JRA.
4958 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
4959 time_to_asc(convert_timespec_to_time_t(ft->mtime))));
4962 if (fsp->base_fsp) {
4963 set_sticky_write_time_fsp(fsp->base_fsp,
4966 set_sticky_write_time_fsp(fsp, ft->mtime);
4969 set_sticky_write_time_path(conn, fname,
4970 vfs_file_id_from_sbuf(conn, psbuf),
4975 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
4977 if (fsp && fsp->base_fsp) {
4978 fname = fsp->base_fsp->fsp_name;
4981 if(file_ntimes(conn, fname, ft)!=0) {
4982 return map_nt_error_from_unix(errno);
4984 notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname);
4986 return NT_STATUS_OK;
4989 /****************************************************************************
4990 Deal with setting the dosmode from any of the setfilepathinfo functions.
4991 ****************************************************************************/
4993 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
4995 SMB_STRUCT_STAT *psbuf,
4998 if (!VALID_STAT(*psbuf)) {
4999 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5003 if (S_ISDIR(psbuf->st_mode)) {
5010 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
5012 /* check the mode isn't different, before changing it */
5013 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, psbuf))) {
5015 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode 0x%x\n",
5016 fname, (unsigned int)dosmode ));
5018 if(file_set_dosmode(conn, fname, dosmode, psbuf, NULL, false)) {
5019 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of %s failed (%s)\n",
5020 fname, strerror(errno)));
5021 return map_nt_error_from_unix(errno);
5024 return NT_STATUS_OK;
5027 /****************************************************************************
5028 Deal with setting the size from any of the setfilepathinfo functions.
5029 ****************************************************************************/
5031 static NTSTATUS smb_set_file_size(connection_struct *conn,
5032 struct smb_request *req,
5035 SMB_STRUCT_STAT *psbuf,
5038 NTSTATUS status = NT_STATUS_OK;
5039 files_struct *new_fsp = NULL;
5041 if (!VALID_STAT(*psbuf)) {
5042 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5045 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
5047 if (size == get_file_size(*psbuf)) {
5048 return NT_STATUS_OK;
5051 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5052 fname, (double)size ));
5054 if (fsp && fsp->fh->fd != -1) {
5055 /* Handle based call. */
5056 if (vfs_set_filelen(fsp, size) == -1) {
5057 return map_nt_error_from_unix(errno);
5059 trigger_write_time_update_immediate(fsp);
5060 return NT_STATUS_OK;
5063 status = SMB_VFS_CREATE_FILE(
5066 0, /* root_dir_fid */
5068 0, /* create_file_flags */
5069 FILE_WRITE_ATTRIBUTES, /* access_mask */
5070 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
5072 FILE_OPEN, /* create_disposition*/
5073 0, /* create_options */
5074 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5075 FORCE_OPLOCK_BREAK_TO_NONE, /* oplock_request */
5076 0, /* allocation_size */
5079 &new_fsp, /* result */
5083 if (!NT_STATUS_IS_OK(status)) {
5084 /* NB. We check for open_was_deferred in the caller. */
5088 if (vfs_set_filelen(new_fsp, size) == -1) {
5089 status = map_nt_error_from_unix(errno);
5090 close_file(req, new_fsp,NORMAL_CLOSE);
5094 trigger_write_time_update_immediate(new_fsp);
5095 close_file(req, new_fsp,NORMAL_CLOSE);
5096 return NT_STATUS_OK;
5099 /****************************************************************************
5100 Deal with SMB_INFO_SET_EA.
5101 ****************************************************************************/
5103 static NTSTATUS smb_info_set_ea(connection_struct *conn,
5109 struct ea_list *ea_list = NULL;
5110 TALLOC_CTX *ctx = NULL;
5111 NTSTATUS status = NT_STATUS_OK;
5113 if (total_data < 10) {
5115 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5116 length. They seem to have no effect. Bug #3212. JRA */
5118 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
5119 /* We're done. We only get EA info in this call. */
5120 return NT_STATUS_OK;
5123 return NT_STATUS_INVALID_PARAMETER;
5126 if (IVAL(pdata,0) > total_data) {
5127 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5128 IVAL(pdata,0), (unsigned int)total_data));
5129 return NT_STATUS_INVALID_PARAMETER;
5133 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
5135 return NT_STATUS_INVALID_PARAMETER;
5137 status = set_ea(conn, fsp, fname, ea_list);
5142 /****************************************************************************
5143 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5144 ****************************************************************************/
5146 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
5151 SMB_STRUCT_STAT *psbuf)
5153 NTSTATUS status = NT_STATUS_OK;
5154 bool delete_on_close;
5157 if (total_data < 1) {
5158 return NT_STATUS_INVALID_PARAMETER;
5162 return NT_STATUS_INVALID_HANDLE;
5165 delete_on_close = (CVAL(pdata,0) ? True : False);
5166 dosmode = dos_mode(conn, fname, psbuf);
5168 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5169 "delete_on_close = %u\n",
5171 (unsigned int)dosmode,
5172 (unsigned int)delete_on_close ));
5174 status = can_set_delete_on_close(fsp, delete_on_close, dosmode);
5176 if (!NT_STATUS_IS_OK(status)) {
5180 /* The set is across all open files on this dev/inode pair. */
5181 if (!set_delete_on_close(fsp, delete_on_close,
5182 &conn->server_info->utok)) {
5183 return NT_STATUS_ACCESS_DENIED;
5185 return NT_STATUS_OK;
5188 /****************************************************************************
5189 Deal with SMB_FILE_POSITION_INFORMATION.
5190 ****************************************************************************/
5192 static NTSTATUS smb_file_position_information(connection_struct *conn,
5197 uint64_t position_information;
5199 if (total_data < 8) {
5200 return NT_STATUS_INVALID_PARAMETER;
5204 /* Ignore on pathname based set. */
5205 return NT_STATUS_OK;
5208 position_information = (uint64_t)IVAL(pdata,0);
5209 #ifdef LARGE_SMB_OFF_T
5210 position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
5211 #else /* LARGE_SMB_OFF_T */
5212 if (IVAL(pdata,4) != 0) {
5213 /* more than 32 bits? */
5214 return NT_STATUS_INVALID_PARAMETER;
5216 #endif /* LARGE_SMB_OFF_T */
5218 DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n",
5219 fsp->fsp_name, (double)position_information ));
5220 fsp->fh->position_information = position_information;
5221 return NT_STATUS_OK;
5224 /****************************************************************************
5225 Deal with SMB_FILE_MODE_INFORMATION.
5226 ****************************************************************************/
5228 static NTSTATUS smb_file_mode_information(connection_struct *conn,
5234 if (total_data < 4) {
5235 return NT_STATUS_INVALID_PARAMETER;
5237 mode = IVAL(pdata,0);
5238 if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
5239 return NT_STATUS_INVALID_PARAMETER;
5241 return NT_STATUS_OK;
5244 /****************************************************************************
5245 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
5246 ****************************************************************************/
5248 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
5249 struct smb_request *req,
5254 char *link_target = NULL;
5255 const char *newname = fname;
5256 NTSTATUS status = NT_STATUS_OK;
5257 TALLOC_CTX *ctx = talloc_tos();
5259 /* Set a symbolic link. */
5260 /* Don't allow this if follow links is false. */
5262 if (total_data == 0) {
5263 return NT_STATUS_INVALID_PARAMETER;
5266 if (!lp_symlinks(SNUM(conn))) {
5267 return NT_STATUS_ACCESS_DENIED;
5270 srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
5271 total_data, STR_TERMINATE);
5274 return NT_STATUS_INVALID_PARAMETER;
5277 /* !widelinks forces the target path to be within the share. */
5278 /* This means we can interpret the target as a pathname. */
5279 if (!lp_widelinks(SNUM(conn))) {
5280 char *rel_name = NULL;
5281 char *last_dirp = NULL;
5283 if (*link_target == '/') {
5284 /* No absolute paths allowed. */
5285 return NT_STATUS_ACCESS_DENIED;
5287 rel_name = talloc_strdup(ctx,newname);
5289 return NT_STATUS_NO_MEMORY;
5291 last_dirp = strrchr_m(rel_name, '/');
5293 last_dirp[1] = '\0';
5295 rel_name = talloc_strdup(ctx,"./");
5297 return NT_STATUS_NO_MEMORY;
5300 rel_name = talloc_asprintf_append(rel_name,
5304 return NT_STATUS_NO_MEMORY;
5307 status = check_name(conn, rel_name);
5308 if (!NT_STATUS_IS_OK(status)) {
5313 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
5314 newname, link_target ));
5316 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) {
5317 return map_nt_error_from_unix(errno);
5320 return NT_STATUS_OK;
5323 /****************************************************************************
5324 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
5325 ****************************************************************************/
5327 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
5328 struct smb_request *req,
5329 const char *pdata, int total_data,
5332 char *oldname = NULL;
5333 TALLOC_CTX *ctx = talloc_tos();
5334 NTSTATUS status = NT_STATUS_OK;
5336 /* Set a hard link. */
5337 if (total_data == 0) {
5338 return NT_STATUS_INVALID_PARAMETER;
5341 srvstr_get_path(ctx, pdata, req->flags2, &oldname, pdata,
5342 total_data, STR_TERMINATE, &status);
5343 if (!NT_STATUS_IS_OK(status)) {
5347 status = resolve_dfspath(ctx, conn,
5348 req->flags2 & FLAGS2_DFS_PATHNAMES,
5351 if (!NT_STATUS_IS_OK(status)) {
5355 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
5358 return hardlink_internals(ctx, conn, oldname, fname);
5361 /****************************************************************************
5362 Deal with SMB_FILE_RENAME_INFORMATION.
5363 ****************************************************************************/
5365 static NTSTATUS smb_file_rename_information(connection_struct *conn,
5366 struct smb_request *req,
5375 char *newname = NULL;
5376 char *base_name = NULL;
5377 bool dest_has_wcard = False;
5378 SMB_STRUCT_STAT sbuf;
5379 char *newname_last_component = NULL;
5380 NTSTATUS status = NT_STATUS_OK;
5382 TALLOC_CTX *ctx = talloc_tos();
5384 if (total_data < 13) {
5385 return NT_STATUS_INVALID_PARAMETER;
5390 overwrite = (CVAL(pdata,0) ? True : False);
5391 root_fid = IVAL(pdata,4);
5392 len = IVAL(pdata,8);
5394 if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
5395 return NT_STATUS_INVALID_PARAMETER;
5398 srvstr_get_path_wcard(ctx, pdata, req->flags2, &newname, &pdata[12],
5401 if (!NT_STATUS_IS_OK(status)) {
5405 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
5408 status = resolve_dfspath_wcard(ctx, conn,
5409 req->flags2 & FLAGS2_DFS_PATHNAMES,
5413 if (!NT_STATUS_IS_OK(status)) {
5417 /* Check the new name has no '/' characters. */
5418 if (strchr_m(newname, '/')) {
5419 return NT_STATUS_NOT_SUPPORTED;
5422 if (fsp && fsp->base_fsp) {
5423 /* newname must be a stream name. */
5424 if (newname[0] != ':') {
5425 return NT_STATUS_NOT_SUPPORTED;
5427 base_name = talloc_asprintf(ctx, "%s%s",
5428 fsp->base_fsp->fsp_name,
5431 return NT_STATUS_NO_MEMORY;
5434 /* newname must *not* be a stream name. */
5435 if (is_ntfs_stream_name(newname)) {
5436 return NT_STATUS_NOT_SUPPORTED;
5439 /* Create the base directory. */
5440 base_name = talloc_strdup(ctx, fname);
5442 return NT_STATUS_NO_MEMORY;
5444 p = strrchr_m(base_name, '/');
5448 base_name = talloc_strdup(ctx, "./");
5450 return NT_STATUS_NO_MEMORY;
5453 /* Append the new name. */
5454 base_name = talloc_asprintf_append(base_name,
5458 return NT_STATUS_NO_MEMORY;
5461 status = unix_convert(ctx, conn, newname, False,
5463 &newname_last_component,
5466 /* If an error we expect this to be
5467 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
5469 if (!NT_STATUS_IS_OK(status)
5470 && !NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
5477 DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
5478 fsp->fnum, fsp->fsp_name, base_name ));
5479 status = rename_internals_fsp(conn, fsp, base_name,
5480 newname_last_component, 0,
5483 DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
5484 fname, base_name ));
5485 status = rename_internals(ctx, conn, req, fname, base_name, 0,
5486 overwrite, False, dest_has_wcard,
5487 FILE_WRITE_ATTRIBUTES);
5493 /****************************************************************************
5494 Deal with SMB_SET_POSIX_ACL.
5495 ****************************************************************************/
5497 #if defined(HAVE_POSIX_ACLS)
5498 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
5503 SMB_STRUCT_STAT *psbuf)
5505 uint16 posix_acl_version;
5506 uint16 num_file_acls;
5507 uint16 num_def_acls;
5508 bool valid_file_acls = True;
5509 bool valid_def_acls = True;
5511 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
5512 return NT_STATUS_INVALID_PARAMETER;
5514 posix_acl_version = SVAL(pdata,0);
5515 num_file_acls = SVAL(pdata,2);
5516 num_def_acls = SVAL(pdata,4);
5518 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
5519 valid_file_acls = False;
5523 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
5524 valid_def_acls = False;
5528 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
5529 return NT_STATUS_INVALID_PARAMETER;
5532 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
5533 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
5534 return NT_STATUS_INVALID_PARAMETER;
5537 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
5538 fname ? fname : fsp->fsp_name,
5539 (unsigned int)num_file_acls,
5540 (unsigned int)num_def_acls));
5542 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
5543 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
5544 return map_nt_error_from_unix(errno);
5547 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, psbuf, num_def_acls,
5548 pdata + SMB_POSIX_ACL_HEADER_SIZE +
5549 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
5550 return map_nt_error_from_unix(errno);
5552 return NT_STATUS_OK;
5556 /****************************************************************************
5557 Deal with SMB_SET_POSIX_LOCK.
5558 ****************************************************************************/
5560 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
5561 struct smb_request *req,
5569 bool blocking_lock = False;
5570 enum brl_type lock_type;
5572 NTSTATUS status = NT_STATUS_OK;
5574 if (fsp == NULL || fsp->fh->fd == -1) {
5575 return NT_STATUS_INVALID_HANDLE;
5578 if (total_data != POSIX_LOCK_DATA_SIZE) {
5579 return NT_STATUS_INVALID_PARAMETER;
5582 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
5583 case POSIX_LOCK_TYPE_READ:
5584 lock_type = READ_LOCK;
5586 case POSIX_LOCK_TYPE_WRITE:
5587 /* Return the right POSIX-mappable error code for files opened read-only. */
5588 if (!fsp->can_write) {
5589 return NT_STATUS_INVALID_HANDLE;
5591 lock_type = WRITE_LOCK;
5593 case POSIX_LOCK_TYPE_UNLOCK:
5594 lock_type = UNLOCK_LOCK;
5597 return NT_STATUS_INVALID_PARAMETER;
5600 if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
5601 blocking_lock = False;
5602 } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
5603 blocking_lock = True;
5605 return NT_STATUS_INVALID_PARAMETER;
5608 if (!lp_blocking_locks(SNUM(conn))) {
5609 blocking_lock = False;
5612 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
5613 #if defined(HAVE_LONGLONG)
5614 offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
5615 ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
5616 count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
5617 ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
5618 #else /* HAVE_LONGLONG */
5619 offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
5620 count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
5621 #endif /* HAVE_LONGLONG */
5623 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
5624 "lock_pid = %u, count = %.0f, offset = %.0f\n",
5626 (unsigned int)lock_type,
5627 (unsigned int)lock_pid,
5631 if (lock_type == UNLOCK_LOCK) {
5632 status = do_unlock(smbd_messaging_context(),
5639 uint32 block_smbpid;
5641 struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(),
5652 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
5654 * A blocking lock was requested. Package up
5655 * this smb into a queued request and push it
5656 * onto the blocking lock queue.
5658 if(push_blocking_lock_request(br_lck,
5661 -1, /* infinite timeout. */
5669 TALLOC_FREE(br_lck);
5673 TALLOC_FREE(br_lck);
5679 /****************************************************************************
5680 Deal with SMB_INFO_STANDARD.
5681 ****************************************************************************/
5683 static NTSTATUS smb_set_info_standard(connection_struct *conn,
5688 const SMB_STRUCT_STAT *psbuf)
5690 struct smb_file_time ft;
5693 if (total_data < 12) {
5694 return NT_STATUS_INVALID_PARAMETER;
5698 ft.create_time = interpret_long_date(pdata);
5701 ft.atime = interpret_long_date(pdata + 8);
5704 ft.mtime = interpret_long_date(pdata + 16);
5706 DEBUG(10,("smb_set_info_standard: file %s\n",
5707 fname ? fname : fsp->fsp_name ));
5709 return smb_set_file_time(conn,
5717 /****************************************************************************
5718 Deal with SMB_SET_FILE_BASIC_INFO.
5719 ****************************************************************************/
5721 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
5726 SMB_STRUCT_STAT *psbuf)
5728 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
5729 struct timespec write_time;
5730 struct timespec changed_time;
5731 struct smb_file_time ft;
5733 NTSTATUS status = NT_STATUS_OK;
5734 bool setting_write_time = true;
5738 if (total_data < 36) {
5739 return NT_STATUS_INVALID_PARAMETER;
5742 /* Set the attributes */
5743 dosmode = IVAL(pdata,32);
5744 status = smb_set_file_dosmode(conn, fname, psbuf, dosmode);
5745 if (!NT_STATUS_IS_OK(status)) {
5751 ft.atime = interpret_long_date(pdata+8);
5753 write_time = interpret_long_date(pdata+16);
5754 changed_time = interpret_long_date(pdata+24);
5757 ft.mtime = timespec_min(&write_time, &changed_time);
5760 ft.create_time = interpret_long_date(pdata);
5762 if ((timespec_compare(&write_time, &ft.mtime) == 1) &&
5763 !null_timespec(write_time)) {
5764 ft.mtime = write_time;
5767 /* Prefer a defined time to an undefined one. */
5768 if (null_timespec(ft.mtime)) {
5769 if (null_timespec(write_time)) {
5770 ft.mtime = changed_time;
5771 setting_write_time = false;
5773 ft.mtime = write_time;
5777 DEBUG(10,("smb_set_file_basic_info: file %s\n",
5778 fname ? fname : fsp->fsp_name ));
5780 return smb_set_file_time(conn,
5785 setting_write_time);
5788 /****************************************************************************
5789 Deal with SMB_SET_FILE_ALLOCATION_INFO.
5790 ****************************************************************************/
5792 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
5793 struct smb_request *req,
5798 SMB_STRUCT_STAT *psbuf)
5800 uint64_t allocation_size = 0;
5801 NTSTATUS status = NT_STATUS_OK;
5802 files_struct *new_fsp = NULL;
5804 if (!VALID_STAT(*psbuf)) {
5805 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5808 if (total_data < 8) {
5809 return NT_STATUS_INVALID_PARAMETER;
5812 allocation_size = (uint64_t)IVAL(pdata,0);
5813 #ifdef LARGE_SMB_OFF_T
5814 allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
5815 #else /* LARGE_SMB_OFF_T */
5816 if (IVAL(pdata,4) != 0) {
5817 /* more than 32 bits? */
5818 return NT_STATUS_INVALID_PARAMETER;
5820 #endif /* LARGE_SMB_OFF_T */
5822 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for file %s to %.0f\n",
5823 fname, (double)allocation_size ));
5825 if (allocation_size) {
5826 allocation_size = smb_roundup(conn, allocation_size);
5829 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new allocation size to %.0f\n",
5830 fname, (double)allocation_size ));
5832 if (fsp && fsp->fh->fd != -1) {
5833 /* Open file handle. */
5834 /* Only change if needed. */
5835 if (allocation_size != get_file_size(*psbuf)) {
5836 if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
5837 return map_nt_error_from_unix(errno);
5840 /* But always update the time. */
5842 * This is equivalent to a write. Ensure it's seen immediately
5843 * if there are no pending writes.
5845 trigger_write_time_update_immediate(fsp);
5846 return NT_STATUS_OK;
5849 /* Pathname or stat or directory file. */
5851 status = SMB_VFS_CREATE_FILE(
5854 0, /* root_dir_fid */
5856 0, /* create_file_flags */
5857 FILE_WRITE_DATA, /* access_mask */
5858 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
5860 FILE_OPEN, /* create_disposition*/
5861 0, /* create_options */
5862 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5863 FORCE_OPLOCK_BREAK_TO_NONE, /* oplock_request */
5864 0, /* allocation_size */
5867 &new_fsp, /* result */
5871 if (!NT_STATUS_IS_OK(status)) {
5872 /* NB. We check for open_was_deferred in the caller. */
5876 /* Only change if needed. */
5877 if (allocation_size != get_file_size(*psbuf)) {
5878 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
5879 status = map_nt_error_from_unix(errno);
5880 close_file(req, new_fsp, NORMAL_CLOSE);
5885 /* Changing the allocation size should set the last mod time. */
5887 * This is equivalent to a write. Ensure it's seen immediately
5888 * if there are no pending writes.
5890 trigger_write_time_update_immediate(new_fsp);
5892 close_file(req, new_fsp, NORMAL_CLOSE);
5893 return NT_STATUS_OK;
5896 /****************************************************************************
5897 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
5898 ****************************************************************************/
5900 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
5901 struct smb_request *req,
5906 SMB_STRUCT_STAT *psbuf)
5910 if (total_data < 8) {
5911 return NT_STATUS_INVALID_PARAMETER;
5914 size = IVAL(pdata,0);
5915 #ifdef LARGE_SMB_OFF_T
5916 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
5917 #else /* LARGE_SMB_OFF_T */
5918 if (IVAL(pdata,4) != 0) {
5919 /* more than 32 bits? */
5920 return NT_STATUS_INVALID_PARAMETER;
5922 #endif /* LARGE_SMB_OFF_T */
5923 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
5924 "file %s to %.0f\n", fname, (double)size ));
5926 return smb_set_file_size(conn, req,
5933 /****************************************************************************
5934 Allow a UNIX info mknod.
5935 ****************************************************************************/
5937 static NTSTATUS smb_unix_mknod(connection_struct *conn,
5941 SMB_STRUCT_STAT *psbuf)
5943 uint32 file_type = IVAL(pdata,56);
5944 #if defined(HAVE_MAKEDEV)
5945 uint32 dev_major = IVAL(pdata,60);
5946 uint32 dev_minor = IVAL(pdata,68);
5948 SMB_DEV_T dev = (SMB_DEV_T)0;
5949 uint32 raw_unixmode = IVAL(pdata,84);
5953 if (total_data < 100) {
5954 return NT_STATUS_INVALID_PARAMETER;
5957 status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_FILE, &unixmode);
5958 if (!NT_STATUS_IS_OK(status)) {
5962 #if defined(HAVE_MAKEDEV)
5963 dev = makedev(dev_major, dev_minor);
5966 switch (file_type) {
5967 #if defined(S_IFIFO)
5968 case UNIX_TYPE_FIFO:
5969 unixmode |= S_IFIFO;
5972 #if defined(S_IFSOCK)
5973 case UNIX_TYPE_SOCKET:
5974 unixmode |= S_IFSOCK;
5977 #if defined(S_IFCHR)
5978 case UNIX_TYPE_CHARDEV:
5979 unixmode |= S_IFCHR;
5982 #if defined(S_IFBLK)
5983 case UNIX_TYPE_BLKDEV:
5984 unixmode |= S_IFBLK;
5988 return NT_STATUS_INVALID_PARAMETER;
5991 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
5992 0%o for file %s\n", (double)dev, (unsigned int)unixmode, fname ));
5994 /* Ok - do the mknod. */
5995 if (SMB_VFS_MKNOD(conn, fname, unixmode, dev) != 0) {
5996 return map_nt_error_from_unix(errno);
5999 /* If any of the other "set" calls fail we
6000 * don't want to end up with a half-constructed mknod.
6003 if (lp_inherit_perms(SNUM(conn))) {
6005 if (!parent_dirname(talloc_tos(), fname, &parent, NULL)) {
6006 return NT_STATUS_NO_MEMORY;
6008 inherit_access_posix_acl(conn, parent, fname, unixmode);
6009 TALLOC_FREE(parent);
6012 if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
6013 status = map_nt_error_from_unix(errno);
6014 SMB_VFS_UNLINK(conn,fname);
6017 return NT_STATUS_OK;
6020 /****************************************************************************
6021 Deal with SMB_SET_FILE_UNIX_BASIC.
6022 ****************************************************************************/
6024 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
6025 struct smb_request *req,
6030 SMB_STRUCT_STAT *psbuf)
6032 struct smb_file_time ft;
6033 uint32 raw_unixmode;
6036 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
6037 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
6038 NTSTATUS status = NT_STATUS_OK;
6039 bool delete_on_fail = False;
6040 enum perm_type ptype;
6044 if (total_data < 100) {
6045 return NT_STATUS_INVALID_PARAMETER;
6048 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
6049 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
6050 size=IVAL(pdata,0); /* first 8 Bytes are size */
6051 #ifdef LARGE_SMB_OFF_T
6052 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
6053 #else /* LARGE_SMB_OFF_T */
6054 if (IVAL(pdata,4) != 0) {
6055 /* more than 32 bits? */
6056 return NT_STATUS_INVALID_PARAMETER;
6058 #endif /* LARGE_SMB_OFF_T */
6061 ft.atime = interpret_long_date(pdata+24); /* access_time */
6062 ft.mtime = interpret_long_date(pdata+32); /* modification_time */
6063 set_owner = (uid_t)IVAL(pdata,40);
6064 set_grp = (gid_t)IVAL(pdata,48);
6065 raw_unixmode = IVAL(pdata,84);
6067 if (VALID_STAT(*psbuf)) {
6068 if (S_ISDIR(psbuf->st_mode)) {
6069 ptype = PERM_EXISTING_DIR;
6071 ptype = PERM_EXISTING_FILE;
6074 ptype = PERM_NEW_FILE;
6077 status = unix_perms_from_wire(conn, psbuf, raw_unixmode, ptype, &unixmode);
6078 if (!NT_STATUS_IS_OK(status)) {
6082 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = %s \
6083 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
6084 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
6086 if (!VALID_STAT(*psbuf)) {
6088 * The only valid use of this is to create character and block
6089 * devices, and named pipes. This is deprecated (IMHO) and
6090 * a new info level should be used for mknod. JRA.
6093 status = smb_unix_mknod(conn,
6098 if (!NT_STATUS_IS_OK(status)) {
6102 /* Ensure we don't try and change anything else. */
6103 raw_unixmode = SMB_MODE_NO_CHANGE;
6104 size = get_file_size(*psbuf);
6105 ft.atime = get_atimespec(psbuf);
6106 ft.mtime = get_mtimespec(psbuf);
6108 * We continue here as we might want to change the
6111 delete_on_fail = True;
6115 /* Horrible backwards compatibility hack as an old server bug
6116 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
6120 size = get_file_size(*psbuf);
6125 * Deal with the UNIX specific mode set.
6128 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
6129 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
6130 (unsigned int)unixmode, fname ));
6131 if (SMB_VFS_CHMOD(conn, fname, unixmode) != 0) {
6132 return map_nt_error_from_unix(errno);
6137 * Deal with the UNIX specific uid set.
6140 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_uid != set_owner)) {
6143 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing owner %u for path %s\n",
6144 (unsigned int)set_owner, fname ));
6146 if (S_ISLNK(psbuf->st_mode)) {
6147 ret = SMB_VFS_LCHOWN(conn, fname, set_owner, (gid_t)-1);
6149 ret = SMB_VFS_CHOWN(conn, fname, set_owner, (gid_t)-1);
6153 status = map_nt_error_from_unix(errno);
6154 if (delete_on_fail) {
6155 SMB_VFS_UNLINK(conn,fname);
6162 * Deal with the UNIX specific gid set.
6165 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_gid != set_grp)) {
6166 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
6167 (unsigned int)set_owner, fname ));
6168 if (SMB_VFS_CHOWN(conn, fname, (uid_t)-1, set_grp) != 0) {
6169 status = map_nt_error_from_unix(errno);
6170 if (delete_on_fail) {
6171 SMB_VFS_UNLINK(conn,fname);
6177 /* Deal with any size changes. */
6179 status = smb_set_file_size(conn, req,
6184 if (!NT_STATUS_IS_OK(status)) {
6188 /* Deal with any time changes. */
6190 return smb_set_file_time(conn,
6198 /****************************************************************************
6199 Deal with SMB_SET_FILE_UNIX_INFO2.
6200 ****************************************************************************/
6202 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
6203 struct smb_request *req,
6208 SMB_STRUCT_STAT *psbuf)
6214 if (total_data < 116) {
6215 return NT_STATUS_INVALID_PARAMETER;
6218 /* Start by setting all the fields that are common between UNIX_BASIC
6221 status = smb_set_file_unix_basic(conn, req, pdata, total_data,
6223 if (!NT_STATUS_IS_OK(status)) {
6227 smb_fflags = IVAL(pdata, 108);
6228 smb_fmask = IVAL(pdata, 112);
6230 /* NB: We should only attempt to alter the file flags if the client
6231 * sends a non-zero mask.
6233 if (smb_fmask != 0) {
6234 int stat_fflags = 0;
6236 if (!map_info2_flags_to_sbuf(psbuf, smb_fflags, smb_fmask,
6238 /* Client asked to alter a flag we don't understand. */
6239 return NT_STATUS_INVALID_PARAMETER;
6242 if (fsp && fsp->fh->fd != -1) {
6243 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
6244 return NT_STATUS_NOT_SUPPORTED;
6246 if (SMB_VFS_CHFLAGS(conn, fname, stat_fflags) != 0) {
6247 return map_nt_error_from_unix(errno);
6252 /* XXX: need to add support for changing the create_time here. You
6253 * can do this for paths on Darwin with setattrlist(2). The right way
6254 * to hook this up is probably by extending the VFS utimes interface.
6257 return NT_STATUS_OK;
6260 /****************************************************************************
6261 Create a directory with POSIX semantics.
6262 ****************************************************************************/
6264 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
6265 struct smb_request *req,
6269 SMB_STRUCT_STAT *psbuf,
6270 int *pdata_return_size)
6272 NTSTATUS status = NT_STATUS_OK;
6273 uint32 raw_unixmode = 0;
6274 uint32 mod_unixmode = 0;
6275 mode_t unixmode = (mode_t)0;
6276 files_struct *fsp = NULL;
6277 uint16 info_level_return = 0;
6279 char *pdata = *ppdata;
6281 if (total_data < 18) {
6282 return NT_STATUS_INVALID_PARAMETER;
6285 raw_unixmode = IVAL(pdata,8);
6286 /* Next 4 bytes are not yet defined. */
6288 status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_DIR, &unixmode);
6289 if (!NT_STATUS_IS_OK(status)) {
6293 mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
6295 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
6296 fname, (unsigned int)unixmode ));
6298 status = SMB_VFS_CREATE_FILE(
6301 0, /* root_dir_fid */
6303 0, /* create_file_flags */
6304 FILE_READ_ATTRIBUTES, /* access_mask */
6305 FILE_SHARE_NONE, /* share_access */
6306 FILE_CREATE, /* create_disposition*/
6307 FILE_DIRECTORY_FILE, /* create_options */
6308 mod_unixmode, /* file_attributes */
6309 0, /* oplock_request */
6310 0, /* allocation_size */
6317 if (NT_STATUS_IS_OK(status)) {
6318 close_file(req, fsp, NORMAL_CLOSE);
6321 info_level_return = SVAL(pdata,16);
6323 if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
6324 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
6325 } else if (info_level_return == SMB_QUERY_FILE_UNIX_INFO2) {
6326 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
6328 *pdata_return_size = 12;
6331 /* Realloc the data size */
6332 *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
6333 if (*ppdata == NULL) {
6334 *pdata_return_size = 0;
6335 return NT_STATUS_NO_MEMORY;
6339 SSVAL(pdata,0,NO_OPLOCK_RETURN);
6340 SSVAL(pdata,2,0); /* No fnum. */
6341 SIVAL(pdata,4,info); /* Was directory created. */
6343 switch (info_level_return) {
6344 case SMB_QUERY_FILE_UNIX_BASIC:
6345 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
6346 SSVAL(pdata,10,0); /* Padding. */
6347 store_file_unix_basic(conn, pdata + 12, fsp, psbuf);
6349 case SMB_QUERY_FILE_UNIX_INFO2:
6350 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
6351 SSVAL(pdata,10,0); /* Padding. */
6352 store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf);
6355 SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
6356 SSVAL(pdata,10,0); /* Padding. */
6363 /****************************************************************************
6364 Open/Create a file with POSIX semantics.
6365 ****************************************************************************/
6367 static NTSTATUS smb_posix_open(connection_struct *conn,
6368 struct smb_request *req,
6372 SMB_STRUCT_STAT *psbuf,
6373 int *pdata_return_size)
6375 bool extended_oplock_granted = False;
6376 char *pdata = *ppdata;
6378 uint32 wire_open_mode = 0;
6379 uint32 raw_unixmode = 0;
6380 uint32 mod_unixmode = 0;
6381 uint32 create_disp = 0;
6382 uint32 access_mask = 0;
6383 uint32 create_options = 0;
6384 NTSTATUS status = NT_STATUS_OK;
6385 mode_t unixmode = (mode_t)0;
6386 files_struct *fsp = NULL;
6387 int oplock_request = 0;
6389 uint16 info_level_return = 0;
6391 if (total_data < 18) {
6392 return NT_STATUS_INVALID_PARAMETER;
6395 flags = IVAL(pdata,0);
6396 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
6397 if (oplock_request) {
6398 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
6401 wire_open_mode = IVAL(pdata,4);
6403 if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
6404 return smb_posix_mkdir(conn, req,
6412 switch (wire_open_mode & SMB_ACCMODE) {
6414 access_mask = FILE_READ_DATA;
6417 access_mask = FILE_WRITE_DATA;
6420 access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
6423 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
6424 (unsigned int)wire_open_mode ));
6425 return NT_STATUS_INVALID_PARAMETER;
6428 wire_open_mode &= ~SMB_ACCMODE;
6430 if((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) == (SMB_O_CREAT | SMB_O_EXCL)) {
6431 create_disp = FILE_CREATE;
6432 } else if((wire_open_mode & (SMB_O_CREAT | SMB_O_TRUNC)) == (SMB_O_CREAT | SMB_O_TRUNC)) {
6433 create_disp = FILE_OVERWRITE_IF;
6434 } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
6435 create_disp = FILE_OPEN_IF;
6437 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
6438 (unsigned int)wire_open_mode ));
6439 return NT_STATUS_INVALID_PARAMETER;
6442 raw_unixmode = IVAL(pdata,8);
6443 /* Next 4 bytes are not yet defined. */
6445 status = unix_perms_from_wire(conn,
6448 VALID_STAT(*psbuf) ? PERM_EXISTING_FILE : PERM_NEW_FILE,
6451 if (!NT_STATUS_IS_OK(status)) {
6455 mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
6457 if (wire_open_mode & SMB_O_SYNC) {
6458 create_options |= FILE_WRITE_THROUGH;
6460 if (wire_open_mode & SMB_O_APPEND) {
6461 access_mask |= FILE_APPEND_DATA;
6463 if (wire_open_mode & SMB_O_DIRECT) {
6464 mod_unixmode |= FILE_FLAG_NO_BUFFERING;
6467 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
6469 (unsigned int)wire_open_mode,
6470 (unsigned int)unixmode ));
6472 status = SMB_VFS_CREATE_FILE(
6475 0, /* root_dir_fid */
6477 0, /* create_file_flags */
6478 access_mask, /* access_mask */
6479 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
6481 create_disp, /* create_disposition*/
6482 0, /* create_options */
6483 mod_unixmode, /* file_attributes */
6484 oplock_request, /* oplock_request */
6485 0, /* allocation_size */
6492 if (!NT_STATUS_IS_OK(status)) {
6496 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
6497 extended_oplock_granted = True;
6500 if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
6501 extended_oplock_granted = True;
6504 info_level_return = SVAL(pdata,16);
6506 /* Allocate the correct return size. */
6508 if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
6509 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
6510 } else if (info_level_return == SMB_QUERY_FILE_UNIX_INFO2) {
6511 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
6513 *pdata_return_size = 12;
6516 /* Realloc the data size */
6517 *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
6518 if (*ppdata == NULL) {
6519 close_file(req, fsp, ERROR_CLOSE);
6520 *pdata_return_size = 0;
6521 return NT_STATUS_NO_MEMORY;
6525 if (extended_oplock_granted) {
6526 if (flags & REQUEST_BATCH_OPLOCK) {
6527 SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
6529 SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
6531 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
6532 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
6534 SSVAL(pdata,0,NO_OPLOCK_RETURN);
6537 SSVAL(pdata,2,fsp->fnum);
6538 SIVAL(pdata,4,info); /* Was file created etc. */
6540 switch (info_level_return) {
6541 case SMB_QUERY_FILE_UNIX_BASIC:
6542 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
6543 SSVAL(pdata,10,0); /* padding. */
6544 store_file_unix_basic(conn, pdata + 12, fsp, psbuf);
6546 case SMB_QUERY_FILE_UNIX_INFO2:
6547 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
6548 SSVAL(pdata,10,0); /* padding. */
6549 store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf);
6552 SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
6553 SSVAL(pdata,10,0); /* padding. */
6556 return NT_STATUS_OK;
6559 /****************************************************************************
6560 Delete a file with POSIX semantics.
6561 ****************************************************************************/
6563 static NTSTATUS smb_posix_unlink(connection_struct *conn,
6564 struct smb_request *req,
6568 SMB_STRUCT_STAT *psbuf)
6570 NTSTATUS status = NT_STATUS_OK;
6571 files_struct *fsp = NULL;
6575 int create_options = 0;
6577 struct share_mode_lock *lck = NULL;
6579 if (total_data < 2) {
6580 return NT_STATUS_INVALID_PARAMETER;
6583 flags = SVAL(pdata,0);
6585 if (!VALID_STAT(*psbuf)) {
6586 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6589 if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
6590 !VALID_STAT_OF_DIR(*psbuf)) {
6591 return NT_STATUS_NOT_A_DIRECTORY;
6594 DEBUG(10,("smb_posix_unlink: %s %s\n",
6595 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
6598 if (VALID_STAT_OF_DIR(*psbuf)) {
6599 create_options |= FILE_DIRECTORY_FILE;
6602 status = SMB_VFS_CREATE_FILE(
6605 0, /* root_dir_fid */
6607 0, /* create_file_flags */
6608 DELETE_ACCESS, /* access_mask */
6609 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
6611 FILE_OPEN, /* create_disposition*/
6612 create_options, /* create_options */
6613 FILE_FLAG_POSIX_SEMANTICS|0777, /* file_attributes */
6614 0, /* oplock_request */
6615 0, /* allocation_size */
6622 if (!NT_STATUS_IS_OK(status)) {
6627 * Don't lie to client. If we can't really delete due to
6628 * non-POSIX opens return SHARING_VIOLATION.
6631 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
6634 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
6635 "lock for file %s\n", fsp->fsp_name));
6636 close_file(req, fsp, NORMAL_CLOSE);
6637 return NT_STATUS_INVALID_PARAMETER;
6641 * See if others still have the file open. If this is the case, then
6642 * don't delete. If all opens are POSIX delete we can set the delete
6643 * on close disposition.
6645 for (i=0; i<lck->num_share_modes; i++) {
6646 struct share_mode_entry *e = &lck->share_modes[i];
6647 if (is_valid_share_mode_entry(e)) {
6648 if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
6651 /* Fail with sharing violation. */
6652 close_file(req, fsp, NORMAL_CLOSE);
6654 return NT_STATUS_SHARING_VIOLATION;
6659 * Set the delete on close.
6661 status = smb_set_file_disposition_info(conn,
6668 if (!NT_STATUS_IS_OK(status)) {
6669 close_file(req, fsp, NORMAL_CLOSE);
6674 return close_file(req, fsp, NORMAL_CLOSE);
6677 /****************************************************************************
6678 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
6679 ****************************************************************************/
6681 static void call_trans2setfilepathinfo(connection_struct *conn,
6682 struct smb_request *req,
6683 unsigned int tran_call,
6684 char **pparams, int total_params,
6685 char **ppdata, int total_data,
6686 unsigned int max_data_bytes)
6688 char *params = *pparams;
6689 char *pdata = *ppdata;
6691 SMB_STRUCT_STAT sbuf;
6693 files_struct *fsp = NULL;
6694 NTSTATUS status = NT_STATUS_OK;
6695 int data_return_size = 0;
6696 TALLOC_CTX *ctx = talloc_tos();
6699 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6705 if (tran_call == TRANSACT2_SETFILEINFO) {
6706 if (total_params < 4) {
6707 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6711 fsp = file_fsp(req, SVAL(params,0));
6712 /* Basic check for non-null fsp. */
6713 if (!check_fsp_open(conn, req, fsp)) {
6716 info_level = SVAL(params,2);
6718 fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
6720 reply_nterror(req, NT_STATUS_NO_MEMORY);
6724 if(fsp->is_directory || fsp->fh->fd == -1) {
6726 * This is actually a SETFILEINFO on a directory
6727 * handle (returned from an NT SMB). NT5.0 seems
6728 * to do this call. JRA.
6730 if (INFO_LEVEL_IS_UNIX(info_level)) {
6731 /* Always do lstat for UNIX calls. */
6732 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
6733 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
6734 reply_unixerror(req,ERRDOS,ERRbadpath);
6738 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
6739 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
6740 reply_unixerror(req,ERRDOS,ERRbadpath);
6744 } else if (fsp->print_file) {
6746 * Doing a DELETE_ON_CLOSE should cancel a print job.
6748 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
6749 fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
6751 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
6754 send_trans2_replies(conn, req, params, 2,
6759 reply_unixerror(req, ERRDOS, ERRbadpath);
6764 * Original code - this is an open file.
6766 if (!check_fsp(conn, req, fsp)) {
6770 if (SMB_VFS_FSTAT(fsp, &sbuf) != 0) {
6771 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
6772 reply_unixerror(req, ERRDOS, ERRbadfid);
6778 if (total_params < 7) {
6779 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6783 info_level = SVAL(params,0);
6784 srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6],
6785 total_params - 6, STR_TERMINATE,
6787 if (!NT_STATUS_IS_OK(status)) {
6788 reply_nterror(req, status);
6792 status = resolve_dfspath(ctx, conn,
6793 req->flags2 & FLAGS2_DFS_PATHNAMES,
6796 if (!NT_STATUS_IS_OK(status)) {
6797 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6798 reply_botherror(req,
6799 NT_STATUS_PATH_NOT_COVERED,
6800 ERRSRV, ERRbadpath);
6803 reply_nterror(req, status);
6807 status = unix_convert(ctx, conn, fname, False,
6808 &fname, NULL, &sbuf);
6809 if (!NT_STATUS_IS_OK(status)) {
6810 reply_nterror(req, status);
6814 status = check_name(conn, fname);
6815 if (!NT_STATUS_IS_OK(status)) {
6816 reply_nterror(req, status);
6820 if (INFO_LEVEL_IS_UNIX(info_level)) {
6822 * For CIFS UNIX extensions the target name may not exist.
6825 /* Always do lstat for UNIX calls. */
6826 SMB_VFS_LSTAT(conn,fname,&sbuf);
6828 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
6829 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
6830 reply_unixerror(req, ERRDOS, ERRbadpath);
6835 if (!CAN_WRITE(conn)) {
6836 reply_doserror(req, ERRSRV, ERRaccess);
6840 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
6841 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6845 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
6846 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
6848 /* Realloc the parameter size */
6849 *pparams = (char *)SMB_REALLOC(*pparams,2);
6850 if (*pparams == NULL) {
6851 reply_nterror(req, NT_STATUS_NO_MEMORY);
6858 switch (info_level) {
6860 case SMB_INFO_STANDARD:
6862 status = smb_set_info_standard(conn,
6871 case SMB_INFO_SET_EA:
6873 status = smb_info_set_ea(conn,
6881 case SMB_SET_FILE_BASIC_INFO:
6882 case SMB_FILE_BASIC_INFORMATION:
6884 status = smb_set_file_basic_info(conn,
6893 case SMB_FILE_ALLOCATION_INFORMATION:
6894 case SMB_SET_FILE_ALLOCATION_INFO:
6896 status = smb_set_file_allocation_info(conn, req,
6905 case SMB_FILE_END_OF_FILE_INFORMATION:
6906 case SMB_SET_FILE_END_OF_FILE_INFO:
6908 status = smb_set_file_end_of_file_info(conn, req,
6917 case SMB_FILE_DISPOSITION_INFORMATION:
6918 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
6921 /* JRA - We used to just ignore this on a path ?
6922 * Shouldn't this be invalid level on a pathname
6925 if (tran_call != TRANSACT2_SETFILEINFO) {
6926 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
6929 status = smb_set_file_disposition_info(conn,
6938 case SMB_FILE_POSITION_INFORMATION:
6940 status = smb_file_position_information(conn,
6947 /* From tridge Samba4 :
6948 * MODE_INFORMATION in setfileinfo (I have no
6949 * idea what "mode information" on a file is - it takes a value of 0,
6950 * 2, 4 or 6. What could it be?).
6953 case SMB_FILE_MODE_INFORMATION:
6955 status = smb_file_mode_information(conn,
6962 * CIFS UNIX extensions.
6965 case SMB_SET_FILE_UNIX_BASIC:
6967 status = smb_set_file_unix_basic(conn, req,
6976 case SMB_SET_FILE_UNIX_INFO2:
6978 status = smb_set_file_unix_info2(conn, req,
6987 case SMB_SET_FILE_UNIX_LINK:
6989 if (tran_call != TRANSACT2_SETPATHINFO) {
6990 /* We must have a pathname for this. */
6991 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6994 status = smb_set_file_unix_link(conn, req, pdata,
6999 case SMB_SET_FILE_UNIX_HLINK:
7001 if (tran_call != TRANSACT2_SETPATHINFO) {
7002 /* We must have a pathname for this. */
7003 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
7006 status = smb_set_file_unix_hlink(conn, req,
7012 case SMB_FILE_RENAME_INFORMATION:
7014 status = smb_file_rename_information(conn, req,
7020 #if defined(HAVE_POSIX_ACLS)
7021 case SMB_SET_POSIX_ACL:
7023 status = smb_set_posix_acl(conn,
7033 case SMB_SET_POSIX_LOCK:
7035 if (tran_call != TRANSACT2_SETFILEINFO) {
7036 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
7039 status = smb_set_posix_lock(conn, req,
7040 pdata, total_data, fsp);
7044 case SMB_POSIX_PATH_OPEN:
7046 if (tran_call != TRANSACT2_SETPATHINFO) {
7047 /* We must have a pathname for this. */
7048 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
7052 status = smb_posix_open(conn, req,
7061 case SMB_POSIX_PATH_UNLINK:
7063 if (tran_call != TRANSACT2_SETPATHINFO) {
7064 /* We must have a pathname for this. */
7065 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
7069 status = smb_posix_unlink(conn, req,
7078 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
7083 if (!NT_STATUS_IS_OK(status)) {
7084 if (open_was_deferred(req->mid)) {
7085 /* We have re-scheduled this call. */
7088 if (blocking_lock_was_deferred(req->mid)) {
7089 /* We have re-scheduled this call. */
7092 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
7093 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
7094 ERRSRV, ERRbadpath);
7097 if (info_level == SMB_POSIX_PATH_OPEN) {
7098 reply_openerror(req, status);
7102 reply_nterror(req, status);
7107 send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
7113 /****************************************************************************
7114 Reply to a TRANS2_MKDIR (make directory with extended attributes).
7115 ****************************************************************************/
7117 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
7118 char **pparams, int total_params,
7119 char **ppdata, int total_data,
7120 unsigned int max_data_bytes)
7122 char *params = *pparams;
7123 char *pdata = *ppdata;
7124 char *directory = NULL;
7125 SMB_STRUCT_STAT sbuf;
7126 NTSTATUS status = NT_STATUS_OK;
7127 struct ea_list *ea_list = NULL;
7128 TALLOC_CTX *ctx = talloc_tos();
7130 if (!CAN_WRITE(conn)) {
7131 reply_doserror(req, ERRSRV, ERRaccess);
7135 if (total_params < 5) {
7136 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7140 srvstr_get_path(ctx, params, req->flags2, &directory, ¶ms[4],
7141 total_params - 4, STR_TERMINATE,
7143 if (!NT_STATUS_IS_OK(status)) {
7144 reply_nterror(req, status);
7148 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
7150 status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
7151 if (!NT_STATUS_IS_OK(status)) {
7152 reply_nterror(req, status);
7156 status = check_name(conn, directory);
7157 if (!NT_STATUS_IS_OK(status)) {
7158 DEBUG(5,("call_trans2mkdir error (%s)\n", nt_errstr(status)));
7159 reply_nterror(req, status);
7163 /* Any data in this call is an EA list. */
7164 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
7165 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
7170 * OS/2 workplace shell seems to send SET_EA requests of "null"
7171 * length (4 bytes containing IVAL 4).
7172 * They seem to have no effect. Bug #3212. JRA.
7175 if (total_data != 4) {
7176 if (total_data < 10) {
7177 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7181 if (IVAL(pdata,0) > total_data) {
7182 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
7183 IVAL(pdata,0), (unsigned int)total_data));
7184 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7188 ea_list = read_ea_list(talloc_tos(), pdata + 4,
7191 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7195 /* If total_data == 4 Windows doesn't care what values
7196 * are placed in that field, it just ignores them.
7197 * The System i QNTC IBM SMB client puts bad values here,
7198 * so ignore them. */
7200 status = create_directory(conn, req, directory);
7202 if (!NT_STATUS_IS_OK(status)) {
7203 reply_nterror(req, status);
7207 /* Try and set any given EA. */
7209 status = set_ea(conn, NULL, directory, ea_list);
7210 if (!NT_STATUS_IS_OK(status)) {
7211 reply_nterror(req, status);
7216 /* Realloc the parameter and data sizes */
7217 *pparams = (char *)SMB_REALLOC(*pparams,2);
7218 if(*pparams == NULL) {
7219 reply_nterror(req, NT_STATUS_NO_MEMORY);
7226 send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
7231 /****************************************************************************
7232 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
7233 We don't actually do this - we just send a null response.
7234 ****************************************************************************/
7236 static void call_trans2findnotifyfirst(connection_struct *conn,
7237 struct smb_request *req,
7238 char **pparams, int total_params,
7239 char **ppdata, int total_data,
7240 unsigned int max_data_bytes)
7242 char *params = *pparams;
7245 if (total_params < 6) {
7246 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7250 info_level = SVAL(params,4);
7251 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
7253 switch (info_level) {
7258 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
7262 /* Realloc the parameter and data sizes */
7263 *pparams = (char *)SMB_REALLOC(*pparams,6);
7264 if (*pparams == NULL) {
7265 reply_nterror(req, NT_STATUS_NO_MEMORY);
7270 SSVAL(params,0,fnf_handle);
7271 SSVAL(params,2,0); /* No changes */
7272 SSVAL(params,4,0); /* No EA errors */
7279 send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
7284 /****************************************************************************
7285 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
7286 changes). Currently this does nothing.
7287 ****************************************************************************/
7289 static void call_trans2findnotifynext(connection_struct *conn,
7290 struct smb_request *req,
7291 char **pparams, int total_params,
7292 char **ppdata, int total_data,
7293 unsigned int max_data_bytes)
7295 char *params = *pparams;
7297 DEBUG(3,("call_trans2findnotifynext\n"));
7299 /* Realloc the parameter and data sizes */
7300 *pparams = (char *)SMB_REALLOC(*pparams,4);
7301 if (*pparams == NULL) {
7302 reply_nterror(req, NT_STATUS_NO_MEMORY);
7307 SSVAL(params,0,0); /* No changes */
7308 SSVAL(params,2,0); /* No EA errors */
7310 send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
7315 /****************************************************************************
7316 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
7317 ****************************************************************************/
7319 static void call_trans2getdfsreferral(connection_struct *conn,
7320 struct smb_request *req,
7321 char **pparams, int total_params,
7322 char **ppdata, int total_data,
7323 unsigned int max_data_bytes)
7325 char *params = *pparams;
7326 char *pathname = NULL;
7328 int max_referral_level;
7329 NTSTATUS status = NT_STATUS_OK;
7330 TALLOC_CTX *ctx = talloc_tos();
7332 DEBUG(10,("call_trans2getdfsreferral\n"));
7334 if (total_params < 3) {
7335 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7339 max_referral_level = SVAL(params,0);
7341 if(!lp_host_msdfs()) {
7342 reply_doserror(req, ERRDOS, ERRbadfunc);
7346 srvstr_pull_talloc(ctx, params, req->flags2, &pathname, ¶ms[2],
7347 total_params - 2, STR_TERMINATE);
7349 reply_nterror(req, NT_STATUS_NOT_FOUND);
7352 if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
7353 ppdata,&status)) < 0) {
7354 reply_nterror(req, status);
7358 SSVAL(req->inbuf, smb_flg2,
7359 SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
7360 send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
7365 #define LMCAT_SPL 0x53
7366 #define LMFUNC_GETJOBID 0x60
7368 /****************************************************************************
7369 Reply to a TRANS2_IOCTL - used for OS/2 printing.
7370 ****************************************************************************/
7372 static void call_trans2ioctl(connection_struct *conn,
7373 struct smb_request *req,
7374 char **pparams, int total_params,
7375 char **ppdata, int total_data,
7376 unsigned int max_data_bytes)
7378 char *pdata = *ppdata;
7379 files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
7381 /* check for an invalid fid before proceeding */
7384 reply_doserror(req, ERRDOS, ERRbadfid);
7388 if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
7389 && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
7390 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
7391 if (*ppdata == NULL) {
7392 reply_nterror(req, NT_STATUS_NO_MEMORY);
7397 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
7398 CAN ACCEPT THIS IN UNICODE. JRA. */
7400 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
7401 srvstr_push(pdata, req->flags2, pdata + 2,
7402 global_myname(), 15,
7403 STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
7404 srvstr_push(pdata, req->flags2, pdata+18,
7405 lp_servicename(SNUM(conn)), 13,
7406 STR_ASCII|STR_TERMINATE); /* Service name */
7407 send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
7412 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
7413 reply_doserror(req, ERRSRV, ERRerror);
7416 /****************************************************************************
7417 Reply to a SMBfindclose (stop trans2 directory search).
7418 ****************************************************************************/
7420 void reply_findclose(struct smb_request *req)
7424 START_PROFILE(SMBfindclose);
7427 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7428 END_PROFILE(SMBfindclose);
7432 dptr_num = SVALS(req->vwv+0, 0);
7434 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
7436 dptr_close(&dptr_num);
7438 reply_outbuf(req, 0, 0);
7440 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
7442 END_PROFILE(SMBfindclose);
7446 /****************************************************************************
7447 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
7448 ****************************************************************************/
7450 void reply_findnclose(struct smb_request *req)
7454 START_PROFILE(SMBfindnclose);
7457 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7458 END_PROFILE(SMBfindnclose);
7462 dptr_num = SVAL(req->vwv+0, 0);
7464 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
7466 /* We never give out valid handles for a
7467 findnotifyfirst - so any dptr_num is ok here.
7470 reply_outbuf(req, 0, 0);
7472 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
7474 END_PROFILE(SMBfindnclose);
7478 static void handle_trans2(connection_struct *conn, struct smb_request *req,
7479 struct trans_state *state)
7481 if (Protocol >= PROTOCOL_NT1) {
7482 req->flags2 |= 0x40; /* IS_LONG_NAME */
7483 SSVAL(req->inbuf,smb_flg2,req->flags2);
7486 if (conn->encrypt_level == Required && !req->encrypted) {
7487 if (state->call != TRANSACT2_QFSINFO &&
7488 state->call != TRANSACT2_SETFSINFO) {
7489 DEBUG(0,("handle_trans2: encryption required "
7491 (unsigned int)state->call));
7492 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
7497 /* Now we must call the relevant TRANS2 function */
7498 switch(state->call) {
7499 case TRANSACT2_OPEN:
7501 START_PROFILE(Trans2_open);
7502 call_trans2open(conn, req,
7503 &state->param, state->total_param,
7504 &state->data, state->total_data,
7505 state->max_data_return);
7506 END_PROFILE(Trans2_open);
7510 case TRANSACT2_FINDFIRST:
7512 START_PROFILE(Trans2_findfirst);
7513 call_trans2findfirst(conn, req,
7514 &state->param, state->total_param,
7515 &state->data, state->total_data,
7516 state->max_data_return);
7517 END_PROFILE(Trans2_findfirst);
7521 case TRANSACT2_FINDNEXT:
7523 START_PROFILE(Trans2_findnext);
7524 call_trans2findnext(conn, req,
7525 &state->param, state->total_param,
7526 &state->data, state->total_data,
7527 state->max_data_return);
7528 END_PROFILE(Trans2_findnext);
7532 case TRANSACT2_QFSINFO:
7534 START_PROFILE(Trans2_qfsinfo);
7535 call_trans2qfsinfo(conn, req,
7536 &state->param, state->total_param,
7537 &state->data, state->total_data,
7538 state->max_data_return);
7539 END_PROFILE(Trans2_qfsinfo);
7543 case TRANSACT2_SETFSINFO:
7545 START_PROFILE(Trans2_setfsinfo);
7546 call_trans2setfsinfo(conn, req,
7547 &state->param, state->total_param,
7548 &state->data, state->total_data,
7549 state->max_data_return);
7550 END_PROFILE(Trans2_setfsinfo);
7554 case TRANSACT2_QPATHINFO:
7555 case TRANSACT2_QFILEINFO:
7557 START_PROFILE(Trans2_qpathinfo);
7558 call_trans2qfilepathinfo(conn, req, state->call,
7559 &state->param, state->total_param,
7560 &state->data, state->total_data,
7561 state->max_data_return);
7562 END_PROFILE(Trans2_qpathinfo);
7566 case TRANSACT2_SETPATHINFO:
7567 case TRANSACT2_SETFILEINFO:
7569 START_PROFILE(Trans2_setpathinfo);
7570 call_trans2setfilepathinfo(conn, req, state->call,
7571 &state->param, state->total_param,
7572 &state->data, state->total_data,
7573 state->max_data_return);
7574 END_PROFILE(Trans2_setpathinfo);
7578 case TRANSACT2_FINDNOTIFYFIRST:
7580 START_PROFILE(Trans2_findnotifyfirst);
7581 call_trans2findnotifyfirst(conn, req,
7582 &state->param, state->total_param,
7583 &state->data, state->total_data,
7584 state->max_data_return);
7585 END_PROFILE(Trans2_findnotifyfirst);
7589 case TRANSACT2_FINDNOTIFYNEXT:
7591 START_PROFILE(Trans2_findnotifynext);
7592 call_trans2findnotifynext(conn, req,
7593 &state->param, state->total_param,
7594 &state->data, state->total_data,
7595 state->max_data_return);
7596 END_PROFILE(Trans2_findnotifynext);
7600 case TRANSACT2_MKDIR:
7602 START_PROFILE(Trans2_mkdir);
7603 call_trans2mkdir(conn, req,
7604 &state->param, state->total_param,
7605 &state->data, state->total_data,
7606 state->max_data_return);
7607 END_PROFILE(Trans2_mkdir);
7611 case TRANSACT2_GET_DFS_REFERRAL:
7613 START_PROFILE(Trans2_get_dfs_referral);
7614 call_trans2getdfsreferral(conn, req,
7615 &state->param, state->total_param,
7616 &state->data, state->total_data,
7617 state->max_data_return);
7618 END_PROFILE(Trans2_get_dfs_referral);
7622 case TRANSACT2_IOCTL:
7624 START_PROFILE(Trans2_ioctl);
7625 call_trans2ioctl(conn, req,
7626 &state->param, state->total_param,
7627 &state->data, state->total_data,
7628 state->max_data_return);
7629 END_PROFILE(Trans2_ioctl);
7634 /* Error in request */
7635 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
7636 reply_doserror(req, ERRSRV,ERRerror);
7640 /****************************************************************************
7641 Reply to a SMBtrans2.
7642 ****************************************************************************/
7644 void reply_trans2(struct smb_request *req)
7646 connection_struct *conn = req->conn;
7651 unsigned int tran_call;
7652 struct trans_state *state;
7655 START_PROFILE(SMBtrans2);
7657 if (req->wct < 14) {
7658 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7659 END_PROFILE(SMBtrans2);
7663 dsoff = SVAL(req->vwv+12, 0);
7664 dscnt = SVAL(req->vwv+11, 0);
7665 psoff = SVAL(req->vwv+10, 0);
7666 pscnt = SVAL(req->vwv+9, 0);
7667 tran_call = SVAL(req->vwv+14, 0);
7669 result = allow_new_trans(conn->pending_trans, req->mid);
7670 if (!NT_STATUS_IS_OK(result)) {
7671 DEBUG(2, ("Got invalid trans2 request: %s\n",
7672 nt_errstr(result)));
7673 reply_nterror(req, result);
7674 END_PROFILE(SMBtrans2);
7679 switch (tran_call) {
7680 /* List the allowed trans2 calls on IPC$ */
7681 case TRANSACT2_OPEN:
7682 case TRANSACT2_GET_DFS_REFERRAL:
7683 case TRANSACT2_QFILEINFO:
7684 case TRANSACT2_QFSINFO:
7685 case TRANSACT2_SETFSINFO:
7688 reply_doserror(req, ERRSRV, ERRaccess);
7689 END_PROFILE(SMBtrans2);
7694 if ((state = TALLOC_P(conn, struct trans_state)) == NULL) {
7695 DEBUG(0, ("talloc failed\n"));
7696 reply_nterror(req, NT_STATUS_NO_MEMORY);
7697 END_PROFILE(SMBtrans2);
7701 state->cmd = SMBtrans2;
7703 state->mid = req->mid;
7704 state->vuid = req->vuid;
7705 state->setup_count = SVAL(req->vwv+13, 0);
7706 state->setup = NULL;
7707 state->total_param = SVAL(req->vwv+0, 0);
7708 state->param = NULL;
7709 state->total_data = SVAL(req->vwv+1, 0);
7711 state->max_param_return = SVAL(req->vwv+2, 0);
7712 state->max_data_return = SVAL(req->vwv+3, 0);
7713 state->max_setup_return = SVAL(req->vwv+4, 0);
7714 state->close_on_completion = BITSETW(req->vwv+5, 0);
7715 state->one_way = BITSETW(req->vwv+5, 1);
7717 state->call = tran_call;
7719 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
7720 is so as a sanity check */
7721 if (state->setup_count != 1) {
7723 * Need to have rc=0 for ioctl to get job id for OS/2.
7724 * Network printing will fail if function is not successful.
7725 * Similar function in reply.c will be used if protocol
7726 * is LANMAN1.0 instead of LM1.2X002.
7727 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
7728 * outbuf doesn't have to be set(only job id is used).
7730 if ( (state->setup_count == 4)
7731 && (tran_call == TRANSACT2_IOCTL)
7732 && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
7733 && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
7734 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
7736 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
7737 DEBUG(2,("Transaction is %d\n",tran_call));
7739 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7740 END_PROFILE(SMBtrans2);
7745 if ((dscnt > state->total_data) || (pscnt > state->total_param))
7748 if (state->total_data) {
7750 if (trans_oob(state->total_data, 0, dscnt)
7751 || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
7755 /* Can't use talloc here, the core routines do realloc on the
7756 * params and data. */
7757 state->data = (char *)SMB_MALLOC(state->total_data);
7758 if (state->data == NULL) {
7759 DEBUG(0,("reply_trans2: data malloc fail for %u "
7760 "bytes !\n", (unsigned int)state->total_data));
7762 reply_nterror(req, NT_STATUS_NO_MEMORY);
7763 END_PROFILE(SMBtrans2);
7767 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
7770 if (state->total_param) {
7772 if (trans_oob(state->total_param, 0, pscnt)
7773 || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
7777 /* Can't use talloc here, the core routines do realloc on the
7778 * params and data. */
7779 state->param = (char *)SMB_MALLOC(state->total_param);
7780 if (state->param == NULL) {
7781 DEBUG(0,("reply_trans: param malloc fail for %u "
7782 "bytes !\n", (unsigned int)state->total_param));
7783 SAFE_FREE(state->data);
7785 reply_nterror(req, NT_STATUS_NO_MEMORY);
7786 END_PROFILE(SMBtrans2);
7790 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
7793 state->received_data = dscnt;
7794 state->received_param = pscnt;
7796 if ((state->received_param == state->total_param) &&
7797 (state->received_data == state->total_data)) {
7799 handle_trans2(conn, req, state);
7801 SAFE_FREE(state->data);
7802 SAFE_FREE(state->param);
7804 END_PROFILE(SMBtrans2);
7808 DLIST_ADD(conn->pending_trans, state);
7810 /* We need to send an interim response then receive the rest
7811 of the parameter/data bytes */
7812 reply_outbuf(req, 0, 0);
7813 show_msg((char *)req->outbuf);
7814 END_PROFILE(SMBtrans2);
7819 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
7820 SAFE_FREE(state->data);
7821 SAFE_FREE(state->param);
7823 END_PROFILE(SMBtrans2);
7824 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7828 /****************************************************************************
7829 Reply to a SMBtranss2
7830 ****************************************************************************/
7832 void reply_transs2(struct smb_request *req)
7834 connection_struct *conn = req->conn;
7835 unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
7836 struct trans_state *state;
7838 START_PROFILE(SMBtranss2);
7840 show_msg((char *)req->inbuf);
7843 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7844 END_PROFILE(SMBtranss2);
7848 for (state = conn->pending_trans; state != NULL;
7849 state = state->next) {
7850 if (state->mid == req->mid) {
7855 if ((state == NULL) || (state->cmd != SMBtrans2)) {
7856 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7857 END_PROFILE(SMBtranss2);
7861 /* Revise state->total_param and state->total_data in case they have
7862 changed downwards */
7864 if (SVAL(req->vwv+0, 0) < state->total_param)
7865 state->total_param = SVAL(req->vwv+0, 0);
7866 if (SVAL(req->vwv+1, 0) < state->total_data)
7867 state->total_data = SVAL(req->vwv+1, 0);
7869 pcnt = SVAL(req->vwv+2, 0);
7870 poff = SVAL(req->vwv+3, 0);
7871 pdisp = SVAL(req->vwv+4, 0);
7873 dcnt = SVAL(req->vwv+5, 0);
7874 doff = SVAL(req->vwv+6, 0);
7875 ddisp = SVAL(req->vwv+7, 0);
7877 state->received_param += pcnt;
7878 state->received_data += dcnt;
7880 if ((state->received_data > state->total_data) ||
7881 (state->received_param > state->total_param))
7885 if (trans_oob(state->total_param, pdisp, pcnt)
7886 || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
7889 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
7893 if (trans_oob(state->total_data, ddisp, dcnt)
7894 || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
7897 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
7900 if ((state->received_param < state->total_param) ||
7901 (state->received_data < state->total_data)) {
7902 END_PROFILE(SMBtranss2);
7906 handle_trans2(conn, req, state);
7908 DLIST_REMOVE(conn->pending_trans, state);
7909 SAFE_FREE(state->data);
7910 SAFE_FREE(state->param);
7913 END_PROFILE(SMBtranss2);
7918 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
7919 DLIST_REMOVE(conn->pending_trans, state);
7920 SAFE_FREE(state->data);
7921 SAFE_FREE(state->param);
7923 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7924 END_PROFILE(SMBtranss2);