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/>.
27 #include "system/filesys.h"
29 #include "smbd/smbd.h"
30 #include "smbd/globals.h"
31 #include "../libcli/auth/libcli_auth.h"
32 #include "../librpc/gen_ndr/xattr.h"
33 #include "../librpc/gen_ndr/ndr_security.h"
34 #include "../librpc/gen_ndr/open_files.h"
35 #include "libcli/security/security.h"
38 #include "smbprofile.h"
39 #include "rpc_server/srv_pipe_hnd.h"
42 #define DIR_ENTRY_SAFETY_MARGIN 4096
44 static char *store_file_unix_basic(connection_struct
*conn
,
47 const SMB_STRUCT_STAT
*psbuf
);
49 static char *store_file_unix_basic_info2(connection_struct
*conn
,
52 const SMB_STRUCT_STAT
*psbuf
);
54 /********************************************************************
55 The canonical "check access" based on object handle or path function.
56 ********************************************************************/
58 NTSTATUS
check_access(connection_struct
*conn
,
60 const struct smb_filename
*smb_fname
,
64 if (!(fsp
->access_mask
& access_mask
)) {
65 return NT_STATUS_ACCESS_DENIED
;
68 NTSTATUS status
= smbd_check_access_rights(conn
,
72 if (!NT_STATUS_IS_OK(status
)) {
79 /********************************************************************
80 Roundup a value to the nearest allocation roundup size boundary.
81 Only do this for Windows clients.
82 ********************************************************************/
84 uint64_t smb_roundup(connection_struct
*conn
, uint64_t val
)
86 uint64_t rval
= lp_allocation_roundup_size(SNUM(conn
));
88 /* Only roundup for Windows clients. */
89 enum remote_arch_types ra_type
= get_remote_arch();
90 if (rval
&& (ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
91 val
= SMB_ROUNDUP(val
,rval
);
96 /********************************************************************
97 Create a 64 bit FileIndex. If the file is on the same device as
98 the root of the share, just return the 64-bit inode. If it isn't,
99 mangle as we used to do.
100 ********************************************************************/
102 uint64_t get_FileIndex(connection_struct
*conn
, const SMB_STRUCT_STAT
*psbuf
)
105 if (conn
->base_share_dev
== psbuf
->st_ex_dev
) {
106 return (uint64_t)psbuf
->st_ex_ino
;
108 file_index
= ((psbuf
->st_ex_ino
) & UINT32_MAX
); /* FileIndexLow */
109 file_index
|= ((uint64_t)((psbuf
->st_ex_dev
) & UINT32_MAX
)) << 32; /* FileIndexHigh */
113 /****************************************************************************
114 Utility functions for dealing with extended attributes.
115 ****************************************************************************/
117 /****************************************************************************
118 Refuse to allow clients to overwrite our private xattrs.
119 ****************************************************************************/
121 static bool samba_private_attr_name(const char *unix_ea_name
)
123 static const char * const prohibited_ea_names
[] = {
124 SAMBA_POSIX_INHERITANCE_EA_NAME
,
125 SAMBA_XATTR_DOS_ATTRIB
,
133 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
134 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
137 if (strncasecmp_m(unix_ea_name
, SAMBA_XATTR_DOSSTREAM_PREFIX
,
138 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX
)) == 0) {
144 /****************************************************************************
145 Get one EA value. Fill in a struct ea_struct.
146 ****************************************************************************/
148 NTSTATUS
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
149 files_struct
*fsp
, const char *fname
,
150 const char *ea_name
, struct ea_struct
*pea
)
152 /* Get the value of this xattr. Max size is 64k. */
153 size_t attr_size
= 256;
159 val
= talloc_realloc(mem_ctx
, val
, char, attr_size
);
161 return NT_STATUS_NO_MEMORY
;
164 if (fsp
&& fsp
->fh
->fd
!= -1) {
165 sizeret
= SMB_VFS_FGETXATTR(fsp
, ea_name
, val
, attr_size
);
167 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
170 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
176 return map_nt_error_from_unix(errno
);
179 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name
, (unsigned int)sizeret
));
180 dump_data(10, (uint8
*)val
, sizeret
);
183 if (strnequal(ea_name
, "user.", 5)) {
184 pea
->name
= talloc_strdup(mem_ctx
, &ea_name
[5]);
186 pea
->name
= talloc_strdup(mem_ctx
, ea_name
);
188 if (pea
->name
== NULL
) {
190 return NT_STATUS_NO_MEMORY
;
192 pea
->value
.data
= (unsigned char *)val
;
193 pea
->value
.length
= (size_t)sizeret
;
197 NTSTATUS
get_ea_names_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
198 files_struct
*fsp
, const char *fname
,
199 char ***pnames
, size_t *pnum_names
)
201 /* Get a list of all xattrs. Max namesize is 64k. */
202 size_t ea_namelist_size
= 1024;
203 char *ea_namelist
= NULL
;
208 ssize_t sizeret
= -1;
210 if (!lp_ea_support(SNUM(conn
))) {
219 * TALLOC the result early to get the talloc hierarchy right.
222 names
= talloc_array(mem_ctx
, char *, 1);
224 DEBUG(0, ("talloc failed\n"));
225 return NT_STATUS_NO_MEMORY
;
228 while (ea_namelist_size
<= 65536) {
230 ea_namelist
= talloc_realloc(
231 names
, ea_namelist
, char, ea_namelist_size
);
232 if (ea_namelist
== NULL
) {
233 DEBUG(0, ("talloc failed\n"));
235 return NT_STATUS_NO_MEMORY
;
238 if (fsp
&& fsp
->fh
->fd
!= -1) {
239 sizeret
= SMB_VFS_FLISTXATTR(fsp
, ea_namelist
,
242 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
,
246 if ((sizeret
== -1) && (errno
== ERANGE
)) {
247 ea_namelist_size
*= 2;
256 return map_nt_error_from_unix(errno
);
259 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
260 (unsigned int)sizeret
));
272 * Ensure the result is 0-terminated
275 if (ea_namelist
[sizeret
-1] != '\0') {
277 return NT_STATUS_INTERNAL_ERROR
;
285 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
289 tmp
= talloc_realloc(mem_ctx
, names
, char *, num_names
);
291 DEBUG(0, ("talloc failed\n"));
293 return NT_STATUS_NO_MEMORY
;
299 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
300 names
[num_names
++] = p
;
308 *pnum_names
= num_names
;
312 /****************************************************************************
313 Return a linked list of the total EA's. Plus the total size
314 ****************************************************************************/
316 static NTSTATUS
get_ea_list_from_file_path(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
317 const char *fname
, size_t *pea_total_len
, struct ea_list
**ea_list
)
319 /* Get a list of all xattrs. Max namesize is 64k. */
322 struct ea_list
*ea_list_head
= NULL
;
328 status
= get_ea_names_from_file(talloc_tos(), conn
, fsp
, fname
,
331 if (!NT_STATUS_IS_OK(status
)) {
335 if (num_names
== 0) {
340 for (i
=0; i
<num_names
; i
++) {
341 struct ea_list
*listp
;
344 if (strnequal(names
[i
], "system.", 7)
345 || samba_private_attr_name(names
[i
]))
348 listp
= talloc(mem_ctx
, struct ea_list
);
350 return NT_STATUS_NO_MEMORY
;
353 status
= get_ea_value(mem_ctx
, conn
, fsp
,
357 if (!NT_STATUS_IS_OK(status
)) {
361 if (listp
->ea
.value
.length
== 0) {
363 * We can never return a zero length EA.
364 * Windows reports the EA's as corrupted.
370 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
373 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
375 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
376 "= %u\n", (unsigned int)*pea_total_len
, dos_ea_name
,
377 (unsigned int)listp
->ea
.value
.length
));
379 DLIST_ADD_END(ea_list_head
, listp
, struct ea_list
*);
383 /* Add on 4 for total length. */
384 if (*pea_total_len
) {
388 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
389 (unsigned int)*pea_total_len
));
391 *ea_list
= ea_list_head
;
395 static NTSTATUS
get_ea_list_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
396 const struct smb_filename
*smb_fname
, size_t *pea_total_len
, struct ea_list
**ea_list
)
401 if (!lp_ea_support(SNUM(conn
))) {
405 if (is_ntfs_stream_smb_fname(smb_fname
)) {
406 return NT_STATUS_INVALID_PARAMETER
;
409 return get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, smb_fname
->base_name
, pea_total_len
, ea_list
);
412 /****************************************************************************
413 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
415 ****************************************************************************/
417 static unsigned int fill_ea_buffer(TALLOC_CTX
*mem_ctx
, char *pdata
, unsigned int total_data_size
,
418 connection_struct
*conn
, struct ea_list
*ea_list
)
420 unsigned int ret_data_size
= 4;
423 SMB_ASSERT(total_data_size
>= 4);
425 if (!lp_ea_support(SNUM(conn
))) {
430 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
433 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
434 dos_namelen
= strlen(dos_ea_name
);
435 if (dos_namelen
> 255 || dos_namelen
== 0) {
438 if (ea_list
->ea
.value
.length
> 65535) {
441 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
445 /* We know we have room. */
446 SCVAL(p
,0,ea_list
->ea
.flags
);
447 SCVAL(p
,1,dos_namelen
);
448 SSVAL(p
,2,ea_list
->ea
.value
.length
);
449 strlcpy(p
+4, dos_ea_name
, dos_namelen
+1);
450 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
452 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
453 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
456 ret_data_size
= PTR_DIFF(p
, pdata
);
457 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size
));
458 SIVAL(pdata
,0,ret_data_size
);
459 return ret_data_size
;
462 static NTSTATUS
fill_ea_chained_buffer(TALLOC_CTX
*mem_ctx
,
464 unsigned int total_data_size
,
465 unsigned int *ret_data_size
,
466 connection_struct
*conn
,
467 struct ea_list
*ea_list
)
469 uint8_t *p
= (uint8_t *)pdata
;
470 uint8_t *last_start
= NULL
;
471 bool do_store_data
= (pdata
!= NULL
);
475 if (!lp_ea_support(SNUM(conn
))) {
476 return NT_STATUS_NO_EAS_ON_FILE
;
479 for (; ea_list
; ea_list
= ea_list
->next
) {
485 if (last_start
!= NULL
&& do_store_data
) {
486 SIVAL(last_start
, 0, PTR_DIFF(p
, last_start
));
490 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
491 dos_namelen
= strlen(dos_ea_name
);
492 if (dos_namelen
> 255 || dos_namelen
== 0) {
493 return NT_STATUS_INTERNAL_ERROR
;
495 if (ea_list
->ea
.value
.length
> 65535) {
496 return NT_STATUS_INTERNAL_ERROR
;
499 this_size
= 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
502 pad
= 4 - (this_size
% 4);
507 if (this_size
> total_data_size
) {
508 return NT_STATUS_INFO_LENGTH_MISMATCH
;
511 /* We know we have room. */
512 SIVAL(p
, 0x00, 0); /* next offset */
513 SCVAL(p
, 0x04, ea_list
->ea
.flags
);
514 SCVAL(p
, 0x05, dos_namelen
);
515 SSVAL(p
, 0x06, ea_list
->ea
.value
.length
);
516 strlcpy((char *)(p
+0x08), dos_ea_name
, dos_namelen
+1);
517 memcpy(p
+ 0x08 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
519 memset(p
+ 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
,
523 total_data_size
-= this_size
;
529 *ret_data_size
= PTR_DIFF(p
, pdata
);
530 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size
));
534 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const struct smb_filename
*smb_fname
)
536 size_t total_ea_len
= 0;
538 struct ea_list
*ea_list
= NULL
;
540 if (!lp_ea_support(SNUM(conn
))) {
543 mem_ctx
= talloc_stackframe();
545 /* If this is a stream fsp, then we need to instead find the
546 * estimated ea len from the main file, not the stream
547 * (streams cannot have EAs), but the estimate isn't just 0 in
549 if (is_ntfs_stream_smb_fname(smb_fname
)) {
552 (void)get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, smb_fname
->base_name
, &total_ea_len
, &ea_list
);
553 if(conn
->sconn
->using_smb2
) {
555 unsigned int ret_data_size
;
557 * We're going to be using fill_ea_chained_buffer() to
558 * marshall EA's - this size is significantly larger
559 * than the SMB1 buffer. Re-calculate the size without
562 status
= fill_ea_chained_buffer(mem_ctx
,
568 if (!NT_STATUS_IS_OK(status
)) {
571 total_ea_len
= ret_data_size
;
573 TALLOC_FREE(mem_ctx
);
577 /****************************************************************************
578 Ensure the EA name is case insensitive by matching any existing EA name.
579 ****************************************************************************/
581 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
584 TALLOC_CTX
*mem_ctx
= talloc_tos();
585 struct ea_list
*ea_list
;
586 NTSTATUS status
= get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
, &ea_list
);
587 if (!NT_STATUS_IS_OK(status
)) {
591 for (; ea_list
; ea_list
= ea_list
->next
) {
592 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
593 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
594 &unix_ea_name
[5], ea_list
->ea
.name
));
595 strlcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-5);
601 /****************************************************************************
602 Set or delete an extended attribute.
603 ****************************************************************************/
605 NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
,
606 const struct smb_filename
*smb_fname
, struct ea_list
*ea_list
)
611 if (!lp_ea_support(SNUM(conn
))) {
612 return NT_STATUS_EAS_NOT_SUPPORTED
;
615 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_EA
);
616 if (!NT_STATUS_IS_OK(status
)) {
620 /* Setting EAs on streams isn't supported. */
621 if (is_ntfs_stream_smb_fname(smb_fname
)) {
622 return NT_STATUS_INVALID_PARAMETER
;
625 fname
= smb_fname
->base_name
;
627 for (;ea_list
; ea_list
= ea_list
->next
) {
629 fstring unix_ea_name
;
631 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
632 fstrcat(unix_ea_name
, ea_list
->ea
.name
);
634 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
636 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, (unsigned int)ea_list
->ea
.value
.length
));
638 if (samba_private_attr_name(unix_ea_name
)) {
639 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
640 return NT_STATUS_ACCESS_DENIED
;
643 if (ea_list
->ea
.value
.length
== 0) {
644 /* Remove the attribute. */
645 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
646 DEBUG(10,("set_ea: deleting ea name %s on "
647 "file %s by file descriptor.\n",
648 unix_ea_name
, fsp_str_dbg(fsp
)));
649 ret
= SMB_VFS_FREMOVEXATTR(fsp
, unix_ea_name
);
651 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
652 unix_ea_name
, fname
));
653 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
656 /* Removing a non existent attribute always succeeds. */
657 if (ret
== -1 && errno
== ENOATTR
) {
658 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
664 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
665 DEBUG(10,("set_ea: setting ea name %s on file "
666 "%s by file descriptor.\n",
667 unix_ea_name
, fsp_str_dbg(fsp
)));
668 ret
= SMB_VFS_FSETXATTR(fsp
, unix_ea_name
,
669 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
671 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
672 unix_ea_name
, fname
));
673 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
,
674 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
680 if (errno
== ENOTSUP
) {
681 return NT_STATUS_EAS_NOT_SUPPORTED
;
684 return map_nt_error_from_unix(errno
);
690 /****************************************************************************
691 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
692 ****************************************************************************/
694 static struct ea_list
*read_ea_name_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
696 struct ea_list
*ea_list_head
= NULL
;
697 size_t converted_size
, offset
= 0;
699 while (offset
+ 2 < data_size
) {
700 struct ea_list
*eal
= talloc_zero(ctx
, struct ea_list
);
701 unsigned int namelen
= CVAL(pdata
,offset
);
703 offset
++; /* Go past the namelen byte. */
705 /* integer wrap paranioa. */
706 if ((offset
+ namelen
< offset
) || (offset
+ namelen
< namelen
) ||
707 (offset
> data_size
) || (namelen
> data_size
) ||
708 (offset
+ namelen
>= data_size
)) {
711 /* Ensure the name is null terminated. */
712 if (pdata
[offset
+ namelen
] != '\0') {
715 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, &pdata
[offset
],
717 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
718 "failed: %s", strerror(errno
)));
724 offset
+= (namelen
+ 1); /* Go past the name + terminating zero. */
725 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
726 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal
->ea
.name
));
732 /****************************************************************************
733 Read one EA list entry from the buffer.
734 ****************************************************************************/
736 struct ea_list
*read_ea_list_entry(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
, size_t *pbytes_used
)
738 struct ea_list
*eal
= talloc_zero(ctx
, struct ea_list
);
740 unsigned int namelen
;
741 size_t converted_size
;
751 eal
->ea
.flags
= CVAL(pdata
,0);
752 namelen
= CVAL(pdata
,1);
753 val_len
= SVAL(pdata
,2);
755 if (4 + namelen
+ 1 + val_len
> data_size
) {
759 /* Ensure the name is null terminated. */
760 if (pdata
[namelen
+ 4] != '\0') {
763 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, pdata
+ 4, &converted_size
)) {
764 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
771 eal
->ea
.value
= data_blob_talloc(eal
, NULL
, (size_t)val_len
+ 1);
772 if (!eal
->ea
.value
.data
) {
776 memcpy(eal
->ea
.value
.data
, pdata
+ 4 + namelen
+ 1, val_len
);
778 /* Ensure we're null terminated just in case we print the value. */
779 eal
->ea
.value
.data
[val_len
] = '\0';
780 /* But don't count the null. */
781 eal
->ea
.value
.length
--;
784 *pbytes_used
= 4 + namelen
+ 1 + val_len
;
787 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal
->ea
.name
));
788 dump_data(10, eal
->ea
.value
.data
, eal
->ea
.value
.length
);
793 /****************************************************************************
794 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
795 ****************************************************************************/
797 static struct ea_list
*read_ea_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
799 struct ea_list
*ea_list_head
= NULL
;
801 size_t bytes_used
= 0;
803 while (offset
< data_size
) {
804 struct ea_list
*eal
= read_ea_list_entry(ctx
, pdata
+ offset
, data_size
- offset
, &bytes_used
);
810 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
811 offset
+= bytes_used
;
817 /****************************************************************************
818 Count the total EA size needed.
819 ****************************************************************************/
821 static size_t ea_list_size(struct ea_list
*ealist
)
824 struct ea_list
*listp
;
827 for (listp
= ealist
; listp
; listp
= listp
->next
) {
828 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
829 ret
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
831 /* Add on 4 for total length. */
839 /****************************************************************************
840 Return a union of EA's from a file list and a list of names.
841 The TALLOC context for the two lists *MUST* be identical as we steal
842 memory from one list to add to another. JRA.
843 ****************************************************************************/
845 static struct ea_list
*ea_list_union(struct ea_list
*name_list
, struct ea_list
*file_list
, size_t *total_ea_len
)
847 struct ea_list
*nlistp
, *flistp
;
849 for (nlistp
= name_list
; nlistp
; nlistp
= nlistp
->next
) {
850 for (flistp
= file_list
; flistp
; flistp
= flistp
->next
) {
851 if (strequal(nlistp
->ea
.name
, flistp
->ea
.name
)) {
857 /* Copy the data from this entry. */
858 nlistp
->ea
.flags
= flistp
->ea
.flags
;
859 nlistp
->ea
.value
= flistp
->ea
.value
;
862 nlistp
->ea
.flags
= 0;
863 ZERO_STRUCT(nlistp
->ea
.value
);
867 *total_ea_len
= ea_list_size(name_list
);
871 /****************************************************************************
872 Send the required number of replies back.
873 We assume all fields other than the data fields are
874 set correctly for the type of call.
875 HACK ! Always assumes smb_setup field is zero.
876 ****************************************************************************/
878 void send_trans2_replies(connection_struct
*conn
,
879 struct smb_request
*req
,
886 /* As we are using a protocol > LANMAN1 then the max_send
887 variable must have been set in the sessetupX call.
888 This takes precedence over the max_xmit field in the
889 global struct. These different max_xmit variables should
890 be merged as this is now too confusing */
892 int data_to_send
= datasize
;
893 int params_to_send
= paramsize
;
895 const char *pp
= params
;
896 const char *pd
= pdata
;
897 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
898 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
899 int data_alignment_offset
= 0;
900 bool overflow
= False
;
901 struct smbd_server_connection
*sconn
= req
->sconn
;
902 int max_send
= sconn
->smb1
.sessions
.max_send
;
904 /* Modify the data_to_send and datasize and set the error if
905 we're trying to send more than max_data_bytes. We still send
906 the part of the packet(s) that fit. Strange, but needed
909 if (max_data_bytes
> 0 && datasize
> max_data_bytes
) {
910 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
911 max_data_bytes
, datasize
));
912 datasize
= data_to_send
= max_data_bytes
;
916 /* If there genuinely are no parameters or data to send just send the empty packet */
918 if(params_to_send
== 0 && data_to_send
== 0) {
919 reply_outbuf(req
, 10, 0);
920 show_msg((char *)req
->outbuf
);
921 if (!srv_send_smb(sconn
,
924 IS_CONN_ENCRYPTED(conn
),
926 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
928 TALLOC_FREE(req
->outbuf
);
932 /* When sending params and data ensure that both are nicely aligned */
933 /* Only do this alignment when there is also data to send - else
934 can cause NT redirector problems. */
936 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
937 data_alignment_offset
= 4 - (params_to_send
% 4);
939 /* Space is bufsize minus Netbios over TCP header minus SMB header */
940 /* The alignment_offset is to align the param bytes on an even byte
941 boundary. NT 4.0 Beta needs this to work correctly. */
943 useable_space
= max_send
- (smb_size
946 + data_alignment_offset
);
948 if (useable_space
< 0) {
949 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
950 "= %d!!!", useable_space
));
951 exit_server_cleanly("send_trans2_replies: Not enough space");
954 while (params_to_send
|| data_to_send
) {
955 /* Calculate whether we will totally or partially fill this packet */
957 total_sent_thistime
= params_to_send
+ data_to_send
;
959 /* We can never send more than useable_space */
961 * Note that 'useable_space' does not include the alignment offsets,
962 * but we must include the alignment offsets in the calculation of
963 * the length of the data we send over the wire, as the alignment offsets
964 * are sent here. Fix from Marc_Jacobsen@hp.com.
967 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
);
969 reply_outbuf(req
, 10, total_sent_thistime
+ alignment_offset
970 + data_alignment_offset
);
972 /* Set total params and data to be sent */
973 SSVAL(req
->outbuf
,smb_tprcnt
,paramsize
);
974 SSVAL(req
->outbuf
,smb_tdrcnt
,datasize
);
976 /* Calculate how many parameters and data we can fit into
977 * this packet. Parameters get precedence
980 params_sent_thistime
= MIN(params_to_send
,useable_space
);
981 data_sent_thistime
= useable_space
- params_sent_thistime
;
982 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
984 SSVAL(req
->outbuf
,smb_prcnt
, params_sent_thistime
);
986 /* smb_proff is the offset from the start of the SMB header to the
987 parameter bytes, however the first 4 bytes of outbuf are
988 the Netbios over TCP header. Thus use smb_base() to subtract
989 them from the calculation */
991 SSVAL(req
->outbuf
,smb_proff
,
992 ((smb_buf(req
->outbuf
)+alignment_offset
)
993 - smb_base(req
->outbuf
)));
995 if(params_sent_thistime
== 0)
996 SSVAL(req
->outbuf
,smb_prdisp
,0);
998 /* Absolute displacement of param bytes sent in this packet */
999 SSVAL(req
->outbuf
,smb_prdisp
,pp
- params
);
1001 SSVAL(req
->outbuf
,smb_drcnt
, data_sent_thistime
);
1002 if(data_sent_thistime
== 0) {
1003 SSVAL(req
->outbuf
,smb_droff
,0);
1004 SSVAL(req
->outbuf
,smb_drdisp
, 0);
1006 /* The offset of the data bytes is the offset of the
1007 parameter bytes plus the number of parameters being sent this time */
1008 SSVAL(req
->outbuf
, smb_droff
,
1009 ((smb_buf(req
->outbuf
)+alignment_offset
)
1010 - smb_base(req
->outbuf
))
1011 + params_sent_thistime
+ data_alignment_offset
);
1012 SSVAL(req
->outbuf
,smb_drdisp
, pd
- pdata
);
1015 /* Initialize the padding for alignment */
1017 if (alignment_offset
!= 0) {
1018 memset(smb_buf(req
->outbuf
), 0, alignment_offset
);
1021 /* Copy the param bytes into the packet */
1023 if(params_sent_thistime
) {
1024 memcpy((smb_buf(req
->outbuf
)+alignment_offset
), pp
,
1025 params_sent_thistime
);
1028 /* Copy in the data bytes */
1029 if(data_sent_thistime
) {
1030 if (data_alignment_offset
!= 0) {
1031 memset((smb_buf(req
->outbuf
)+alignment_offset
+
1032 params_sent_thistime
), 0,
1033 data_alignment_offset
);
1035 memcpy(smb_buf(req
->outbuf
)+alignment_offset
1036 +params_sent_thistime
+data_alignment_offset
,
1037 pd
,data_sent_thistime
);
1040 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
1041 params_sent_thistime
, data_sent_thistime
, useable_space
));
1042 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
1043 params_to_send
, data_to_send
, paramsize
, datasize
));
1046 error_packet_set((char *)req
->outbuf
,
1047 ERRDOS
,ERRbufferoverflow
,
1048 STATUS_BUFFER_OVERFLOW
,
1052 /* Send the packet */
1053 show_msg((char *)req
->outbuf
);
1054 if (!srv_send_smb(sconn
,
1055 (char *)req
->outbuf
,
1056 true, req
->seqnum
+1,
1057 IS_CONN_ENCRYPTED(conn
),
1059 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
1061 TALLOC_FREE(req
->outbuf
);
1063 pp
+= params_sent_thistime
;
1064 pd
+= data_sent_thistime
;
1066 params_to_send
-= params_sent_thistime
;
1067 data_to_send
-= data_sent_thistime
;
1070 if(params_to_send
< 0 || data_to_send
< 0) {
1071 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
1072 params_to_send
, data_to_send
));
1080 /****************************************************************************
1081 Reply to a TRANSACT2_OPEN.
1082 ****************************************************************************/
1084 static void call_trans2open(connection_struct
*conn
,
1085 struct smb_request
*req
,
1086 char **pparams
, int total_params
,
1087 char **ppdata
, int total_data
,
1088 unsigned int max_data_bytes
)
1090 struct smb_filename
*smb_fname
= NULL
;
1091 char *params
= *pparams
;
1092 char *pdata
= *ppdata
;
1095 bool oplock_request
;
1097 bool return_additional_info
;
1106 int fattr
=0,mtime
=0;
1107 SMB_INO_T inode
= 0;
1110 struct ea_list
*ea_list
= NULL
;
1115 uint32 create_disposition
;
1116 uint32 create_options
= 0;
1117 uint32_t private_flags
= 0;
1118 TALLOC_CTX
*ctx
= talloc_tos();
1121 * Ensure we have enough parameters to perform the operation.
1124 if (total_params
< 29) {
1125 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1129 flags
= SVAL(params
, 0);
1130 deny_mode
= SVAL(params
, 2);
1131 open_attr
= SVAL(params
,6);
1132 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
1133 if (oplock_request
) {
1134 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
1138 return_additional_info
= BITSETW(params
,0);
1139 open_sattr
= SVAL(params
, 4);
1140 open_time
= make_unix_date3(params
+8);
1142 open_ofun
= SVAL(params
,12);
1143 open_size
= IVAL(params
,14);
1144 pname
= ¶ms
[28];
1147 reply_nterror(req
, NT_STATUS_NETWORK_ACCESS_DENIED
);
1151 srvstr_get_path(ctx
, params
, req
->flags2
, &fname
, pname
,
1152 total_params
- 28, STR_TERMINATE
,
1154 if (!NT_STATUS_IS_OK(status
)) {
1155 reply_nterror(req
, status
);
1159 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1160 fname
, (unsigned int)deny_mode
, (unsigned int)open_attr
,
1161 (unsigned int)open_ofun
, open_size
));
1163 status
= filename_convert(ctx
,
1165 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1170 if (!NT_STATUS_IS_OK(status
)) {
1171 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1172 reply_botherror(req
,
1173 NT_STATUS_PATH_NOT_COVERED
,
1174 ERRSRV
, ERRbadpath
);
1177 reply_nterror(req
, status
);
1181 if (open_ofun
== 0) {
1182 reply_nterror(req
, NT_STATUS_OBJECT_NAME_COLLISION
);
1186 if (!map_open_params_to_ntcreate(smb_fname
->base_name
, deny_mode
,
1188 &access_mask
, &share_mode
,
1189 &create_disposition
,
1192 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1196 /* Any data in this call is an EA list. */
1197 if (total_data
&& (total_data
!= 4)) {
1198 if (total_data
< 10) {
1199 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1203 if (IVAL(pdata
,0) > total_data
) {
1204 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1205 IVAL(pdata
,0), (unsigned int)total_data
));
1206 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1210 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
1213 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1217 if (!lp_ea_support(SNUM(conn
))) {
1218 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
1223 status
= SMB_VFS_CREATE_FILE(
1226 0, /* root_dir_fid */
1227 smb_fname
, /* fname */
1228 access_mask
, /* access_mask */
1229 share_mode
, /* share_access */
1230 create_disposition
, /* create_disposition*/
1231 create_options
, /* create_options */
1232 open_attr
, /* file_attributes */
1233 oplock_request
, /* oplock_request */
1234 open_size
, /* allocation_size */
1237 ea_list
, /* ea_list */
1239 &smb_action
); /* psbuf */
1241 if (!NT_STATUS_IS_OK(status
)) {
1242 if (open_was_deferred(req
->sconn
, req
->mid
)) {
1243 /* We have re-scheduled this call. */
1246 reply_openerror(req
, status
);
1250 size
= get_file_size_stat(&smb_fname
->st
);
1251 fattr
= dos_mode(conn
, smb_fname
);
1252 mtime
= convert_timespec_to_time_t(smb_fname
->st
.st_ex_mtime
);
1253 inode
= smb_fname
->st
.st_ex_ino
;
1254 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
1255 close_file(req
, fsp
, ERROR_CLOSE
);
1256 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1260 /* Realloc the size of parameters and data we will return */
1261 *pparams
= (char *)SMB_REALLOC(*pparams
, 30);
1262 if(*pparams
== NULL
) {
1263 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1268 SSVAL(params
,0,fsp
->fnum
);
1269 SSVAL(params
,2,fattr
);
1270 srv_put_dos_date2(params
,4, mtime
);
1271 SIVAL(params
,8, (uint32
)size
);
1272 SSVAL(params
,12,deny_mode
);
1273 SSVAL(params
,14,0); /* open_type - file or directory. */
1274 SSVAL(params
,16,0); /* open_state - only valid for IPC device. */
1276 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1277 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1280 SSVAL(params
,18,smb_action
);
1283 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1285 SIVAL(params
,20,inode
);
1286 SSVAL(params
,24,0); /* Padding. */
1288 uint32 ea_size
= estimate_ea_size(conn
, fsp
,
1290 SIVAL(params
, 26, ea_size
);
1292 SIVAL(params
, 26, 0);
1295 /* Send the required number of replies */
1296 send_trans2_replies(conn
, req
, params
, 30, *ppdata
, 0, max_data_bytes
);
1298 TALLOC_FREE(smb_fname
);
1301 /*********************************************************
1302 Routine to check if a given string matches exactly.
1303 as a special case a mask of "." does NOT match. That
1304 is required for correct wildcard semantics
1305 Case can be significant or not.
1306 **********************************************************/
1308 static bool exact_match(bool has_wild
,
1309 bool case_sensitive
,
1313 if (mask
[0] == '.' && mask
[1] == 0) {
1321 if (case_sensitive
) {
1322 return strcmp(str
,mask
)==0;
1324 return strcasecmp_m(str
,mask
) == 0;
1328 /****************************************************************************
1329 Return the filetype for UNIX extensions.
1330 ****************************************************************************/
1332 static uint32
unix_filetype(mode_t mode
)
1335 return UNIX_TYPE_FILE
;
1336 else if(S_ISDIR(mode
))
1337 return UNIX_TYPE_DIR
;
1339 else if(S_ISLNK(mode
))
1340 return UNIX_TYPE_SYMLINK
;
1343 else if(S_ISCHR(mode
))
1344 return UNIX_TYPE_CHARDEV
;
1347 else if(S_ISBLK(mode
))
1348 return UNIX_TYPE_BLKDEV
;
1351 else if(S_ISFIFO(mode
))
1352 return UNIX_TYPE_FIFO
;
1355 else if(S_ISSOCK(mode
))
1356 return UNIX_TYPE_SOCKET
;
1359 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode
));
1360 return UNIX_TYPE_UNKNOWN
;
1363 /****************************************************************************
1364 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1365 ****************************************************************************/
1367 enum perm_type
{ PERM_NEW_FILE
, PERM_NEW_DIR
, PERM_EXISTING_FILE
, PERM_EXISTING_DIR
};
1369 static NTSTATUS
unix_perms_from_wire( connection_struct
*conn
,
1370 const SMB_STRUCT_STAT
*psbuf
,
1372 enum perm_type ptype
,
1377 if (perms
== SMB_MODE_NO_CHANGE
) {
1378 if (!VALID_STAT(*psbuf
)) {
1379 return NT_STATUS_INVALID_PARAMETER
;
1381 *ret_perms
= psbuf
->st_ex_mode
;
1382 return NT_STATUS_OK
;
1386 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
1387 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
1388 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
1389 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
1390 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
1391 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
1392 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
1393 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
1394 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
1396 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
1399 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
1402 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
1407 case PERM_EXISTING_FILE
:
1408 /* Apply mode mask */
1409 ret
&= lp_create_mask(SNUM(conn
));
1410 /* Add in force bits */
1411 ret
|= lp_force_create_mode(SNUM(conn
));
1414 case PERM_EXISTING_DIR
:
1415 ret
&= lp_dir_mask(SNUM(conn
));
1416 /* Add in force bits */
1417 ret
|= lp_force_dir_mode(SNUM(conn
));
1422 return NT_STATUS_OK
;
1425 /****************************************************************************
1426 Needed to show the msdfs symlinks as directories. Modifies psbuf
1427 to be a directory if it's a msdfs link.
1428 ****************************************************************************/
1430 static bool check_msdfs_link(connection_struct
*conn
,
1431 const char *pathname
,
1432 SMB_STRUCT_STAT
*psbuf
)
1434 int saved_errno
= errno
;
1435 if(lp_host_msdfs() &&
1436 lp_msdfs_root(SNUM(conn
)) &&
1437 is_msdfs_link(conn
, pathname
, psbuf
)) {
1439 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1442 psbuf
->st_ex_mode
= (psbuf
->st_ex_mode
& 0xFFF) | S_IFDIR
;
1443 errno
= saved_errno
;
1446 errno
= saved_errno
;
1451 /****************************************************************************
1452 Get a level dependent lanman2 dir entry.
1453 ****************************************************************************/
1455 struct smbd_dirptr_lanman2_state
{
1456 connection_struct
*conn
;
1457 uint32_t info_level
;
1458 bool check_mangled_names
;
1460 bool got_exact_match
;
1463 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX
*ctx
,
1469 struct smbd_dirptr_lanman2_state
*state
=
1470 (struct smbd_dirptr_lanman2_state
*)private_data
;
1472 char mangled_name
[13]; /* mangled 8.3 name. */
1476 /* Mangle fname if it's an illegal name. */
1477 if (mangle_must_mangle(dname
, state
->conn
->params
)) {
1478 ok
= name_to_8_3(dname
, mangled_name
,
1479 true, state
->conn
->params
);
1483 fname
= mangled_name
;
1488 got_match
= exact_match(state
->has_wild
,
1489 state
->conn
->case_sensitive
,
1491 state
->got_exact_match
= got_match
;
1493 got_match
= mask_match(fname
, mask
,
1494 state
->conn
->case_sensitive
);
1497 if(!got_match
&& state
->check_mangled_names
&&
1498 !mangle_is_8_3(fname
, false, state
->conn
->params
)) {
1500 * It turns out that NT matches wildcards against
1501 * both long *and* short names. This may explain some
1502 * of the wildcard wierdness from old DOS clients
1503 * that some people have been seeing.... JRA.
1505 /* Force the mangling into 8.3. */
1506 ok
= name_to_8_3(fname
, mangled_name
,
1507 false, state
->conn
->params
);
1512 got_match
= exact_match(state
->has_wild
,
1513 state
->conn
->case_sensitive
,
1514 mangled_name
, mask
);
1515 state
->got_exact_match
= got_match
;
1517 got_match
= mask_match(mangled_name
, mask
,
1518 state
->conn
->case_sensitive
);
1526 *_fname
= talloc_strdup(ctx
, fname
);
1527 if (*_fname
== NULL
) {
1534 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX
*ctx
,
1536 struct smb_filename
*smb_fname
,
1539 struct smbd_dirptr_lanman2_state
*state
=
1540 (struct smbd_dirptr_lanman2_state
*)private_data
;
1541 bool ms_dfs_link
= false;
1544 if (INFO_LEVEL_IS_UNIX(state
->info_level
)) {
1545 if (SMB_VFS_LSTAT(state
->conn
, smb_fname
) != 0) {
1546 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1547 "Couldn't lstat [%s] (%s)\n",
1548 smb_fname_str_dbg(smb_fname
),
1552 } else if (!VALID_STAT(smb_fname
->st
) &&
1553 SMB_VFS_STAT(state
->conn
, smb_fname
) != 0) {
1554 /* Needed to show the msdfs symlinks as
1557 ms_dfs_link
= check_msdfs_link(state
->conn
,
1558 smb_fname
->base_name
,
1561 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1562 "Couldn't stat [%s] (%s)\n",
1563 smb_fname_str_dbg(smb_fname
),
1570 mode
= dos_mode_msdfs(state
->conn
, smb_fname
);
1572 mode
= dos_mode(state
->conn
, smb_fname
);
1579 static bool smbd_marshall_dir_entry(TALLOC_CTX
*ctx
,
1580 connection_struct
*conn
,
1582 uint32_t info_level
,
1583 struct ea_list
*name_list
,
1584 bool check_mangled_names
,
1585 bool requires_resume_key
,
1588 const struct smb_filename
*smb_fname
,
1589 int space_remaining
,
1596 uint64_t *last_entry_off
)
1598 char *p
, *q
, *pdata
= *ppdata
;
1600 uint64_t file_size
= 0;
1601 uint64_t allocation_size
= 0;
1602 uint64_t file_index
= 0;
1604 struct timespec mdate_ts
, adate_ts
, cdate_ts
, create_date_ts
;
1605 time_t mdate
= (time_t)0, adate
= (time_t)0, create_date
= (time_t)0;
1607 char *last_entry_ptr
;
1612 *out_of_space
= false;
1614 ZERO_STRUCT(mdate_ts
);
1615 ZERO_STRUCT(adate_ts
);
1616 ZERO_STRUCT(create_date_ts
);
1617 ZERO_STRUCT(cdate_ts
);
1619 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
1620 file_size
= get_file_size_stat(&smb_fname
->st
);
1622 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, NULL
, &smb_fname
->st
);
1624 file_index
= get_FileIndex(conn
, &smb_fname
->st
);
1626 mdate_ts
= smb_fname
->st
.st_ex_mtime
;
1627 adate_ts
= smb_fname
->st
.st_ex_atime
;
1628 create_date_ts
= get_create_timespec(conn
, NULL
, smb_fname
);
1629 cdate_ts
= get_change_timespec(conn
, NULL
, smb_fname
);
1631 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1632 dos_filetime_timespec(&create_date_ts
);
1633 dos_filetime_timespec(&mdate_ts
);
1634 dos_filetime_timespec(&adate_ts
);
1635 dos_filetime_timespec(&cdate_ts
);
1638 create_date
= convert_timespec_to_time_t(create_date_ts
);
1639 mdate
= convert_timespec_to_time_t(mdate_ts
);
1640 adate
= convert_timespec_to_time_t(adate_ts
);
1642 /* align the record */
1643 SMB_ASSERT(align
>= 1);
1645 off
= (int)PTR_DIFF(pdata
, base_data
);
1646 pad
= (off
+ (align
-1)) & ~(align
-1);
1649 if (pad
&& pad
> space_remaining
) {
1650 *out_of_space
= true;
1651 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1652 "for padding (wanted %u, had %d)\n",
1655 return false; /* Not finished - just out of space */
1659 /* initialize padding to 0 */
1661 memset(pdata
, 0, pad
);
1663 space_remaining
-= pad
;
1665 DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1675 switch (info_level
) {
1676 case SMB_FIND_INFO_STANDARD
:
1677 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1678 if(requires_resume_key
) {
1682 srv_put_dos_date2(p
,0,create_date
);
1683 srv_put_dos_date2(p
,4,adate
);
1684 srv_put_dos_date2(p
,8,mdate
);
1685 SIVAL(p
,12,(uint32
)file_size
);
1686 SIVAL(p
,16,(uint32
)allocation_size
);
1690 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1691 p
+= ucs2_align(base_data
, p
, 0);
1693 len
= srvstr_push(base_data
, flags2
, p
,
1694 fname
, PTR_DIFF(end_data
, p
),
1696 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1698 SCVAL(nameptr
, -1, len
- 2);
1700 SCVAL(nameptr
, -1, 0);
1704 SCVAL(nameptr
, -1, len
- 1);
1706 SCVAL(nameptr
, -1, 0);
1712 case SMB_FIND_EA_SIZE
:
1713 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1714 if (requires_resume_key
) {
1718 srv_put_dos_date2(p
,0,create_date
);
1719 srv_put_dos_date2(p
,4,adate
);
1720 srv_put_dos_date2(p
,8,mdate
);
1721 SIVAL(p
,12,(uint32
)file_size
);
1722 SIVAL(p
,16,(uint32
)allocation_size
);
1725 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1727 SIVAL(p
,22,ea_size
); /* Extended attributes */
1731 len
= srvstr_push(base_data
, flags2
,
1732 p
, fname
, PTR_DIFF(end_data
, p
),
1733 STR_TERMINATE
| STR_NOALIGN
);
1734 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1747 SCVAL(nameptr
,0,len
);
1749 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1752 case SMB_FIND_EA_LIST
:
1754 struct ea_list
*file_list
= NULL
;
1758 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1762 if (requires_resume_key
) {
1766 srv_put_dos_date2(p
,0,create_date
);
1767 srv_put_dos_date2(p
,4,adate
);
1768 srv_put_dos_date2(p
,8,mdate
);
1769 SIVAL(p
,12,(uint32
)file_size
);
1770 SIVAL(p
,16,(uint32
)allocation_size
);
1772 p
+= 22; /* p now points to the EA area. */
1774 status
= get_ea_list_from_file(ctx
, conn
, NULL
,
1776 &ea_len
, &file_list
);
1777 if (!NT_STATUS_IS_OK(status
)) {
1780 name_list
= ea_list_union(name_list
, file_list
, &ea_len
);
1782 /* We need to determine if this entry will fit in the space available. */
1783 /* Max string size is 255 bytes. */
1784 if (PTR_DIFF(p
+ 255 + ea_len
,pdata
) > space_remaining
) {
1785 *out_of_space
= true;
1786 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1787 "(wanted %u, had %d)\n",
1788 (unsigned int)PTR_DIFF(p
+ 255 + ea_len
,pdata
),
1790 return False
; /* Not finished - just out of space */
1793 /* Push the ea_data followed by the name. */
1794 p
+= fill_ea_buffer(ctx
, p
, space_remaining
, conn
, name_list
);
1796 len
= srvstr_push(base_data
, flags2
,
1797 p
+ 1, fname
, PTR_DIFF(end_data
, p
+1),
1798 STR_TERMINATE
| STR_NOALIGN
);
1799 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1812 SCVAL(nameptr
,0,len
);
1814 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1818 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1819 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1820 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1822 SIVAL(p
,0,reskey
); p
+= 4;
1823 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1824 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1825 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1826 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1827 SOFF_T(p
,0,file_size
); p
+= 8;
1828 SOFF_T(p
,0,allocation_size
); p
+= 8;
1829 SIVAL(p
,0,mode
); p
+= 4;
1830 q
= p
; p
+= 4; /* q is placeholder for name length. */
1832 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1834 SIVAL(p
,0,ea_size
); /* Extended attributes */
1837 /* Clear the short name buffer. This is
1838 * IMPORTANT as not doing so will trigger
1839 * a Win2k client bug. JRA.
1841 if (!was_8_3
&& check_mangled_names
) {
1842 char mangled_name
[13]; /* mangled 8.3 name. */
1843 if (!name_to_8_3(fname
,mangled_name
,True
,
1845 /* Error - mangle failed ! */
1846 memset(mangled_name
,'\0',12);
1848 mangled_name
[12] = 0;
1849 len
= srvstr_push(base_data
, flags2
,
1850 p
+2, mangled_name
, 24,
1851 STR_UPPER
|STR_UNICODE
);
1853 memset(p
+ 2 + len
,'\0',24 - len
);
1860 len
= srvstr_push(base_data
, flags2
, p
,
1861 fname
, PTR_DIFF(end_data
, p
),
1862 STR_TERMINATE_ASCII
);
1866 len
= PTR_DIFF(p
, pdata
);
1867 pad
= (len
+ (align
-1)) & ~(align
-1);
1869 * offset to the next entry, the caller
1870 * will overwrite it for the last entry
1871 * that's why we always include the padding
1875 * set padding to zero
1878 memset(p
, 0, pad
- len
);
1885 case SMB_FIND_FILE_DIRECTORY_INFO
:
1886 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1888 SIVAL(p
,0,reskey
); p
+= 4;
1889 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1890 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1891 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1892 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1893 SOFF_T(p
,0,file_size
); p
+= 8;
1894 SOFF_T(p
,0,allocation_size
); p
+= 8;
1895 SIVAL(p
,0,mode
); p
+= 4;
1896 len
= srvstr_push(base_data
, flags2
,
1897 p
+ 4, fname
, PTR_DIFF(end_data
, p
+4),
1898 STR_TERMINATE_ASCII
);
1902 len
= PTR_DIFF(p
, pdata
);
1903 pad
= (len
+ (align
-1)) & ~(align
-1);
1905 * offset to the next entry, the caller
1906 * will overwrite it for the last entry
1907 * that's why we always include the padding
1911 * set padding to zero
1914 memset(p
, 0, pad
- len
);
1921 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1922 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1924 SIVAL(p
,0,reskey
); p
+= 4;
1925 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1926 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1927 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1928 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1929 SOFF_T(p
,0,file_size
); p
+= 8;
1930 SOFF_T(p
,0,allocation_size
); p
+= 8;
1931 SIVAL(p
,0,mode
); p
+= 4;
1932 q
= p
; p
+= 4; /* q is placeholder for name length. */
1934 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1936 SIVAL(p
,0,ea_size
); /* Extended attributes */
1939 len
= srvstr_push(base_data
, flags2
, p
,
1940 fname
, PTR_DIFF(end_data
, p
),
1941 STR_TERMINATE_ASCII
);
1945 len
= PTR_DIFF(p
, pdata
);
1946 pad
= (len
+ (align
-1)) & ~(align
-1);
1948 * offset to the next entry, the caller
1949 * will overwrite it for the last entry
1950 * that's why we always include the padding
1954 * set padding to zero
1957 memset(p
, 0, pad
- len
);
1964 case SMB_FIND_FILE_NAMES_INFO
:
1965 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1967 SIVAL(p
,0,reskey
); p
+= 4;
1969 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1970 acl on a dir (tridge) */
1971 len
= srvstr_push(base_data
, flags2
, p
,
1972 fname
, PTR_DIFF(end_data
, p
),
1973 STR_TERMINATE_ASCII
);
1977 len
= PTR_DIFF(p
, pdata
);
1978 pad
= (len
+ (align
-1)) & ~(align
-1);
1980 * offset to the next entry, the caller
1981 * will overwrite it for the last entry
1982 * that's why we always include the padding
1986 * set padding to zero
1989 memset(p
, 0, pad
- len
);
1996 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1997 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1999 SIVAL(p
,0,reskey
); p
+= 4;
2000 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
2001 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
2002 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
2003 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
2004 SOFF_T(p
,0,file_size
); p
+= 8;
2005 SOFF_T(p
,0,allocation_size
); p
+= 8;
2006 SIVAL(p
,0,mode
); p
+= 4;
2007 q
= p
; p
+= 4; /* q is placeholder for name length. */
2009 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
2011 SIVAL(p
,0,ea_size
); /* Extended attributes */
2014 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
2015 SBVAL(p
,0,file_index
); p
+= 8;
2016 len
= srvstr_push(base_data
, flags2
, p
,
2017 fname
, PTR_DIFF(end_data
, p
),
2018 STR_TERMINATE_ASCII
);
2022 len
= PTR_DIFF(p
, pdata
);
2023 pad
= (len
+ (align
-1)) & ~(align
-1);
2025 * offset to the next entry, the caller
2026 * will overwrite it for the last entry
2027 * that's why we always include the padding
2031 * set padding to zero
2034 memset(p
, 0, pad
- len
);
2041 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2042 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
2043 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
2045 SIVAL(p
,0,reskey
); p
+= 4;
2046 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
2047 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
2048 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
2049 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
2050 SOFF_T(p
,0,file_size
); p
+= 8;
2051 SOFF_T(p
,0,allocation_size
); p
+= 8;
2052 SIVAL(p
,0,mode
); p
+= 4;
2053 q
= p
; p
+= 4; /* q is placeholder for name length */
2055 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
2057 SIVAL(p
,0,ea_size
); /* Extended attributes */
2060 /* Clear the short name buffer. This is
2061 * IMPORTANT as not doing so will trigger
2062 * a Win2k client bug. JRA.
2064 if (!was_8_3
&& check_mangled_names
) {
2065 char mangled_name
[13]; /* mangled 8.3 name. */
2066 if (!name_to_8_3(fname
,mangled_name
,True
,
2068 /* Error - mangle failed ! */
2069 memset(mangled_name
,'\0',12);
2071 mangled_name
[12] = 0;
2072 len
= srvstr_push(base_data
, flags2
,
2073 p
+2, mangled_name
, 24,
2074 STR_UPPER
|STR_UNICODE
);
2077 memset(p
+ 2 + len
,'\0',24 - len
);
2084 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
2085 SBVAL(p
,0,file_index
); p
+= 8;
2086 len
= srvstr_push(base_data
, flags2
, p
,
2087 fname
, PTR_DIFF(end_data
, p
),
2088 STR_TERMINATE_ASCII
);
2092 len
= PTR_DIFF(p
, pdata
);
2093 pad
= (len
+ (align
-1)) & ~(align
-1);
2095 * offset to the next entry, the caller
2096 * will overwrite it for the last entry
2097 * that's why we always include the padding
2101 * set padding to zero
2104 memset(p
, 0, pad
- len
);
2111 /* CIFS UNIX Extension. */
2113 case SMB_FIND_FILE_UNIX
:
2114 case SMB_FIND_FILE_UNIX_INFO2
:
2116 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
2118 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2120 if (info_level
== SMB_FIND_FILE_UNIX
) {
2121 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2122 p
= store_file_unix_basic(conn
, p
,
2123 NULL
, &smb_fname
->st
);
2124 len
= srvstr_push(base_data
, flags2
, p
,
2125 fname
, PTR_DIFF(end_data
, p
),
2128 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2129 p
= store_file_unix_basic_info2(conn
, p
,
2130 NULL
, &smb_fname
->st
);
2133 len
= srvstr_push(base_data
, flags2
, p
, fname
,
2134 PTR_DIFF(end_data
, p
), 0);
2135 SIVAL(nameptr
, 0, len
);
2140 len
= PTR_DIFF(p
, pdata
);
2141 pad
= (len
+ (align
-1)) & ~(align
-1);
2143 * offset to the next entry, the caller
2144 * will overwrite it for the last entry
2145 * that's why we always include the padding
2149 * set padding to zero
2152 memset(p
, 0, pad
- len
);
2157 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2165 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
2166 *out_of_space
= true;
2167 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2168 "(wanted %u, had %d)\n",
2169 (unsigned int)PTR_DIFF(p
,pdata
),
2171 return false; /* Not finished - just out of space */
2174 /* Setup the last entry pointer, as an offset from base_data */
2175 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
2176 /* Advance the data pointer to the next slot */
2182 bool smbd_dirptr_lanman2_entry(TALLOC_CTX
*ctx
,
2183 connection_struct
*conn
,
2184 struct dptr_struct
*dirptr
,
2186 const char *path_mask
,
2189 int requires_resume_key
,
2197 int space_remaining
,
2199 bool *got_exact_match
,
2200 int *_last_entry_off
,
2201 struct ea_list
*name_list
)
2204 const char *mask
= NULL
;
2205 long prev_dirpos
= 0;
2208 struct smb_filename
*smb_fname
= NULL
;
2209 struct smbd_dirptr_lanman2_state state
;
2211 uint64_t last_entry_off
= 0;
2215 state
.info_level
= info_level
;
2216 state
.check_mangled_names
= lp_manglednames(conn
->params
);
2217 state
.has_wild
= dptr_has_wild(dirptr
);
2218 state
.got_exact_match
= false;
2220 *out_of_space
= false;
2221 *got_exact_match
= false;
2223 p
= strrchr_m(path_mask
,'/');
2234 ok
= smbd_dirptr_get_entry(ctx
,
2240 smbd_dirptr_lanman2_match_fn
,
2241 smbd_dirptr_lanman2_mode_fn
,
2251 *got_exact_match
= state
.got_exact_match
;
2253 ok
= smbd_marshall_dir_entry(ctx
,
2258 state
.check_mangled_names
,
2259 requires_resume_key
,
2272 TALLOC_FREE(smb_fname
);
2273 if (*out_of_space
) {
2274 dptr_SeekDir(dirptr
, prev_dirpos
);
2281 *_last_entry_off
= last_entry_off
;
2285 static bool get_lanman2_dir_entry(TALLOC_CTX
*ctx
,
2286 connection_struct
*conn
,
2287 struct dptr_struct
*dirptr
,
2289 const char *path_mask
,
2292 bool requires_resume_key
,
2298 int space_remaining
,
2300 bool *got_exact_match
,
2301 int *last_entry_off
,
2302 struct ea_list
*name_list
)
2305 const bool do_pad
= true;
2307 if (info_level
>= 1 && info_level
<= 3) {
2308 /* No alignment on earlier info levels. */
2312 return smbd_dirptr_lanman2_entry(ctx
, conn
, dirptr
, flags2
,
2313 path_mask
, dirtype
, info_level
,
2314 requires_resume_key
, dont_descend
, ask_sharemode
,
2316 ppdata
, base_data
, end_data
,
2318 out_of_space
, got_exact_match
,
2319 last_entry_off
, name_list
);
2322 /****************************************************************************
2323 Reply to a TRANS2_FINDFIRST.
2324 ****************************************************************************/
2326 static void call_trans2findfirst(connection_struct
*conn
,
2327 struct smb_request
*req
,
2328 char **pparams
, int total_params
,
2329 char **ppdata
, int total_data
,
2330 unsigned int max_data_bytes
)
2332 /* We must be careful here that we don't return more than the
2333 allowed number of data bytes. If this means returning fewer than
2334 maxentries then so be it. We assume that the redirector has
2335 enough room for the fixed number of parameter bytes it has
2337 struct smb_filename
*smb_dname
= NULL
;
2338 char *params
= *pparams
;
2339 char *pdata
= *ppdata
;
2343 uint16 findfirst_flags
;
2344 bool close_after_first
;
2346 bool requires_resume_key
;
2348 char *directory
= NULL
;
2351 int last_entry_off
=0;
2355 bool finished
= False
;
2356 bool dont_descend
= False
;
2357 bool out_of_space
= False
;
2358 int space_remaining
;
2359 bool mask_contains_wcard
= False
;
2360 struct ea_list
*ea_list
= NULL
;
2361 NTSTATUS ntstatus
= NT_STATUS_OK
;
2362 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2363 TALLOC_CTX
*ctx
= talloc_tos();
2364 struct dptr_struct
*dirptr
= NULL
;
2365 struct smbd_server_connection
*sconn
= req
->sconn
;
2366 uint32_t ucf_flags
= (UCF_SAVE_LCOMP
| UCF_ALWAYS_ALLOW_WCARD_LCOMP
);
2367 bool backup_priv
= false;
2369 if (total_params
< 13) {
2370 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2374 dirtype
= SVAL(params
,0);
2375 maxentries
= SVAL(params
,2);
2376 findfirst_flags
= SVAL(params
,4);
2377 close_after_first
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE
);
2378 close_if_end
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2379 requires_resume_key
= (findfirst_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2380 backup_priv
= ((findfirst_flags
& FLAG_TRANS2_FIND_BACKUP_INTENT
) &&
2381 security_token_has_privilege(get_current_nttok(conn
),
2384 info_level
= SVAL(params
,6);
2386 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2387 close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
2388 (unsigned int)dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
2390 info_level
, max_data_bytes
));
2393 /* W2K3 seems to treat zero as 1. */
2397 switch (info_level
) {
2398 case SMB_FIND_INFO_STANDARD
:
2399 case SMB_FIND_EA_SIZE
:
2400 case SMB_FIND_EA_LIST
:
2401 case SMB_FIND_FILE_DIRECTORY_INFO
:
2402 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2403 case SMB_FIND_FILE_NAMES_INFO
:
2404 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2405 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2406 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2408 case SMB_FIND_FILE_UNIX
:
2409 case SMB_FIND_FILE_UNIX_INFO2
:
2410 /* Always use filesystem for UNIX mtime query. */
2411 ask_sharemode
= false;
2412 if (!lp_unix_extensions()) {
2413 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2416 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
2419 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2423 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &directory
,
2424 params
+12, total_params
- 12,
2425 STR_TERMINATE
, &ntstatus
, &mask_contains_wcard
);
2426 if (!NT_STATUS_IS_OK(ntstatus
)) {
2427 reply_nterror(req
, ntstatus
);
2433 ntstatus
= filename_convert_with_privilege(ctx
,
2438 &mask_contains_wcard
,
2441 ntstatus
= filename_convert(ctx
, conn
,
2442 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2445 &mask_contains_wcard
,
2449 if (!NT_STATUS_IS_OK(ntstatus
)) {
2450 if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_PATH_NOT_COVERED
)) {
2451 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
2452 ERRSRV
, ERRbadpath
);
2455 reply_nterror(req
, ntstatus
);
2459 mask
= smb_dname
->original_lcomp
;
2461 directory
= smb_dname
->base_name
;
2463 p
= strrchr_m(directory
,'/');
2465 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2466 if((directory
[0] == '.') && (directory
[1] == '\0')) {
2467 mask
= talloc_strdup(ctx
,"*");
2469 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2472 mask_contains_wcard
= True
;
2478 if (p
== NULL
|| p
== directory
) {
2479 /* Ensure we don't have a directory name of "". */
2480 directory
= talloc_strdup(talloc_tos(), ".");
2482 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2487 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
2489 if (info_level
== SMB_FIND_EA_LIST
) {
2492 if (total_data
< 4) {
2493 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2497 ea_size
= IVAL(pdata
,0);
2498 if (ea_size
!= total_data
) {
2499 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2500 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2501 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2505 if (!lp_ea_support(SNUM(conn
))) {
2506 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2510 /* Pull out the list of names. */
2511 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2513 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2518 *ppdata
= (char *)SMB_REALLOC(
2519 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2520 if(*ppdata
== NULL
) {
2521 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2525 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2527 /* Realloc the params space */
2528 *pparams
= (char *)SMB_REALLOC(*pparams
, 10);
2529 if (*pparams
== NULL
) {
2530 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2535 /* Save the wildcard match and attribs we are using on this directory -
2536 needed as lanman2 assumes these are being saved between calls */
2538 ntstatus
= dptr_create(conn
,
2546 mask_contains_wcard
,
2550 if (!NT_STATUS_IS_OK(ntstatus
)) {
2551 reply_nterror(req
, ntstatus
);
2556 /* Remember this in case we have
2557 to do a findnext. */
2558 dptr_set_priv(dirptr
);
2561 dptr_num
= dptr_dnum(dirptr
);
2562 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num
, mask
, dirtype
));
2564 /* Initialize per TRANS2_FIND_FIRST operation data */
2565 dptr_init_search_op(dirptr
);
2567 /* We don't need to check for VOL here as this is returned by
2568 a different TRANS2 call. */
2570 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2571 directory
,lp_dontdescend(ctx
, SNUM(conn
))));
2572 if (in_list(directory
,lp_dontdescend(ctx
, SNUM(conn
)),conn
->case_sensitive
))
2573 dont_descend
= True
;
2576 space_remaining
= max_data_bytes
;
2577 out_of_space
= False
;
2579 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
2580 bool got_exact_match
= False
;
2582 /* this is a heuristic to avoid seeking the dirptr except when
2583 absolutely necessary. It allows for a filename of about 40 chars */
2584 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2585 out_of_space
= True
;
2588 finished
= !get_lanman2_dir_entry(ctx
,
2592 mask
,dirtype
,info_level
,
2593 requires_resume_key
,dont_descend
,
2596 space_remaining
, &out_of_space
,
2598 &last_entry_off
, ea_list
);
2601 if (finished
&& out_of_space
)
2604 if (!finished
&& !out_of_space
)
2608 * As an optimisation if we know we aren't looking
2609 * for a wildcard name (ie. the name matches the wildcard exactly)
2610 * then we can finish on any (first) match.
2611 * This speeds up large directory searches. JRA.
2617 /* Ensure space_remaining never goes -ve. */
2618 if (PTR_DIFF(p
,pdata
) > max_data_bytes
) {
2619 space_remaining
= 0;
2620 out_of_space
= true;
2622 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2626 /* Check if we can close the dirptr */
2627 if(close_after_first
|| (finished
&& close_if_end
)) {
2628 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
2629 dptr_close(sconn
, &dptr_num
);
2633 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2634 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2635 * the protocol level is less than NT1. Tested with smbclient. JRA.
2636 * This should fix the OS/2 client bug #2335.
2639 if(numentries
== 0) {
2640 dptr_close(sconn
, &dptr_num
);
2641 if (get_Protocol() < PROTOCOL_NT1
) {
2642 reply_force_doserror(req
, ERRDOS
, ERRnofiles
);
2645 reply_botherror(req
, NT_STATUS_NO_SUCH_FILE
,
2646 ERRDOS
, ERRbadfile
);
2651 /* At this point pdata points to numentries directory entries. */
2653 /* Set up the return parameter block */
2654 SSVAL(params
,0,dptr_num
);
2655 SSVAL(params
,2,numentries
);
2656 SSVAL(params
,4,finished
);
2657 SSVAL(params
,6,0); /* Never an EA error */
2658 SSVAL(params
,8,last_entry_off
);
2660 send_trans2_replies(conn
, req
, params
, 10, pdata
, PTR_DIFF(p
,pdata
),
2663 if ((! *directory
) && dptr_path(sconn
, dptr_num
)) {
2664 directory
= talloc_strdup(talloc_tos(),dptr_path(sconn
, dptr_num
));
2666 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2670 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2671 smb_fn_name(req
->cmd
),
2672 mask
, directory
, dirtype
, numentries
) );
2675 * Force a name mangle here to ensure that the
2676 * mask as an 8.3 name is top of the mangled cache.
2677 * The reasons for this are subtle. Don't remove
2678 * this code unless you know what you are doing
2679 * (see PR#13758). JRA.
2682 if(!mangle_is_8_3_wildcards( mask
, False
, conn
->params
)) {
2683 char mangled_name
[13];
2684 name_to_8_3(mask
, mangled_name
, True
, conn
->params
);
2692 TALLOC_FREE(smb_dname
);
2696 /****************************************************************************
2697 Reply to a TRANS2_FINDNEXT.
2698 ****************************************************************************/
2700 static void call_trans2findnext(connection_struct
*conn
,
2701 struct smb_request
*req
,
2702 char **pparams
, int total_params
,
2703 char **ppdata
, int total_data
,
2704 unsigned int max_data_bytes
)
2706 /* We must be careful here that we don't return more than the
2707 allowed number of data bytes. If this means returning fewer than
2708 maxentries then so be it. We assume that the redirector has
2709 enough room for the fixed number of parameter bytes it has
2711 char *params
= *pparams
;
2712 char *pdata
= *ppdata
;
2718 uint16 findnext_flags
;
2719 bool close_after_request
;
2721 bool requires_resume_key
;
2723 bool mask_contains_wcard
= False
;
2724 char *resume_name
= NULL
;
2725 const char *mask
= NULL
;
2726 const char *directory
= NULL
;
2730 int i
, last_entry_off
=0;
2731 bool finished
= False
;
2732 bool dont_descend
= False
;
2733 bool out_of_space
= False
;
2734 int space_remaining
;
2735 struct ea_list
*ea_list
= NULL
;
2736 NTSTATUS ntstatus
= NT_STATUS_OK
;
2737 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2738 TALLOC_CTX
*ctx
= talloc_tos();
2739 struct dptr_struct
*dirptr
;
2740 struct smbd_server_connection
*sconn
= req
->sconn
;
2741 bool backup_priv
= false;
2743 if (total_params
< 13) {
2744 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2748 dptr_num
= SVAL(params
,0);
2749 maxentries
= SVAL(params
,2);
2750 info_level
= SVAL(params
,4);
2751 resume_key
= IVAL(params
,6);
2752 findnext_flags
= SVAL(params
,10);
2753 close_after_request
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE
);
2754 close_if_end
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2755 requires_resume_key
= (findnext_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2756 continue_bit
= (findnext_flags
& FLAG_TRANS2_FIND_CONTINUE
);
2758 if (!continue_bit
) {
2759 /* We only need resume_name if continue_bit is zero. */
2760 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &resume_name
,
2762 total_params
- 12, STR_TERMINATE
, &ntstatus
,
2763 &mask_contains_wcard
);
2764 if (!NT_STATUS_IS_OK(ntstatus
)) {
2765 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2766 complain (it thinks we're asking for the directory above the shared
2767 path or an invalid name). Catch this as the resume name is only compared, never used in
2768 a file access. JRA. */
2769 srvstr_pull_talloc(ctx
, params
, req
->flags2
,
2770 &resume_name
, params
+12,
2774 if (!resume_name
|| !(ISDOT(resume_name
) || ISDOTDOT(resume_name
))) {
2775 reply_nterror(req
, ntstatus
);
2781 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2782 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2783 resume_key = %d resume name = %s continue=%d level = %d\n",
2784 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
2785 requires_resume_key
, resume_key
,
2786 resume_name
? resume_name
: "(NULL)", continue_bit
, info_level
));
2789 /* W2K3 seems to treat zero as 1. */
2793 switch (info_level
) {
2794 case SMB_FIND_INFO_STANDARD
:
2795 case SMB_FIND_EA_SIZE
:
2796 case SMB_FIND_EA_LIST
:
2797 case SMB_FIND_FILE_DIRECTORY_INFO
:
2798 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2799 case SMB_FIND_FILE_NAMES_INFO
:
2800 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2801 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2802 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2804 case SMB_FIND_FILE_UNIX
:
2805 case SMB_FIND_FILE_UNIX_INFO2
:
2806 /* Always use filesystem for UNIX mtime query. */
2807 ask_sharemode
= false;
2808 if (!lp_unix_extensions()) {
2809 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2814 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2818 if (info_level
== SMB_FIND_EA_LIST
) {
2821 if (total_data
< 4) {
2822 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2826 ea_size
= IVAL(pdata
,0);
2827 if (ea_size
!= total_data
) {
2828 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2829 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2830 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2834 if (!lp_ea_support(SNUM(conn
))) {
2835 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2839 /* Pull out the list of names. */
2840 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2842 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2847 *ppdata
= (char *)SMB_REALLOC(
2848 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2849 if(*ppdata
== NULL
) {
2850 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2855 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2857 /* Realloc the params space */
2858 *pparams
= (char *)SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
2859 if(*pparams
== NULL
) {
2860 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2866 /* Check that the dptr is valid */
2867 if(!(dirptr
= dptr_fetch_lanman2(sconn
, dptr_num
))) {
2868 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2872 directory
= dptr_path(sconn
, dptr_num
);
2874 /* Get the wildcard mask from the dptr */
2875 if((mask
= dptr_wcard(sconn
, dptr_num
))== NULL
) {
2876 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
2877 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2881 /* Get the attr mask from the dptr */
2882 dirtype
= dptr_attr(sconn
, dptr_num
);
2884 backup_priv
= dptr_get_priv(dirptr
);
2886 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
2887 "backup_priv = %d\n",
2888 dptr_num
, mask
, dirtype
,
2890 dptr_TellDir(dirptr
),
2893 /* Initialize per TRANS2_FIND_NEXT operation data */
2894 dptr_init_search_op(dirptr
);
2896 /* We don't need to check for VOL here as this is returned by
2897 a different TRANS2 call. */
2899 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2900 directory
,lp_dontdescend(ctx
, SNUM(conn
))));
2901 if (in_list(directory
,lp_dontdescend(ctx
, SNUM(conn
)),conn
->case_sensitive
))
2902 dont_descend
= True
;
2905 space_remaining
= max_data_bytes
;
2906 out_of_space
= False
;
2913 * Seek to the correct position. We no longer use the resume key but
2914 * depend on the last file name instead.
2917 if(!continue_bit
&& resume_name
&& *resume_name
) {
2920 long current_pos
= 0;
2922 * Remember, name_to_8_3 is called by
2923 * get_lanman2_dir_entry(), so the resume name
2924 * could be mangled. Ensure we check the unmangled name.
2927 if (mangle_is_mangled(resume_name
, conn
->params
)) {
2928 char *new_resume_name
= NULL
;
2929 mangle_lookup_name_from_8_3(ctx
,
2933 if (new_resume_name
) {
2934 resume_name
= new_resume_name
;
2939 * Fix for NT redirector problem triggered by resume key indexes
2940 * changing between directory scans. We now return a resume key of 0
2941 * and instead look for the filename to continue from (also given
2942 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2943 * findfirst/findnext (as is usual) then the directory pointer
2944 * should already be at the correct place.
2947 finished
= !dptr_SearchDir(dirptr
, resume_name
, ¤t_pos
, &st
);
2948 } /* end if resume_name && !continue_bit */
2950 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
2951 bool got_exact_match
= False
;
2953 /* this is a heuristic to avoid seeking the dirptr except when
2954 absolutely necessary. It allows for a filename of about 40 chars */
2955 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2956 out_of_space
= True
;
2959 finished
= !get_lanman2_dir_entry(ctx
,
2963 mask
,dirtype
,info_level
,
2964 requires_resume_key
,dont_descend
,
2967 space_remaining
, &out_of_space
,
2969 &last_entry_off
, ea_list
);
2972 if (finished
&& out_of_space
)
2975 if (!finished
&& !out_of_space
)
2979 * As an optimisation if we know we aren't looking
2980 * for a wildcard name (ie. the name matches the wildcard exactly)
2981 * then we can finish on any (first) match.
2982 * This speeds up large directory searches. JRA.
2988 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2991 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2992 smb_fn_name(req
->cmd
),
2993 mask
, directory
, dirtype
, numentries
) );
2995 /* Check if we can close the dirptr */
2996 if(close_after_request
|| (finished
&& close_if_end
)) {
2997 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
2998 dptr_close(sconn
, &dptr_num
); /* This frees up the saved mask */
3005 /* Set up the return parameter block */
3006 SSVAL(params
,0,numentries
);
3007 SSVAL(params
,2,finished
);
3008 SSVAL(params
,4,0); /* Never an EA error */
3009 SSVAL(params
,6,last_entry_off
);
3011 send_trans2_replies(conn
, req
, params
, 8, pdata
, PTR_DIFF(p
,pdata
),
3017 unsigned char *create_volume_objectid(connection_struct
*conn
, unsigned char objid
[16])
3019 E_md4hash(lp_servicename(talloc_tos(), SNUM(conn
)),objid
);
3023 static void samba_extended_info_version(struct smb_extended_info
*extended_info
)
3025 SMB_ASSERT(extended_info
!= NULL
);
3027 extended_info
->samba_magic
= SAMBA_EXTENDED_INFO_MAGIC
;
3028 extended_info
->samba_version
= ((SAMBA_VERSION_MAJOR
& 0xff) << 24)
3029 | ((SAMBA_VERSION_MINOR
& 0xff) << 16)
3030 | ((SAMBA_VERSION_RELEASE
& 0xff) << 8);
3031 #ifdef SAMBA_VERSION_REVISION
3032 extended_info
->samba_version
|= (tolower(*SAMBA_VERSION_REVISION
) - 'a' + 1) & 0xff;
3034 extended_info
->samba_subversion
= 0;
3035 #ifdef SAMBA_VERSION_RC_RELEASE
3036 extended_info
->samba_subversion
|= (SAMBA_VERSION_RC_RELEASE
& 0xff) << 24;
3038 #ifdef SAMBA_VERSION_PRE_RELEASE
3039 extended_info
->samba_subversion
|= (SAMBA_VERSION_PRE_RELEASE
& 0xff) << 16;
3042 #ifdef SAMBA_VERSION_VENDOR_PATCH
3043 extended_info
->samba_subversion
|= (SAMBA_VERSION_VENDOR_PATCH
& 0xffff);
3045 extended_info
->samba_gitcommitdate
= 0;
3046 #ifdef SAMBA_VERSION_COMMIT_TIME
3047 unix_to_nt_time(&extended_info
->samba_gitcommitdate
, SAMBA_VERSION_COMMIT_TIME
);
3050 memset(extended_info
->samba_version_string
, 0,
3051 sizeof(extended_info
->samba_version_string
));
3053 snprintf (extended_info
->samba_version_string
,
3054 sizeof(extended_info
->samba_version_string
),
3055 "%s", samba_version_string());
3058 NTSTATUS
smbd_do_qfsinfo(connection_struct
*conn
,
3059 TALLOC_CTX
*mem_ctx
,
3060 uint16_t info_level
,
3062 unsigned int max_data_bytes
,
3063 struct smb_filename
*fname
,
3067 char *pdata
, *end_data
;
3068 int data_len
= 0, len
;
3069 const char *vname
= volume_label(talloc_tos(), SNUM(conn
));
3070 int snum
= SNUM(conn
);
3071 char *fstype
= lp_fstype(talloc_tos(), SNUM(conn
));
3072 char *filename
= NULL
;
3073 uint32 additional_flags
= 0;
3074 struct smb_filename smb_fname
;
3077 if (fname
== NULL
|| fname
->base_name
== NULL
) {
3080 filename
= fname
->base_name
;
3084 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3085 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3086 "info level (0x%x) on IPC$.\n",
3087 (unsigned int)info_level
));
3088 return NT_STATUS_ACCESS_DENIED
;
3092 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level
));
3094 ZERO_STRUCT(smb_fname
);
3095 smb_fname
.base_name
= discard_const_p(char, filename
);
3097 if(SMB_VFS_STAT(conn
, &smb_fname
) != 0) {
3098 DEBUG(2,("stat of . failed (%s)\n", strerror(errno
)));
3099 return map_nt_error_from_unix(errno
);
3104 *ppdata
= (char *)SMB_REALLOC(
3105 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3106 if (*ppdata
== NULL
) {
3107 return NT_STATUS_NO_MEMORY
;
3111 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3112 end_data
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
3114 switch (info_level
) {
3115 case SMB_INFO_ALLOCATION
:
3117 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3119 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3120 return map_nt_error_from_unix(errno
);
3123 block_size
= lp_block_size(snum
);
3124 if (bsize
< block_size
) {
3125 uint64_t factor
= block_size
/bsize
;
3130 if (bsize
> block_size
) {
3131 uint64_t factor
= bsize
/block_size
;
3136 bytes_per_sector
= 512;
3137 sectors_per_unit
= bsize
/bytes_per_sector
;
3139 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3140 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_ex_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3141 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3143 SIVAL(pdata
,l1_idFileSystem
,st
.st_ex_dev
);
3144 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
3145 SIVAL(pdata
,l1_cUnit
,dsize
);
3146 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
3147 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
3151 case SMB_INFO_VOLUME
:
3152 /* Return volume name */
3154 * Add volume serial number - hash of a combination of
3155 * the called hostname and the service name.
3157 SIVAL(pdata
,0,str_checksum(lp_servicename(talloc_tos(), snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
3159 * Win2k3 and previous mess this up by sending a name length
3160 * one byte short. I believe only older clients (OS/2 Win9x) use
3161 * this call so try fixing this by adding a terminating null to
3162 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3166 pdata
+l2_vol_szVolLabel
, vname
,
3167 PTR_DIFF(end_data
, pdata
+l2_vol_szVolLabel
),
3168 STR_NOALIGN
|STR_TERMINATE
);
3169 SCVAL(pdata
,l2_vol_cch
,len
);
3170 data_len
= l2_vol_szVolLabel
+ len
;
3171 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
3172 (unsigned)convert_timespec_to_time_t(st
.st_ex_ctime
),
3176 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
3177 case SMB_FS_ATTRIBUTE_INFORMATION
:
3179 additional_flags
= 0;
3180 #if defined(HAVE_SYS_QUOTAS)
3181 additional_flags
|= FILE_VOLUME_QUOTAS
;
3184 if(lp_nt_acl_support(SNUM(conn
))) {
3185 additional_flags
|= FILE_PERSISTENT_ACLS
;
3188 /* Capabilities are filled in at connection time through STATVFS call */
3189 additional_flags
|= conn
->fs_capabilities
;
3190 additional_flags
|= lp_parm_int(conn
->params
->service
,
3191 "share", "fake_fscaps",
3194 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
3195 FILE_SUPPORTS_OBJECT_IDS
|FILE_UNICODE_ON_DISK
|
3196 additional_flags
); /* FS ATTRIBUTES */
3198 SIVAL(pdata
,4,255); /* Max filename component length */
3199 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3200 and will think we can't do long filenames */
3201 len
= srvstr_push(pdata
, flags2
, pdata
+12, fstype
,
3202 PTR_DIFF(end_data
, pdata
+12),
3205 data_len
= 12 + len
;
3208 case SMB_QUERY_FS_LABEL_INFO
:
3209 case SMB_FS_LABEL_INFORMATION
:
3210 len
= srvstr_push(pdata
, flags2
, pdata
+4, vname
,
3211 PTR_DIFF(end_data
, pdata
+4), 0);
3216 case SMB_QUERY_FS_VOLUME_INFO
:
3217 case SMB_FS_VOLUME_INFORMATION
:
3220 * Add volume serial number - hash of a combination of
3221 * the called hostname and the service name.
3223 SIVAL(pdata
,8,str_checksum(lp_servicename(talloc_tos(), snum
)) ^
3224 (str_checksum(get_local_machine_name())<<16));
3226 /* Max label len is 32 characters. */
3227 len
= srvstr_push(pdata
, flags2
, pdata
+18, vname
,
3228 PTR_DIFF(end_data
, pdata
+18),
3230 SIVAL(pdata
,12,len
);
3233 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3234 (int)strlen(vname
),vname
,
3235 lp_servicename(talloc_tos(), snum
)));
3238 case SMB_QUERY_FS_SIZE_INFO
:
3239 case SMB_FS_SIZE_INFORMATION
:
3241 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3243 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3244 return map_nt_error_from_unix(errno
);
3246 block_size
= lp_block_size(snum
);
3247 if (bsize
< block_size
) {
3248 uint64_t factor
= block_size
/bsize
;
3253 if (bsize
> block_size
) {
3254 uint64_t factor
= bsize
/block_size
;
3259 bytes_per_sector
= 512;
3260 sectors_per_unit
= bsize
/bytes_per_sector
;
3261 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3262 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3263 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3264 SBIG_UINT(pdata
,0,dsize
);
3265 SBIG_UINT(pdata
,8,dfree
);
3266 SIVAL(pdata
,16,sectors_per_unit
);
3267 SIVAL(pdata
,20,bytes_per_sector
);
3271 case SMB_FS_FULL_SIZE_INFORMATION
:
3273 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3275 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3276 return map_nt_error_from_unix(errno
);
3278 block_size
= lp_block_size(snum
);
3279 if (bsize
< block_size
) {
3280 uint64_t factor
= block_size
/bsize
;
3285 if (bsize
> block_size
) {
3286 uint64_t factor
= bsize
/block_size
;
3291 bytes_per_sector
= 512;
3292 sectors_per_unit
= bsize
/bytes_per_sector
;
3293 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3294 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3295 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3296 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
3297 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
3298 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
3299 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
3300 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
3304 case SMB_QUERY_FS_DEVICE_INFO
:
3305 case SMB_FS_DEVICE_INFORMATION
:
3307 uint32_t characteristics
= FILE_DEVICE_IS_MOUNTED
;
3309 if (!CAN_WRITE(conn
)) {
3310 characteristics
|= FILE_READ_ONLY_DEVICE
;
3313 SIVAL(pdata
,0,FILE_DEVICE_DISK
); /* dev type */
3314 SIVAL(pdata
,4,characteristics
);
3318 #ifdef HAVE_SYS_QUOTAS
3319 case SMB_FS_QUOTA_INFORMATION
:
3321 * what we have to send --metze:
3323 * Unknown1: 24 NULL bytes
3324 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3325 * Hard Quota Limit: 8 bytes seems like uint64_t or so
3326 * Quota Flags: 2 byte :
3327 * Unknown3: 6 NULL bytes
3331 * details for Quota Flags:
3333 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3334 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
3335 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3336 * 0x0001 Enable Quotas: enable quota for this fs
3340 /* we need to fake up a fsp here,
3341 * because its not send in this call
3344 SMB_NTQUOTA_STRUCT quotas
;
3347 ZERO_STRUCT(quotas
);
3350 fsp
.fnum
= FNUM_FIELD_INVALID
;
3353 if (get_current_uid(conn
) != 0) {
3354 DEBUG(0,("set_user_quota: access_denied "
3355 "service [%s] user [%s]\n",
3356 lp_servicename(talloc_tos(), SNUM(conn
)),
3357 conn
->session_info
->unix_info
->unix_name
));
3358 return NT_STATUS_ACCESS_DENIED
;
3361 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3362 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3363 return map_nt_error_from_unix(errno
);
3368 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3369 lp_servicename(talloc_tos(), SNUM(conn
))));
3371 /* Unknown1 24 NULL bytes*/
3372 SBIG_UINT(pdata
,0,(uint64_t)0);
3373 SBIG_UINT(pdata
,8,(uint64_t)0);
3374 SBIG_UINT(pdata
,16,(uint64_t)0);
3376 /* Default Soft Quota 8 bytes */
3377 SBIG_UINT(pdata
,24,quotas
.softlim
);
3379 /* Default Hard Quota 8 bytes */
3380 SBIG_UINT(pdata
,32,quotas
.hardlim
);
3382 /* Quota flag 2 bytes */
3383 SSVAL(pdata
,40,quotas
.qflags
);
3385 /* Unknown3 6 NULL bytes */
3391 #endif /* HAVE_SYS_QUOTAS */
3392 case SMB_FS_OBJECTID_INFORMATION
:
3394 unsigned char objid
[16];
3395 struct smb_extended_info extended_info
;
3396 memcpy(pdata
,create_volume_objectid(conn
, objid
),16);
3397 samba_extended_info_version (&extended_info
);
3398 SIVAL(pdata
,16,extended_info
.samba_magic
);
3399 SIVAL(pdata
,20,extended_info
.samba_version
);
3400 SIVAL(pdata
,24,extended_info
.samba_subversion
);
3401 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
3402 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
3408 * Query the version and capabilities of the CIFS UNIX extensions
3412 case SMB_QUERY_CIFS_UNIX_INFO
:
3414 bool large_write
= lp_min_receive_file_size() &&
3415 !srv_is_signing_active(conn
->sconn
);
3416 bool large_read
= !srv_is_signing_active(conn
->sconn
);
3417 int encrypt_caps
= 0;
3419 if (!lp_unix_extensions()) {
3420 return NT_STATUS_INVALID_LEVEL
;
3423 switch (conn
->encrypt_level
) {
3424 case SMB_SIGNING_OFF
:
3427 case SMB_SIGNING_IF_REQUIRED
:
3428 case SMB_SIGNING_DEFAULT
:
3429 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
;
3431 case SMB_SIGNING_REQUIRED
:
3432 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
|
3433 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP
;
3434 large_write
= false;
3440 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
3441 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
3443 /* We have POSIX ACLs, pathname, encryption,
3444 * large read/write, and locking capability. */
3446 SBIG_UINT(pdata
,4,((uint64_t)(
3447 CIFS_UNIX_POSIX_ACLS_CAP
|
3448 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
3449 CIFS_UNIX_FCNTL_LOCKS_CAP
|
3450 CIFS_UNIX_EXTATTR_CAP
|
3451 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
|
3453 (large_read
? CIFS_UNIX_LARGE_READ_CAP
: 0) |
3455 CIFS_UNIX_LARGE_WRITE_CAP
: 0))));
3459 case SMB_QUERY_POSIX_FS_INFO
:
3462 vfs_statvfs_struct svfs
;
3464 if (!lp_unix_extensions()) {
3465 return NT_STATUS_INVALID_LEVEL
;
3468 rc
= SMB_VFS_STATVFS(conn
, filename
, &svfs
);
3472 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
3473 SIVAL(pdata
,4,svfs
.BlockSize
);
3474 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
3475 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
3476 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
3477 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
3478 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
3479 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
3480 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3482 } else if (rc
== EOPNOTSUPP
) {
3483 return NT_STATUS_INVALID_LEVEL
;
3484 #endif /* EOPNOTSUPP */
3486 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3487 return NT_STATUS_DOS(ERRSRV
, ERRerror
);
3492 case SMB_QUERY_POSIX_WHOAMI
:
3498 if (!lp_unix_extensions()) {
3499 return NT_STATUS_INVALID_LEVEL
;
3502 if (max_data_bytes
< 40) {
3503 return NT_STATUS_BUFFER_TOO_SMALL
;
3506 if (security_session_user_level(conn
->session_info
, NULL
) < SECURITY_USER
) {
3507 flags
|= SMB_WHOAMI_GUEST
;
3510 /* NOTE: 8 bytes for UID/GID, irrespective of native
3511 * platform size. This matches
3512 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3514 data_len
= 4 /* flags */
3521 + 4 /* pad/reserved */
3522 + (conn
->session_info
->unix_token
->ngroups
* 8)
3524 + (conn
->session_info
->security_token
->num_sids
*
3528 SIVAL(pdata
, 0, flags
);
3529 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
3531 (uint64_t)conn
->session_info
->unix_token
->uid
);
3532 SBIG_UINT(pdata
, 16,
3533 (uint64_t)conn
->session_info
->unix_token
->gid
);
3536 if (data_len
>= max_data_bytes
) {
3537 /* Potential overflow, skip the GIDs and SIDs. */
3539 SIVAL(pdata
, 24, 0); /* num_groups */
3540 SIVAL(pdata
, 28, 0); /* num_sids */
3541 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
3542 SIVAL(pdata
, 36, 0); /* reserved */
3548 SIVAL(pdata
, 24, conn
->session_info
->unix_token
->ngroups
);
3549 SIVAL(pdata
, 28, conn
->session_info
->security_token
->num_sids
);
3551 /* We walk the SID list twice, but this call is fairly
3552 * infrequent, and I don't expect that it's performance
3553 * sensitive -- jpeach
3555 for (i
= 0, sid_bytes
= 0;
3556 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3557 sid_bytes
+= ndr_size_dom_sid(
3558 &conn
->session_info
->security_token
->sids
[i
],
3562 /* SID list byte count */
3563 SIVAL(pdata
, 32, sid_bytes
);
3565 /* 4 bytes pad/reserved - must be zero */
3566 SIVAL(pdata
, 36, 0);
3570 for (i
= 0; i
< conn
->session_info
->unix_token
->ngroups
; ++i
) {
3571 SBIG_UINT(pdata
, data_len
,
3572 (uint64_t)conn
->session_info
->unix_token
->groups
[i
]);
3578 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3579 int sid_len
= ndr_size_dom_sid(
3580 &conn
->session_info
->security_token
->sids
[i
],
3583 sid_linearize(pdata
+ data_len
, sid_len
,
3584 &conn
->session_info
->security_token
->sids
[i
]);
3585 data_len
+= sid_len
;
3591 case SMB_MAC_QUERY_FS_INFO
:
3593 * Thursby MAC extension... ONLY on NTFS filesystems
3594 * once we do streams then we don't need this
3596 if (strequal(lp_fstype(talloc_tos(), SNUM(conn
)),"NTFS")) {
3598 SIVAL(pdata
,84,0x100); /* Don't support mac... */
3603 return NT_STATUS_INVALID_LEVEL
;
3606 *ret_data_len
= data_len
;
3607 return NT_STATUS_OK
;
3610 /****************************************************************************
3611 Reply to a TRANS2_QFSINFO (query filesystem info).
3612 ****************************************************************************/
3614 static void call_trans2qfsinfo(connection_struct
*conn
,
3615 struct smb_request
*req
,
3616 char **pparams
, int total_params
,
3617 char **ppdata
, int total_data
,
3618 unsigned int max_data_bytes
)
3620 char *params
= *pparams
;
3621 uint16_t info_level
;
3625 if (total_params
< 2) {
3626 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3630 info_level
= SVAL(params
,0);
3632 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3633 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3634 DEBUG(0,("call_trans2qfsinfo: encryption required "
3635 "and info level 0x%x sent.\n",
3636 (unsigned int)info_level
));
3637 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3642 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
3644 status
= smbd_do_qfsinfo(conn
, req
,
3650 if (!NT_STATUS_IS_OK(status
)) {
3651 reply_nterror(req
, status
);
3655 send_trans2_replies(conn
, req
, params
, 0, *ppdata
, data_len
,
3658 DEBUG( 4, ( "%s info_level = %d\n",
3659 smb_fn_name(req
->cmd
), info_level
) );
3664 /****************************************************************************
3665 Reply to a TRANS2_SETFSINFO (set filesystem info).
3666 ****************************************************************************/
3668 static void call_trans2setfsinfo(connection_struct
*conn
,
3669 struct smb_request
*req
,
3670 char **pparams
, int total_params
,
3671 char **ppdata
, int total_data
,
3672 unsigned int max_data_bytes
)
3674 struct smbd_server_connection
*sconn
= req
->sconn
;
3675 char *pdata
= *ppdata
;
3676 char *params
= *pparams
;
3679 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
3680 lp_servicename(talloc_tos(), SNUM(conn
))));
3683 if (total_params
< 4) {
3684 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3686 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3690 info_level
= SVAL(params
,2);
3693 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
&&
3694 info_level
!= SMB_SET_CIFS_UNIX_INFO
) {
3695 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3696 "info level (0x%x) on IPC$.\n",
3697 (unsigned int)info_level
));
3698 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3703 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3704 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
) {
3705 DEBUG(0,("call_trans2setfsinfo: encryption required "
3706 "and info level 0x%x sent.\n",
3707 (unsigned int)info_level
));
3708 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3713 switch(info_level
) {
3714 case SMB_SET_CIFS_UNIX_INFO
:
3715 if (!lp_unix_extensions()) {
3716 DEBUG(2,("call_trans2setfsinfo: "
3717 "SMB_SET_CIFS_UNIX_INFO is invalid with "
3718 "unix extensions off\n"));
3720 NT_STATUS_INVALID_LEVEL
);
3724 /* There should be 12 bytes of capabilities set. */
3725 if (total_data
< 12) {
3728 NT_STATUS_INVALID_PARAMETER
);
3731 sconn
->smb1
.unix_info
.client_major
= SVAL(pdata
,0);
3732 sconn
->smb1
.unix_info
.client_minor
= SVAL(pdata
,2);
3733 sconn
->smb1
.unix_info
.client_cap_low
= IVAL(pdata
,4);
3734 sconn
->smb1
.unix_info
.client_cap_high
= IVAL(pdata
,8);
3735 /* Just print these values for now. */
3736 DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
3737 "major = %u, minor = %u cap_low = 0x%x, "
3739 (unsigned int)sconn
->
3740 smb1
.unix_info
.client_major
,
3741 (unsigned int)sconn
->
3742 smb1
.unix_info
.client_minor
,
3743 (unsigned int)sconn
->
3744 smb1
.unix_info
.client_cap_low
,
3745 (unsigned int)sconn
->
3746 smb1
.unix_info
.client_cap_high
));
3748 /* Here is where we must switch to posix pathname processing... */
3749 if (sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
3750 lp_set_posix_pathnames();
3751 mangle_change_to_posix();
3754 if ((sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_FCNTL_LOCKS_CAP
) &&
3755 !(sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)) {
3756 /* Client that knows how to do posix locks,
3757 * but not posix open/mkdir operations. Set a
3758 * default type for read/write checks. */
3760 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK
);
3765 case SMB_REQUEST_TRANSPORT_ENCRYPTION
:
3768 size_t param_len
= 0;
3769 size_t data_len
= total_data
;
3771 if (!lp_unix_extensions()) {
3774 NT_STATUS_INVALID_LEVEL
);
3778 if (lp_smb_encrypt(SNUM(conn
)) == SMB_SIGNING_OFF
) {
3781 NT_STATUS_NOT_SUPPORTED
);
3785 if (req
->sconn
->smb1
.echo_handler
.trusted_fde
) {
3786 DEBUG( 2,("call_trans2setfsinfo: "
3787 "request transport encryption disabled"
3788 "with 'fork echo handler = yes'\n"));
3791 NT_STATUS_NOT_SUPPORTED
);
3795 DEBUG( 4,("call_trans2setfsinfo: "
3796 "request transport encryption.\n"));
3798 status
= srv_request_encryption_setup(conn
,
3799 (unsigned char **)ppdata
,
3801 (unsigned char **)pparams
,
3804 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
3805 !NT_STATUS_IS_OK(status
)) {
3806 reply_nterror(req
, status
);
3810 send_trans2_replies(conn
, req
,
3817 if (NT_STATUS_IS_OK(status
)) {
3818 /* Server-side transport
3819 * encryption is now *on*. */
3820 status
= srv_encryption_start(conn
);
3821 if (!NT_STATUS_IS_OK(status
)) {
3822 char *reason
= talloc_asprintf(talloc_tos(),
3823 "Failure in setting "
3824 "up encrypted transport: %s",
3826 exit_server_cleanly(reason
);
3832 case SMB_FS_QUOTA_INFORMATION
:
3834 files_struct
*fsp
= NULL
;
3835 SMB_NTQUOTA_STRUCT quotas
;
3837 ZERO_STRUCT(quotas
);
3840 if ((get_current_uid(conn
) != 0) || !CAN_WRITE(conn
)) {
3841 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3842 lp_servicename(talloc_tos(), SNUM(conn
)),
3843 conn
->session_info
->unix_info
->unix_name
));
3844 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3848 /* note: normaly there're 48 bytes,
3849 * but we didn't use the last 6 bytes for now
3852 fsp
= file_fsp(req
, SVAL(params
,0));
3854 if (!check_fsp_ntquota_handle(conn
, req
,
3856 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3858 req
, NT_STATUS_INVALID_HANDLE
);
3862 if (total_data
< 42) {
3863 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3867 NT_STATUS_INVALID_PARAMETER
);
3871 /* unknown_1 24 NULL bytes in pdata*/
3873 /* the soft quotas 8 bytes (uint64_t)*/
3874 quotas
.softlim
= BVAL(pdata
,24);
3876 /* the hard quotas 8 bytes (uint64_t)*/
3877 quotas
.hardlim
= BVAL(pdata
,32);
3879 /* quota_flags 2 bytes **/
3880 quotas
.qflags
= SVAL(pdata
,40);
3882 /* unknown_2 6 NULL bytes follow*/
3884 /* now set the quotas */
3885 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3886 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3887 reply_nterror(req
, map_nt_error_from_unix(errno
));
3894 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3896 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
3902 * sending this reply works fine,
3903 * but I'm not sure it's the same
3904 * like windows do...
3907 reply_outbuf(req
, 10, 0);
3910 #if defined(HAVE_POSIX_ACLS)
3911 /****************************************************************************
3912 Utility function to count the number of entries in a POSIX acl.
3913 ****************************************************************************/
3915 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
3917 unsigned int ace_count
= 0;
3918 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3919 SMB_ACL_ENTRY_T entry
;
3921 while ( posix_acl
&& (sys_acl_get_entry(posix_acl
, entry_id
, &entry
) == 1)) {
3923 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3924 entry_id
= SMB_ACL_NEXT_ENTRY
;
3931 /****************************************************************************
3932 Utility function to marshall a POSIX acl into wire format.
3933 ****************************************************************************/
3935 static bool marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
3937 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3938 SMB_ACL_ENTRY_T entry
;
3940 while ( posix_acl
&& (sys_acl_get_entry(posix_acl
, entry_id
, &entry
) == 1)) {
3941 SMB_ACL_TAG_T tagtype
;
3942 SMB_ACL_PERMSET_T permset
;
3943 unsigned char perms
= 0;
3944 unsigned int own_grp
;
3947 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3948 entry_id
= SMB_ACL_NEXT_ENTRY
;
3951 if (sys_acl_get_tag_type(entry
, &tagtype
) == -1) {
3952 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3956 if (sys_acl_get_permset(entry
, &permset
) == -1) {
3957 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3961 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
3962 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
3963 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
3965 SCVAL(pdata
,1,perms
);
3968 case SMB_ACL_USER_OBJ
:
3969 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
3970 own_grp
= (unsigned int)pst
->st_ex_uid
;
3971 SIVAL(pdata
,2,own_grp
);
3976 uid_t
*puid
= (uid_t
*)sys_acl_get_qualifier(entry
);
3978 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3981 own_grp
= (unsigned int)*puid
;
3982 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
3983 SIVAL(pdata
,2,own_grp
);
3987 case SMB_ACL_GROUP_OBJ
:
3988 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
3989 own_grp
= (unsigned int)pst
->st_ex_gid
;
3990 SIVAL(pdata
,2,own_grp
);
3995 gid_t
*pgid
= (gid_t
*)sys_acl_get_qualifier(entry
);
3997 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
4000 own_grp
= (unsigned int)*pgid
;
4001 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
4002 SIVAL(pdata
,2,own_grp
);
4007 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
4008 SIVAL(pdata
,2,0xFFFFFFFF);
4009 SIVAL(pdata
,6,0xFFFFFFFF);
4012 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
4013 SIVAL(pdata
,2,0xFFFFFFFF);
4014 SIVAL(pdata
,6,0xFFFFFFFF);
4017 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
4020 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
4027 /****************************************************************************
4028 Store the FILE_UNIX_BASIC info.
4029 ****************************************************************************/
4031 static char *store_file_unix_basic(connection_struct
*conn
,
4034 const SMB_STRUCT_STAT
*psbuf
)
4036 uint64_t file_index
= get_FileIndex(conn
, psbuf
);
4039 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
4040 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_ex_mode
));
4042 SOFF_T(pdata
,0,get_file_size_stat(psbuf
)); /* File size 64 Bit */
4045 SOFF_T(pdata
,0,SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
4048 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
, psbuf
->st_ex_ctime
); /* Change Time 64 Bit */
4049 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
+8, psbuf
->st_ex_atime
); /* Last access time 64 Bit */
4050 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
+16, psbuf
->st_ex_mtime
); /* Last modification time 64 Bit */
4053 SIVAL(pdata
,0,psbuf
->st_ex_uid
); /* user id for the owner */
4057 SIVAL(pdata
,0,psbuf
->st_ex_gid
); /* group id of owner */
4061 SIVAL(pdata
,0,unix_filetype(psbuf
->st_ex_mode
));
4064 if (S_ISBLK(psbuf
->st_ex_mode
) || S_ISCHR(psbuf
->st_ex_mode
)) {
4065 devno
= psbuf
->st_ex_rdev
;
4067 devno
= psbuf
->st_ex_dev
;
4070 SIVAL(pdata
,0,unix_dev_major(devno
)); /* Major device number if type is device */
4074 SIVAL(pdata
,0,unix_dev_minor(devno
)); /* Minor device number if type is device */
4078 SINO_T_VAL(pdata
,0,(SMB_INO_T
)file_index
); /* inode number */
4081 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_ex_mode
)); /* Standard UNIX file permissions */
4085 SIVAL(pdata
,0,psbuf
->st_ex_nlink
); /* number of hard links */
4092 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4093 * the chflags(2) (or equivalent) flags.
4095 * XXX: this really should be behind the VFS interface. To do this, we would
4096 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4097 * Each VFS module could then implement its own mapping as appropriate for the
4098 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4100 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
4104 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
4108 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
4112 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
4116 { UF_HIDDEN
, EXT_HIDDEN
},
4119 /* Do not remove. We need to guarantee that this array has at least one
4120 * entry to build on HP-UX.
4126 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4127 uint32
*smb_fflags
, uint32
*smb_fmask
)
4131 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4132 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
4133 if (psbuf
->st_ex_flags
& info2_flags_map
[i
].stat_fflag
) {
4134 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
4139 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4140 const uint32 smb_fflags
,
4141 const uint32 smb_fmask
,
4144 uint32 max_fmask
= 0;
4147 *stat_fflags
= psbuf
->st_ex_flags
;
4149 /* For each flags requested in smb_fmask, check the state of the
4150 * corresponding flag in smb_fflags and set or clear the matching
4154 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4155 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
4156 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
4157 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
4158 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
4160 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
4165 /* If smb_fmask is asking to set any bits that are not supported by
4166 * our flag mappings, we should fail.
4168 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
4176 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4177 * of file flags and birth (create) time.
4179 static char *store_file_unix_basic_info2(connection_struct
*conn
,
4182 const SMB_STRUCT_STAT
*psbuf
)
4184 uint32 file_flags
= 0;
4185 uint32 flags_mask
= 0;
4187 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4189 /* Create (birth) time 64 bit */
4190 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
, psbuf
->st_ex_btime
);
4193 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
4194 SIVAL(pdata
, 0, file_flags
); /* flags */
4195 SIVAL(pdata
, 4, flags_mask
); /* mask */
4201 static NTSTATUS
marshall_stream_info(unsigned int num_streams
,
4202 const struct stream_struct
*streams
,
4204 unsigned int max_data_bytes
,
4205 unsigned int *data_size
)
4208 unsigned int ofs
= 0;
4210 for (i
= 0; i
< num_streams
; i
++) {
4211 unsigned int next_offset
;
4213 smb_ucs2_t
*namebuf
;
4215 if (!push_ucs2_talloc(talloc_tos(), &namebuf
,
4216 streams
[i
].name
, &namelen
) ||
4219 return NT_STATUS_INVALID_PARAMETER
;
4223 * name_buf is now null-terminated, we need to marshall as not
4230 * We cannot overflow ...
4232 if ((ofs
+ 24 + namelen
) > max_data_bytes
) {
4233 DEBUG(10, ("refusing to overflow reply at stream %u\n",
4235 TALLOC_FREE(namebuf
);
4236 return STATUS_BUFFER_OVERFLOW
;
4239 SIVAL(data
, ofs
+4, namelen
);
4240 SOFF_T(data
, ofs
+8, streams
[i
].size
);
4241 SOFF_T(data
, ofs
+16, streams
[i
].alloc_size
);
4242 memcpy(data
+ofs
+24, namebuf
, namelen
);
4243 TALLOC_FREE(namebuf
);
4245 next_offset
= ofs
+ 24 + namelen
;
4247 if (i
== num_streams
-1) {
4248 SIVAL(data
, ofs
, 0);
4251 unsigned int align
= ndr_align_size(next_offset
, 8);
4253 if ((next_offset
+ align
) > max_data_bytes
) {
4254 DEBUG(10, ("refusing to overflow align "
4255 "reply at stream %u\n",
4257 TALLOC_FREE(namebuf
);
4258 return STATUS_BUFFER_OVERFLOW
;
4261 memset(data
+next_offset
, 0, align
);
4262 next_offset
+= align
;
4264 SIVAL(data
, ofs
, next_offset
- ofs
);
4271 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes
, ofs
));
4275 return NT_STATUS_OK
;
4278 /****************************************************************************
4279 Reply to a TRANSACT2_QFILEINFO on a PIPE !
4280 ****************************************************************************/
4282 static void call_trans2qpipeinfo(connection_struct
*conn
,
4283 struct smb_request
*req
,
4284 unsigned int tran_call
,
4285 char **pparams
, int total_params
,
4286 char **ppdata
, int total_data
,
4287 unsigned int max_data_bytes
)
4289 char *params
= *pparams
;
4290 char *pdata
= *ppdata
;
4291 unsigned int data_size
= 0;
4292 unsigned int param_size
= 2;
4297 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4301 if (total_params
< 4) {
4302 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4306 fsp
= file_fsp(req
, SVAL(params
,0));
4307 if (!fsp_is_np(fsp
)) {
4308 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
4312 info_level
= SVAL(params
,2);
4314 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
4315 if (*pparams
== NULL
) {
4316 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4321 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4322 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4323 if (*ppdata
== NULL
) {
4324 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4329 switch (info_level
) {
4330 case SMB_FILE_STANDARD_INFORMATION
:
4332 SOFF_T(pdata
,0,4096LL);
4339 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
4343 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
4349 NTSTATUS
smbd_do_qfilepathinfo(connection_struct
*conn
,
4350 TALLOC_CTX
*mem_ctx
,
4351 uint16_t info_level
,
4353 struct smb_filename
*smb_fname
,
4354 bool delete_pending
,
4355 struct timespec write_time_ts
,
4356 struct ea_list
*ea_list
,
4357 int lock_data_count
,
4360 unsigned int max_data_bytes
,
4362 unsigned int *pdata_size
)
4364 char *pdata
= *ppdata
;
4365 char *dstart
, *dend
;
4366 unsigned int data_size
;
4367 struct timespec create_time_ts
, mtime_ts
, atime_ts
, ctime_ts
;
4368 time_t create_time
, mtime
, atime
, c_time
;
4369 SMB_STRUCT_STAT
*psbuf
= &smb_fname
->st
;
4376 uint64_t file_size
= 0;
4378 uint64_t allocation_size
= 0;
4379 uint64_t file_index
= 0;
4380 uint32_t access_mask
= 0;
4382 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
4383 return NT_STATUS_INVALID_LEVEL
;
4386 DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
4387 smb_fname_str_dbg(smb_fname
),
4389 info_level
, max_data_bytes
));
4391 mode
= dos_mode(conn
, smb_fname
);
4392 nlink
= psbuf
->st_ex_nlink
;
4394 if (nlink
&& (mode
&FILE_ATTRIBUTE_DIRECTORY
)) {
4398 if ((nlink
> 0) && delete_pending
) {
4402 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4403 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4404 if (*ppdata
== NULL
) {
4405 return NT_STATUS_NO_MEMORY
;
4409 dend
= dstart
+ data_size
- 1;
4411 if (!null_timespec(write_time_ts
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
4412 update_stat_ex_mtime(psbuf
, write_time_ts
);
4415 create_time_ts
= get_create_timespec(conn
, fsp
, smb_fname
);
4416 mtime_ts
= psbuf
->st_ex_mtime
;
4417 atime_ts
= psbuf
->st_ex_atime
;
4418 ctime_ts
= get_change_timespec(conn
, fsp
, smb_fname
);
4420 if (lp_dos_filetime_resolution(SNUM(conn
))) {
4421 dos_filetime_timespec(&create_time_ts
);
4422 dos_filetime_timespec(&mtime_ts
);
4423 dos_filetime_timespec(&atime_ts
);
4424 dos_filetime_timespec(&ctime_ts
);
4427 create_time
= convert_timespec_to_time_t(create_time_ts
);
4428 mtime
= convert_timespec_to_time_t(mtime_ts
);
4429 atime
= convert_timespec_to_time_t(atime_ts
);
4430 c_time
= convert_timespec_to_time_t(ctime_ts
);
4432 p
= strrchr_m(smb_fname
->base_name
,'/');
4434 base_name
= smb_fname
->base_name
;
4438 /* NT expects the name to be in an exact form of the *full*
4439 filename. See the trans2 torture test */
4440 if (ISDOT(base_name
)) {
4441 dos_fname
= talloc_strdup(mem_ctx
, "\\");
4443 return NT_STATUS_NO_MEMORY
;
4446 dos_fname
= talloc_asprintf(mem_ctx
,
4448 smb_fname
->base_name
);
4450 return NT_STATUS_NO_MEMORY
;
4452 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4453 dos_fname
= talloc_asprintf(dos_fname
, "%s",
4454 smb_fname
->stream_name
);
4456 return NT_STATUS_NO_MEMORY
;
4460 string_replace(dos_fname
, '/', '\\');
4463 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, psbuf
);
4466 /* Do we have this path open ? */
4468 struct file_id fileid
= vfs_file_id_from_sbuf(conn
, psbuf
);
4469 fsp1
= file_find_di_first(conn
->sconn
, fileid
);
4470 if (fsp1
&& fsp1
->initial_allocation_size
) {
4471 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp1
, psbuf
);
4475 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
4476 file_size
= get_file_size_stat(psbuf
);
4480 pos
= fsp
->fh
->position_information
;
4484 access_mask
= fsp
->access_mask
;
4486 /* GENERIC_EXECUTE mapping from Windows */
4487 access_mask
= 0x12019F;
4490 /* This should be an index number - looks like
4493 I think this causes us to fail the IFSKIT
4494 BasicFileInformationTest. -tpot */
4495 file_index
= get_FileIndex(conn
, psbuf
);
4497 switch (info_level
) {
4498 case SMB_INFO_STANDARD
:
4499 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4501 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
4502 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
4503 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
4504 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
4505 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
4506 SSVAL(pdata
,l1_attrFile
,mode
);
4509 case SMB_INFO_QUERY_EA_SIZE
:
4511 unsigned int ea_size
=
4512 estimate_ea_size(conn
, fsp
,
4514 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4516 srv_put_dos_date2(pdata
,0,create_time
);
4517 srv_put_dos_date2(pdata
,4,atime
);
4518 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
4519 SIVAL(pdata
,12,(uint32
)file_size
);
4520 SIVAL(pdata
,16,(uint32
)allocation_size
);
4521 SSVAL(pdata
,20,mode
);
4522 SIVAL(pdata
,22,ea_size
);
4526 case SMB_INFO_IS_NAME_VALID
:
4527 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4529 /* os/2 needs this ? really ?*/
4530 return NT_STATUS_DOS(ERRDOS
, ERRbadfunc
);
4532 /* This is only reached for qpathinfo */
4536 case SMB_INFO_QUERY_EAS_FROM_LIST
:
4538 size_t total_ea_len
= 0;
4539 struct ea_list
*ea_file_list
= NULL
;
4540 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4543 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4545 &total_ea_len
, &ea_file_list
);
4546 if (!NT_STATUS_IS_OK(status
)) {
4550 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
4552 if (!ea_list
|| (total_ea_len
> data_size
)) {
4554 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4558 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4562 case SMB_INFO_QUERY_ALL_EAS
:
4564 /* We have data_size bytes to put EA's into. */
4565 size_t total_ea_len
= 0;
4566 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4568 status
= get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4570 &total_ea_len
, &ea_list
);
4571 if (!NT_STATUS_IS_OK(status
)) {
4575 if (!ea_list
|| (total_ea_len
> data_size
)) {
4577 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4581 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4585 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4587 /* This is FileFullEaInformation - 0xF which maps to
4588 * 1015 (decimal) in smbd_do_setfilepathinfo. */
4590 /* We have data_size bytes to put EA's into. */
4591 size_t total_ea_len
= 0;
4592 struct ea_list
*ea_file_list
= NULL
;
4594 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4596 /*TODO: add filtering and index handling */
4599 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4601 &total_ea_len
, &ea_file_list
);
4602 if (!NT_STATUS_IS_OK(status
)) {
4605 if (!ea_file_list
) {
4606 return NT_STATUS_NO_EAS_ON_FILE
;
4609 status
= fill_ea_chained_buffer(mem_ctx
,
4613 conn
, ea_file_list
);
4614 if (!NT_STATUS_IS_OK(status
)) {
4620 case SMB_FILE_BASIC_INFORMATION
:
4621 case SMB_QUERY_FILE_BASIC_INFO
:
4623 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
4624 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4625 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
4627 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4631 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4632 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4633 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4634 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4635 SIVAL(pdata
,32,mode
);
4637 DEBUG(5,("SMB_QFBI - "));
4638 DEBUG(5,("create: %s ", ctime(&create_time
)));
4639 DEBUG(5,("access: %s ", ctime(&atime
)));
4640 DEBUG(5,("write: %s ", ctime(&mtime
)));
4641 DEBUG(5,("change: %s ", ctime(&c_time
)));
4642 DEBUG(5,("mode: %x\n", mode
));
4645 case SMB_FILE_STANDARD_INFORMATION
:
4646 case SMB_QUERY_FILE_STANDARD_INFO
:
4648 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4650 SOFF_T(pdata
,0,allocation_size
);
4651 SOFF_T(pdata
,8,file_size
);
4652 SIVAL(pdata
,16,nlink
);
4653 SCVAL(pdata
,20,delete_pending
?1:0);
4654 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4655 SSVAL(pdata
,22,0); /* Padding. */
4658 case SMB_FILE_EA_INFORMATION
:
4659 case SMB_QUERY_FILE_EA_INFO
:
4661 unsigned int ea_size
=
4662 estimate_ea_size(conn
, fsp
, smb_fname
);
4663 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4665 SIVAL(pdata
,0,ea_size
);
4669 /* Get the 8.3 name - used if NT SMB was negotiated. */
4670 case SMB_QUERY_FILE_ALT_NAME_INFO
:
4671 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
4674 char mangled_name
[13];
4675 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4676 if (!name_to_8_3(base_name
,mangled_name
,
4677 True
,conn
->params
)) {
4678 return NT_STATUS_NO_MEMORY
;
4680 len
= srvstr_push(dstart
, flags2
,
4681 pdata
+4, mangled_name
,
4682 PTR_DIFF(dend
, pdata
+4),
4684 data_size
= 4 + len
;
4689 case SMB_QUERY_FILE_NAME_INFO
:
4693 this must be *exactly* right for ACLs on mapped drives to work
4695 len
= srvstr_push(dstart
, flags2
,
4697 PTR_DIFF(dend
, pdata
+4),
4699 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4700 data_size
= 4 + len
;
4705 case SMB_FILE_ALLOCATION_INFORMATION
:
4706 case SMB_QUERY_FILE_ALLOCATION_INFO
:
4707 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4709 SOFF_T(pdata
,0,allocation_size
);
4712 case SMB_FILE_END_OF_FILE_INFORMATION
:
4713 case SMB_QUERY_FILE_END_OF_FILEINFO
:
4714 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4716 SOFF_T(pdata
,0,file_size
);
4719 case SMB_QUERY_FILE_ALL_INFO
:
4720 case SMB_FILE_ALL_INFORMATION
:
4723 unsigned int ea_size
=
4724 estimate_ea_size(conn
, fsp
, smb_fname
);
4725 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4726 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4727 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4728 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4729 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4730 SIVAL(pdata
,32,mode
);
4731 SIVAL(pdata
,36,0); /* padding. */
4733 SOFF_T(pdata
,0,allocation_size
);
4734 SOFF_T(pdata
,8,file_size
);
4735 SIVAL(pdata
,16,nlink
);
4736 SCVAL(pdata
,20,delete_pending
);
4737 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4740 SIVAL(pdata
,0,ea_size
);
4741 pdata
+= 4; /* EA info */
4742 len
= srvstr_push(dstart
, flags2
,
4744 PTR_DIFF(dend
, pdata
+4),
4748 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4752 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4755 unsigned int ea_size
=
4756 estimate_ea_size(conn
, fsp
, smb_fname
);
4757 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4758 put_long_date_timespec(conn
->ts_res
,pdata
+0x00,create_time_ts
);
4759 put_long_date_timespec(conn
->ts_res
,pdata
+0x08,atime_ts
);
4760 put_long_date_timespec(conn
->ts_res
,pdata
+0x10,mtime_ts
); /* write time */
4761 put_long_date_timespec(conn
->ts_res
,pdata
+0x18,ctime_ts
); /* change time */
4762 SIVAL(pdata
, 0x20, mode
);
4763 SIVAL(pdata
, 0x24, 0); /* padding. */
4764 SBVAL(pdata
, 0x28, allocation_size
);
4765 SBVAL(pdata
, 0x30, file_size
);
4766 SIVAL(pdata
, 0x38, nlink
);
4767 SCVAL(pdata
, 0x3C, delete_pending
);
4768 SCVAL(pdata
, 0x3D, (mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4769 SSVAL(pdata
, 0x3E, 0); /* padding */
4770 SBVAL(pdata
, 0x40, file_index
);
4771 SIVAL(pdata
, 0x48, ea_size
);
4772 SIVAL(pdata
, 0x4C, access_mask
);
4773 SBVAL(pdata
, 0x50, pos
);
4774 SIVAL(pdata
, 0x58, mode
); /*TODO: mode != mode fix this!!! */
4775 SIVAL(pdata
, 0x5C, 0); /* No alignment needed. */
4779 len
= srvstr_push(dstart
, flags2
,
4781 PTR_DIFF(dend
, pdata
+4),
4785 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4788 case SMB_FILE_INTERNAL_INFORMATION
:
4790 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4791 SBVAL(pdata
, 0, file_index
);
4795 case SMB_FILE_ACCESS_INFORMATION
:
4796 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4797 SIVAL(pdata
, 0, access_mask
);
4801 case SMB_FILE_NAME_INFORMATION
:
4802 /* Pathname with leading '\'. */
4805 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
4806 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4807 SIVAL(pdata
,0,byte_len
);
4808 data_size
= 4 + byte_len
;
4812 case SMB_FILE_DISPOSITION_INFORMATION
:
4813 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4815 SCVAL(pdata
,0,delete_pending
);
4818 case SMB_FILE_POSITION_INFORMATION
:
4819 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4821 SOFF_T(pdata
,0,pos
);
4824 case SMB_FILE_MODE_INFORMATION
:
4825 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4826 SIVAL(pdata
,0,mode
);
4830 case SMB_FILE_ALIGNMENT_INFORMATION
:
4831 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4832 SIVAL(pdata
,0,0); /* No alignment needed. */
4837 * NT4 server just returns "invalid query" to this - if we try
4838 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4841 /* The first statement above is false - verified using Thursby
4842 * client against NT4 -- gcolley.
4844 case SMB_QUERY_FILE_STREAM_INFO
:
4845 case SMB_FILE_STREAM_INFORMATION
: {
4846 unsigned int num_streams
= 0;
4847 struct stream_struct
*streams
= NULL
;
4849 DEBUG(10,("smbd_do_qfilepathinfo: "
4850 "SMB_FILE_STREAM_INFORMATION\n"));
4852 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4853 return NT_STATUS_INVALID_PARAMETER
;
4856 status
= vfs_streaminfo(conn
, fsp
, smb_fname
->base_name
,
4857 talloc_tos(), &num_streams
, &streams
);
4859 if (!NT_STATUS_IS_OK(status
)) {
4860 DEBUG(10, ("could not get stream info: %s\n",
4861 nt_errstr(status
)));
4865 status
= marshall_stream_info(num_streams
, streams
,
4866 pdata
, max_data_bytes
,
4869 if (!NT_STATUS_IS_OK(status
)) {
4870 DEBUG(10, ("marshall_stream_info failed: %s\n",
4871 nt_errstr(status
)));
4872 TALLOC_FREE(streams
);
4876 TALLOC_FREE(streams
);
4880 case SMB_QUERY_COMPRESSION_INFO
:
4881 case SMB_FILE_COMPRESSION_INFORMATION
:
4882 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4883 SOFF_T(pdata
,0,file_size
);
4884 SIVAL(pdata
,8,0); /* ??? */
4885 SIVAL(pdata
,12,0); /* ??? */
4889 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
4890 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4891 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4892 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4893 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4894 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4895 SOFF_T(pdata
,32,allocation_size
);
4896 SOFF_T(pdata
,40,file_size
);
4897 SIVAL(pdata
,48,mode
);
4898 SIVAL(pdata
,52,0); /* ??? */
4902 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
4903 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4904 SIVAL(pdata
,0,mode
);
4910 * CIFS UNIX Extensions.
4913 case SMB_QUERY_FILE_UNIX_BASIC
:
4915 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4916 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4918 DEBUG(4,("smbd_do_qfilepathinfo: "
4919 "SMB_QUERY_FILE_UNIX_BASIC\n"));
4920 dump_data(4, (uint8_t *)(*ppdata
), data_size
);
4924 case SMB_QUERY_FILE_UNIX_INFO2
:
4926 pdata
= store_file_unix_basic_info2(conn
, pdata
, fsp
, psbuf
);
4927 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4931 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4933 for (i
=0; i
<100; i
++)
4934 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
4940 case SMB_QUERY_FILE_UNIX_LINK
:
4943 char *buffer
= talloc_array(mem_ctx
, char, PATH_MAX
+1);
4946 return NT_STATUS_NO_MEMORY
;
4949 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4951 if(!S_ISLNK(psbuf
->st_ex_mode
)) {
4952 return NT_STATUS_DOS(ERRSRV
, ERRbadlink
);
4955 return NT_STATUS_DOS(ERRDOS
, ERRbadlink
);
4957 len
= SMB_VFS_READLINK(conn
,
4958 smb_fname
->base_name
,
4961 return map_nt_error_from_unix(errno
);
4964 len
= srvstr_push(dstart
, flags2
,
4966 PTR_DIFF(dend
, pdata
),
4969 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4974 #if defined(HAVE_POSIX_ACLS)
4975 case SMB_QUERY_POSIX_ACL
:
4977 SMB_ACL_T file_acl
= NULL
;
4978 SMB_ACL_T def_acl
= NULL
;
4979 uint16 num_file_acls
= 0;
4980 uint16 num_def_acls
= 0;
4982 if (fsp
&& fsp
->fh
->fd
!= -1) {
4983 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
,
4987 SMB_VFS_SYS_ACL_GET_FILE(conn
,
4988 smb_fname
->base_name
,
4989 SMB_ACL_TYPE_ACCESS
,
4993 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
4994 DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4995 "not implemented on "
4996 "filesystem containing %s\n",
4997 smb_fname
->base_name
));
4998 return NT_STATUS_NOT_IMPLEMENTED
;
5001 if (S_ISDIR(psbuf
->st_ex_mode
)) {
5002 if (fsp
&& fsp
->is_directory
) {
5004 SMB_VFS_SYS_ACL_GET_FILE(
5006 fsp
->fsp_name
->base_name
,
5007 SMB_ACL_TYPE_DEFAULT
,
5011 SMB_VFS_SYS_ACL_GET_FILE(
5013 smb_fname
->base_name
,
5014 SMB_ACL_TYPE_DEFAULT
,
5017 def_acl
= free_empty_sys_acl(conn
, def_acl
);
5020 num_file_acls
= count_acl_entries(conn
, file_acl
);
5021 num_def_acls
= count_acl_entries(conn
, def_acl
);
5023 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
5024 DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
5026 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
5027 SMB_POSIX_ACL_HEADER_SIZE
) ));
5029 TALLOC_FREE(file_acl
);
5032 TALLOC_FREE(def_acl
);
5034 return NT_STATUS_BUFFER_TOO_SMALL
;
5037 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
5038 SSVAL(pdata
,2,num_file_acls
);
5039 SSVAL(pdata
,4,num_def_acls
);
5040 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, psbuf
, file_acl
)) {
5042 TALLOC_FREE(file_acl
);
5045 TALLOC_FREE(def_acl
);
5047 return NT_STATUS_INTERNAL_ERROR
;
5049 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), psbuf
, def_acl
)) {
5051 TALLOC_FREE(file_acl
);
5054 TALLOC_FREE(def_acl
);
5056 return NT_STATUS_INTERNAL_ERROR
;
5060 TALLOC_FREE(file_acl
);
5063 TALLOC_FREE(def_acl
);
5065 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
5071 case SMB_QUERY_POSIX_LOCK
:
5076 enum brl_type lock_type
;
5078 /* We need an open file with a real fd for this. */
5079 if (!fsp
|| fsp
->fh
->fd
== -1) {
5080 return NT_STATUS_INVALID_LEVEL
;
5083 if (lock_data_count
!= POSIX_LOCK_DATA_SIZE
) {
5084 return NT_STATUS_INVALID_PARAMETER
;
5087 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
5088 case POSIX_LOCK_TYPE_READ
:
5089 lock_type
= READ_LOCK
;
5091 case POSIX_LOCK_TYPE_WRITE
:
5092 lock_type
= WRITE_LOCK
;
5094 case POSIX_LOCK_TYPE_UNLOCK
:
5096 /* There's no point in asking for an unlock... */
5097 return NT_STATUS_INVALID_PARAMETER
;
5100 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
5101 #if defined(HAVE_LONGLONG)
5102 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
5103 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
5104 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
5105 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
5106 #else /* HAVE_LONGLONG */
5107 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
5108 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
5109 #endif /* HAVE_LONGLONG */
5111 status
= query_lock(fsp
,
5118 if (ERROR_WAS_LOCK_DENIED(status
)) {
5119 /* Here we need to report who has it locked... */
5120 data_size
= POSIX_LOCK_DATA_SIZE
;
5122 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, lock_type
);
5123 SSVAL(pdata
, POSIX_LOCK_FLAGS_OFFSET
, 0);
5124 SIVAL(pdata
, POSIX_LOCK_PID_OFFSET
, (uint32_t)smblctx
);
5125 #if defined(HAVE_LONGLONG)
5126 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, (uint32
)(offset
& 0xFFFFFFFF));
5127 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
+ 4, (uint32
)((offset
>> 32) & 0xFFFFFFFF));
5128 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, (uint32
)(count
& 0xFFFFFFFF));
5129 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
+ 4, (uint32
)((count
>> 32) & 0xFFFFFFFF));
5130 #else /* HAVE_LONGLONG */
5131 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, offset
);
5132 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, count
);
5133 #endif /* HAVE_LONGLONG */
5135 } else if (NT_STATUS_IS_OK(status
)) {
5136 /* For success we just return a copy of what we sent
5137 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5138 data_size
= POSIX_LOCK_DATA_SIZE
;
5139 memcpy(pdata
, lock_data
, POSIX_LOCK_DATA_SIZE
);
5140 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
5148 return NT_STATUS_INVALID_LEVEL
;
5151 *pdata_size
= data_size
;
5152 return NT_STATUS_OK
;
5155 /****************************************************************************
5156 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5157 file name or file id).
5158 ****************************************************************************/
5160 static void call_trans2qfilepathinfo(connection_struct
*conn
,
5161 struct smb_request
*req
,
5162 unsigned int tran_call
,
5163 char **pparams
, int total_params
,
5164 char **ppdata
, int total_data
,
5165 unsigned int max_data_bytes
)
5167 char *params
= *pparams
;
5168 char *pdata
= *ppdata
;
5170 unsigned int data_size
= 0;
5171 unsigned int param_size
= 2;
5172 struct smb_filename
*smb_fname
= NULL
;
5173 bool delete_pending
= False
;
5174 struct timespec write_time_ts
;
5175 files_struct
*fsp
= NULL
;
5176 struct file_id fileid
;
5177 struct ea_list
*ea_list
= NULL
;
5178 int lock_data_count
= 0;
5179 char *lock_data
= NULL
;
5180 NTSTATUS status
= NT_STATUS_OK
;
5183 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5187 ZERO_STRUCT(write_time_ts
);
5189 if (tran_call
== TRANSACT2_QFILEINFO
) {
5190 if (total_params
< 4) {
5191 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5196 call_trans2qpipeinfo(conn
, req
, tran_call
,
5197 pparams
, total_params
,
5203 fsp
= file_fsp(req
, SVAL(params
,0));
5204 info_level
= SVAL(params
,2);
5206 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
5208 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
5209 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5213 /* Initial check for valid fsp ptr. */
5214 if (!check_fsp_open(conn
, req
, fsp
)) {
5218 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
5220 if (!NT_STATUS_IS_OK(status
)) {
5221 reply_nterror(req
, status
);
5225 if(fsp
->fake_file_handle
) {
5227 * This is actually for the QUOTA_FAKE_FILE --metze
5230 /* We know this name is ok, it's already passed the checks. */
5232 } else if(fsp
->fh
->fd
== -1) {
5234 * This is actually a QFILEINFO on a directory
5235 * handle (returned from an NT SMB). NT5.0 seems
5236 * to do this call. JRA.
5239 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5240 /* Always do lstat for UNIX calls. */
5241 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5242 DEBUG(3,("call_trans2qfilepathinfo: "
5243 "SMB_VFS_LSTAT of %s failed "
5245 smb_fname_str_dbg(smb_fname
),
5248 map_nt_error_from_unix(errno
));
5251 } else if (SMB_VFS_STAT(conn
, smb_fname
)) {
5252 DEBUG(3,("call_trans2qfilepathinfo: "
5253 "SMB_VFS_STAT of %s failed (%s)\n",
5254 smb_fname_str_dbg(smb_fname
),
5257 map_nt_error_from_unix(errno
));
5261 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5262 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5265 * Original code - this is an open file.
5267 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
5268 DEBUG(3, ("fstat of %s failed (%s)\n",
5269 fsp_fnum_dbg(fsp
), strerror(errno
)));
5271 map_nt_error_from_unix(errno
));
5274 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5275 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5281 uint32_t ucf_flags
= 0;
5284 if (total_params
< 7) {
5285 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5289 info_level
= SVAL(params
,0);
5291 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
5293 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5294 if (!lp_unix_extensions()) {
5295 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5298 if (info_level
== SMB_QUERY_FILE_UNIX_BASIC
||
5299 info_level
== SMB_QUERY_FILE_UNIX_INFO2
||
5300 info_level
== SMB_QUERY_FILE_UNIX_LINK
) {
5301 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
5305 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
5307 STR_TERMINATE
, &status
);
5308 if (!NT_STATUS_IS_OK(status
)) {
5309 reply_nterror(req
, status
);
5313 status
= filename_convert(req
,
5315 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5320 if (!NT_STATUS_IS_OK(status
)) {
5321 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5322 reply_botherror(req
,
5323 NT_STATUS_PATH_NOT_COVERED
,
5324 ERRSRV
, ERRbadpath
);
5327 reply_nterror(req
, status
);
5331 /* If this is a stream, check if there is a delete_pending. */
5332 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5333 && is_ntfs_stream_smb_fname(smb_fname
)) {
5334 struct smb_filename
*smb_fname_base
= NULL
;
5336 /* Create an smb_filename with stream_name == NULL. */
5338 create_synthetic_smb_fname(talloc_tos(),
5339 smb_fname
->base_name
,
5342 if (!NT_STATUS_IS_OK(status
)) {
5343 reply_nterror(req
, status
);
5347 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5348 /* Always do lstat for UNIX calls. */
5349 if (SMB_VFS_LSTAT(conn
, smb_fname_base
) != 0) {
5350 DEBUG(3,("call_trans2qfilepathinfo: "
5351 "SMB_VFS_LSTAT of %s failed "
5353 smb_fname_str_dbg(smb_fname_base
),
5355 TALLOC_FREE(smb_fname_base
);
5357 map_nt_error_from_unix(errno
));
5361 if (SMB_VFS_STAT(conn
, smb_fname_base
) != 0) {
5362 DEBUG(3,("call_trans2qfilepathinfo: "
5363 "fileinfo of %s failed "
5365 smb_fname_str_dbg(smb_fname_base
),
5367 TALLOC_FREE(smb_fname_base
);
5369 map_nt_error_from_unix(errno
));
5374 status
= file_name_hash(conn
,
5375 smb_fname_str_dbg(smb_fname_base
),
5377 if (!NT_STATUS_IS_OK(status
)) {
5378 TALLOC_FREE(smb_fname_base
);
5379 reply_nterror(req
, status
);
5383 fileid
= vfs_file_id_from_sbuf(conn
,
5384 &smb_fname_base
->st
);
5385 TALLOC_FREE(smb_fname_base
);
5386 get_file_infos(fileid
, name_hash
, &delete_pending
, NULL
);
5387 if (delete_pending
) {
5388 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5393 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5394 /* Always do lstat for UNIX calls. */
5395 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5396 DEBUG(3,("call_trans2qfilepathinfo: "
5397 "SMB_VFS_LSTAT of %s failed (%s)\n",
5398 smb_fname_str_dbg(smb_fname
),
5401 map_nt_error_from_unix(errno
));
5406 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
5407 DEBUG(3,("call_trans2qfilepathinfo: "
5408 "SMB_VFS_STAT of %s failed (%s)\n",
5409 smb_fname_str_dbg(smb_fname
),
5412 map_nt_error_from_unix(errno
));
5417 status
= file_name_hash(conn
,
5418 smb_fname_str_dbg(smb_fname
),
5420 if (!NT_STATUS_IS_OK(status
)) {
5421 reply_nterror(req
, status
);
5425 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5426 get_file_infos(fileid
, name_hash
, &delete_pending
, &write_time_ts
);
5427 if (delete_pending
) {
5428 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5433 DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
5434 "total_data=%d\n", smb_fname_str_dbg(smb_fname
),
5436 info_level
,tran_call
,total_data
));
5438 /* Pull out any data sent here before we realloc. */
5439 switch (info_level
) {
5440 case SMB_INFO_QUERY_EAS_FROM_LIST
:
5442 /* Pull any EA list from the data portion. */
5445 if (total_data
< 4) {
5447 req
, NT_STATUS_INVALID_PARAMETER
);
5450 ea_size
= IVAL(pdata
,0);
5452 if (total_data
> 0 && ea_size
!= total_data
) {
5453 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5454 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
5456 req
, NT_STATUS_INVALID_PARAMETER
);
5460 if (!lp_ea_support(SNUM(conn
))) {
5461 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
5465 /* Pull out the list of names. */
5466 ea_list
= read_ea_name_list(req
, pdata
+ 4, ea_size
- 4);
5469 req
, NT_STATUS_INVALID_PARAMETER
);
5475 case SMB_QUERY_POSIX_LOCK
:
5477 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
5478 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
5482 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
5484 req
, NT_STATUS_INVALID_PARAMETER
);
5488 /* Copy the lock range data. */
5489 lock_data
= (char *)talloc_memdup(
5490 req
, pdata
, total_data
);
5492 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5495 lock_data_count
= total_data
;
5501 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
5502 if (*pparams
== NULL
) {
5503 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5510 * draft-leach-cifs-v1-spec-02.txt
5511 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5514 * The requested information is placed in the Data portion of the
5515 * transaction response. For the information levels greater than 0x100,
5516 * the transaction response has 1 parameter word which should be
5517 * ignored by the client.
5519 * However Windows only follows this rule for the IS_NAME_VALID call.
5521 switch (info_level
) {
5522 case SMB_INFO_IS_NAME_VALID
:
5527 if ((info_level
& 0xFF00) == 0xFF00) {
5529 * We use levels that start with 0xFF00
5530 * internally to represent SMB2 specific levels
5532 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5536 status
= smbd_do_qfilepathinfo(conn
, req
, info_level
,
5538 delete_pending
, write_time_ts
,
5540 lock_data_count
, lock_data
,
5541 req
->flags2
, max_data_bytes
,
5542 ppdata
, &data_size
);
5543 if (!NT_STATUS_IS_OK(status
)) {
5544 reply_nterror(req
, status
);
5548 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
5554 /****************************************************************************
5555 Set a hard link (called by UNIX extensions and by NT rename with HARD link
5557 ****************************************************************************/
5559 NTSTATUS
hardlink_internals(TALLOC_CTX
*ctx
,
5560 connection_struct
*conn
,
5561 struct smb_request
*req
,
5562 bool overwrite_if_exists
,
5563 const struct smb_filename
*smb_fname_old
,
5564 struct smb_filename
*smb_fname_new
)
5566 NTSTATUS status
= NT_STATUS_OK
;
5568 /* source must already exist. */
5569 if (!VALID_STAT(smb_fname_old
->st
)) {
5570 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5573 if (VALID_STAT(smb_fname_new
->st
)) {
5574 if (overwrite_if_exists
) {
5575 if (S_ISDIR(smb_fname_new
->st
.st_ex_mode
)) {
5576 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5578 status
= unlink_internals(conn
,
5580 FILE_ATTRIBUTE_NORMAL
,
5583 if (!NT_STATUS_IS_OK(status
)) {
5587 /* Disallow if newname already exists. */
5588 return NT_STATUS_OBJECT_NAME_COLLISION
;
5592 /* No links from a directory. */
5593 if (S_ISDIR(smb_fname_old
->st
.st_ex_mode
)) {
5594 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5597 /* Setting a hardlink to/from a stream isn't currently supported. */
5598 if (is_ntfs_stream_smb_fname(smb_fname_old
) ||
5599 is_ntfs_stream_smb_fname(smb_fname_new
)) {
5600 return NT_STATUS_INVALID_PARAMETER
;
5603 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5604 smb_fname_old
->base_name
, smb_fname_new
->base_name
));
5606 if (SMB_VFS_LINK(conn
, smb_fname_old
->base_name
,
5607 smb_fname_new
->base_name
) != 0) {
5608 status
= map_nt_error_from_unix(errno
);
5609 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5610 nt_errstr(status
), smb_fname_old
->base_name
,
5611 smb_fname_new
->base_name
));
5616 /****************************************************************************
5617 Deal with setting the time from any of the setfilepathinfo functions.
5618 NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
5619 calling this function.
5620 ****************************************************************************/
5622 NTSTATUS
smb_set_file_time(connection_struct
*conn
,
5624 const struct smb_filename
*smb_fname
,
5625 struct smb_file_time
*ft
,
5626 bool setting_write_time
)
5628 struct smb_filename smb_fname_base
;
5630 FILE_NOTIFY_CHANGE_LAST_ACCESS
5631 |FILE_NOTIFY_CHANGE_LAST_WRITE
5632 |FILE_NOTIFY_CHANGE_CREATION
;
5634 if (!VALID_STAT(smb_fname
->st
)) {
5635 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5638 /* get some defaults (no modifications) if any info is zero or -1. */
5639 if (null_timespec(ft
->create_time
)) {
5640 action
&= ~FILE_NOTIFY_CHANGE_CREATION
;
5643 if (null_timespec(ft
->atime
)) {
5644 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
5647 if (null_timespec(ft
->mtime
)) {
5648 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5651 if (!setting_write_time
) {
5652 /* ft->mtime comes from change time, not write time. */
5653 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5656 /* Ensure the resolution is the correct for
5657 * what we can store on this filesystem. */
5659 round_timespec(conn
->ts_res
, &ft
->create_time
);
5660 round_timespec(conn
->ts_res
, &ft
->ctime
);
5661 round_timespec(conn
->ts_res
, &ft
->atime
);
5662 round_timespec(conn
->ts_res
, &ft
->mtime
);
5664 DEBUG(5,("smb_set_filetime: actime: %s\n ",
5665 time_to_asc(convert_timespec_to_time_t(ft
->atime
))));
5666 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5667 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5668 DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5669 time_to_asc(convert_timespec_to_time_t(ft
->ctime
))));
5670 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5671 time_to_asc(convert_timespec_to_time_t(ft
->create_time
))));
5673 if (setting_write_time
) {
5675 * This was a Windows setfileinfo on an open file.
5676 * NT does this a lot. We also need to
5677 * set the time here, as it can be read by
5678 * FindFirst/FindNext and with the patch for bug #2045
5679 * in smbd/fileio.c it ensures that this timestamp is
5680 * kept sticky even after a write. We save the request
5681 * away and will set it on file close and after a write. JRA.
5684 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5685 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5688 if (fsp
->base_fsp
) {
5689 set_sticky_write_time_fsp(fsp
->base_fsp
,
5692 set_sticky_write_time_fsp(fsp
, ft
->mtime
);
5695 set_sticky_write_time_path(
5696 vfs_file_id_from_sbuf(conn
, &smb_fname
->st
),
5701 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5703 /* Always call ntimes on the base, even if a stream was passed in. */
5704 smb_fname_base
= *smb_fname
;
5705 smb_fname_base
.stream_name
= NULL
;
5707 if(file_ntimes(conn
, &smb_fname_base
, ft
)!=0) {
5708 return map_nt_error_from_unix(errno
);
5711 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
,
5712 smb_fname
->base_name
);
5713 return NT_STATUS_OK
;
5716 /****************************************************************************
5717 Deal with setting the dosmode from any of the setfilepathinfo functions.
5718 NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
5719 done before calling this function.
5720 ****************************************************************************/
5722 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
5723 const struct smb_filename
*smb_fname
,
5726 struct smb_filename
*smb_fname_base
= NULL
;
5729 if (!VALID_STAT(smb_fname
->st
)) {
5730 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5733 /* Always operate on the base_name, even if a stream was passed in. */
5734 status
= create_synthetic_smb_fname(talloc_tos(), smb_fname
->base_name
,
5735 NULL
, &smb_fname
->st
,
5737 if (!NT_STATUS_IS_OK(status
)) {
5742 if (S_ISDIR(smb_fname_base
->st
.st_ex_mode
)) {
5743 dosmode
|= FILE_ATTRIBUTE_DIRECTORY
;
5745 dosmode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
5749 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode
));
5751 /* check the mode isn't different, before changing it */
5752 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, smb_fname_base
))) {
5753 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5754 "0x%x\n", smb_fname_str_dbg(smb_fname_base
),
5755 (unsigned int)dosmode
));
5757 if(file_set_dosmode(conn
, smb_fname_base
, dosmode
, NULL
,
5759 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5761 smb_fname_str_dbg(smb_fname_base
),
5763 status
= map_nt_error_from_unix(errno
);
5767 status
= NT_STATUS_OK
;
5769 TALLOC_FREE(smb_fname_base
);
5773 /****************************************************************************
5774 Deal with setting the size from any of the setfilepathinfo functions.
5775 ****************************************************************************/
5777 static NTSTATUS
smb_set_file_size(connection_struct
*conn
,
5778 struct smb_request
*req
,
5780 const struct smb_filename
*smb_fname
,
5781 const SMB_STRUCT_STAT
*psbuf
,
5783 bool fail_after_createfile
)
5785 NTSTATUS status
= NT_STATUS_OK
;
5786 struct smb_filename
*smb_fname_tmp
= NULL
;
5787 files_struct
*new_fsp
= NULL
;
5789 if (!VALID_STAT(*psbuf
)) {
5790 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5793 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size
));
5795 if (size
== get_file_size_stat(psbuf
)) {
5796 return NT_STATUS_OK
;
5799 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5800 smb_fname_str_dbg(smb_fname
), (double)size
));
5802 if (fsp
&& fsp
->fh
->fd
!= -1) {
5803 /* Handle based call. */
5804 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
5805 return NT_STATUS_ACCESS_DENIED
;
5808 if (vfs_set_filelen(fsp
, size
) == -1) {
5809 return map_nt_error_from_unix(errno
);
5811 trigger_write_time_update_immediate(fsp
);
5812 return NT_STATUS_OK
;
5815 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
5816 if (!NT_STATUS_IS_OK(status
)) {
5820 smb_fname_tmp
->st
= *psbuf
;
5822 status
= SMB_VFS_CREATE_FILE(
5825 0, /* root_dir_fid */
5826 smb_fname_tmp
, /* fname */
5827 FILE_WRITE_DATA
, /* access_mask */
5828 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5830 FILE_OPEN
, /* create_disposition*/
5831 0, /* create_options */
5832 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5833 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
5834 0, /* allocation_size */
5835 0, /* private_flags */
5838 &new_fsp
, /* result */
5841 TALLOC_FREE(smb_fname_tmp
);
5843 if (!NT_STATUS_IS_OK(status
)) {
5844 /* NB. We check for open_was_deferred in the caller. */
5848 /* See RAW-SFILEINFO-END-OF-FILE */
5849 if (fail_after_createfile
) {
5850 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5851 return NT_STATUS_INVALID_LEVEL
;
5854 if (vfs_set_filelen(new_fsp
, size
) == -1) {
5855 status
= map_nt_error_from_unix(errno
);
5856 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5860 trigger_write_time_update_immediate(new_fsp
);
5861 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5862 return NT_STATUS_OK
;
5865 /****************************************************************************
5866 Deal with SMB_INFO_SET_EA.
5867 ****************************************************************************/
5869 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
5873 const struct smb_filename
*smb_fname
)
5875 struct ea_list
*ea_list
= NULL
;
5876 TALLOC_CTX
*ctx
= NULL
;
5877 NTSTATUS status
= NT_STATUS_OK
;
5879 if (total_data
< 10) {
5881 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5882 length. They seem to have no effect. Bug #3212. JRA */
5884 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
5885 /* We're done. We only get EA info in this call. */
5886 return NT_STATUS_OK
;
5889 return NT_STATUS_INVALID_PARAMETER
;
5892 if (IVAL(pdata
,0) > total_data
) {
5893 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5894 IVAL(pdata
,0), (unsigned int)total_data
));
5895 return NT_STATUS_INVALID_PARAMETER
;
5899 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
5901 return NT_STATUS_INVALID_PARAMETER
;
5904 status
= set_ea(conn
, fsp
, smb_fname
, ea_list
);
5909 /****************************************************************************
5910 Deal with SMB_FILE_FULL_EA_INFORMATION set.
5911 ****************************************************************************/
5913 static NTSTATUS
smb_set_file_full_ea_info(connection_struct
*conn
,
5918 struct ea_list
*ea_list
= NULL
;
5922 return NT_STATUS_INVALID_HANDLE
;
5925 if (!lp_ea_support(SNUM(conn
))) {
5926 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5927 "EA's not supported.\n",
5928 (unsigned int)total_data
));
5929 return NT_STATUS_EAS_NOT_SUPPORTED
;
5932 if (total_data
< 10) {
5933 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5935 (unsigned int)total_data
));
5936 return NT_STATUS_INVALID_PARAMETER
;
5939 ea_list
= read_nttrans_ea_list(talloc_tos(),
5944 return NT_STATUS_INVALID_PARAMETER
;
5947 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
5949 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5950 smb_fname_str_dbg(fsp
->fsp_name
),
5951 nt_errstr(status
) ));
5957 /****************************************************************************
5958 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5959 ****************************************************************************/
5961 static NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
5965 struct smb_filename
*smb_fname
)
5967 NTSTATUS status
= NT_STATUS_OK
;
5968 bool delete_on_close
;
5971 if (total_data
< 1) {
5972 return NT_STATUS_INVALID_PARAMETER
;
5976 return NT_STATUS_INVALID_HANDLE
;
5979 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
5980 dosmode
= dos_mode(conn
, smb_fname
);
5982 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5983 "delete_on_close = %u\n",
5984 smb_fname_str_dbg(smb_fname
),
5985 (unsigned int)dosmode
,
5986 (unsigned int)delete_on_close
));
5988 if (delete_on_close
) {
5989 status
= can_set_delete_on_close(fsp
, dosmode
);
5990 if (!NT_STATUS_IS_OK(status
)) {
5995 /* The set is across all open files on this dev/inode pair. */
5996 if (!set_delete_on_close(fsp
, delete_on_close
,
5997 conn
->session_info
->security_token
,
5998 conn
->session_info
->unix_token
)) {
5999 return NT_STATUS_ACCESS_DENIED
;
6001 return NT_STATUS_OK
;
6004 /****************************************************************************
6005 Deal with SMB_FILE_POSITION_INFORMATION.
6006 ****************************************************************************/
6008 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
6013 uint64_t position_information
;
6015 if (total_data
< 8) {
6016 return NT_STATUS_INVALID_PARAMETER
;
6020 /* Ignore on pathname based set. */
6021 return NT_STATUS_OK
;
6024 position_information
= (uint64_t)IVAL(pdata
,0);
6025 position_information
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6027 DEBUG(10,("smb_file_position_information: Set file position "
6028 "information for file %s to %.0f\n", fsp_str_dbg(fsp
),
6029 (double)position_information
));
6030 fsp
->fh
->position_information
= position_information
;
6031 return NT_STATUS_OK
;
6034 /****************************************************************************
6035 Deal with SMB_FILE_MODE_INFORMATION.
6036 ****************************************************************************/
6038 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
6044 if (total_data
< 4) {
6045 return NT_STATUS_INVALID_PARAMETER
;
6047 mode
= IVAL(pdata
,0);
6048 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
6049 return NT_STATUS_INVALID_PARAMETER
;
6051 return NT_STATUS_OK
;
6054 /****************************************************************************
6055 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
6056 ****************************************************************************/
6058 static NTSTATUS
smb_set_file_unix_link(connection_struct
*conn
,
6059 struct smb_request
*req
,
6062 const struct smb_filename
*smb_fname
)
6064 char *link_target
= NULL
;
6065 const char *newname
= smb_fname
->base_name
;
6066 TALLOC_CTX
*ctx
= talloc_tos();
6068 /* Set a symbolic link. */
6069 /* Don't allow this if follow links is false. */
6071 if (total_data
== 0) {
6072 return NT_STATUS_INVALID_PARAMETER
;
6075 if (!lp_symlinks(SNUM(conn
))) {
6076 return NT_STATUS_ACCESS_DENIED
;
6079 srvstr_pull_talloc(ctx
, pdata
, req
->flags2
, &link_target
, pdata
,
6080 total_data
, STR_TERMINATE
);
6083 return NT_STATUS_INVALID_PARAMETER
;
6086 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
6087 newname
, link_target
));
6089 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0) {
6090 return map_nt_error_from_unix(errno
);
6093 return NT_STATUS_OK
;
6096 /****************************************************************************
6097 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
6098 ****************************************************************************/
6100 static NTSTATUS
smb_set_file_unix_hlink(connection_struct
*conn
,
6101 struct smb_request
*req
,
6102 const char *pdata
, int total_data
,
6103 struct smb_filename
*smb_fname_new
)
6105 char *oldname
= NULL
;
6106 struct smb_filename
*smb_fname_old
= NULL
;
6107 TALLOC_CTX
*ctx
= talloc_tos();
6108 NTSTATUS status
= NT_STATUS_OK
;
6110 /* Set a hard link. */
6111 if (total_data
== 0) {
6112 return NT_STATUS_INVALID_PARAMETER
;
6115 srvstr_get_path(ctx
, pdata
, req
->flags2
, &oldname
, pdata
,
6116 total_data
, STR_TERMINATE
, &status
);
6117 if (!NT_STATUS_IS_OK(status
)) {
6121 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6122 smb_fname_str_dbg(smb_fname_new
), oldname
));
6124 status
= filename_convert(ctx
,
6126 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6131 if (!NT_STATUS_IS_OK(status
)) {
6135 return hardlink_internals(ctx
, conn
, req
, false,
6136 smb_fname_old
, smb_fname_new
);
6139 /****************************************************************************
6140 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6141 ****************************************************************************/
6143 static NTSTATUS
smb2_file_rename_information(connection_struct
*conn
,
6144 struct smb_request
*req
,
6148 struct smb_filename
*smb_fname_src
)
6152 char *newname
= NULL
;
6153 struct smb_filename
*smb_fname_dst
= NULL
;
6154 NTSTATUS status
= NT_STATUS_OK
;
6155 TALLOC_CTX
*ctx
= talloc_tos();
6158 return NT_STATUS_INVALID_HANDLE
;
6161 if (total_data
< 20) {
6162 return NT_STATUS_INVALID_PARAMETER
;
6165 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6166 len
= IVAL(pdata
,16);
6168 if (len
> (total_data
- 20) || (len
== 0)) {
6169 return NT_STATUS_INVALID_PARAMETER
;
6172 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6173 &pdata
[20], len
, STR_TERMINATE
,
6175 if (!NT_STATUS_IS_OK(status
)) {
6179 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
6182 status
= filename_convert(ctx
,
6184 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6189 if (!NT_STATUS_IS_OK(status
)) {
6193 if (fsp
->base_fsp
) {
6194 /* newname must be a stream name. */
6195 if (newname
[0] != ':') {
6196 return NT_STATUS_NOT_SUPPORTED
;
6199 /* Create an smb_fname to call rename_internals_fsp() with. */
6200 status
= create_synthetic_smb_fname(talloc_tos(),
6201 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6203 if (!NT_STATUS_IS_OK(status
)) {
6208 * Set the original last component, since
6209 * rename_internals_fsp() requires it.
6211 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6213 if (smb_fname_dst
->original_lcomp
== NULL
) {
6214 status
= NT_STATUS_NO_MEMORY
;
6220 DEBUG(10,("smb2_file_rename_information: "
6221 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6222 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6223 smb_fname_str_dbg(smb_fname_dst
)));
6224 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6225 (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
),
6229 TALLOC_FREE(smb_fname_dst
);
6233 static NTSTATUS
smb_file_link_information(connection_struct
*conn
,
6234 struct smb_request
*req
,
6238 struct smb_filename
*smb_fname_src
)
6242 char *newname
= NULL
;
6243 struct smb_filename
*smb_fname_dst
= NULL
;
6244 NTSTATUS status
= NT_STATUS_OK
;
6245 TALLOC_CTX
*ctx
= talloc_tos();
6248 return NT_STATUS_INVALID_HANDLE
;
6251 if (total_data
< 20) {
6252 return NT_STATUS_INVALID_PARAMETER
;
6255 overwrite
= (CVAL(pdata
,0) ? true : false);
6256 len
= IVAL(pdata
,16);
6258 if (len
> (total_data
- 20) || (len
== 0)) {
6259 return NT_STATUS_INVALID_PARAMETER
;
6262 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6263 &pdata
[20], len
, STR_TERMINATE
,
6265 if (!NT_STATUS_IS_OK(status
)) {
6269 DEBUG(10,("smb_file_link_information: got name |%s|\n",
6272 status
= filename_convert(ctx
,
6274 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6279 if (!NT_STATUS_IS_OK(status
)) {
6283 if (fsp
->base_fsp
) {
6284 /* No stream names. */
6285 return NT_STATUS_NOT_SUPPORTED
;
6288 DEBUG(10,("smb_file_link_information: "
6289 "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
6290 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6291 smb_fname_str_dbg(smb_fname_dst
)));
6292 status
= hardlink_internals(ctx
,
6299 TALLOC_FREE(smb_fname_dst
);
6303 /****************************************************************************
6304 Deal with SMB_FILE_RENAME_INFORMATION.
6305 ****************************************************************************/
6307 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
6308 struct smb_request
*req
,
6312 struct smb_filename
*smb_fname_src
)
6317 char *newname
= NULL
;
6318 struct smb_filename
*smb_fname_dst
= NULL
;
6319 bool dest_has_wcard
= False
;
6320 NTSTATUS status
= NT_STATUS_OK
;
6322 TALLOC_CTX
*ctx
= talloc_tos();
6324 if (total_data
< 13) {
6325 return NT_STATUS_INVALID_PARAMETER
;
6328 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6329 root_fid
= IVAL(pdata
,4);
6330 len
= IVAL(pdata
,8);
6332 if (len
> (total_data
- 12) || (len
== 0) || (root_fid
!= 0)) {
6333 return NT_STATUS_INVALID_PARAMETER
;
6336 srvstr_get_path_wcard(ctx
, pdata
, req
->flags2
, &newname
, &pdata
[12],
6339 if (!NT_STATUS_IS_OK(status
)) {
6343 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6346 status
= resolve_dfspath_wcard(ctx
, conn
,
6347 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6350 !conn
->sconn
->using_smb2
,
6353 if (!NT_STATUS_IS_OK(status
)) {
6357 /* Check the new name has no '/' characters. */
6358 if (strchr_m(newname
, '/')) {
6359 return NT_STATUS_NOT_SUPPORTED
;
6362 if (fsp
&& fsp
->base_fsp
) {
6363 /* newname must be a stream name. */
6364 if (newname
[0] != ':') {
6365 return NT_STATUS_NOT_SUPPORTED
;
6368 /* Create an smb_fname to call rename_internals_fsp() with. */
6369 status
= create_synthetic_smb_fname(talloc_tos(),
6370 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6372 if (!NT_STATUS_IS_OK(status
)) {
6377 * Set the original last component, since
6378 * rename_internals_fsp() requires it.
6380 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6382 if (smb_fname_dst
->original_lcomp
== NULL
) {
6383 status
= NT_STATUS_NO_MEMORY
;
6389 * Build up an smb_fname_dst based on the filename passed in.
6390 * We basically just strip off the last component, and put on
6391 * the newname instead.
6393 char *base_name
= NULL
;
6395 /* newname must *not* be a stream name. */
6396 if (newname
[0] == ':') {
6397 return NT_STATUS_NOT_SUPPORTED
;
6401 * Strip off the last component (filename) of the path passed
6404 base_name
= talloc_strdup(ctx
, smb_fname_src
->base_name
);
6406 return NT_STATUS_NO_MEMORY
;
6408 p
= strrchr_m(base_name
, '/');
6412 base_name
= talloc_strdup(ctx
, "");
6414 return NT_STATUS_NO_MEMORY
;
6417 /* Append the new name. */
6418 base_name
= talloc_asprintf_append(base_name
,
6422 return NT_STATUS_NO_MEMORY
;
6425 status
= unix_convert(ctx
, conn
, base_name
, &smb_fname_dst
,
6428 UCF_ALWAYS_ALLOW_WCARD_LCOMP
:
6431 /* If an error we expect this to be
6432 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6434 if (!NT_STATUS_IS_OK(status
)) {
6435 if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND
,
6439 /* Create an smb_fname to call rename_internals_fsp() */
6440 status
= create_synthetic_smb_fname(ctx
,
6444 if (!NT_STATUS_IS_OK(status
)) {
6451 DEBUG(10,("smb_file_rename_information: "
6452 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6453 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6454 smb_fname_str_dbg(smb_fname_dst
)));
6455 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
, 0,
6458 DEBUG(10,("smb_file_rename_information: "
6459 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6460 smb_fname_str_dbg(smb_fname_src
),
6461 smb_fname_str_dbg(smb_fname_dst
)));
6462 status
= rename_internals(ctx
, conn
, req
, smb_fname_src
,
6463 smb_fname_dst
, 0, overwrite
, false,
6465 FILE_WRITE_ATTRIBUTES
);
6468 TALLOC_FREE(smb_fname_dst
);
6472 /****************************************************************************
6473 Deal with SMB_SET_POSIX_ACL.
6474 ****************************************************************************/
6476 #if defined(HAVE_POSIX_ACLS)
6477 static NTSTATUS
smb_set_posix_acl(connection_struct
*conn
,
6481 const struct smb_filename
*smb_fname
)
6483 uint16 posix_acl_version
;
6484 uint16 num_file_acls
;
6485 uint16 num_def_acls
;
6486 bool valid_file_acls
= True
;
6487 bool valid_def_acls
= True
;
6489 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
6490 return NT_STATUS_INVALID_PARAMETER
;
6492 posix_acl_version
= SVAL(pdata
,0);
6493 num_file_acls
= SVAL(pdata
,2);
6494 num_def_acls
= SVAL(pdata
,4);
6496 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6497 valid_file_acls
= False
;
6501 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6502 valid_def_acls
= False
;
6506 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
6507 return NT_STATUS_INVALID_PARAMETER
;
6510 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
6511 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
6512 return NT_STATUS_INVALID_PARAMETER
;
6515 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6516 smb_fname
? smb_fname_str_dbg(smb_fname
) : fsp_str_dbg(fsp
),
6517 (unsigned int)num_file_acls
,
6518 (unsigned int)num_def_acls
));
6520 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
,
6521 smb_fname
->base_name
, num_file_acls
,
6522 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
6523 return map_nt_error_from_unix(errno
);
6526 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
,
6527 smb_fname
->base_name
, &smb_fname
->st
, num_def_acls
,
6528 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
6529 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
6530 return map_nt_error_from_unix(errno
);
6532 return NT_STATUS_OK
;
6536 /****************************************************************************
6537 Deal with SMB_SET_POSIX_LOCK.
6538 ****************************************************************************/
6540 static NTSTATUS
smb_set_posix_lock(connection_struct
*conn
,
6541 struct smb_request
*req
,
6549 bool blocking_lock
= False
;
6550 enum brl_type lock_type
;
6552 NTSTATUS status
= NT_STATUS_OK
;
6554 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
6555 return NT_STATUS_INVALID_HANDLE
;
6558 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
6559 return NT_STATUS_INVALID_PARAMETER
;
6562 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
6563 case POSIX_LOCK_TYPE_READ
:
6564 lock_type
= READ_LOCK
;
6566 case POSIX_LOCK_TYPE_WRITE
:
6567 /* Return the right POSIX-mappable error code for files opened read-only. */
6568 if (!fsp
->can_write
) {
6569 return NT_STATUS_INVALID_HANDLE
;
6571 lock_type
= WRITE_LOCK
;
6573 case POSIX_LOCK_TYPE_UNLOCK
:
6574 lock_type
= UNLOCK_LOCK
;
6577 return NT_STATUS_INVALID_PARAMETER
;
6580 if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_NOWAIT
) {
6581 blocking_lock
= False
;
6582 } else if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_WAIT
) {
6583 blocking_lock
= True
;
6585 return NT_STATUS_INVALID_PARAMETER
;
6588 if (!lp_blocking_locks(SNUM(conn
))) {
6589 blocking_lock
= False
;
6592 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
6593 #if defined(HAVE_LONGLONG)
6594 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
6595 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
6596 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
6597 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
6598 #else /* HAVE_LONGLONG */
6599 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
6600 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
6601 #endif /* HAVE_LONGLONG */
6603 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6604 "smblctx = %llu, count = %.0f, offset = %.0f\n",
6606 (unsigned int)lock_type
,
6607 (unsigned long long)smblctx
,
6611 if (lock_type
== UNLOCK_LOCK
) {
6612 status
= do_unlock(req
->sconn
->msg_ctx
,
6619 uint64_t block_smblctx
;
6621 struct byte_range_lock
*br_lck
= do_lock(req
->sconn
->msg_ctx
,
6633 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
6635 * A blocking lock was requested. Package up
6636 * this smb into a queued request and push it
6637 * onto the blocking lock queue.
6639 if(push_blocking_lock_request(br_lck
,
6642 -1, /* infinite timeout. */
6650 TALLOC_FREE(br_lck
);
6654 TALLOC_FREE(br_lck
);
6660 /****************************************************************************
6661 Deal with SMB_SET_FILE_BASIC_INFO.
6662 ****************************************************************************/
6664 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
6668 const struct smb_filename
*smb_fname
)
6670 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6671 struct smb_file_time ft
;
6673 NTSTATUS status
= NT_STATUS_OK
;
6677 if (total_data
< 36) {
6678 return NT_STATUS_INVALID_PARAMETER
;
6681 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_ATTRIBUTES
);
6682 if (!NT_STATUS_IS_OK(status
)) {
6686 /* Set the attributes */
6687 dosmode
= IVAL(pdata
,32);
6688 status
= smb_set_file_dosmode(conn
, smb_fname
, dosmode
);
6689 if (!NT_STATUS_IS_OK(status
)) {
6694 ft
.create_time
= interpret_long_date(pdata
);
6697 ft
.atime
= interpret_long_date(pdata
+8);
6700 ft
.mtime
= interpret_long_date(pdata
+16);
6703 ft
.ctime
= interpret_long_date(pdata
+24);
6705 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6706 smb_fname_str_dbg(smb_fname
)));
6708 return smb_set_file_time(conn
, fsp
, smb_fname
, &ft
,
6712 /****************************************************************************
6713 Deal with SMB_INFO_STANDARD.
6714 ****************************************************************************/
6716 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
6720 const struct smb_filename
*smb_fname
)
6723 struct smb_file_time ft
;
6727 if (total_data
< 12) {
6728 return NT_STATUS_INVALID_PARAMETER
;
6732 ft
.create_time
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
));
6734 ft
.atime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+4));
6736 ft
.mtime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+8));
6738 DEBUG(10,("smb_set_info_standard: file %s\n",
6739 smb_fname_str_dbg(smb_fname
)));
6741 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_ATTRIBUTES
);
6742 if (!NT_STATUS_IS_OK(status
)) {
6746 return smb_set_file_time(conn
,
6753 /****************************************************************************
6754 Deal with SMB_SET_FILE_ALLOCATION_INFO.
6755 ****************************************************************************/
6757 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
6758 struct smb_request
*req
,
6762 struct smb_filename
*smb_fname
)
6764 uint64_t allocation_size
= 0;
6765 NTSTATUS status
= NT_STATUS_OK
;
6766 files_struct
*new_fsp
= NULL
;
6768 if (!VALID_STAT(smb_fname
->st
)) {
6769 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6772 if (total_data
< 8) {
6773 return NT_STATUS_INVALID_PARAMETER
;
6776 allocation_size
= (uint64_t)IVAL(pdata
,0);
6777 allocation_size
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6778 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6779 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6780 (double)allocation_size
));
6782 if (allocation_size
) {
6783 allocation_size
= smb_roundup(conn
, allocation_size
);
6786 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6787 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname
),
6788 (double)allocation_size
));
6790 if (fsp
&& fsp
->fh
->fd
!= -1) {
6791 /* Open file handle. */
6792 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6793 return NT_STATUS_ACCESS_DENIED
;
6796 /* Only change if needed. */
6797 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6798 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
6799 return map_nt_error_from_unix(errno
);
6802 /* But always update the time. */
6804 * This is equivalent to a write. Ensure it's seen immediately
6805 * if there are no pending writes.
6807 trigger_write_time_update_immediate(fsp
);
6808 return NT_STATUS_OK
;
6811 /* Pathname or stat or directory file. */
6812 status
= SMB_VFS_CREATE_FILE(
6815 0, /* root_dir_fid */
6816 smb_fname
, /* fname */
6817 FILE_WRITE_DATA
, /* access_mask */
6818 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
6820 FILE_OPEN
, /* create_disposition*/
6821 0, /* create_options */
6822 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
6823 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
6824 0, /* allocation_size */
6825 0, /* private_flags */
6828 &new_fsp
, /* result */
6831 if (!NT_STATUS_IS_OK(status
)) {
6832 /* NB. We check for open_was_deferred in the caller. */
6836 /* Only change if needed. */
6837 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6838 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
6839 status
= map_nt_error_from_unix(errno
);
6840 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6845 /* Changing the allocation size should set the last mod time. */
6847 * This is equivalent to a write. Ensure it's seen immediately
6848 * if there are no pending writes.
6850 trigger_write_time_update_immediate(new_fsp
);
6852 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6853 return NT_STATUS_OK
;
6856 /****************************************************************************
6857 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6858 ****************************************************************************/
6860 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
6861 struct smb_request
*req
,
6865 const struct smb_filename
*smb_fname
,
6866 bool fail_after_createfile
)
6870 if (total_data
< 8) {
6871 return NT_STATUS_INVALID_PARAMETER
;
6874 size
= IVAL(pdata
,0);
6875 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
6876 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6877 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6880 return smb_set_file_size(conn
, req
,
6885 fail_after_createfile
);
6888 /****************************************************************************
6889 Allow a UNIX info mknod.
6890 ****************************************************************************/
6892 static NTSTATUS
smb_unix_mknod(connection_struct
*conn
,
6895 const struct smb_filename
*smb_fname
)
6897 uint32 file_type
= IVAL(pdata
,56);
6898 #if defined(HAVE_MAKEDEV)
6899 uint32 dev_major
= IVAL(pdata
,60);
6900 uint32 dev_minor
= IVAL(pdata
,68);
6902 SMB_DEV_T dev
= (SMB_DEV_T
)0;
6903 uint32 raw_unixmode
= IVAL(pdata
,84);
6907 if (total_data
< 100) {
6908 return NT_STATUS_INVALID_PARAMETER
;
6911 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6912 PERM_NEW_FILE
, &unixmode
);
6913 if (!NT_STATUS_IS_OK(status
)) {
6917 #if defined(HAVE_MAKEDEV)
6918 dev
= makedev(dev_major
, dev_minor
);
6921 switch (file_type
) {
6922 #if defined(S_IFIFO)
6923 case UNIX_TYPE_FIFO
:
6924 unixmode
|= S_IFIFO
;
6927 #if defined(S_IFSOCK)
6928 case UNIX_TYPE_SOCKET
:
6929 unixmode
|= S_IFSOCK
;
6932 #if defined(S_IFCHR)
6933 case UNIX_TYPE_CHARDEV
:
6934 unixmode
|= S_IFCHR
;
6937 #if defined(S_IFBLK)
6938 case UNIX_TYPE_BLKDEV
:
6939 unixmode
|= S_IFBLK
;
6943 return NT_STATUS_INVALID_PARAMETER
;
6946 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6947 "%.0f mode 0%o for file %s\n", (double)dev
,
6948 (unsigned int)unixmode
, smb_fname_str_dbg(smb_fname
)));
6950 /* Ok - do the mknod. */
6951 if (SMB_VFS_MKNOD(conn
, smb_fname
->base_name
, unixmode
, dev
) != 0) {
6952 return map_nt_error_from_unix(errno
);
6955 /* If any of the other "set" calls fail we
6956 * don't want to end up with a half-constructed mknod.
6959 if (lp_inherit_perms(SNUM(conn
))) {
6961 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
,
6963 return NT_STATUS_NO_MEMORY
;
6965 inherit_access_posix_acl(conn
, parent
, smb_fname
->base_name
,
6967 TALLOC_FREE(parent
);
6970 return NT_STATUS_OK
;
6973 /****************************************************************************
6974 Deal with SMB_SET_FILE_UNIX_BASIC.
6975 ****************************************************************************/
6977 static NTSTATUS
smb_set_file_unix_basic(connection_struct
*conn
,
6978 struct smb_request
*req
,
6982 const struct smb_filename
*smb_fname
)
6984 struct smb_file_time ft
;
6985 uint32 raw_unixmode
;
6988 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
6989 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
6990 NTSTATUS status
= NT_STATUS_OK
;
6991 bool delete_on_fail
= False
;
6992 enum perm_type ptype
;
6993 files_struct
*all_fsps
= NULL
;
6994 bool modify_mtime
= true;
6996 struct smb_filename
*smb_fname_tmp
= NULL
;
6997 SMB_STRUCT_STAT sbuf
;
7001 if (total_data
< 100) {
7002 return NT_STATUS_INVALID_PARAMETER
;
7005 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
7006 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
7007 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
7008 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
7011 ft
.atime
= interpret_long_date(pdata
+24); /* access_time */
7012 ft
.mtime
= interpret_long_date(pdata
+32); /* modification_time */
7013 set_owner
= (uid_t
)IVAL(pdata
,40);
7014 set_grp
= (gid_t
)IVAL(pdata
,48);
7015 raw_unixmode
= IVAL(pdata
,84);
7017 if (VALID_STAT(smb_fname
->st
)) {
7018 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
7019 ptype
= PERM_EXISTING_DIR
;
7021 ptype
= PERM_EXISTING_FILE
;
7024 ptype
= PERM_NEW_FILE
;
7027 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7029 if (!NT_STATUS_IS_OK(status
)) {
7033 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
7034 "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
7035 smb_fname_str_dbg(smb_fname
), (double)size
,
7036 (unsigned int)set_owner
, (unsigned int)set_grp
,
7037 (int)raw_unixmode
));
7039 sbuf
= smb_fname
->st
;
7041 if (!VALID_STAT(sbuf
)) {
7043 * The only valid use of this is to create character and block
7044 * devices, and named pipes. This is deprecated (IMHO) and
7045 * a new info level should be used for mknod. JRA.
7048 status
= smb_unix_mknod(conn
,
7052 if (!NT_STATUS_IS_OK(status
)) {
7056 status
= copy_smb_filename(talloc_tos(), smb_fname
,
7058 if (!NT_STATUS_IS_OK(status
)) {
7062 if (SMB_VFS_STAT(conn
, smb_fname_tmp
) != 0) {
7063 status
= map_nt_error_from_unix(errno
);
7064 TALLOC_FREE(smb_fname_tmp
);
7065 SMB_VFS_UNLINK(conn
, smb_fname
);
7069 sbuf
= smb_fname_tmp
->st
;
7070 smb_fname
= smb_fname_tmp
;
7072 /* Ensure we don't try and change anything else. */
7073 raw_unixmode
= SMB_MODE_NO_CHANGE
;
7074 size
= get_file_size_stat(&sbuf
);
7075 ft
.atime
= sbuf
.st_ex_atime
;
7076 ft
.mtime
= sbuf
.st_ex_mtime
;
7078 * We continue here as we might want to change the
7081 delete_on_fail
= True
;
7085 /* Horrible backwards compatibility hack as an old server bug
7086 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
7090 size
= get_file_size_stat(&sbuf
);
7095 * Deal with the UNIX specific mode set.
7098 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
7099 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7100 "setting mode 0%o for file %s\n",
7101 (unsigned int)unixmode
,
7102 smb_fname_str_dbg(smb_fname
)));
7103 if (SMB_VFS_CHMOD(conn
, smb_fname
->base_name
, unixmode
) != 0) {
7104 return map_nt_error_from_unix(errno
);
7109 * Deal with the UNIX specific uid set.
7112 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) &&
7113 (sbuf
.st_ex_uid
!= set_owner
)) {
7116 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7117 "changing owner %u for path %s\n",
7118 (unsigned int)set_owner
,
7119 smb_fname_str_dbg(smb_fname
)));
7121 if (S_ISLNK(sbuf
.st_ex_mode
)) {
7122 ret
= SMB_VFS_LCHOWN(conn
, smb_fname
->base_name
,
7123 set_owner
, (gid_t
)-1);
7125 ret
= SMB_VFS_CHOWN(conn
, smb_fname
->base_name
,
7126 set_owner
, (gid_t
)-1);
7130 status
= map_nt_error_from_unix(errno
);
7131 if (delete_on_fail
) {
7132 SMB_VFS_UNLINK(conn
, smb_fname
);
7139 * Deal with the UNIX specific gid set.
7142 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) &&
7143 (sbuf
.st_ex_gid
!= set_grp
)) {
7144 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7145 "changing group %u for file %s\n",
7146 (unsigned int)set_owner
,
7147 smb_fname_str_dbg(smb_fname
)));
7148 if (SMB_VFS_CHOWN(conn
, smb_fname
->base_name
, (uid_t
)-1,
7150 status
= map_nt_error_from_unix(errno
);
7151 if (delete_on_fail
) {
7152 SMB_VFS_UNLINK(conn
, smb_fname
);
7158 /* Deal with any size changes. */
7160 status
= smb_set_file_size(conn
, req
,
7166 if (!NT_STATUS_IS_OK(status
)) {
7170 /* Deal with any time changes. */
7171 if (null_timespec(ft
.mtime
) && null_timespec(ft
.atime
)) {
7172 /* No change, don't cancel anything. */
7176 id
= vfs_file_id_from_sbuf(conn
, &sbuf
);
7177 for(all_fsps
= file_find_di_first(conn
->sconn
, id
); all_fsps
;
7178 all_fsps
= file_find_di_next(all_fsps
)) {
7180 * We're setting the time explicitly for UNIX.
7181 * Cancel any pending changes over all handles.
7183 all_fsps
->update_write_time_on_close
= false;
7184 TALLOC_FREE(all_fsps
->update_write_time_event
);
7188 * Override the "setting_write_time"
7189 * parameter here as it almost does what
7190 * we need. Just remember if we modified
7191 * mtime and send the notify ourselves.
7193 if (null_timespec(ft
.mtime
)) {
7194 modify_mtime
= false;
7197 status
= smb_set_file_time(conn
,
7203 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
7204 FILE_NOTIFY_CHANGE_LAST_WRITE
, smb_fname
->base_name
);
7209 /****************************************************************************
7210 Deal with SMB_SET_FILE_UNIX_INFO2.
7211 ****************************************************************************/
7213 static NTSTATUS
smb_set_file_unix_info2(connection_struct
*conn
,
7214 struct smb_request
*req
,
7218 const struct smb_filename
*smb_fname
)
7224 if (total_data
< 116) {
7225 return NT_STATUS_INVALID_PARAMETER
;
7228 /* Start by setting all the fields that are common between UNIX_BASIC
7231 status
= smb_set_file_unix_basic(conn
, req
, pdata
, total_data
,
7233 if (!NT_STATUS_IS_OK(status
)) {
7237 smb_fflags
= IVAL(pdata
, 108);
7238 smb_fmask
= IVAL(pdata
, 112);
7240 /* NB: We should only attempt to alter the file flags if the client
7241 * sends a non-zero mask.
7243 if (smb_fmask
!= 0) {
7244 int stat_fflags
= 0;
7246 if (!map_info2_flags_to_sbuf(&smb_fname
->st
, smb_fflags
,
7247 smb_fmask
, &stat_fflags
)) {
7248 /* Client asked to alter a flag we don't understand. */
7249 return NT_STATUS_INVALID_PARAMETER
;
7252 if (fsp
&& fsp
->fh
->fd
!= -1) {
7253 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
7254 return NT_STATUS_NOT_SUPPORTED
;
7256 if (SMB_VFS_CHFLAGS(conn
, smb_fname
->base_name
,
7257 stat_fflags
) != 0) {
7258 return map_nt_error_from_unix(errno
);
7263 /* XXX: need to add support for changing the create_time here. You
7264 * can do this for paths on Darwin with setattrlist(2). The right way
7265 * to hook this up is probably by extending the VFS utimes interface.
7268 return NT_STATUS_OK
;
7271 /****************************************************************************
7272 Create a directory with POSIX semantics.
7273 ****************************************************************************/
7275 static NTSTATUS
smb_posix_mkdir(connection_struct
*conn
,
7276 struct smb_request
*req
,
7279 struct smb_filename
*smb_fname
,
7280 int *pdata_return_size
)
7282 NTSTATUS status
= NT_STATUS_OK
;
7283 uint32 raw_unixmode
= 0;
7284 uint32 mod_unixmode
= 0;
7285 mode_t unixmode
= (mode_t
)0;
7286 files_struct
*fsp
= NULL
;
7287 uint16 info_level_return
= 0;
7289 char *pdata
= *ppdata
;
7291 if (total_data
< 18) {
7292 return NT_STATUS_INVALID_PARAMETER
;
7295 raw_unixmode
= IVAL(pdata
,8);
7296 /* Next 4 bytes are not yet defined. */
7298 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7299 PERM_NEW_DIR
, &unixmode
);
7300 if (!NT_STATUS_IS_OK(status
)) {
7304 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7306 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7307 smb_fname_str_dbg(smb_fname
), (unsigned int)unixmode
));
7309 status
= SMB_VFS_CREATE_FILE(
7312 0, /* root_dir_fid */
7313 smb_fname
, /* fname */
7314 FILE_READ_ATTRIBUTES
, /* access_mask */
7315 FILE_SHARE_NONE
, /* share_access */
7316 FILE_CREATE
, /* create_disposition*/
7317 FILE_DIRECTORY_FILE
, /* create_options */
7318 mod_unixmode
, /* file_attributes */
7319 0, /* oplock_request */
7320 0, /* allocation_size */
7321 0, /* private_flags */
7327 if (NT_STATUS_IS_OK(status
)) {
7328 close_file(req
, fsp
, NORMAL_CLOSE
);
7331 info_level_return
= SVAL(pdata
,16);
7333 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7334 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7335 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7336 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7338 *pdata_return_size
= 12;
7341 /* Realloc the data size */
7342 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7343 if (*ppdata
== NULL
) {
7344 *pdata_return_size
= 0;
7345 return NT_STATUS_NO_MEMORY
;
7349 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7350 SSVAL(pdata
,2,0); /* No fnum. */
7351 SIVAL(pdata
,4,info
); /* Was directory created. */
7353 switch (info_level_return
) {
7354 case SMB_QUERY_FILE_UNIX_BASIC
:
7355 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7356 SSVAL(pdata
,10,0); /* Padding. */
7357 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7360 case SMB_QUERY_FILE_UNIX_INFO2
:
7361 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7362 SSVAL(pdata
,10,0); /* Padding. */
7363 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7367 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7368 SSVAL(pdata
,10,0); /* Padding. */
7375 /****************************************************************************
7376 Open/Create a file with POSIX semantics.
7377 ****************************************************************************/
7379 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7380 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7382 static NTSTATUS
smb_posix_open(connection_struct
*conn
,
7383 struct smb_request
*req
,
7386 struct smb_filename
*smb_fname
,
7387 int *pdata_return_size
)
7389 bool extended_oplock_granted
= False
;
7390 char *pdata
= *ppdata
;
7392 uint32 wire_open_mode
= 0;
7393 uint32 raw_unixmode
= 0;
7394 uint32 mod_unixmode
= 0;
7395 uint32 create_disp
= 0;
7396 uint32 access_mask
= 0;
7397 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
7398 NTSTATUS status
= NT_STATUS_OK
;
7399 mode_t unixmode
= (mode_t
)0;
7400 files_struct
*fsp
= NULL
;
7401 int oplock_request
= 0;
7403 uint16 info_level_return
= 0;
7405 if (total_data
< 18) {
7406 return NT_STATUS_INVALID_PARAMETER
;
7409 flags
= IVAL(pdata
,0);
7410 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
7411 if (oplock_request
) {
7412 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
7415 wire_open_mode
= IVAL(pdata
,4);
7417 if (wire_open_mode
== (SMB_O_CREAT
|SMB_O_DIRECTORY
)) {
7418 return smb_posix_mkdir(conn
, req
,
7425 switch (wire_open_mode
& SMB_ACCMODE
) {
7427 access_mask
= SMB_O_RDONLY_MAPPING
;
7430 access_mask
= SMB_O_WRONLY_MAPPING
;
7433 access_mask
= (SMB_O_RDONLY_MAPPING
|
7434 SMB_O_WRONLY_MAPPING
);
7437 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7438 (unsigned int)wire_open_mode
));
7439 return NT_STATUS_INVALID_PARAMETER
;
7442 wire_open_mode
&= ~SMB_ACCMODE
;
7444 /* First take care of O_CREAT|O_EXCL interactions. */
7445 switch (wire_open_mode
& (SMB_O_CREAT
| SMB_O_EXCL
)) {
7446 case (SMB_O_CREAT
| SMB_O_EXCL
):
7447 /* File exists fail. File not exist create. */
7448 create_disp
= FILE_CREATE
;
7451 /* File exists open. File not exist create. */
7452 create_disp
= FILE_OPEN_IF
;
7455 /* O_EXCL on its own without O_CREAT is undefined.
7456 We deliberately ignore it as some versions of
7457 Linux CIFSFS can send a bare O_EXCL on the
7458 wire which other filesystems in the kernel
7459 ignore. See bug 9519 for details. */
7464 /* File exists open. File not exist fail. */
7465 create_disp
= FILE_OPEN
;
7468 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7469 (unsigned int)wire_open_mode
));
7470 return NT_STATUS_INVALID_PARAMETER
;
7473 /* Next factor in the effects of O_TRUNC. */
7474 wire_open_mode
&= ~(SMB_O_CREAT
| SMB_O_EXCL
);
7476 if (wire_open_mode
& SMB_O_TRUNC
) {
7477 switch (create_disp
) {
7479 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7480 /* Leave create_disp alone as
7481 (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7483 /* File exists fail. File not exist create. */
7486 /* SMB_O_CREAT | SMB_O_TRUNC */
7487 /* File exists overwrite. File not exist create. */
7488 create_disp
= FILE_OVERWRITE_IF
;
7492 /* File exists overwrite. File not exist fail. */
7493 create_disp
= FILE_OVERWRITE
;
7496 /* Cannot get here. */
7497 smb_panic("smb_posix_open: logic error");
7498 return NT_STATUS_INVALID_PARAMETER
;
7502 raw_unixmode
= IVAL(pdata
,8);
7503 /* Next 4 bytes are not yet defined. */
7505 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7506 (VALID_STAT(smb_fname
->st
) ?
7507 PERM_EXISTING_FILE
: PERM_NEW_FILE
),
7510 if (!NT_STATUS_IS_OK(status
)) {
7514 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7516 if (wire_open_mode
& SMB_O_SYNC
) {
7517 create_options
|= FILE_WRITE_THROUGH
;
7519 if (wire_open_mode
& SMB_O_APPEND
) {
7520 access_mask
|= FILE_APPEND_DATA
;
7522 if (wire_open_mode
& SMB_O_DIRECT
) {
7523 mod_unixmode
|= FILE_FLAG_NO_BUFFERING
;
7526 if ((wire_open_mode
& SMB_O_DIRECTORY
) ||
7527 VALID_STAT_OF_DIR(smb_fname
->st
)) {
7528 if (access_mask
!= SMB_O_RDONLY_MAPPING
) {
7529 return NT_STATUS_FILE_IS_A_DIRECTORY
;
7531 create_options
&= ~FILE_NON_DIRECTORY_FILE
;
7532 create_options
|= FILE_DIRECTORY_FILE
;
7535 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7536 smb_fname_str_dbg(smb_fname
),
7537 (unsigned int)wire_open_mode
,
7538 (unsigned int)unixmode
));
7540 status
= SMB_VFS_CREATE_FILE(
7543 0, /* root_dir_fid */
7544 smb_fname
, /* fname */
7545 access_mask
, /* access_mask */
7546 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7548 create_disp
, /* create_disposition*/
7549 create_options
, /* create_options */
7550 mod_unixmode
, /* file_attributes */
7551 oplock_request
, /* oplock_request */
7552 0, /* allocation_size */
7553 0, /* private_flags */
7559 if (!NT_STATUS_IS_OK(status
)) {
7563 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
7564 extended_oplock_granted
= True
;
7567 if(oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
7568 extended_oplock_granted
= True
;
7571 info_level_return
= SVAL(pdata
,16);
7573 /* Allocate the correct return size. */
7575 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7576 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7577 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7578 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7580 *pdata_return_size
= 12;
7583 /* Realloc the data size */
7584 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7585 if (*ppdata
== NULL
) {
7586 close_file(req
, fsp
, ERROR_CLOSE
);
7587 *pdata_return_size
= 0;
7588 return NT_STATUS_NO_MEMORY
;
7592 if (extended_oplock_granted
) {
7593 if (flags
& REQUEST_BATCH_OPLOCK
) {
7594 SSVAL(pdata
,0, BATCH_OPLOCK_RETURN
);
7596 SSVAL(pdata
,0, EXCLUSIVE_OPLOCK_RETURN
);
7598 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
7599 SSVAL(pdata
,0, LEVEL_II_OPLOCK_RETURN
);
7601 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7604 SSVAL(pdata
,2,fsp
->fnum
);
7605 SIVAL(pdata
,4,info
); /* Was file created etc. */
7607 switch (info_level_return
) {
7608 case SMB_QUERY_FILE_UNIX_BASIC
:
7609 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7610 SSVAL(pdata
,10,0); /* padding. */
7611 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7614 case SMB_QUERY_FILE_UNIX_INFO2
:
7615 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7616 SSVAL(pdata
,10,0); /* padding. */
7617 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7621 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7622 SSVAL(pdata
,10,0); /* padding. */
7625 return NT_STATUS_OK
;
7628 /****************************************************************************
7629 Delete a file with POSIX semantics.
7630 ****************************************************************************/
7632 static NTSTATUS
smb_posix_unlink(connection_struct
*conn
,
7633 struct smb_request
*req
,
7636 struct smb_filename
*smb_fname
)
7638 NTSTATUS status
= NT_STATUS_OK
;
7639 files_struct
*fsp
= NULL
;
7643 int create_options
= 0;
7645 struct share_mode_lock
*lck
= NULL
;
7647 if (total_data
< 2) {
7648 return NT_STATUS_INVALID_PARAMETER
;
7651 flags
= SVAL(pdata
,0);
7653 if (!VALID_STAT(smb_fname
->st
)) {
7654 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
7657 if ((flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) &&
7658 !VALID_STAT_OF_DIR(smb_fname
->st
)) {
7659 return NT_STATUS_NOT_A_DIRECTORY
;
7662 DEBUG(10,("smb_posix_unlink: %s %s\n",
7663 (flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) ? "directory" : "file",
7664 smb_fname_str_dbg(smb_fname
)));
7666 if (VALID_STAT_OF_DIR(smb_fname
->st
)) {
7667 create_options
|= FILE_DIRECTORY_FILE
;
7670 status
= SMB_VFS_CREATE_FILE(
7673 0, /* root_dir_fid */
7674 smb_fname
, /* fname */
7675 DELETE_ACCESS
, /* access_mask */
7676 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7678 FILE_OPEN
, /* create_disposition*/
7679 create_options
, /* create_options */
7680 FILE_FLAG_POSIX_SEMANTICS
|0777, /* file_attributes */
7681 0, /* oplock_request */
7682 0, /* allocation_size */
7683 0, /* private_flags */
7689 if (!NT_STATUS_IS_OK(status
)) {
7694 * Don't lie to client. If we can't really delete due to
7695 * non-POSIX opens return SHARING_VIOLATION.
7698 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
7700 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7701 "lock for file %s\n", fsp_str_dbg(fsp
)));
7702 close_file(req
, fsp
, NORMAL_CLOSE
);
7703 return NT_STATUS_INVALID_PARAMETER
;
7707 * See if others still have the file open. If this is the case, then
7708 * don't delete. If all opens are POSIX delete we can set the delete
7709 * on close disposition.
7711 for (i
=0; i
<lck
->data
->num_share_modes
; i
++) {
7712 struct share_mode_entry
*e
= &lck
->data
->share_modes
[i
];
7713 if (is_valid_share_mode_entry(e
)) {
7714 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
7717 if (share_mode_stale_pid(lck
->data
, i
)) {
7720 /* Fail with sharing violation. */
7722 close_file(req
, fsp
, NORMAL_CLOSE
);
7723 return NT_STATUS_SHARING_VIOLATION
;
7728 * Set the delete on close.
7730 status
= smb_set_file_disposition_info(conn
,
7738 if (!NT_STATUS_IS_OK(status
)) {
7739 close_file(req
, fsp
, NORMAL_CLOSE
);
7742 return close_file(req
, fsp
, NORMAL_CLOSE
);
7745 NTSTATUS
smbd_do_setfilepathinfo(connection_struct
*conn
,
7746 struct smb_request
*req
,
7747 TALLOC_CTX
*mem_ctx
,
7748 uint16_t info_level
,
7750 struct smb_filename
*smb_fname
,
7751 char **ppdata
, int total_data
,
7754 char *pdata
= *ppdata
;
7755 NTSTATUS status
= NT_STATUS_OK
;
7756 int data_return_size
= 0;
7760 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
7761 return NT_STATUS_INVALID_LEVEL
;
7764 if (!CAN_WRITE(conn
)) {
7765 /* Allow POSIX opens. The open path will deny
7766 * any non-readonly opens. */
7767 if (info_level
!= SMB_POSIX_PATH_OPEN
) {
7768 return NT_STATUS_DOS(ERRSRV
, ERRaccess
);
7772 DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
7773 "totdata=%d\n", smb_fname_str_dbg(smb_fname
),
7775 info_level
, total_data
));
7777 switch (info_level
) {
7779 case SMB_INFO_STANDARD
:
7781 status
= smb_set_info_standard(conn
,
7789 case SMB_INFO_SET_EA
:
7791 status
= smb_info_set_ea(conn
,
7799 case SMB_SET_FILE_BASIC_INFO
:
7800 case SMB_FILE_BASIC_INFORMATION
:
7802 status
= smb_set_file_basic_info(conn
,
7810 case SMB_FILE_ALLOCATION_INFORMATION
:
7811 case SMB_SET_FILE_ALLOCATION_INFO
:
7813 status
= smb_set_file_allocation_info(conn
, req
,
7821 case SMB_FILE_END_OF_FILE_INFORMATION
:
7822 case SMB_SET_FILE_END_OF_FILE_INFO
:
7825 * XP/Win7 both fail after the createfile with
7826 * SMB_SET_FILE_END_OF_FILE_INFO but not
7827 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7828 * The level is known here, so pass it down
7832 (info_level
== SMB_SET_FILE_END_OF_FILE_INFO
);
7834 status
= smb_set_file_end_of_file_info(conn
, req
,
7843 case SMB_FILE_DISPOSITION_INFORMATION
:
7844 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
7847 /* JRA - We used to just ignore this on a path ?
7848 * Shouldn't this be invalid level on a pathname
7851 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
7852 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
7855 status
= smb_set_file_disposition_info(conn
,
7863 case SMB_FILE_POSITION_INFORMATION
:
7865 status
= smb_file_position_information(conn
,
7872 case SMB_FILE_FULL_EA_INFORMATION
:
7874 status
= smb_set_file_full_ea_info(conn
,
7881 /* From tridge Samba4 :
7882 * MODE_INFORMATION in setfileinfo (I have no
7883 * idea what "mode information" on a file is - it takes a value of 0,
7884 * 2, 4 or 6. What could it be?).
7887 case SMB_FILE_MODE_INFORMATION
:
7889 status
= smb_file_mode_information(conn
,
7896 * CIFS UNIX extensions.
7899 case SMB_SET_FILE_UNIX_BASIC
:
7901 status
= smb_set_file_unix_basic(conn
, req
,
7909 case SMB_SET_FILE_UNIX_INFO2
:
7911 status
= smb_set_file_unix_info2(conn
, req
,
7919 case SMB_SET_FILE_UNIX_LINK
:
7922 /* We must have a pathname for this. */
7923 return NT_STATUS_INVALID_LEVEL
;
7925 status
= smb_set_file_unix_link(conn
, req
, pdata
,
7926 total_data
, smb_fname
);
7930 case SMB_SET_FILE_UNIX_HLINK
:
7933 /* We must have a pathname for this. */
7934 return NT_STATUS_INVALID_LEVEL
;
7936 status
= smb_set_file_unix_hlink(conn
, req
,
7942 case SMB_FILE_RENAME_INFORMATION
:
7944 status
= smb_file_rename_information(conn
, req
,
7950 case SMB2_FILE_RENAME_INFORMATION_INTERNAL
:
7952 /* SMB2 rename information. */
7953 status
= smb2_file_rename_information(conn
, req
,
7959 case SMB_FILE_LINK_INFORMATION
:
7961 status
= smb_file_link_information(conn
, req
,
7967 #if defined(HAVE_POSIX_ACLS)
7968 case SMB_SET_POSIX_ACL
:
7970 status
= smb_set_posix_acl(conn
,
7979 case SMB_SET_POSIX_LOCK
:
7982 return NT_STATUS_INVALID_LEVEL
;
7984 status
= smb_set_posix_lock(conn
, req
,
7985 pdata
, total_data
, fsp
);
7989 case SMB_POSIX_PATH_OPEN
:
7992 /* We must have a pathname for this. */
7993 return NT_STATUS_INVALID_LEVEL
;
7996 status
= smb_posix_open(conn
, req
,
8004 case SMB_POSIX_PATH_UNLINK
:
8007 /* We must have a pathname for this. */
8008 return NT_STATUS_INVALID_LEVEL
;
8011 status
= smb_posix_unlink(conn
, req
,
8019 return NT_STATUS_INVALID_LEVEL
;
8022 if (!NT_STATUS_IS_OK(status
)) {
8026 *ret_data_size
= data_return_size
;
8027 return NT_STATUS_OK
;
8030 /****************************************************************************
8031 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
8032 ****************************************************************************/
8034 static void call_trans2setfilepathinfo(connection_struct
*conn
,
8035 struct smb_request
*req
,
8036 unsigned int tran_call
,
8037 char **pparams
, int total_params
,
8038 char **ppdata
, int total_data
,
8039 unsigned int max_data_bytes
)
8041 char *params
= *pparams
;
8042 char *pdata
= *ppdata
;
8044 struct smb_filename
*smb_fname
= NULL
;
8045 files_struct
*fsp
= NULL
;
8046 NTSTATUS status
= NT_STATUS_OK
;
8047 int data_return_size
= 0;
8050 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8054 if (tran_call
== TRANSACT2_SETFILEINFO
) {
8055 if (total_params
< 4) {
8056 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8060 fsp
= file_fsp(req
, SVAL(params
,0));
8061 /* Basic check for non-null fsp. */
8062 if (!check_fsp_open(conn
, req
, fsp
)) {
8065 info_level
= SVAL(params
,2);
8067 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
8069 if (!NT_STATUS_IS_OK(status
)) {
8070 reply_nterror(req
, status
);
8074 if(fsp
->fh
->fd
== -1) {
8076 * This is actually a SETFILEINFO on a directory
8077 * handle (returned from an NT SMB). NT5.0 seems
8078 * to do this call. JRA.
8080 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8081 /* Always do lstat for UNIX calls. */
8082 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
8083 DEBUG(3,("call_trans2setfilepathinfo: "
8084 "SMB_VFS_LSTAT of %s failed "
8086 smb_fname_str_dbg(smb_fname
),
8088 reply_nterror(req
, map_nt_error_from_unix(errno
));
8092 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
8093 DEBUG(3,("call_trans2setfilepathinfo: "
8094 "fileinfo of %s failed (%s)\n",
8095 smb_fname_str_dbg(smb_fname
),
8097 reply_nterror(req
, map_nt_error_from_unix(errno
));
8101 } else if (fsp
->print_file
) {
8103 * Doing a DELETE_ON_CLOSE should cancel a print job.
8105 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
8106 fsp
->fh
->private_options
|= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE
;
8108 DEBUG(3,("call_trans2setfilepathinfo: "
8109 "Cancelling print job (%s)\n",
8113 send_trans2_replies(conn
, req
, params
, 2,
8119 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
8124 * Original code - this is an open file.
8126 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
8127 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8128 "of %s failed (%s)\n", fsp_fnum_dbg(fsp
),
8130 reply_nterror(req
, map_nt_error_from_unix(errno
));
8136 uint32_t ucf_flags
= 0;
8139 if (total_params
< 7) {
8140 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8144 info_level
= SVAL(params
,0);
8145 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
8146 total_params
- 6, STR_TERMINATE
,
8148 if (!NT_STATUS_IS_OK(status
)) {
8149 reply_nterror(req
, status
);
8153 if (info_level
== SMB_SET_FILE_UNIX_BASIC
||
8154 info_level
== SMB_SET_FILE_UNIX_INFO2
||
8155 info_level
== SMB_FILE_RENAME_INFORMATION
||
8156 info_level
== SMB_POSIX_PATH_UNLINK
) {
8157 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
8160 status
= filename_convert(req
, conn
,
8161 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8166 if (!NT_STATUS_IS_OK(status
)) {
8167 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8168 reply_botherror(req
,
8169 NT_STATUS_PATH_NOT_COVERED
,
8170 ERRSRV
, ERRbadpath
);
8173 reply_nterror(req
, status
);
8177 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8179 * For CIFS UNIX extensions the target name may not exist.
8182 /* Always do lstat for UNIX calls. */
8183 SMB_VFS_LSTAT(conn
, smb_fname
);
8185 } else if (!VALID_STAT(smb_fname
->st
) &&
8186 SMB_VFS_STAT(conn
, smb_fname
)) {
8187 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8189 smb_fname_str_dbg(smb_fname
),
8191 reply_nterror(req
, map_nt_error_from_unix(errno
));
8196 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
8197 "totdata=%d\n", tran_call
, smb_fname_str_dbg(smb_fname
),
8199 info_level
,total_data
));
8201 /* Realloc the parameter size */
8202 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8203 if (*pparams
== NULL
) {
8204 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8211 status
= smbd_do_setfilepathinfo(conn
, req
, req
,
8217 if (!NT_STATUS_IS_OK(status
)) {
8218 if (open_was_deferred(req
->sconn
, req
->mid
)) {
8219 /* We have re-scheduled this call. */
8222 if (blocking_lock_was_deferred_smb1(req
->sconn
, req
->mid
)) {
8223 /* We have re-scheduled this call. */
8226 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8227 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
8228 ERRSRV
, ERRbadpath
);
8231 if (info_level
== SMB_POSIX_PATH_OPEN
) {
8232 reply_openerror(req
, status
);
8236 reply_nterror(req
, status
);
8240 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, data_return_size
,
8246 /****************************************************************************
8247 Reply to a TRANS2_MKDIR (make directory with extended attributes).
8248 ****************************************************************************/
8250 static void call_trans2mkdir(connection_struct
*conn
, struct smb_request
*req
,
8251 char **pparams
, int total_params
,
8252 char **ppdata
, int total_data
,
8253 unsigned int max_data_bytes
)
8255 struct smb_filename
*smb_dname
= NULL
;
8256 char *params
= *pparams
;
8257 char *pdata
= *ppdata
;
8258 char *directory
= NULL
;
8259 NTSTATUS status
= NT_STATUS_OK
;
8260 struct ea_list
*ea_list
= NULL
;
8261 TALLOC_CTX
*ctx
= talloc_tos();
8263 if (!CAN_WRITE(conn
)) {
8264 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8268 if (total_params
< 5) {
8269 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8273 srvstr_get_path(ctx
, params
, req
->flags2
, &directory
, ¶ms
[4],
8274 total_params
- 4, STR_TERMINATE
,
8276 if (!NT_STATUS_IS_OK(status
)) {
8277 reply_nterror(req
, status
);
8281 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
8283 status
= filename_convert(ctx
,
8285 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8291 if (!NT_STATUS_IS_OK(status
)) {
8292 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8293 reply_botherror(req
,
8294 NT_STATUS_PATH_NOT_COVERED
,
8295 ERRSRV
, ERRbadpath
);
8298 reply_nterror(req
, status
);
8303 * OS/2 workplace shell seems to send SET_EA requests of "null"
8304 * length (4 bytes containing IVAL 4).
8305 * They seem to have no effect. Bug #3212. JRA.
8308 if (total_data
&& (total_data
!= 4)) {
8309 /* Any data in this call is an EA list. */
8310 if (total_data
< 10) {
8311 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8315 if (IVAL(pdata
,0) > total_data
) {
8316 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8317 IVAL(pdata
,0), (unsigned int)total_data
));
8318 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8322 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
8325 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8329 if (!lp_ea_support(SNUM(conn
))) {
8330 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
8334 /* If total_data == 4 Windows doesn't care what values
8335 * are placed in that field, it just ignores them.
8336 * The System i QNTC IBM SMB client puts bad values here,
8337 * so ignore them. */
8339 status
= create_directory(conn
, req
, smb_dname
);
8341 if (!NT_STATUS_IS_OK(status
)) {
8342 reply_nterror(req
, status
);
8346 /* Try and set any given EA. */
8348 status
= set_ea(conn
, NULL
, smb_dname
, ea_list
);
8349 if (!NT_STATUS_IS_OK(status
)) {
8350 reply_nterror(req
, status
);
8355 /* Realloc the parameter and data sizes */
8356 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8357 if(*pparams
== NULL
) {
8358 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8365 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, 0, max_data_bytes
);
8368 TALLOC_FREE(smb_dname
);
8372 /****************************************************************************
8373 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8374 We don't actually do this - we just send a null response.
8375 ****************************************************************************/
8377 static void call_trans2findnotifyfirst(connection_struct
*conn
,
8378 struct smb_request
*req
,
8379 char **pparams
, int total_params
,
8380 char **ppdata
, int total_data
,
8381 unsigned int max_data_bytes
)
8383 char *params
= *pparams
;
8386 if (total_params
< 6) {
8387 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8391 info_level
= SVAL(params
,4);
8392 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
8394 switch (info_level
) {
8399 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
8403 /* Realloc the parameter and data sizes */
8404 *pparams
= (char *)SMB_REALLOC(*pparams
,6);
8405 if (*pparams
== NULL
) {
8406 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8411 SSVAL(params
,0,fnf_handle
);
8412 SSVAL(params
,2,0); /* No changes */
8413 SSVAL(params
,4,0); /* No EA errors */
8420 send_trans2_replies(conn
, req
, params
, 6, *ppdata
, 0, max_data_bytes
);
8425 /****************************************************************************
8426 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
8427 changes). Currently this does nothing.
8428 ****************************************************************************/
8430 static void call_trans2findnotifynext(connection_struct
*conn
,
8431 struct smb_request
*req
,
8432 char **pparams
, int total_params
,
8433 char **ppdata
, int total_data
,
8434 unsigned int max_data_bytes
)
8436 char *params
= *pparams
;
8438 DEBUG(3,("call_trans2findnotifynext\n"));
8440 /* Realloc the parameter and data sizes */
8441 *pparams
= (char *)SMB_REALLOC(*pparams
,4);
8442 if (*pparams
== NULL
) {
8443 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8448 SSVAL(params
,0,0); /* No changes */
8449 SSVAL(params
,2,0); /* No EA errors */
8451 send_trans2_replies(conn
, req
, params
, 4, *ppdata
, 0, max_data_bytes
);
8456 /****************************************************************************
8457 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8458 ****************************************************************************/
8460 static void call_trans2getdfsreferral(connection_struct
*conn
,
8461 struct smb_request
*req
,
8462 char **pparams
, int total_params
,
8463 char **ppdata
, int total_data
,
8464 unsigned int max_data_bytes
)
8466 char *params
= *pparams
;
8467 char *pathname
= NULL
;
8469 int max_referral_level
;
8470 NTSTATUS status
= NT_STATUS_OK
;
8471 TALLOC_CTX
*ctx
= talloc_tos();
8473 DEBUG(10,("call_trans2getdfsreferral\n"));
8475 if (total_params
< 3) {
8476 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8480 max_referral_level
= SVAL(params
,0);
8482 if(!lp_host_msdfs()) {
8483 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8487 srvstr_pull_talloc(ctx
, params
, req
->flags2
, &pathname
, ¶ms
[2],
8488 total_params
- 2, STR_TERMINATE
);
8490 reply_nterror(req
, NT_STATUS_NOT_FOUND
);
8493 if((reply_size
= setup_dfs_referral(conn
, pathname
, max_referral_level
,
8494 ppdata
,&status
)) < 0) {
8495 reply_nterror(req
, status
);
8499 SSVAL((discard_const_p(uint8_t, req
->inbuf
)), smb_flg2
,
8500 SVAL(req
->inbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
8501 send_trans2_replies(conn
, req
,0,0,*ppdata
,reply_size
, max_data_bytes
);
8506 #define LMCAT_SPL 0x53
8507 #define LMFUNC_GETJOBID 0x60
8509 /****************************************************************************
8510 Reply to a TRANS2_IOCTL - used for OS/2 printing.
8511 ****************************************************************************/
8513 static void call_trans2ioctl(connection_struct
*conn
,
8514 struct smb_request
*req
,
8515 char **pparams
, int total_params
,
8516 char **ppdata
, int total_data
,
8517 unsigned int max_data_bytes
)
8519 char *pdata
= *ppdata
;
8520 files_struct
*fsp
= file_fsp(req
, SVAL(req
->vwv
+15, 0));
8522 /* check for an invalid fid before proceeding */
8525 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8529 if ((SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8530 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8531 *ppdata
= (char *)SMB_REALLOC(*ppdata
, 32);
8532 if (*ppdata
== NULL
) {
8533 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8538 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8539 CAN ACCEPT THIS IN UNICODE. JRA. */
8542 SSVAL(pdata
, 0, print_spool_rap_jobid(fsp
->print_file
));
8544 srvstr_push(pdata
, req
->flags2
, pdata
+ 2,
8545 lp_netbios_name(), 15,
8546 STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
8547 srvstr_push(pdata
, req
->flags2
, pdata
+18,
8548 lp_servicename(talloc_tos(), SNUM(conn
)), 13,
8549 STR_ASCII
|STR_TERMINATE
); /* Service name */
8550 send_trans2_replies(conn
, req
, *pparams
, 0, *ppdata
, 32,
8555 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8556 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8559 /****************************************************************************
8560 Reply to a SMBfindclose (stop trans2 directory search).
8561 ****************************************************************************/
8563 void reply_findclose(struct smb_request
*req
)
8566 struct smbd_server_connection
*sconn
= req
->sconn
;
8568 START_PROFILE(SMBfindclose
);
8571 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8572 END_PROFILE(SMBfindclose
);
8576 dptr_num
= SVALS(req
->vwv
+0, 0);
8578 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
8580 dptr_close(sconn
, &dptr_num
);
8582 reply_outbuf(req
, 0, 0);
8584 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
8586 END_PROFILE(SMBfindclose
);
8590 /****************************************************************************
8591 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8592 ****************************************************************************/
8594 void reply_findnclose(struct smb_request
*req
)
8598 START_PROFILE(SMBfindnclose
);
8601 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8602 END_PROFILE(SMBfindnclose
);
8606 dptr_num
= SVAL(req
->vwv
+0, 0);
8608 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
8610 /* We never give out valid handles for a
8611 findnotifyfirst - so any dptr_num is ok here.
8614 reply_outbuf(req
, 0, 0);
8616 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
8618 END_PROFILE(SMBfindnclose
);
8622 static void handle_trans2(connection_struct
*conn
, struct smb_request
*req
,
8623 struct trans_state
*state
)
8625 if (get_Protocol() >= PROTOCOL_NT1
) {
8626 req
->flags2
|= 0x40; /* IS_LONG_NAME */
8627 SSVAL((discard_const_p(uint8_t, req
->inbuf
)),smb_flg2
,req
->flags2
);
8630 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
8631 if (state
->call
!= TRANSACT2_QFSINFO
&&
8632 state
->call
!= TRANSACT2_SETFSINFO
) {
8633 DEBUG(0,("handle_trans2: encryption required "
8635 (unsigned int)state
->call
));
8636 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8641 SMB_PERFCOUNT_SET_SUBOP(&req
->pcd
, state
->call
);
8643 /* Now we must call the relevant TRANS2 function */
8644 switch(state
->call
) {
8645 case TRANSACT2_OPEN
:
8647 START_PROFILE(Trans2_open
);
8648 call_trans2open(conn
, req
,
8649 &state
->param
, state
->total_param
,
8650 &state
->data
, state
->total_data
,
8651 state
->max_data_return
);
8652 END_PROFILE(Trans2_open
);
8656 case TRANSACT2_FINDFIRST
:
8658 START_PROFILE(Trans2_findfirst
);
8659 call_trans2findfirst(conn
, req
,
8660 &state
->param
, state
->total_param
,
8661 &state
->data
, state
->total_data
,
8662 state
->max_data_return
);
8663 END_PROFILE(Trans2_findfirst
);
8667 case TRANSACT2_FINDNEXT
:
8669 START_PROFILE(Trans2_findnext
);
8670 call_trans2findnext(conn
, req
,
8671 &state
->param
, state
->total_param
,
8672 &state
->data
, state
->total_data
,
8673 state
->max_data_return
);
8674 END_PROFILE(Trans2_findnext
);
8678 case TRANSACT2_QFSINFO
:
8680 START_PROFILE(Trans2_qfsinfo
);
8681 call_trans2qfsinfo(conn
, req
,
8682 &state
->param
, state
->total_param
,
8683 &state
->data
, state
->total_data
,
8684 state
->max_data_return
);
8685 END_PROFILE(Trans2_qfsinfo
);
8689 case TRANSACT2_SETFSINFO
:
8691 START_PROFILE(Trans2_setfsinfo
);
8692 call_trans2setfsinfo(conn
, req
,
8693 &state
->param
, state
->total_param
,
8694 &state
->data
, state
->total_data
,
8695 state
->max_data_return
);
8696 END_PROFILE(Trans2_setfsinfo
);
8700 case TRANSACT2_QPATHINFO
:
8701 case TRANSACT2_QFILEINFO
:
8703 START_PROFILE(Trans2_qpathinfo
);
8704 call_trans2qfilepathinfo(conn
, req
, state
->call
,
8705 &state
->param
, state
->total_param
,
8706 &state
->data
, state
->total_data
,
8707 state
->max_data_return
);
8708 END_PROFILE(Trans2_qpathinfo
);
8712 case TRANSACT2_SETPATHINFO
:
8713 case TRANSACT2_SETFILEINFO
:
8715 START_PROFILE(Trans2_setpathinfo
);
8716 call_trans2setfilepathinfo(conn
, req
, state
->call
,
8717 &state
->param
, state
->total_param
,
8718 &state
->data
, state
->total_data
,
8719 state
->max_data_return
);
8720 END_PROFILE(Trans2_setpathinfo
);
8724 case TRANSACT2_FINDNOTIFYFIRST
:
8726 START_PROFILE(Trans2_findnotifyfirst
);
8727 call_trans2findnotifyfirst(conn
, req
,
8728 &state
->param
, state
->total_param
,
8729 &state
->data
, state
->total_data
,
8730 state
->max_data_return
);
8731 END_PROFILE(Trans2_findnotifyfirst
);
8735 case TRANSACT2_FINDNOTIFYNEXT
:
8737 START_PROFILE(Trans2_findnotifynext
);
8738 call_trans2findnotifynext(conn
, req
,
8739 &state
->param
, state
->total_param
,
8740 &state
->data
, state
->total_data
,
8741 state
->max_data_return
);
8742 END_PROFILE(Trans2_findnotifynext
);
8746 case TRANSACT2_MKDIR
:
8748 START_PROFILE(Trans2_mkdir
);
8749 call_trans2mkdir(conn
, req
,
8750 &state
->param
, state
->total_param
,
8751 &state
->data
, state
->total_data
,
8752 state
->max_data_return
);
8753 END_PROFILE(Trans2_mkdir
);
8757 case TRANSACT2_GET_DFS_REFERRAL
:
8759 START_PROFILE(Trans2_get_dfs_referral
);
8760 call_trans2getdfsreferral(conn
, req
,
8761 &state
->param
, state
->total_param
,
8762 &state
->data
, state
->total_data
,
8763 state
->max_data_return
);
8764 END_PROFILE(Trans2_get_dfs_referral
);
8768 case TRANSACT2_IOCTL
:
8770 START_PROFILE(Trans2_ioctl
);
8771 call_trans2ioctl(conn
, req
,
8772 &state
->param
, state
->total_param
,
8773 &state
->data
, state
->total_data
,
8774 state
->max_data_return
);
8775 END_PROFILE(Trans2_ioctl
);
8780 /* Error in request */
8781 DEBUG(2,("Unknown request %d in trans2 call\n", state
->call
));
8782 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8786 /****************************************************************************
8787 Reply to a SMBtrans2.
8788 ****************************************************************************/
8790 void reply_trans2(struct smb_request
*req
)
8792 connection_struct
*conn
= req
->conn
;
8797 unsigned int tran_call
;
8798 struct trans_state
*state
;
8801 START_PROFILE(SMBtrans2
);
8803 if (req
->wct
< 14) {
8804 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8805 END_PROFILE(SMBtrans2
);
8809 dsoff
= SVAL(req
->vwv
+12, 0);
8810 dscnt
= SVAL(req
->vwv
+11, 0);
8811 psoff
= SVAL(req
->vwv
+10, 0);
8812 pscnt
= SVAL(req
->vwv
+9, 0);
8813 tran_call
= SVAL(req
->vwv
+14, 0);
8815 result
= allow_new_trans(conn
->pending_trans
, req
->mid
);
8816 if (!NT_STATUS_IS_OK(result
)) {
8817 DEBUG(2, ("Got invalid trans2 request: %s\n",
8818 nt_errstr(result
)));
8819 reply_nterror(req
, result
);
8820 END_PROFILE(SMBtrans2
);
8825 switch (tran_call
) {
8826 /* List the allowed trans2 calls on IPC$ */
8827 case TRANSACT2_OPEN
:
8828 case TRANSACT2_GET_DFS_REFERRAL
:
8829 case TRANSACT2_QFILEINFO
:
8830 case TRANSACT2_QFSINFO
:
8831 case TRANSACT2_SETFSINFO
:
8834 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8835 END_PROFILE(SMBtrans2
);
8840 if ((state
= talloc(conn
, struct trans_state
)) == NULL
) {
8841 DEBUG(0, ("talloc failed\n"));
8842 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8843 END_PROFILE(SMBtrans2
);
8847 state
->cmd
= SMBtrans2
;
8849 state
->mid
= req
->mid
;
8850 state
->vuid
= req
->vuid
;
8851 state
->setup_count
= SVAL(req
->vwv
+13, 0);
8852 state
->setup
= NULL
;
8853 state
->total_param
= SVAL(req
->vwv
+0, 0);
8854 state
->param
= NULL
;
8855 state
->total_data
= SVAL(req
->vwv
+1, 0);
8857 state
->max_param_return
= SVAL(req
->vwv
+2, 0);
8858 state
->max_data_return
= SVAL(req
->vwv
+3, 0);
8859 state
->max_setup_return
= SVAL(req
->vwv
+4, 0);
8860 state
->close_on_completion
= BITSETW(req
->vwv
+5, 0);
8861 state
->one_way
= BITSETW(req
->vwv
+5, 1);
8863 state
->call
= tran_call
;
8865 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8866 is so as a sanity check */
8867 if (state
->setup_count
!= 1) {
8869 * Need to have rc=0 for ioctl to get job id for OS/2.
8870 * Network printing will fail if function is not successful.
8871 * Similar function in reply.c will be used if protocol
8872 * is LANMAN1.0 instead of LM1.2X002.
8873 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
8874 * outbuf doesn't have to be set(only job id is used).
8876 if ( (state
->setup_count
== 4)
8877 && (tran_call
== TRANSACT2_IOCTL
)
8878 && (SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8879 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8880 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8882 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state
->setup_count
));
8883 DEBUG(2,("Transaction is %d\n",tran_call
));
8885 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8886 END_PROFILE(SMBtrans2
);
8891 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
8894 if (state
->total_data
) {
8896 if (trans_oob(state
->total_data
, 0, dscnt
)
8897 || trans_oob(smb_len(req
->inbuf
), dsoff
, dscnt
)) {
8901 /* Can't use talloc here, the core routines do realloc on the
8902 * params and data. */
8903 state
->data
= (char *)SMB_MALLOC(state
->total_data
);
8904 if (state
->data
== NULL
) {
8905 DEBUG(0,("reply_trans2: data malloc fail for %u "
8906 "bytes !\n", (unsigned int)state
->total_data
));
8908 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8909 END_PROFILE(SMBtrans2
);
8913 memcpy(state
->data
,smb_base(req
->inbuf
)+dsoff
,dscnt
);
8916 if (state
->total_param
) {
8918 if (trans_oob(state
->total_param
, 0, pscnt
)
8919 || trans_oob(smb_len(req
->inbuf
), psoff
, pscnt
)) {
8923 /* Can't use talloc here, the core routines do realloc on the
8924 * params and data. */
8925 state
->param
= (char *)SMB_MALLOC(state
->total_param
);
8926 if (state
->param
== NULL
) {
8927 DEBUG(0,("reply_trans: param malloc fail for %u "
8928 "bytes !\n", (unsigned int)state
->total_param
));
8929 SAFE_FREE(state
->data
);
8931 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8932 END_PROFILE(SMBtrans2
);
8936 memcpy(state
->param
,smb_base(req
->inbuf
)+psoff
,pscnt
);
8939 state
->received_data
= dscnt
;
8940 state
->received_param
= pscnt
;
8942 if ((state
->received_param
== state
->total_param
) &&
8943 (state
->received_data
== state
->total_data
)) {
8945 handle_trans2(conn
, req
, state
);
8947 SAFE_FREE(state
->data
);
8948 SAFE_FREE(state
->param
);
8950 END_PROFILE(SMBtrans2
);
8954 DLIST_ADD(conn
->pending_trans
, state
);
8956 /* We need to send an interim response then receive the rest
8957 of the parameter/data bytes */
8958 reply_outbuf(req
, 0, 0);
8959 show_msg((char *)req
->outbuf
);
8960 END_PROFILE(SMBtrans2
);
8965 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8966 SAFE_FREE(state
->data
);
8967 SAFE_FREE(state
->param
);
8969 END_PROFILE(SMBtrans2
);
8970 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8974 /****************************************************************************
8975 Reply to a SMBtranss2
8976 ****************************************************************************/
8978 void reply_transs2(struct smb_request
*req
)
8980 connection_struct
*conn
= req
->conn
;
8981 unsigned int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
8982 struct trans_state
*state
;
8984 START_PROFILE(SMBtranss2
);
8986 show_msg((const char *)req
->inbuf
);
8988 /* Windows clients expect all replies to
8989 a transact secondary (SMBtranss2 0x33)
8990 to have a command code of transact
8991 (SMBtrans2 0x32). See bug #8989
8992 and also [MS-CIFS] section 2.2.4.47.2
8995 req
->cmd
= SMBtrans2
;
8998 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8999 END_PROFILE(SMBtranss2
);
9003 for (state
= conn
->pending_trans
; state
!= NULL
;
9004 state
= state
->next
) {
9005 if (state
->mid
== req
->mid
) {
9010 if ((state
== NULL
) || (state
->cmd
!= SMBtrans2
)) {
9011 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9012 END_PROFILE(SMBtranss2
);
9016 /* Revise state->total_param and state->total_data in case they have
9017 changed downwards */
9019 if (SVAL(req
->vwv
+0, 0) < state
->total_param
)
9020 state
->total_param
= SVAL(req
->vwv
+0, 0);
9021 if (SVAL(req
->vwv
+1, 0) < state
->total_data
)
9022 state
->total_data
= SVAL(req
->vwv
+1, 0);
9024 pcnt
= SVAL(req
->vwv
+2, 0);
9025 poff
= SVAL(req
->vwv
+3, 0);
9026 pdisp
= SVAL(req
->vwv
+4, 0);
9028 dcnt
= SVAL(req
->vwv
+5, 0);
9029 doff
= SVAL(req
->vwv
+6, 0);
9030 ddisp
= SVAL(req
->vwv
+7, 0);
9032 state
->received_param
+= pcnt
;
9033 state
->received_data
+= dcnt
;
9035 if ((state
->received_data
> state
->total_data
) ||
9036 (state
->received_param
> state
->total_param
))
9040 if (trans_oob(state
->total_param
, pdisp
, pcnt
)
9041 || trans_oob(smb_len(req
->inbuf
), poff
, pcnt
)) {
9044 memcpy(state
->param
+pdisp
,smb_base(req
->inbuf
)+poff
,pcnt
);
9048 if (trans_oob(state
->total_data
, ddisp
, dcnt
)
9049 || trans_oob(smb_len(req
->inbuf
), doff
, dcnt
)) {
9052 memcpy(state
->data
+ddisp
, smb_base(req
->inbuf
)+doff
,dcnt
);
9055 if ((state
->received_param
< state
->total_param
) ||
9056 (state
->received_data
< state
->total_data
)) {
9057 END_PROFILE(SMBtranss2
);
9061 handle_trans2(conn
, req
, state
);
9063 DLIST_REMOVE(conn
->pending_trans
, state
);
9064 SAFE_FREE(state
->data
);
9065 SAFE_FREE(state
->param
);
9068 END_PROFILE(SMBtranss2
);
9073 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
9074 DLIST_REMOVE(conn
->pending_trans
, state
);
9075 SAFE_FREE(state
->data
);
9076 SAFE_FREE(state
->param
);
9078 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9079 END_PROFILE(SMBtranss2
);