2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2007
5 Copyright (C) Stefan (metze) Metzmacher 2003
6 Copyright (C) Volker Lendecke 2005-2007
7 Copyright (C) Steve French 2005
8 Copyright (C) James Peach 2006-2007
10 Extensively modified by Andrew Tridgell, 1995
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include "system/filesys.h"
29 #include "lib/util/time_basic.h"
31 #include "smbd/smbd.h"
32 #include "smbd/globals.h"
33 #include "../libcli/auth/libcli_auth.h"
34 #include "../librpc/gen_ndr/xattr.h"
35 #include "../librpc/gen_ndr/ndr_security.h"
36 #include "libcli/security/security.h"
39 #include "smbprofile.h"
40 #include "rpc_server/srv_pipe_hnd.h"
42 #include "lib/util_ea.h"
43 #include "lib/readdir_attr.h"
45 #include "libcli/smb/smb2_posix.h"
46 #include "lib/util/string_wrappers.h"
47 #include "source3/lib/substitute.h"
48 #include "source3/lib/adouble.h"
50 #define DIR_ENTRY_SAFETY_MARGIN 4096
52 static uint32_t generate_volume_serial_number(
53 const struct loadparm_substitution
*lp_sub
,
56 /****************************************************************************
57 Check if an open file handle is a symlink.
58 ****************************************************************************/
60 NTSTATUS
refuse_symlink_fsp(const files_struct
*fsp
)
63 if (!VALID_STAT(fsp
->fsp_name
->st
)) {
64 return NT_STATUS_ACCESS_DENIED
;
66 if (S_ISLNK(fsp
->fsp_name
->st
.st_ex_mode
)) {
67 return NT_STATUS_ACCESS_DENIED
;
69 if (fsp_get_pathref_fd(fsp
) == -1) {
70 return NT_STATUS_ACCESS_DENIED
;
75 NTSTATUS
check_access_fsp(struct files_struct
*fsp
,
78 if (!fsp
->fsp_flags
.is_fsa
) {
79 return smbd_check_access_rights_fsp(fsp
->conn
->cwd_fsp
,
84 if (!(fsp
->access_mask
& access_mask
)) {
85 return NT_STATUS_ACCESS_DENIED
;
90 /********************************************************************
91 Roundup a value to the nearest allocation roundup size boundary.
92 Only do this for Windows clients.
93 ********************************************************************/
95 uint64_t smb_roundup(connection_struct
*conn
, uint64_t val
)
97 uint64_t rval
= lp_allocation_roundup_size(SNUM(conn
));
99 /* Only roundup for Windows clients. */
100 enum remote_arch_types ra_type
= get_remote_arch();
101 if (rval
&& (ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
102 val
= SMB_ROUNDUP(val
,rval
);
107 /****************************************************************************
108 Utility functions for dealing with extended attributes.
109 ****************************************************************************/
111 /****************************************************************************
112 Refuse to allow clients to overwrite our private xattrs.
113 ****************************************************************************/
115 bool samba_private_attr_name(const char *unix_ea_name
)
117 bool prohibited
= false;
119 prohibited
|= strequal(unix_ea_name
, SAMBA_POSIX_INHERITANCE_EA_NAME
);
120 prohibited
|= strequal(unix_ea_name
, SAMBA_XATTR_DOS_ATTRIB
);
121 prohibited
|= strequal(unix_ea_name
, SAMBA_XATTR_MARKER
);
122 prohibited
|= strequal(unix_ea_name
, XATTR_NTACL_NAME
);
123 prohibited
|= strequal(unix_ea_name
, AFPINFO_EA_NETATALK
);
129 if (strncasecmp_m(unix_ea_name
, SAMBA_XATTR_DOSSTREAM_PREFIX
,
130 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX
)) == 0) {
136 /****************************************************************************
137 Get one EA value. Fill in a struct ea_struct.
138 ****************************************************************************/
140 NTSTATUS
get_ea_value_fsp(TALLOC_CTX
*mem_ctx
,
143 struct ea_struct
*pea
)
145 /* Get the value of this xattr. Max size is 64k. */
146 size_t attr_size
= 256;
149 size_t max_xattr_size
= 0;
152 return NT_STATUS_INVALID_HANDLE
;
155 max_xattr_size
= lp_smbd_max_xattr_size(SNUM(fsp
->conn
));
159 val
= talloc_realloc(mem_ctx
, val
, char, attr_size
);
161 return NT_STATUS_NO_MEMORY
;
164 sizeret
= SMB_VFS_FGETXATTR(fsp
, ea_name
, val
, attr_size
);
165 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
< max_xattr_size
) {
166 attr_size
= max_xattr_size
;
171 return map_nt_error_from_unix(errno
);
174 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name
, (unsigned int)sizeret
));
175 dump_data(10, (uint8_t *)val
, sizeret
);
178 if (strnequal(ea_name
, "user.", 5)) {
179 pea
->name
= talloc_strdup(mem_ctx
, &ea_name
[5]);
181 pea
->name
= talloc_strdup(mem_ctx
, ea_name
);
183 if (pea
->name
== NULL
) {
185 return NT_STATUS_NO_MEMORY
;
187 pea
->value
.data
= (unsigned char *)val
;
188 pea
->value
.length
= (size_t)sizeret
;
192 NTSTATUS
get_ea_names_from_fsp(TALLOC_CTX
*mem_ctx
,
198 /* Get a list of all xattrs. Max namesize is 64k. */
199 size_t ea_namelist_size
= 1024;
200 char *ea_namelist
= smallbuf
;
201 char *to_free
= NULL
;
206 ssize_t sizeret
= -1;
216 * Callers may pass fsp == NULL when passing smb_fname->fsp of a
217 * symlink. This is ok, handle it here, by just return no EA's
223 /* should be the case that fsp != NULL */
224 SMB_ASSERT(fsp
!= NULL
);
226 sizeret
= SMB_VFS_FLISTXATTR(fsp
, ea_namelist
,
229 if ((sizeret
== -1) && (errno
== ERANGE
)) {
230 ea_namelist_size
= 65536;
231 ea_namelist
= talloc_array(mem_ctx
, char, ea_namelist_size
);
232 if (ea_namelist
== NULL
) {
233 return NT_STATUS_NO_MEMORY
;
235 to_free
= ea_namelist
;
237 sizeret
= SMB_VFS_FLISTXATTR(fsp
, ea_namelist
,
242 status
= map_nt_error_from_unix(errno
);
243 TALLOC_FREE(to_free
);
247 DBG_DEBUG("ea_namelist size = %zd\n", sizeret
);
250 TALLOC_FREE(to_free
);
255 * Ensure the result is 0-terminated
258 if (ea_namelist
[sizeret
-1] != '\0') {
259 TALLOC_FREE(to_free
);
260 return NT_STATUS_INTERNAL_ERROR
;
268 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
272 *pnum_names
= num_names
;
274 if (pnames
== NULL
) {
275 TALLOC_FREE(to_free
);
279 names
= talloc_array(mem_ctx
, char *, num_names
);
281 DEBUG(0, ("talloc failed\n"));
282 TALLOC_FREE(to_free
);
283 return NT_STATUS_NO_MEMORY
;
286 if (ea_namelist
== smallbuf
) {
287 ea_namelist
= talloc_memdup(names
, smallbuf
, sizeret
);
288 if (ea_namelist
== NULL
) {
290 return NT_STATUS_NO_MEMORY
;
293 talloc_steal(names
, ea_namelist
);
295 ea_namelist
= talloc_realloc(names
, ea_namelist
, char,
297 if (ea_namelist
== NULL
) {
299 return NT_STATUS_NO_MEMORY
;
305 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
306 names
[num_names
++] = p
;
314 /****************************************************************************
315 Return a linked list of the total EA's. Plus the total size
316 ****************************************************************************/
318 static NTSTATUS
get_ea_list_from_fsp(TALLOC_CTX
*mem_ctx
,
320 size_t *pea_total_len
,
321 struct ea_list
**ea_list
)
323 /* Get a list of all xattrs. Max namesize is 64k. */
326 struct ea_list
*ea_list_head
= NULL
;
327 bool posix_pathnames
= false;
338 if (!lp_ea_support(SNUM(fsp
->conn
))) {
342 if (fsp_is_alternate_stream(fsp
)) {
343 return NT_STATUS_INVALID_PARAMETER
;
346 posix_pathnames
= (fsp
->fsp_name
->flags
& SMB_FILENAME_POSIX_PATH
);
348 status
= get_ea_names_from_fsp(talloc_tos(),
353 if (!NT_STATUS_IS_OK(status
)) {
357 if (num_names
== 0) {
361 for (i
=0; i
<num_names
; i
++) {
362 struct ea_list
*listp
;
366 * POSIX EA names are divided into several namespaces by
367 * means of string prefixes. Usually, the system controls
368 * semantics for each namespace, but the 'user' namespace is
369 * available for arbitrary use, which comes closest to
370 * Windows EA semantics. Hence, we map POSIX EAs from the
371 * 'user' namespace to Windows EAs, and just ignore all the
372 * other namespaces. Also, a few specific names in the 'user'
373 * namespace are used by Samba internally. Filter them out as
374 * well, and only present the EAs that are available for
377 if (!strnequal(names
[i
], "user.", 5)
378 || samba_private_attr_name(names
[i
]))
382 * Filter out any underlying POSIX EA names
383 * that a Windows client can't handle.
385 if (!posix_pathnames
&&
386 is_invalid_windows_ea_name(names
[i
])) {
390 listp
= talloc(mem_ctx
, struct ea_list
);
392 return NT_STATUS_NO_MEMORY
;
395 status
= get_ea_value_fsp(listp
,
400 if (!NT_STATUS_IS_OK(status
)) {
405 if (listp
->ea
.value
.length
== 0) {
407 * We can never return a zero length EA.
408 * Windows reports the EA's as corrupted.
412 } else if (listp
->ea
.value
.length
> 65536) {
414 * SMB clients may report error with file
415 * if large EA is presented to them.
417 DBG_ERR("EA [%s] on file [%s] exceeds "
418 "maximum permitted EA size of 64KiB: %zu\n.",
419 listp
->ea
.name
, fsp_str_dbg(fsp
),
420 listp
->ea
.value
.length
);
425 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
428 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
430 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
431 "= %u\n", (unsigned int)*pea_total_len
, dos_ea_name
,
432 (unsigned int)listp
->ea
.value
.length
));
434 DLIST_ADD_END(ea_list_head
, listp
);
438 /* Add on 4 for total length. */
439 if (*pea_total_len
) {
443 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
444 (unsigned int)*pea_total_len
));
446 *ea_list
= ea_list_head
;
450 /****************************************************************************
451 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
453 ****************************************************************************/
455 static unsigned int fill_ea_buffer(TALLOC_CTX
*mem_ctx
, char *pdata
, unsigned int total_data_size
,
456 connection_struct
*conn
, struct ea_list
*ea_list
)
458 unsigned int ret_data_size
= 4;
461 SMB_ASSERT(total_data_size
>= 4);
463 if (!lp_ea_support(SNUM(conn
))) {
468 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
471 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
472 dos_namelen
= strlen(dos_ea_name
);
473 if (dos_namelen
> 255 || dos_namelen
== 0) {
476 if (ea_list
->ea
.value
.length
> 65535) {
479 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
483 /* We know we have room. */
484 SCVAL(p
,0,ea_list
->ea
.flags
);
485 SCVAL(p
,1,dos_namelen
);
486 SSVAL(p
,2,ea_list
->ea
.value
.length
);
487 strlcpy(p
+4, dos_ea_name
, dos_namelen
+1);
488 if (ea_list
->ea
.value
.length
> 0) {
489 memcpy(p
+ 4 + dos_namelen
+ 1,
490 ea_list
->ea
.value
.data
,
491 ea_list
->ea
.value
.length
);
494 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
495 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
498 ret_data_size
= PTR_DIFF(p
, pdata
);
499 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size
));
500 SIVAL(pdata
,0,ret_data_size
);
501 return ret_data_size
;
504 static NTSTATUS
fill_ea_chained_buffer(TALLOC_CTX
*mem_ctx
,
506 unsigned int total_data_size
,
507 unsigned int *ret_data_size
,
508 connection_struct
*conn
,
509 struct ea_list
*ea_list
)
511 uint8_t *p
= (uint8_t *)pdata
;
512 uint8_t *last_start
= NULL
;
513 bool do_store_data
= (pdata
!= NULL
);
517 if (!lp_ea_support(SNUM(conn
))) {
518 return NT_STATUS_NO_EAS_ON_FILE
;
521 for (; ea_list
; ea_list
= ea_list
->next
) {
527 if (last_start
!= NULL
&& do_store_data
) {
528 SIVAL(last_start
, 0, PTR_DIFF(p
, last_start
));
532 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
533 dos_namelen
= strlen(dos_ea_name
);
534 if (dos_namelen
> 255 || dos_namelen
== 0) {
535 return NT_STATUS_INTERNAL_ERROR
;
537 if (ea_list
->ea
.value
.length
> 65535) {
538 return NT_STATUS_INTERNAL_ERROR
;
541 this_size
= 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
544 pad
= (4 - (this_size
% 4)) % 4;
549 if (this_size
> total_data_size
) {
550 return NT_STATUS_INFO_LENGTH_MISMATCH
;
553 /* We know we have room. */
554 SIVAL(p
, 0x00, 0); /* next offset */
555 SCVAL(p
, 0x04, ea_list
->ea
.flags
);
556 SCVAL(p
, 0x05, dos_namelen
);
557 SSVAL(p
, 0x06, ea_list
->ea
.value
.length
);
558 strlcpy((char *)(p
+0x08), dos_ea_name
, dos_namelen
+1);
559 memcpy(p
+ 0x08 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
561 memset(p
+ 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
,
565 total_data_size
-= this_size
;
571 *ret_data_size
= PTR_DIFF(p
, pdata
);
572 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size
));
576 unsigned int estimate_ea_size(files_struct
*fsp
)
578 size_t total_ea_len
= 0;
580 struct ea_list
*ea_list
= NULL
;
588 if (!lp_ea_support(SNUM(fsp
->conn
))) {
592 mem_ctx
= talloc_stackframe();
594 /* If this is a stream fsp, then we need to instead find the
595 * estimated ea len from the main file, not the stream
596 * (streams cannot have EAs), but the estimate isn't just 0 in
598 fsp
= metadata_fsp(fsp
);
599 (void)get_ea_list_from_fsp(mem_ctx
,
604 if(fsp
->conn
->sconn
->using_smb2
) {
605 unsigned int ret_data_size
;
607 * We're going to be using fill_ea_chained_buffer() to
608 * marshall EA's - this size is significantly larger
609 * than the SMB1 buffer. Re-calculate the size without
612 status
= fill_ea_chained_buffer(mem_ctx
,
618 if (!NT_STATUS_IS_OK(status
)) {
621 total_ea_len
= ret_data_size
;
623 TALLOC_FREE(mem_ctx
);
627 /****************************************************************************
628 Ensure the EA name is case insensitive by matching any existing EA name.
629 ****************************************************************************/
631 static void canonicalize_ea_name(files_struct
*fsp
,
632 fstring unix_ea_name
)
635 TALLOC_CTX
*mem_ctx
= talloc_tos();
636 struct ea_list
*ea_list
;
637 NTSTATUS status
= get_ea_list_from_fsp(mem_ctx
,
641 if (!NT_STATUS_IS_OK(status
)) {
645 for (; ea_list
; ea_list
= ea_list
->next
) {
646 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
647 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
648 &unix_ea_name
[5], ea_list
->ea
.name
));
649 strlcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-5);
655 /****************************************************************************
656 Set or delete an extended attribute.
657 ****************************************************************************/
659 NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
,
660 struct ea_list
*ea_list
)
663 bool posix_pathnames
= false;
665 if (!lp_ea_support(SNUM(conn
))) {
666 return NT_STATUS_EAS_NOT_SUPPORTED
;
670 return NT_STATUS_INVALID_HANDLE
;
673 posix_pathnames
= (fsp
->fsp_name
->flags
& SMB_FILENAME_POSIX_PATH
);
675 status
= refuse_symlink_fsp(fsp
);
676 if (!NT_STATUS_IS_OK(status
)) {
680 status
= check_access_fsp(fsp
, FILE_WRITE_EA
);
681 if (!NT_STATUS_IS_OK(status
)) {
685 /* Setting EAs on streams isn't supported. */
686 if (fsp_is_alternate_stream(fsp
)) {
687 return NT_STATUS_INVALID_PARAMETER
;
691 * Filter out invalid Windows EA names - before
692 * we set *any* of them.
695 if (!posix_pathnames
&& ea_list_has_invalid_name(ea_list
)) {
696 return STATUS_INVALID_EA_NAME
;
699 for (;ea_list
; ea_list
= ea_list
->next
) {
701 fstring unix_ea_name
;
704 * Complementing the forward mapping from POSIX EAs to
705 * Windows EAs in get_ea_list_from_fsp(), here we map in the
706 * opposite direction from Windows EAs to the 'user' namespace
707 * of POSIX EAs. Hence, all POSIX EA names the we set here must
708 * start with a 'user.' prefix.
710 fstrcpy(unix_ea_name
, "user.");
711 fstrcat(unix_ea_name
, ea_list
->ea
.name
);
713 canonicalize_ea_name(fsp
, unix_ea_name
);
715 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, (unsigned int)ea_list
->ea
.value
.length
));
717 if (samba_private_attr_name(unix_ea_name
)) {
718 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
719 return NT_STATUS_ACCESS_DENIED
;
722 if (ea_list
->ea
.value
.length
== 0) {
723 /* Remove the attribute. */
724 DBG_DEBUG("deleting ea name %s on "
725 "file %s by file descriptor.\n",
726 unix_ea_name
, fsp_str_dbg(fsp
));
727 ret
= SMB_VFS_FREMOVEXATTR(fsp
, unix_ea_name
);
729 /* Removing a non existent attribute always succeeds. */
730 if (ret
== -1 && errno
== ENOATTR
) {
731 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
737 DEBUG(10,("set_ea: setting ea name %s on file "
738 "%s by file descriptor.\n",
739 unix_ea_name
, fsp_str_dbg(fsp
)));
740 ret
= SMB_VFS_FSETXATTR(fsp
, unix_ea_name
,
741 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
746 if (errno
== ENOTSUP
) {
747 return NT_STATUS_EAS_NOT_SUPPORTED
;
750 return map_nt_error_from_unix(errno
);
757 /****************************************************************************
758 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
759 ****************************************************************************/
761 struct ea_list
*read_ea_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
763 struct ea_list
*ea_list_head
= NULL
;
765 size_t bytes_used
= 0;
767 while (offset
< data_size
) {
768 struct ea_list
*eal
= read_ea_list_entry(ctx
, pdata
+ offset
, data_size
- offset
, &bytes_used
);
774 DLIST_ADD_END(ea_list_head
, eal
);
775 offset
+= bytes_used
;
781 /****************************************************************************
782 Count the total EA size needed.
783 ****************************************************************************/
785 static size_t ea_list_size(struct ea_list
*ealist
)
788 struct ea_list
*listp
;
791 for (listp
= ealist
; listp
; listp
= listp
->next
) {
792 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
793 ret
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
795 /* Add on 4 for total length. */
803 /****************************************************************************
804 Return a union of EA's from a file list and a list of names.
805 The TALLOC context for the two lists *MUST* be identical as we steal
806 memory from one list to add to another. JRA.
807 ****************************************************************************/
809 static struct ea_list
*ea_list_union(struct ea_list
*name_list
, struct ea_list
*file_list
, size_t *total_ea_len
)
811 struct ea_list
*nlistp
, *flistp
;
813 for (nlistp
= name_list
; nlistp
; nlistp
= nlistp
->next
) {
814 for (flistp
= file_list
; flistp
; flistp
= flistp
->next
) {
815 if (strequal(nlistp
->ea
.name
, flistp
->ea
.name
)) {
821 /* Copy the data from this entry. */
822 nlistp
->ea
.flags
= flistp
->ea
.flags
;
823 nlistp
->ea
.value
= flistp
->ea
.value
;
826 nlistp
->ea
.flags
= 0;
827 ZERO_STRUCT(nlistp
->ea
.value
);
831 *total_ea_len
= ea_list_size(name_list
);
835 /*********************************************************
836 Routine to check if a given string matches exactly.
837 as a special case a mask of "." does NOT match. That
838 is required for correct wildcard semantics
839 Case can be significant or not.
840 **********************************************************/
842 static bool exact_match(bool has_wild
,
847 if (mask
[0] == '.' && mask
[1] == 0) {
855 if (case_sensitive
) {
856 return strcmp(str
,mask
)==0;
858 return strcasecmp_m(str
,mask
) == 0;
862 /****************************************************************************
863 Return the filetype for UNIX extensions.
864 ****************************************************************************/
866 static uint32_t unix_filetype(mode_t mode
)
869 return UNIX_TYPE_FILE
;
870 else if(S_ISDIR(mode
))
871 return UNIX_TYPE_DIR
;
873 else if(S_ISLNK(mode
))
874 return UNIX_TYPE_SYMLINK
;
877 else if(S_ISCHR(mode
))
878 return UNIX_TYPE_CHARDEV
;
881 else if(S_ISBLK(mode
))
882 return UNIX_TYPE_BLKDEV
;
885 else if(S_ISFIFO(mode
))
886 return UNIX_TYPE_FIFO
;
889 else if(S_ISSOCK(mode
))
890 return UNIX_TYPE_SOCKET
;
893 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode
));
894 return UNIX_TYPE_UNKNOWN
;
897 /****************************************************************************
898 Map wire perms onto standard UNIX permissions. Obey share restrictions.
899 ****************************************************************************/
901 NTSTATUS
unix_perms_from_wire(connection_struct
*conn
,
902 const SMB_STRUCT_STAT
*psbuf
,
904 enum perm_type ptype
,
909 if (perms
== SMB_MODE_NO_CHANGE
) {
910 if (!VALID_STAT(*psbuf
)) {
911 return NT_STATUS_INVALID_PARAMETER
;
913 *ret_perms
= psbuf
->st_ex_mode
;
918 ret
= wire_perms_to_unix(perms
);
920 if (ptype
== PERM_NEW_FILE
) {
922 * "create mask"/"force create mode" are
923 * only applied to new files, not existing ones.
925 ret
&= lp_create_mask(SNUM(conn
));
926 /* Add in force bits */
927 ret
|= lp_force_create_mode(SNUM(conn
));
928 } else if (ptype
== PERM_NEW_DIR
) {
930 * "directory mask"/"force directory mode" are
931 * only applied to new directories, not existing ones.
933 ret
&= lp_directory_mask(SNUM(conn
));
934 /* Add in force bits */
935 ret
|= lp_force_directory_mode(SNUM(conn
));
942 /****************************************************************************
943 Needed to show the msdfs symlinks as directories. Modifies psbuf
944 to be a directory if it's a msdfs link.
945 ****************************************************************************/
947 static bool check_msdfs_link(struct files_struct
*dirfsp
,
948 struct smb_filename
*atname
,
949 struct smb_filename
*smb_fname
)
951 int saved_errno
= errno
;
952 if(lp_host_msdfs() &&
953 lp_msdfs_root(SNUM(dirfsp
->conn
)) &&
954 is_msdfs_link(dirfsp
, atname
)) {
957 * Copy the returned stat struct from the relative
958 * to the full pathname.
960 smb_fname
->st
= atname
->st
;
962 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
964 smb_fname
->base_name
));
965 smb_fname
->st
.st_ex_mode
=
966 (smb_fname
->st
.st_ex_mode
& 0xFFF) | S_IFDIR
;
975 /****************************************************************************
976 Get a level dependent lanman2 dir entry.
977 ****************************************************************************/
979 struct smbd_dirptr_lanman2_state
{
980 connection_struct
*conn
;
982 bool check_mangled_names
;
984 bool got_exact_match
;
988 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX
*ctx
,
994 struct smbd_dirptr_lanman2_state
*state
=
995 (struct smbd_dirptr_lanman2_state
*)private_data
;
997 char mangled_name
[13]; /* mangled 8.3 name. */
1001 /* Mangle fname if it's an illegal name. */
1002 if (mangle_must_mangle(dname
, state
->conn
->params
)) {
1004 * Slow path - ensure we can push the original name as UCS2. If
1005 * not, then just don't return this name.
1009 size_t len
= (strlen(dname
) + 2) * 4; /* Allow enough space. */
1010 uint8_t *tmp
= talloc_array(talloc_tos(),
1014 status
= srvstr_push(NULL
,
1015 FLAGS2_UNICODE_STRINGS
,
1024 if (!NT_STATUS_IS_OK(status
)) {
1028 ok
= name_to_8_3(dname
, mangled_name
,
1029 true, state
->conn
->params
);
1033 fname
= mangled_name
;
1038 got_match
= exact_match(state
->has_wild
,
1039 state
->case_sensitive
,
1041 state
->got_exact_match
= got_match
;
1043 got_match
= mask_match(fname
, mask
,
1044 state
->case_sensitive
);
1047 if(!got_match
&& state
->check_mangled_names
&&
1048 !mangle_is_8_3(fname
, false, state
->conn
->params
)) {
1050 * It turns out that NT matches wildcards against
1051 * both long *and* short names. This may explain some
1052 * of the wildcard wierdness from old DOS clients
1053 * that some people have been seeing.... JRA.
1055 /* Force the mangling into 8.3. */
1056 ok
= name_to_8_3(fname
, mangled_name
,
1057 false, state
->conn
->params
);
1062 got_match
= exact_match(state
->has_wild
,
1063 state
->case_sensitive
,
1064 mangled_name
, mask
);
1065 state
->got_exact_match
= got_match
;
1067 got_match
= mask_match(mangled_name
, mask
,
1068 state
->case_sensitive
);
1076 *_fname
= talloc_strdup(ctx
, fname
);
1077 if (*_fname
== NULL
) {
1084 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX
*ctx
,
1086 struct files_struct
*dirfsp
,
1087 struct smb_filename
*atname
,
1088 struct smb_filename
*smb_fname
,
1092 struct smbd_dirptr_lanman2_state
*state
=
1093 (struct smbd_dirptr_lanman2_state
*)private_data
;
1094 bool ms_dfs_link
= false;
1096 if (smb_fname
->flags
& SMB_FILENAME_POSIX_PATH
) {
1097 if (SMB_VFS_LSTAT(state
->conn
, smb_fname
) != 0) {
1098 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1099 "Couldn't lstat [%s] (%s)\n",
1100 smb_fname_str_dbg(smb_fname
),
1107 if (!VALID_STAT(smb_fname
->st
) &&
1108 SMB_VFS_STAT(state
->conn
, smb_fname
) != 0) {
1109 /* Needed to show the msdfs symlinks as
1112 ms_dfs_link
= check_msdfs_link(dirfsp
,
1116 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1117 "Couldn't stat [%s] (%s)\n",
1118 smb_fname_str_dbg(smb_fname
),
1123 *_mode
= dos_mode_msdfs(state
->conn
, smb_fname
);
1131 *_mode
= fdos_mode(smb_fname
->fsp
);
1132 smb_fname
->st
= smb_fname
->fsp
->fsp_name
->st
;
1137 static uint32_t get_dirent_ea_size(uint32_t mode
, files_struct
*fsp
)
1139 if (!(mode
& FILE_ATTRIBUTE_REPARSE_POINT
)) {
1140 unsigned ea_size
= estimate_ea_size(fsp
);
1143 return IO_REPARSE_TAG_DFS
;
1146 static NTSTATUS
smbd_marshall_dir_entry(TALLOC_CTX
*ctx
,
1147 connection_struct
*conn
,
1149 uint32_t info_level
,
1150 struct ea_list
*name_list
,
1151 bool check_mangled_names
,
1152 bool requires_resume_key
,
1155 const struct smb_filename
*smb_fname
,
1156 int space_remaining
,
1162 uint64_t *last_entry_off
)
1164 char *p
, *q
, *pdata
= *ppdata
;
1166 uint64_t file_size
= 0;
1167 uint64_t allocation_size
= 0;
1168 uint64_t file_id
= 0;
1170 struct timespec mdate_ts
= {0};
1171 struct timespec adate_ts
= {0};
1172 struct timespec cdate_ts
= {0};
1173 struct timespec create_date_ts
= {0};
1174 time_t mdate
= (time_t)0, adate
= (time_t)0, create_date
= (time_t)0;
1176 char *last_entry_ptr
;
1181 struct readdir_attr_data
*readdir_attr_data
= NULL
;
1184 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
1185 file_size
= get_file_size_stat(&smb_fname
->st
);
1187 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, NULL
, &smb_fname
->st
);
1190 * Skip SMB_VFS_FREADDIR_ATTR if the directory entry is a symlink or
1193 if (smb_fname
->fsp
!= NULL
&&
1194 !(mode
& FILE_ATTRIBUTE_REPARSE_POINT
)) {
1195 status
= SMB_VFS_FREADDIR_ATTR(smb_fname
->fsp
,
1197 &readdir_attr_data
);
1198 if (!NT_STATUS_IS_OK(status
)) {
1199 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED
,
1206 file_id
= SMB_VFS_FS_FILE_ID(conn
, &smb_fname
->st
);
1208 mdate_ts
= smb_fname
->st
.st_ex_mtime
;
1209 adate_ts
= smb_fname
->st
.st_ex_atime
;
1210 create_date_ts
= get_create_timespec(conn
, NULL
, smb_fname
);
1211 cdate_ts
= get_change_timespec(conn
, NULL
, smb_fname
);
1213 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1214 dos_filetime_timespec(&create_date_ts
);
1215 dos_filetime_timespec(&mdate_ts
);
1216 dos_filetime_timespec(&adate_ts
);
1217 dos_filetime_timespec(&cdate_ts
);
1220 create_date
= convert_timespec_to_time_t(create_date_ts
);
1221 mdate
= convert_timespec_to_time_t(mdate_ts
);
1222 adate
= convert_timespec_to_time_t(adate_ts
);
1224 /* align the record */
1225 SMB_ASSERT(align
>= 1);
1227 off
= (int)PTR_DIFF(pdata
, base_data
);
1228 pad
= (off
+ (align
-1)) & ~(align
-1);
1231 if (pad
&& pad
> space_remaining
) {
1232 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1233 "for padding (wanted %u, had %d)\n",
1236 return STATUS_MORE_ENTRIES
; /* Not finished - just out of space */
1240 /* initialize padding to 0 */
1242 memset(pdata
, 0, pad
);
1244 space_remaining
-= pad
;
1246 DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1256 switch (info_level
) {
1257 case SMB_FIND_INFO_STANDARD
:
1258 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1259 if(requires_resume_key
) {
1263 srv_put_dos_date2(p
,0,create_date
);
1264 srv_put_dos_date2(p
,4,adate
);
1265 srv_put_dos_date2(p
,8,mdate
);
1266 SIVAL(p
,12,(uint32_t)file_size
);
1267 SIVAL(p
,16,(uint32_t)allocation_size
);
1271 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1272 p
+= ucs2_align(base_data
, p
, 0);
1274 status
= srvstr_push(base_data
, flags2
, p
,
1275 fname
, PTR_DIFF(end_data
, p
),
1276 STR_TERMINATE
, &len
);
1277 if (!NT_STATUS_IS_OK(status
)) {
1280 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1282 SCVAL(nameptr
, -1, len
- 2);
1284 SCVAL(nameptr
, -1, 0);
1288 SCVAL(nameptr
, -1, len
- 1);
1290 SCVAL(nameptr
, -1, 0);
1296 case SMB_FIND_EA_SIZE
:
1297 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1298 if (requires_resume_key
) {
1302 srv_put_dos_date2(p
,0,create_date
);
1303 srv_put_dos_date2(p
,4,adate
);
1304 srv_put_dos_date2(p
,8,mdate
);
1305 SIVAL(p
,12,(uint32_t)file_size
);
1306 SIVAL(p
,16,(uint32_t)allocation_size
);
1309 ea_size
= estimate_ea_size(smb_fname
->fsp
);
1310 SIVAL(p
,22,ea_size
); /* Extended attributes */
1314 status
= srvstr_push(base_data
, flags2
,
1315 p
, fname
, PTR_DIFF(end_data
, p
),
1316 STR_TERMINATE
| STR_NOALIGN
, &len
);
1317 if (!NT_STATUS_IS_OK(status
)) {
1320 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1333 SCVAL(nameptr
,0,len
);
1335 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1338 case SMB_FIND_EA_LIST
:
1340 struct ea_list
*file_list
= NULL
;
1343 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1345 return NT_STATUS_INVALID_PARAMETER
;
1347 if (requires_resume_key
) {
1351 srv_put_dos_date2(p
,0,create_date
);
1352 srv_put_dos_date2(p
,4,adate
);
1353 srv_put_dos_date2(p
,8,mdate
);
1354 SIVAL(p
,12,(uint32_t)file_size
);
1355 SIVAL(p
,16,(uint32_t)allocation_size
);
1357 p
+= 22; /* p now points to the EA area. */
1359 status
= get_ea_list_from_fsp(ctx
,
1361 &ea_len
, &file_list
);
1362 if (!NT_STATUS_IS_OK(status
)) {
1365 name_list
= ea_list_union(name_list
, file_list
, &ea_len
);
1367 /* We need to determine if this entry will fit in the space available. */
1368 /* Max string size is 255 bytes. */
1369 if (PTR_DIFF(p
+ 255 + ea_len
,pdata
) > space_remaining
) {
1370 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1371 "(wanted %u, had %d)\n",
1372 (unsigned int)PTR_DIFF(p
+ 255 + ea_len
,pdata
),
1374 return STATUS_MORE_ENTRIES
; /* Not finished - just out of space */
1377 /* Push the ea_data followed by the name. */
1378 p
+= fill_ea_buffer(ctx
, p
, space_remaining
, conn
, name_list
);
1380 status
= srvstr_push(base_data
, flags2
,
1381 p
+ 1, fname
, PTR_DIFF(end_data
, p
+1),
1382 STR_TERMINATE
| STR_NOALIGN
, &len
);
1383 if (!NT_STATUS_IS_OK(status
)) {
1386 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1399 SCVAL(nameptr
,0,len
);
1401 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1405 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1406 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1407 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1409 SIVAL(p
,0,reskey
); p
+= 4;
1410 put_long_date_full_timespec(conn
->ts_res
,p
,&create_date_ts
); p
+= 8;
1411 put_long_date_full_timespec(conn
->ts_res
,p
,&adate_ts
); p
+= 8;
1412 put_long_date_full_timespec(conn
->ts_res
,p
,&mdate_ts
); p
+= 8;
1413 put_long_date_full_timespec(conn
->ts_res
,p
,&cdate_ts
); p
+= 8;
1414 SOFF_T(p
,0,file_size
); p
+= 8;
1415 SOFF_T(p
,0,allocation_size
); p
+= 8;
1416 SIVAL(p
,0,mode
); p
+= 4;
1417 q
= p
; p
+= 4; /* q is placeholder for name length. */
1418 ea_size
= get_dirent_ea_size(mode
, smb_fname
->fsp
);
1419 SIVAL(p
, 0, ea_size
);
1421 /* Clear the short name buffer. This is
1422 * IMPORTANT as not doing so will trigger
1423 * a Win2k client bug. JRA.
1425 if (!was_8_3
&& check_mangled_names
) {
1426 char mangled_name
[13]; /* mangled 8.3 name. */
1427 if (!name_to_8_3(fname
,mangled_name
,True
,
1429 /* Error - mangle failed ! */
1430 memset(mangled_name
,'\0',12);
1432 mangled_name
[12] = 0;
1433 status
= srvstr_push(base_data
, flags2
,
1434 p
+2, mangled_name
, 24,
1435 STR_UPPER
|STR_UNICODE
, &len
);
1436 if (!NT_STATUS_IS_OK(status
)) {
1440 memset(p
+ 2 + len
,'\0',24 - len
);
1447 status
= srvstr_push(base_data
, flags2
, p
,
1448 fname
, PTR_DIFF(end_data
, p
),
1449 STR_TERMINATE_ASCII
, &len
);
1450 if (!NT_STATUS_IS_OK(status
)) {
1456 len
= PTR_DIFF(p
, pdata
);
1457 pad
= (len
+ (align
-1)) & ~(align
-1);
1459 * offset to the next entry, the caller
1460 * will overwrite it for the last entry
1461 * that's why we always include the padding
1465 * set padding to zero
1468 memset(p
, 0, pad
- len
);
1475 case SMB_FIND_FILE_DIRECTORY_INFO
:
1476 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1478 SIVAL(p
,0,reskey
); p
+= 4;
1479 put_long_date_full_timespec(conn
->ts_res
,p
,&create_date_ts
); p
+= 8;
1480 put_long_date_full_timespec(conn
->ts_res
,p
,&adate_ts
); p
+= 8;
1481 put_long_date_full_timespec(conn
->ts_res
,p
,&mdate_ts
); p
+= 8;
1482 put_long_date_full_timespec(conn
->ts_res
,p
,&cdate_ts
); p
+= 8;
1483 SOFF_T(p
,0,file_size
); p
+= 8;
1484 SOFF_T(p
,0,allocation_size
); p
+= 8;
1485 SIVAL(p
,0,mode
); p
+= 4;
1486 status
= srvstr_push(base_data
, flags2
,
1487 p
+ 4, fname
, PTR_DIFF(end_data
, p
+4),
1488 STR_TERMINATE_ASCII
, &len
);
1489 if (!NT_STATUS_IS_OK(status
)) {
1495 len
= PTR_DIFF(p
, pdata
);
1496 pad
= (len
+ (align
-1)) & ~(align
-1);
1498 * offset to the next entry, the caller
1499 * will overwrite it for the last entry
1500 * that's why we always include the padding
1504 * set padding to zero
1507 memset(p
, 0, pad
- len
);
1514 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1515 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1517 SIVAL(p
,0,reskey
); p
+= 4;
1518 put_long_date_full_timespec(conn
->ts_res
,p
,&create_date_ts
); p
+= 8;
1519 put_long_date_full_timespec(conn
->ts_res
,p
,&adate_ts
); p
+= 8;
1520 put_long_date_full_timespec(conn
->ts_res
,p
,&mdate_ts
); p
+= 8;
1521 put_long_date_full_timespec(conn
->ts_res
,p
,&cdate_ts
); p
+= 8;
1522 SOFF_T(p
,0,file_size
); p
+= 8;
1523 SOFF_T(p
,0,allocation_size
); p
+= 8;
1524 SIVAL(p
,0,mode
); p
+= 4;
1525 q
= p
; p
+= 4; /* q is placeholder for name length. */
1526 ea_size
= get_dirent_ea_size(mode
, smb_fname
->fsp
);
1527 SIVAL(p
, 0, ea_size
);
1529 status
= srvstr_push(base_data
, flags2
, p
,
1530 fname
, PTR_DIFF(end_data
, p
),
1531 STR_TERMINATE_ASCII
, &len
);
1532 if (!NT_STATUS_IS_OK(status
)) {
1538 len
= PTR_DIFF(p
, pdata
);
1539 pad
= (len
+ (align
-1)) & ~(align
-1);
1541 * offset to the next entry, the caller
1542 * will overwrite it for the last entry
1543 * that's why we always include the padding
1547 * set padding to zero
1550 memset(p
, 0, pad
- len
);
1557 case SMB_FIND_FILE_NAMES_INFO
:
1558 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1560 SIVAL(p
,0,reskey
); p
+= 4;
1562 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1563 acl on a dir (tridge) */
1564 status
= srvstr_push(base_data
, flags2
, p
,
1565 fname
, PTR_DIFF(end_data
, p
),
1566 STR_TERMINATE_ASCII
, &len
);
1567 if (!NT_STATUS_IS_OK(status
)) {
1573 len
= PTR_DIFF(p
, pdata
);
1574 pad
= (len
+ (align
-1)) & ~(align
-1);
1576 * offset to the next entry, the caller
1577 * will overwrite it for the last entry
1578 * that's why we always include the padding
1582 * set padding to zero
1585 memset(p
, 0, pad
- len
);
1592 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1593 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1595 SIVAL(p
,0,reskey
); p
+= 4;
1596 put_long_date_full_timespec(conn
->ts_res
,p
,&create_date_ts
); p
+= 8;
1597 put_long_date_full_timespec(conn
->ts_res
,p
,&adate_ts
); p
+= 8;
1598 put_long_date_full_timespec(conn
->ts_res
,p
,&mdate_ts
); p
+= 8;
1599 put_long_date_full_timespec(conn
->ts_res
,p
,&cdate_ts
); p
+= 8;
1600 SOFF_T(p
,0,file_size
); p
+= 8;
1601 SOFF_T(p
,0,allocation_size
); p
+= 8;
1602 SIVAL(p
,0,mode
); p
+= 4;
1603 q
= p
; p
+= 4; /* q is placeholder for name length. */
1604 ea_size
= get_dirent_ea_size(mode
, smb_fname
->fsp
);
1605 SIVAL(p
, 0, ea_size
);
1607 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
1608 SBVAL(p
,0,file_id
); p
+= 8;
1609 status
= srvstr_push(base_data
, flags2
, p
,
1610 fname
, PTR_DIFF(end_data
, p
),
1611 STR_TERMINATE_ASCII
, &len
);
1612 if (!NT_STATUS_IS_OK(status
)) {
1618 len
= PTR_DIFF(p
, pdata
);
1619 pad
= (len
+ (align
-1)) & ~(align
-1);
1621 * offset to the next entry, the caller
1622 * will overwrite it for the last entry
1623 * that's why we always include the padding
1627 * set padding to zero
1630 memset(p
, 0, pad
- len
);
1637 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1638 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1639 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1641 SIVAL(p
,0,reskey
); p
+= 4;
1642 put_long_date_full_timespec(conn
->ts_res
,p
,&create_date_ts
); p
+= 8;
1643 put_long_date_full_timespec(conn
->ts_res
,p
,&adate_ts
); p
+= 8;
1644 put_long_date_full_timespec(conn
->ts_res
,p
,&mdate_ts
); p
+= 8;
1645 put_long_date_full_timespec(conn
->ts_res
,p
,&cdate_ts
); p
+= 8;
1646 SOFF_T(p
,0,file_size
); p
+= 8;
1647 SOFF_T(p
,0,allocation_size
); p
+= 8;
1648 SIVAL(p
,0,mode
); p
+= 4;
1649 q
= p
; p
+= 4; /* q is placeholder for name length */
1650 if (readdir_attr_data
&&
1651 readdir_attr_data
->type
== RDATTR_AAPL
) {
1653 * OS X specific SMB2 extension negotiated via
1654 * AAPL create context: return max_access in
1657 ea_size
= readdir_attr_data
->attr_data
.aapl
.max_access
;
1659 ea_size
= get_dirent_ea_size(mode
, smb_fname
->fsp
);
1661 SIVAL(p
,0,ea_size
); /* Extended attributes */
1664 if (readdir_attr_data
&&
1665 readdir_attr_data
->type
== RDATTR_AAPL
) {
1667 * OS X specific SMB2 extension negotiated via
1668 * AAPL create context: return resource fork
1669 * length and compressed FinderInfo in
1672 * According to documentation short_name_len
1673 * should be 0, but on the wire behaviour
1674 * shows its set to 24 by clients.
1678 /* Resourefork length */
1679 SBVAL(p
, 2, readdir_attr_data
->attr_data
.aapl
.rfork_size
);
1681 /* Compressed FinderInfo */
1682 memcpy(p
+ 10, &readdir_attr_data
->attr_data
.aapl
.finder_info
, 16);
1683 } else if (!was_8_3
&& check_mangled_names
) {
1684 char mangled_name
[13]; /* mangled 8.3 name. */
1685 if (!name_to_8_3(fname
,mangled_name
,True
,
1687 /* Error - mangle failed ! */
1688 memset(mangled_name
,'\0',12);
1690 mangled_name
[12] = 0;
1691 status
= srvstr_push(base_data
, flags2
,
1692 p
+2, mangled_name
, 24,
1693 STR_UPPER
|STR_UNICODE
, &len
);
1694 if (!NT_STATUS_IS_OK(status
)) {
1699 memset(p
+ 2 + len
,'\0',24 - len
);
1703 /* Clear the short name buffer. This is
1704 * IMPORTANT as not doing so will trigger
1705 * a Win2k client bug. JRA.
1712 if (readdir_attr_data
&&
1713 readdir_attr_data
->type
== RDATTR_AAPL
) {
1715 * OS X specific SMB2 extension negotiated via
1716 * AAPL create context: return UNIX mode in
1719 uint16_t aapl_mode
= (uint16_t)readdir_attr_data
->attr_data
.aapl
.unix_mode
;
1720 SSVAL(p
, 0, aapl_mode
);
1726 SBVAL(p
,0,file_id
); p
+= 8;
1727 status
= srvstr_push(base_data
, flags2
, p
,
1728 fname
, PTR_DIFF(end_data
, p
),
1729 STR_TERMINATE_ASCII
, &len
);
1730 if (!NT_STATUS_IS_OK(status
)) {
1736 len
= PTR_DIFF(p
, pdata
);
1737 pad
= (len
+ (align
-1)) & ~(align
-1);
1739 * offset to the next entry, the caller
1740 * will overwrite it for the last entry
1741 * that's why we always include the padding
1745 * set padding to zero
1748 memset(p
, 0, pad
- len
);
1755 /* CIFS UNIX Extension. */
1757 case SMB_FIND_FILE_UNIX
:
1758 case SMB_FIND_FILE_UNIX_INFO2
:
1760 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
1762 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1764 if (info_level
== SMB_FIND_FILE_UNIX
) {
1765 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
1766 p
= store_file_unix_basic(conn
, p
,
1767 NULL
, &smb_fname
->st
);
1768 status
= srvstr_push(base_data
, flags2
, p
,
1769 fname
, PTR_DIFF(end_data
, p
),
1770 STR_TERMINATE
, &len
);
1771 if (!NT_STATUS_IS_OK(status
)) {
1775 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1776 p
= store_file_unix_basic_info2(conn
, p
,
1777 NULL
, &smb_fname
->st
);
1780 status
= srvstr_push(base_data
, flags2
, p
, fname
,
1781 PTR_DIFF(end_data
, p
), 0, &len
);
1782 if (!NT_STATUS_IS_OK(status
)) {
1785 SIVAL(nameptr
, 0, len
);
1790 len
= PTR_DIFF(p
, pdata
);
1791 pad
= (len
+ (align
-1)) & ~(align
-1);
1793 * offset to the next entry, the caller
1794 * will overwrite it for the last entry
1795 * that's why we always include the padding
1799 * set padding to zero
1802 memset(p
, 0, pad
- len
);
1807 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1811 /* SMB2 UNIX Extension. */
1813 case SMB2_FILE_POSIX_INFORMATION
:
1815 uint8_t *buf
= NULL
;
1818 SIVAL(p
,0,reskey
); p
+= 4;
1820 DEBUG(10,("smbd_marshall_dir_entry: "
1821 "SMB2_FILE_POSIX_INFORMATION\n"));
1822 if (!(conn
->sconn
->using_smb2
)) {
1823 return NT_STATUS_INVALID_LEVEL
;
1825 if (!lp_smb3_unix_extensions()) {
1826 return NT_STATUS_INVALID_LEVEL
;
1829 /* Determine the size of the posix info context */
1830 plen
= store_smb2_posix_info(conn
,
1837 return NT_STATUS_INVALID_PARAMETER
;
1839 buf
= talloc_zero_size(ctx
, plen
);
1841 return NT_STATUS_NO_MEMORY
;
1844 /* Store the context in buf */
1845 store_smb2_posix_info(conn
,
1851 memcpy(p
, buf
, plen
);
1857 status
= srvstr_push(base_data
, flags2
, p
, fname
,
1858 PTR_DIFF(end_data
, p
), 0, &len
);
1859 if (!NT_STATUS_IS_OK(status
)) {
1862 SIVAL(nameptr
, 0, len
);
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
1878 return NT_STATUS_INVALID_LEVEL
;
1881 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
1882 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1883 "(wanted %u, had %d)\n",
1884 (unsigned int)PTR_DIFF(p
,pdata
),
1886 return STATUS_MORE_ENTRIES
; /* Not finished - just out of space */
1889 /* Setup the last entry pointer, as an offset from base_data */
1890 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
1891 /* Advance the data pointer to the next slot */
1894 return NT_STATUS_OK
;
1897 NTSTATUS
smbd_dirptr_lanman2_entry(TALLOC_CTX
*ctx
,
1898 connection_struct
*conn
,
1899 struct dptr_struct
*dirptr
,
1901 const char *path_mask
,
1904 int requires_resume_key
,
1913 int space_remaining
,
1914 struct smb_filename
**_smb_fname
,
1915 bool *got_exact_match
,
1916 int *_last_entry_off
,
1917 struct ea_list
*name_list
,
1918 struct file_id
*file_id
)
1921 const char *mask
= NULL
;
1922 long prev_dirpos
= 0;
1925 struct smb_filename
*smb_fname
= NULL
;
1926 struct smbd_dirptr_lanman2_state state
;
1928 uint64_t last_entry_off
= 0;
1930 enum mangled_names_options mangled_names
;
1931 bool marshall_with_83_names
;
1933 mangled_names
= lp_mangled_names(conn
->params
);
1937 state
.info_level
= info_level
;
1938 if (mangled_names
!= MANGLED_NAMES_NO
) {
1939 state
.check_mangled_names
= true;
1941 state
.has_wild
= dptr_has_wild(dirptr
);
1942 state
.got_exact_match
= false;
1943 state
.case_sensitive
= dptr_case_sensitive(dirptr
);
1945 *got_exact_match
= false;
1947 p
= strrchr_m(path_mask
,'/');
1958 ok
= smbd_dirptr_get_entry(ctx
,
1965 smbd_dirptr_lanman2_match_fn
,
1966 smbd_dirptr_lanman2_mode_fn
,
1973 return NT_STATUS_END_OF_FILE
;
1976 *got_exact_match
= state
.got_exact_match
;
1978 marshall_with_83_names
= (mangled_names
== MANGLED_NAMES_YES
);
1980 status
= smbd_marshall_dir_entry(ctx
,
1985 marshall_with_83_names
,
1986 requires_resume_key
,
1997 if (NT_STATUS_EQUAL(status
, NT_STATUS_ILLEGAL_CHARACTER
)) {
1998 DEBUG(1,("Conversion error: illegal character: %s\n",
1999 smb_fname_str_dbg(smb_fname
)));
2002 if (file_id
!= NULL
) {
2003 *file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
2006 if (!NT_STATUS_IS_OK(status
) &&
2007 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
))
2009 TALLOC_FREE(smb_fname
);
2014 if (_smb_fname
!= NULL
) {
2016 * smb_fname is already talloc'ed off ctx.
2017 * We just need to make sure we don't return
2018 * any stream_name, and replace base_name
2019 * with fname in case base_name got mangled.
2020 * This allows us to preserve any smb_fname->fsp
2021 * for asynchronous handle lookups.
2023 TALLOC_FREE(smb_fname
->stream_name
);
2024 TALLOC_FREE(smb_fname
->base_name
);
2025 smb_fname
->base_name
= talloc_strdup(smb_fname
, fname
);
2027 if (smb_fname
->base_name
== NULL
) {
2028 TALLOC_FREE(smb_fname
);
2030 return NT_STATUS_NO_MEMORY
;
2032 *_smb_fname
= smb_fname
;
2034 TALLOC_FREE(smb_fname
);
2038 if (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
2039 dptr_SeekDir(dirptr
, prev_dirpos
);
2043 *_last_entry_off
= last_entry_off
;
2044 return NT_STATUS_OK
;
2047 unsigned char *create_volume_objectid(connection_struct
*conn
, unsigned char objid
[16])
2049 const struct loadparm_substitution
*lp_sub
=
2050 loadparm_s3_global_substitution();
2052 E_md4hash(lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
)),objid
);
2056 static void samba_extended_info_version(struct smb_extended_info
*extended_info
)
2058 SMB_ASSERT(extended_info
!= NULL
);
2060 extended_info
->samba_magic
= SAMBA_EXTENDED_INFO_MAGIC
;
2061 extended_info
->samba_version
= ((SAMBA_VERSION_MAJOR
& 0xff) << 24)
2062 | ((SAMBA_VERSION_MINOR
& 0xff) << 16)
2063 | ((SAMBA_VERSION_RELEASE
& 0xff) << 8);
2064 #ifdef SAMBA_VERSION_REVISION
2065 extended_info
->samba_version
|= (tolower(*SAMBA_VERSION_REVISION
) - 'a' + 1) & 0xff;
2067 extended_info
->samba_subversion
= 0;
2068 #ifdef SAMBA_VERSION_RC_RELEASE
2069 extended_info
->samba_subversion
|= (SAMBA_VERSION_RC_RELEASE
& 0xff) << 24;
2071 #ifdef SAMBA_VERSION_PRE_RELEASE
2072 extended_info
->samba_subversion
|= (SAMBA_VERSION_PRE_RELEASE
& 0xff) << 16;
2075 #ifdef SAMBA_VERSION_VENDOR_PATCH
2076 extended_info
->samba_subversion
|= (SAMBA_VERSION_VENDOR_PATCH
& 0xffff);
2078 extended_info
->samba_gitcommitdate
= 0;
2079 #ifdef SAMBA_VERSION_COMMIT_TIME
2080 unix_to_nt_time(&extended_info
->samba_gitcommitdate
, SAMBA_VERSION_COMMIT_TIME
);
2083 memset(extended_info
->samba_version_string
, 0,
2084 sizeof(extended_info
->samba_version_string
));
2086 snprintf (extended_info
->samba_version_string
,
2087 sizeof(extended_info
->samba_version_string
),
2088 "%s", samba_version_string());
2091 static bool fsinfo_unix_valid_level(connection_struct
*conn
,
2092 uint16_t info_level
)
2094 if (conn
->sconn
->using_smb2
&&
2095 lp_smb3_unix_extensions() &&
2096 info_level
== SMB2_FS_POSIX_INFORMATION_INTERNAL
) {
2099 #if defined(SMB1SERVER)
2100 if (lp_smb1_unix_extensions() &&
2101 info_level
== SMB_QUERY_POSIX_FS_INFO
) {
2108 NTSTATUS
smbd_do_qfsinfo(struct smbXsrv_connection
*xconn
,
2109 connection_struct
*conn
,
2110 TALLOC_CTX
*mem_ctx
,
2111 uint16_t info_level
,
2113 unsigned int max_data_bytes
,
2114 size_t *fixed_portion
,
2115 struct smb_filename
*fname
,
2119 const struct loadparm_substitution
*lp_sub
=
2120 loadparm_s3_global_substitution();
2121 char *pdata
, *end_data
;
2124 const char *vname
= volume_label(talloc_tos(), SNUM(conn
));
2125 int snum
= SNUM(conn
);
2126 const char *fstype
= lp_fstype(SNUM(conn
));
2127 const char *filename
= NULL
;
2128 const uint64_t bytes_per_sector
= 512;
2129 uint32_t additional_flags
= 0;
2130 struct smb_filename smb_fname
;
2132 NTSTATUS status
= NT_STATUS_OK
;
2136 if (fname
== NULL
|| fname
->base_name
== NULL
) {
2139 filename
= fname
->base_name
;
2143 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
2144 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
2145 "info level (0x%x) on IPC$.\n",
2146 (unsigned int)info_level
));
2147 return NT_STATUS_ACCESS_DENIED
;
2151 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level
));
2153 smb_fname
= (struct smb_filename
) {
2154 .base_name
= discard_const_p(char, filename
),
2155 .flags
= fname
? fname
->flags
: 0,
2156 .twrp
= fname
? fname
->twrp
: 0,
2159 if(info_level
!= SMB_FS_QUOTA_INFORMATION
2160 && SMB_VFS_STAT(conn
, &smb_fname
) != 0) {
2161 DEBUG(2,("stat of . failed (%s)\n", strerror(errno
)));
2162 return map_nt_error_from_unix(errno
);
2167 if (max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
< max_data_bytes
) {
2168 return NT_STATUS_INVALID_PARAMETER
;
2171 *ppdata
= (char *)SMB_REALLOC(
2172 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2173 if (*ppdata
== NULL
) {
2174 return NT_STATUS_NO_MEMORY
;
2178 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2179 end_data
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2183 switch (info_level
) {
2184 case SMB_INFO_ALLOCATION
:
2186 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
;
2188 df_ret
= get_dfree_info(conn
, &smb_fname
, &bsize
,
2190 if (df_ret
== (uint64_t)-1) {
2191 return map_nt_error_from_unix(errno
);
2194 block_size
= lp_block_size(snum
);
2195 if (bsize
< block_size
) {
2196 uint64_t factor
= block_size
/bsize
;
2201 if (bsize
> block_size
) {
2202 uint64_t factor
= bsize
/block_size
;
2207 sectors_per_unit
= bsize
/bytes_per_sector
;
2209 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2210 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_ex_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
2211 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
2214 * For large drives, return max values and not modulo.
2216 dsize
= MIN(dsize
, UINT32_MAX
);
2217 dfree
= MIN(dfree
, UINT32_MAX
);
2219 SIVAL(pdata
,l1_idFileSystem
,st
.st_ex_dev
);
2220 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
2221 SIVAL(pdata
,l1_cUnit
,dsize
);
2222 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
2223 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
2227 case SMB_INFO_VOLUME
:
2228 /* Return volume name */
2230 * Add volume serial number - hash of a combination of
2231 * the called hostname and the service name.
2233 serial
= generate_volume_serial_number(lp_sub
, snum
);
2234 SIVAL(pdata
,0,serial
);
2236 * Win2k3 and previous mess this up by sending a name length
2237 * one byte short. I believe only older clients (OS/2 Win9x) use
2238 * this call so try fixing this by adding a terminating null to
2239 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2241 status
= srvstr_push(
2243 pdata
+l2_vol_szVolLabel
, vname
,
2244 PTR_DIFF(end_data
, pdata
+l2_vol_szVolLabel
),
2245 STR_NOALIGN
|STR_TERMINATE
, &len
);
2246 if (!NT_STATUS_IS_OK(status
)) {
2249 SCVAL(pdata
,l2_vol_cch
,len
);
2250 data_len
= l2_vol_szVolLabel
+ len
;
2251 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %u, "
2252 "name = %s serial = 0x%04"PRIx32
"\n",
2253 (unsigned)convert_timespec_to_time_t(st
.st_ex_ctime
),
2254 (unsigned)len
, vname
, serial
));
2257 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
2258 case SMB_FS_ATTRIBUTE_INFORMATION
:
2260 additional_flags
= 0;
2261 #if defined(HAVE_SYS_QUOTAS)
2262 additional_flags
|= FILE_VOLUME_QUOTAS
;
2265 if(lp_nt_acl_support(SNUM(conn
))) {
2266 additional_flags
|= FILE_PERSISTENT_ACLS
;
2269 /* Capabilities are filled in at connection time through STATVFS call */
2270 additional_flags
|= conn
->fs_capabilities
;
2271 additional_flags
|= lp_parm_int(conn
->params
->service
,
2272 "share", "fake_fscaps",
2275 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
2276 FILE_SUPPORTS_OBJECT_IDS
|FILE_UNICODE_ON_DISK
|
2277 additional_flags
); /* FS ATTRIBUTES */
2279 SIVAL(pdata
,4,255); /* Max filename component length */
2280 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2281 and will think we can't do long filenames */
2282 status
= srvstr_push(pdata
, flags2
, pdata
+12, fstype
,
2283 PTR_DIFF(end_data
, pdata
+12),
2285 if (!NT_STATUS_IS_OK(status
)) {
2289 data_len
= 12 + len
;
2290 if (max_data_bytes
>= 16 && data_len
> max_data_bytes
) {
2291 /* the client only requested a portion of the
2293 data_len
= max_data_bytes
;
2294 status
= STATUS_BUFFER_OVERFLOW
;
2296 *fixed_portion
= 16;
2299 case SMB_QUERY_FS_LABEL_INFO
:
2300 case SMB_FS_LABEL_INFORMATION
:
2301 status
= srvstr_push(pdata
, flags2
, pdata
+4, vname
,
2302 PTR_DIFF(end_data
, pdata
+4), 0, &len
);
2303 if (!NT_STATUS_IS_OK(status
)) {
2310 case SMB_QUERY_FS_VOLUME_INFO
:
2311 case SMB_FS_VOLUME_INFORMATION
:
2312 put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER
,
2313 pdata
, &st
.st_ex_btime
);
2315 * Add volume serial number - hash of a combination of
2316 * the called hostname and the service name.
2318 serial
= generate_volume_serial_number(lp_sub
, snum
);
2319 SIVAL(pdata
,8,serial
);
2321 /* Max label len is 32 characters. */
2322 status
= srvstr_push(pdata
, flags2
, pdata
+18, vname
,
2323 PTR_DIFF(end_data
, pdata
+18),
2325 if (!NT_STATUS_IS_OK(status
)) {
2328 SIVAL(pdata
,12,len
);
2331 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO "
2332 "namelen = %d, vol=%s serv=%s "
2333 "serial=0x%04"PRIx32
"\n",
2334 (int)strlen(vname
),vname
,
2335 lp_servicename(talloc_tos(), lp_sub
, snum
),
2337 if (max_data_bytes
>= 24 && data_len
> max_data_bytes
) {
2338 /* the client only requested a portion of the
2340 data_len
= max_data_bytes
;
2341 status
= STATUS_BUFFER_OVERFLOW
;
2343 *fixed_portion
= 24;
2346 case SMB_QUERY_FS_SIZE_INFO
:
2347 case SMB_FS_SIZE_INFORMATION
:
2349 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
;
2351 df_ret
= get_dfree_info(conn
, &smb_fname
, &bsize
,
2353 if (df_ret
== (uint64_t)-1) {
2354 return map_nt_error_from_unix(errno
);
2356 block_size
= lp_block_size(snum
);
2357 if (bsize
< block_size
) {
2358 uint64_t factor
= block_size
/bsize
;
2363 if (bsize
> block_size
) {
2364 uint64_t factor
= bsize
/block_size
;
2369 sectors_per_unit
= bsize
/bytes_per_sector
;
2370 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2371 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
2372 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
2373 SBIG_UINT(pdata
,0,dsize
);
2374 SBIG_UINT(pdata
,8,dfree
);
2375 SIVAL(pdata
,16,sectors_per_unit
);
2376 SIVAL(pdata
,20,bytes_per_sector
);
2377 *fixed_portion
= 24;
2381 case SMB_FS_FULL_SIZE_INFORMATION
:
2383 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
;
2385 df_ret
= get_dfree_info(conn
, &smb_fname
, &bsize
,
2387 if (df_ret
== (uint64_t)-1) {
2388 return map_nt_error_from_unix(errno
);
2390 block_size
= lp_block_size(snum
);
2391 if (bsize
< block_size
) {
2392 uint64_t factor
= block_size
/bsize
;
2397 if (bsize
> block_size
) {
2398 uint64_t factor
= bsize
/block_size
;
2403 sectors_per_unit
= bsize
/bytes_per_sector
;
2404 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2405 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
2406 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
2407 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
2408 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
2409 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
2410 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
2411 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
2412 *fixed_portion
= 32;
2416 case SMB_QUERY_FS_DEVICE_INFO
:
2417 case SMB_FS_DEVICE_INFORMATION
:
2419 uint32_t characteristics
= FILE_DEVICE_IS_MOUNTED
;
2421 if (!CAN_WRITE(conn
)) {
2422 characteristics
|= FILE_READ_ONLY_DEVICE
;
2425 SIVAL(pdata
,0,FILE_DEVICE_DISK
); /* dev type */
2426 SIVAL(pdata
,4,characteristics
);
2431 #ifdef HAVE_SYS_QUOTAS
2432 case SMB_FS_QUOTA_INFORMATION
:
2434 * what we have to send --metze:
2436 * Unknown1: 24 NULL bytes
2437 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
2438 * Hard Quota Limit: 8 bytes seems like uint64_t or so
2439 * Quota Flags: 2 byte :
2440 * Unknown3: 6 NULL bytes
2444 * details for Quota Flags:
2446 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2447 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2448 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2449 * 0x0001 Enable Quotas: enable quota for this fs
2453 /* we need to fake up a fsp here,
2454 * because its not send in this call
2457 SMB_NTQUOTA_STRUCT quotas
;
2460 ZERO_STRUCT(quotas
);
2463 fsp
.fnum
= FNUM_FIELD_INVALID
;
2466 if (get_current_uid(conn
) != 0) {
2467 DEBUG(0,("get_user_quota: access_denied "
2468 "service [%s] user [%s]\n",
2469 lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
)),
2470 conn
->session_info
->unix_info
->unix_name
));
2471 return NT_STATUS_ACCESS_DENIED
;
2474 status
= vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
,
2476 if (!NT_STATUS_IS_OK(status
)) {
2477 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
))));
2483 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
2484 lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
))));
2486 /* Unknown1 24 NULL bytes*/
2487 SBIG_UINT(pdata
,0,(uint64_t)0);
2488 SBIG_UINT(pdata
,8,(uint64_t)0);
2489 SBIG_UINT(pdata
,16,(uint64_t)0);
2491 /* Default Soft Quota 8 bytes */
2492 SBIG_UINT(pdata
,24,quotas
.softlim
);
2494 /* Default Hard Quota 8 bytes */
2495 SBIG_UINT(pdata
,32,quotas
.hardlim
);
2497 /* Quota flag 2 bytes */
2498 SSVAL(pdata
,40,quotas
.qflags
);
2500 /* Unknown3 6 NULL bytes */
2506 #endif /* HAVE_SYS_QUOTAS */
2507 case SMB_FS_OBJECTID_INFORMATION
:
2509 unsigned char objid
[16];
2510 struct smb_extended_info extended_info
;
2511 memcpy(pdata
,create_volume_objectid(conn
, objid
),16);
2512 samba_extended_info_version (&extended_info
);
2513 SIVAL(pdata
,16,extended_info
.samba_magic
);
2514 SIVAL(pdata
,20,extended_info
.samba_version
);
2515 SIVAL(pdata
,24,extended_info
.samba_subversion
);
2516 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
2517 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
2522 case SMB_FS_SECTOR_SIZE_INFORMATION
:
2526 * These values match a physical Windows Server 2012
2527 * share backed by NTFS atop spinning rust.
2529 DEBUG(5, ("SMB_FS_SECTOR_SIZE_INFORMATION:"));
2530 /* logical_bytes_per_sector */
2531 SIVAL(pdata
, 0, bytes_per_sector
);
2532 /* phys_bytes_per_sector_atomic */
2533 SIVAL(pdata
, 4, bytes_per_sector
);
2534 /* phys_bytes_per_sector_perf */
2535 SIVAL(pdata
, 8, bytes_per_sector
);
2536 /* fs_effective_phys_bytes_per_sector_atomic */
2537 SIVAL(pdata
, 12, bytes_per_sector
);
2539 SIVAL(pdata
, 16, SSINFO_FLAGS_ALIGNED_DEVICE
2540 | SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE
);
2541 /* byte_off_sector_align */
2542 SIVAL(pdata
, 20, 0);
2543 /* byte_off_partition_align */
2544 SIVAL(pdata
, 24, 0);
2545 *fixed_portion
= 28;
2550 #if defined(WITH_SMB1SERVER)
2552 * Query the version and capabilities of the CIFS UNIX extensions
2556 case SMB_QUERY_CIFS_UNIX_INFO
:
2558 bool large_write
= lp_min_receive_file_size() &&
2559 !smb1_srv_is_signing_active(xconn
);
2560 bool large_read
= !smb1_srv_is_signing_active(xconn
);
2561 int encrypt_caps
= 0;
2563 if (!lp_smb1_unix_extensions()) {
2564 return NT_STATUS_INVALID_LEVEL
;
2567 switch (conn
->encrypt_level
) {
2568 case SMB_SIGNING_OFF
:
2571 case SMB_SIGNING_DESIRED
:
2572 case SMB_SIGNING_IF_REQUIRED
:
2573 case SMB_SIGNING_DEFAULT
:
2574 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
;
2576 case SMB_SIGNING_REQUIRED
:
2577 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
|
2578 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP
;
2579 large_write
= false;
2585 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
2586 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
2588 /* We have POSIX ACLs, pathname, encryption,
2589 * large read/write, and locking capability. */
2591 SBIG_UINT(pdata
,4,((uint64_t)(
2592 CIFS_UNIX_POSIX_ACLS_CAP
|
2593 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
2594 CIFS_UNIX_FCNTL_LOCKS_CAP
|
2595 CIFS_UNIX_EXTATTR_CAP
|
2596 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
|
2598 (large_read
? CIFS_UNIX_LARGE_READ_CAP
: 0) |
2600 CIFS_UNIX_LARGE_WRITE_CAP
: 0))));
2605 case SMB_QUERY_POSIX_FS_INFO
:
2606 case SMB2_FS_POSIX_INFORMATION_INTERNAL
:
2609 struct vfs_statvfs_struct svfs
;
2611 if (!fsinfo_unix_valid_level(conn
, info_level
)) {
2612 return NT_STATUS_INVALID_LEVEL
;
2615 rc
= SMB_VFS_STATVFS(conn
, &smb_fname
, &svfs
);
2619 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
2620 SIVAL(pdata
,4,svfs
.BlockSize
);
2621 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
2622 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
2623 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
2624 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
2625 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
2626 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
2627 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2629 } else if (rc
== EOPNOTSUPP
) {
2630 return NT_STATUS_INVALID_LEVEL
;
2631 #endif /* EOPNOTSUPP */
2633 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
))));
2634 return NT_STATUS_DOS(ERRSRV
, ERRerror
);
2639 case SMB_QUERY_POSIX_WHOAMI
:
2645 if (!lp_smb1_unix_extensions()) {
2646 return NT_STATUS_INVALID_LEVEL
;
2649 if (max_data_bytes
< 40) {
2650 return NT_STATUS_BUFFER_TOO_SMALL
;
2653 if (security_session_user_level(conn
->session_info
, NULL
) < SECURITY_USER
) {
2654 flags
|= SMB_WHOAMI_GUEST
;
2657 /* NOTE: 8 bytes for UID/GID, irrespective of native
2658 * platform size. This matches
2659 * SMB_QUERY_FILE_UNIX_BASIC and friends.
2661 data_len
= 4 /* flags */
2668 + 4 /* pad/reserved */
2669 + (conn
->session_info
->unix_token
->ngroups
* 8)
2671 + (conn
->session_info
->security_token
->num_sids
*
2675 SIVAL(pdata
, 0, flags
);
2676 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
2678 (uint64_t)conn
->session_info
->unix_token
->uid
);
2679 SBIG_UINT(pdata
, 16,
2680 (uint64_t)conn
->session_info
->unix_token
->gid
);
2683 if (data_len
>= max_data_bytes
) {
2684 /* Potential overflow, skip the GIDs and SIDs. */
2686 SIVAL(pdata
, 24, 0); /* num_groups */
2687 SIVAL(pdata
, 28, 0); /* num_sids */
2688 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
2689 SIVAL(pdata
, 36, 0); /* reserved */
2695 SIVAL(pdata
, 24, conn
->session_info
->unix_token
->ngroups
);
2696 SIVAL(pdata
, 28, conn
->session_info
->security_token
->num_sids
);
2698 /* We walk the SID list twice, but this call is fairly
2699 * infrequent, and I don't expect that it's performance
2700 * sensitive -- jpeach
2702 for (i
= 0, sid_bytes
= 0;
2703 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
2704 sid_bytes
+= ndr_size_dom_sid(
2705 &conn
->session_info
->security_token
->sids
[i
],
2709 /* SID list byte count */
2710 SIVAL(pdata
, 32, sid_bytes
);
2712 /* 4 bytes pad/reserved - must be zero */
2713 SIVAL(pdata
, 36, 0);
2717 for (i
= 0; i
< conn
->session_info
->unix_token
->ngroups
; ++i
) {
2718 SBIG_UINT(pdata
, data_len
,
2719 (uint64_t)conn
->session_info
->unix_token
->groups
[i
]);
2725 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
2726 int sid_len
= ndr_size_dom_sid(
2727 &conn
->session_info
->security_token
->sids
[i
],
2730 sid_linearize((uint8_t *)(pdata
+ data_len
),
2732 &conn
->session_info
->security_token
->sids
[i
]);
2733 data_len
+= sid_len
;
2739 case SMB_MAC_QUERY_FS_INFO
:
2741 * Thursby MAC extension... ONLY on NTFS filesystems
2742 * once we do streams then we don't need this
2744 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
2746 SIVAL(pdata
,84,0x100); /* Don't support mac... */
2752 return NT_STATUS_INVALID_LEVEL
;
2755 *ret_data_len
= data_len
;
2759 NTSTATUS
smb_set_fsquota(connection_struct
*conn
,
2760 struct smb_request
*req
,
2762 const DATA_BLOB
*qdata
)
2764 const struct loadparm_substitution
*lp_sub
=
2765 loadparm_s3_global_substitution();
2767 SMB_NTQUOTA_STRUCT quotas
;
2769 ZERO_STRUCT(quotas
);
2772 if ((get_current_uid(conn
) != 0) || !CAN_WRITE(conn
)) {
2773 DEBUG(3, ("set_fsquota: access_denied service [%s] user [%s]\n",
2774 lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
)),
2775 conn
->session_info
->unix_info
->unix_name
));
2776 return NT_STATUS_ACCESS_DENIED
;
2779 if (!check_fsp_ntquota_handle(conn
, req
,
2781 DEBUG(1, ("set_fsquota: no valid QUOTA HANDLE\n"));
2782 return NT_STATUS_INVALID_HANDLE
;
2785 /* note: normally there're 48 bytes,
2786 * but we didn't use the last 6 bytes for now
2789 if (qdata
->length
< 42) {
2790 DEBUG(0,("set_fsquota: requires total_data(%u) >= 42 bytes!\n",
2791 (unsigned int)qdata
->length
));
2792 return NT_STATUS_INVALID_PARAMETER
;
2795 /* unknown_1 24 NULL bytes in pdata*/
2797 /* the soft quotas 8 bytes (uint64_t)*/
2798 quotas
.softlim
= BVAL(qdata
->data
,24);
2800 /* the hard quotas 8 bytes (uint64_t)*/
2801 quotas
.hardlim
= BVAL(qdata
->data
,32);
2803 /* quota_flags 2 bytes **/
2804 quotas
.qflags
= SVAL(qdata
->data
,40);
2806 /* unknown_2 6 NULL bytes follow*/
2808 /* now set the quotas */
2809 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
2810 DEBUG(1, ("vfs_set_ntquota() failed for service [%s]\n",
2811 lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
))));
2812 status
= map_nt_error_from_unix(errno
);
2814 status
= NT_STATUS_OK
;
2819 NTSTATUS
smbd_do_setfsinfo(connection_struct
*conn
,
2820 struct smb_request
*req
,
2821 TALLOC_CTX
*mem_ctx
,
2822 uint16_t info_level
,
2824 const DATA_BLOB
*pdata
)
2826 switch (info_level
) {
2827 case SMB_FS_QUOTA_INFORMATION
:
2829 return smb_set_fsquota(conn
,
2838 return NT_STATUS_INVALID_LEVEL
;
2841 /****************************************************************************
2842 Store the FILE_UNIX_BASIC info.
2843 ****************************************************************************/
2845 char *store_file_unix_basic(connection_struct
*conn
,
2848 const SMB_STRUCT_STAT
*psbuf
)
2852 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
2853 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_ex_mode
));
2855 SOFF_T(pdata
,0,get_file_size_stat(psbuf
)); /* File size 64 Bit */
2858 SOFF_T(pdata
,0,SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
2861 put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
, &psbuf
->st_ex_ctime
); /* Change Time 64 Bit */
2862 put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
+8, &psbuf
->st_ex_atime
); /* Last access time 64 Bit */
2863 put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
+16, &psbuf
->st_ex_mtime
); /* Last modification time 64 Bit */
2866 SIVAL(pdata
,0,psbuf
->st_ex_uid
); /* user id for the owner */
2870 SIVAL(pdata
,0,psbuf
->st_ex_gid
); /* group id of owner */
2874 SIVAL(pdata
,0,unix_filetype(psbuf
->st_ex_mode
));
2877 if (S_ISBLK(psbuf
->st_ex_mode
) || S_ISCHR(psbuf
->st_ex_mode
)) {
2878 devno
= psbuf
->st_ex_rdev
;
2880 devno
= psbuf
->st_ex_dev
;
2883 SIVAL(pdata
,0,unix_dev_major(devno
)); /* Major device number if type is device */
2887 SIVAL(pdata
,0,unix_dev_minor(devno
)); /* Minor device number if type is device */
2891 SINO_T_VAL(pdata
, 0, psbuf
->st_ex_ino
); /* inode number */
2894 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_ex_mode
)); /* Standard UNIX file permissions */
2898 SIVAL(pdata
,0,psbuf
->st_ex_nlink
); /* number of hard links */
2905 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
2906 * the chflags(2) (or equivalent) flags.
2908 * XXX: this really should be behind the VFS interface. To do this, we would
2909 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
2910 * Each VFS module could then implement its own mapping as appropriate for the
2911 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
2913 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
2917 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
2921 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
2925 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
2929 { UF_HIDDEN
, EXT_HIDDEN
},
2932 /* Do not remove. We need to guarantee that this array has at least one
2933 * entry to build on HP-UX.
2939 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
2940 uint32_t *smb_fflags
, uint32_t *smb_fmask
)
2944 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
2945 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
2946 if (psbuf
->st_ex_flags
& info2_flags_map
[i
].stat_fflag
) {
2947 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
2952 bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
2953 const uint32_t smb_fflags
,
2954 const uint32_t smb_fmask
,
2957 uint32_t max_fmask
= 0;
2960 *stat_fflags
= psbuf
->st_ex_flags
;
2962 /* For each flags requested in smb_fmask, check the state of the
2963 * corresponding flag in smb_fflags and set or clear the matching
2967 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
2968 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
2969 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
2970 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
2971 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
2973 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
2978 /* If smb_fmask is asking to set any bits that are not supported by
2979 * our flag mappings, we should fail.
2981 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
2989 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
2990 * of file flags and birth (create) time.
2992 char *store_file_unix_basic_info2(connection_struct
*conn
,
2995 const SMB_STRUCT_STAT
*psbuf
)
2997 uint32_t file_flags
= 0;
2998 uint32_t flags_mask
= 0;
3000 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
3002 /* Create (birth) time 64 bit */
3003 put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
, &psbuf
->st_ex_btime
);
3006 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
3007 SIVAL(pdata
, 0, file_flags
); /* flags */
3008 SIVAL(pdata
, 4, flags_mask
); /* mask */
3014 static NTSTATUS
marshall_stream_info(unsigned int num_streams
,
3015 const struct stream_struct
*streams
,
3017 unsigned int max_data_bytes
,
3018 unsigned int *data_size
)
3021 unsigned int ofs
= 0;
3023 if (max_data_bytes
< 32) {
3024 return NT_STATUS_INFO_LENGTH_MISMATCH
;
3027 for (i
= 0; i
< num_streams
; i
++) {
3028 unsigned int next_offset
;
3030 smb_ucs2_t
*namebuf
;
3032 if (!push_ucs2_talloc(talloc_tos(), &namebuf
,
3033 streams
[i
].name
, &namelen
) ||
3036 return NT_STATUS_INVALID_PARAMETER
;
3040 * name_buf is now null-terminated, we need to marshall as not
3047 * We cannot overflow ...
3049 if ((ofs
+ 24 + namelen
) > max_data_bytes
) {
3050 DEBUG(10, ("refusing to overflow reply at stream %u\n",
3052 TALLOC_FREE(namebuf
);
3053 return STATUS_BUFFER_OVERFLOW
;
3056 SIVAL(data
, ofs
+4, namelen
);
3057 SOFF_T(data
, ofs
+8, streams
[i
].size
);
3058 SOFF_T(data
, ofs
+16, streams
[i
].alloc_size
);
3059 memcpy(data
+ofs
+24, namebuf
, namelen
);
3060 TALLOC_FREE(namebuf
);
3062 next_offset
= ofs
+ 24 + namelen
;
3064 if (i
== num_streams
-1) {
3065 SIVAL(data
, ofs
, 0);
3068 unsigned int align
= ndr_align_size(next_offset
, 8);
3070 if ((next_offset
+ align
) > max_data_bytes
) {
3071 DEBUG(10, ("refusing to overflow align "
3072 "reply at stream %u\n",
3074 TALLOC_FREE(namebuf
);
3075 return STATUS_BUFFER_OVERFLOW
;
3078 memset(data
+next_offset
, 0, align
);
3079 next_offset
+= align
;
3081 SIVAL(data
, ofs
, next_offset
- ofs
);
3088 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes
, ofs
));
3092 return NT_STATUS_OK
;
3095 NTSTATUS
smbd_do_qfilepathinfo(connection_struct
*conn
,
3096 TALLOC_CTX
*mem_ctx
,
3097 struct smb_request
*req
,
3098 uint16_t info_level
,
3100 struct smb_filename
*smb_fname
,
3101 bool delete_pending
,
3102 struct timespec write_time_ts
,
3103 struct ea_list
*ea_list
,
3105 unsigned int max_data_bytes
,
3106 size_t *fixed_portion
,
3108 unsigned int *pdata_size
)
3110 char *pdata
= *ppdata
;
3111 char *dstart
, *dend
;
3112 unsigned int data_size
;
3113 struct timespec create_time_ts
, mtime_ts
, atime_ts
, ctime_ts
;
3114 time_t create_time
, mtime
, atime
, c_time
;
3115 SMB_STRUCT_STAT
*psbuf
= NULL
;
3116 SMB_STRUCT_STAT
*base_sp
= NULL
;
3123 uint64_t file_size
= 0;
3125 uint64_t allocation_size
= 0;
3126 uint64_t file_id
= 0;
3127 uint32_t access_mask
= 0;
3130 if (INFO_LEVEL_IS_UNIX(info_level
)) {
3133 if (lp_smb1_unix_extensions() && req
->posix_pathnames
) {
3134 DBG_DEBUG("SMB1 unix extensions activated\n");
3138 if (lp_smb3_unix_extensions() &&
3140 (fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
)) {
3141 DBG_DEBUG("SMB2 posix open\n");
3146 return NT_STATUS_INVALID_LEVEL
;
3150 DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
3151 smb_fname_str_dbg(smb_fname
),
3153 info_level
, max_data_bytes
));
3156 * In case of querying a symlink in POSIX context,
3157 * fsp will be NULL. fdos_mode() deals with it.
3160 smb_fname
= fsp
->fsp_name
;
3162 mode
= fdos_mode(fsp
);
3163 psbuf
= &smb_fname
->st
;
3166 base_sp
= fsp
->base_fsp
?
3167 &fsp
->base_fsp
->fsp_name
->st
:
3170 base_sp
= &smb_fname
->st
;
3173 nlink
= psbuf
->st_ex_nlink
;
3175 if (nlink
&& (mode
&FILE_ATTRIBUTE_DIRECTORY
)) {
3179 if ((nlink
> 0) && delete_pending
) {
3183 if (max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
< max_data_bytes
) {
3184 return NT_STATUS_INVALID_PARAMETER
;
3187 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
3188 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
3189 if (*ppdata
== NULL
) {
3190 return NT_STATUS_NO_MEMORY
;
3194 dend
= dstart
+ data_size
- 1;
3196 if (!is_omit_timespec(&write_time_ts
) &&
3197 !INFO_LEVEL_IS_UNIX(info_level
))
3199 update_stat_ex_mtime(psbuf
, write_time_ts
);
3202 create_time_ts
= get_create_timespec(conn
, fsp
, smb_fname
);
3203 mtime_ts
= psbuf
->st_ex_mtime
;
3204 atime_ts
= psbuf
->st_ex_atime
;
3205 ctime_ts
= get_change_timespec(conn
, fsp
, smb_fname
);
3207 if (lp_dos_filetime_resolution(SNUM(conn
))) {
3208 dos_filetime_timespec(&create_time_ts
);
3209 dos_filetime_timespec(&mtime_ts
);
3210 dos_filetime_timespec(&atime_ts
);
3211 dos_filetime_timespec(&ctime_ts
);
3214 create_time
= convert_timespec_to_time_t(create_time_ts
);
3215 mtime
= convert_timespec_to_time_t(mtime_ts
);
3216 atime
= convert_timespec_to_time_t(atime_ts
);
3217 c_time
= convert_timespec_to_time_t(ctime_ts
);
3219 p
= strrchr_m(smb_fname
->base_name
,'/');
3221 base_name
= smb_fname
->base_name
;
3225 /* NT expects the name to be in an exact form of the *full*
3226 filename. See the trans2 torture test */
3227 if (ISDOT(base_name
)) {
3228 dos_fname
= talloc_strdup(mem_ctx
, "\\");
3230 return NT_STATUS_NO_MEMORY
;
3233 dos_fname
= talloc_asprintf(mem_ctx
,
3235 smb_fname
->base_name
);
3237 return NT_STATUS_NO_MEMORY
;
3239 if (is_named_stream(smb_fname
)) {
3240 dos_fname
= talloc_asprintf(dos_fname
, "%s",
3241 smb_fname
->stream_name
);
3243 return NT_STATUS_NO_MEMORY
;
3247 string_replace(dos_fname
, '/', '\\');
3250 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, psbuf
);
3252 if (fsp
== NULL
|| !fsp
->fsp_flags
.is_fsa
) {
3253 /* Do we have this path open ? */
3254 struct file_id fileid
= vfs_file_id_from_sbuf(conn
, psbuf
);
3255 files_struct
*fsp1
= file_find_di_first(
3256 conn
->sconn
, fileid
, true);
3257 if (fsp1
&& fsp1
->initial_allocation_size
) {
3258 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp1
, psbuf
);
3262 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
3263 file_size
= get_file_size_stat(psbuf
);
3267 pos
= fh_get_position_information(fsp
->fh
);
3271 access_mask
= fsp
->access_mask
;
3273 /* GENERIC_EXECUTE mapping from Windows */
3274 access_mask
= 0x12019F;
3277 /* This should be an index number - looks like
3280 I think this causes us to fail the IFSKIT
3281 BasicFileInformationTest. -tpot */
3282 file_id
= SMB_VFS_FS_FILE_ID(conn
, base_sp
);
3286 switch (info_level
) {
3287 case SMB_INFO_STANDARD
:
3288 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
3290 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
3291 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
3292 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
3293 SIVAL(pdata
,l1_cbFile
,(uint32_t)file_size
);
3294 SIVAL(pdata
,l1_cbFileAlloc
,(uint32_t)allocation_size
);
3295 SSVAL(pdata
,l1_attrFile
,mode
);
3298 case SMB_INFO_QUERY_EA_SIZE
:
3300 unsigned int ea_size
=
3301 estimate_ea_size(smb_fname
->fsp
);
3302 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
3304 srv_put_dos_date2(pdata
,0,create_time
);
3305 srv_put_dos_date2(pdata
,4,atime
);
3306 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
3307 SIVAL(pdata
,12,(uint32_t)file_size
);
3308 SIVAL(pdata
,16,(uint32_t)allocation_size
);
3309 SSVAL(pdata
,20,mode
);
3310 SIVAL(pdata
,22,ea_size
);
3314 case SMB_INFO_IS_NAME_VALID
:
3315 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
3317 /* os/2 needs this ? really ?*/
3318 return NT_STATUS_DOS(ERRDOS
, ERRbadfunc
);
3320 /* This is only reached for qpathinfo */
3324 case SMB_INFO_QUERY_EAS_FROM_LIST
:
3326 size_t total_ea_len
= 0;
3327 struct ea_list
*ea_file_list
= NULL
;
3328 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
3331 get_ea_list_from_fsp(mem_ctx
,
3333 &total_ea_len
, &ea_file_list
);
3334 if (!NT_STATUS_IS_OK(status
)) {
3338 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
3340 if (!ea_list
|| (total_ea_len
> data_size
)) {
3342 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
3346 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
3350 case SMB_INFO_QUERY_ALL_EAS
:
3352 /* We have data_size bytes to put EA's into. */
3353 size_t total_ea_len
= 0;
3354 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
3356 status
= get_ea_list_from_fsp(mem_ctx
,
3358 &total_ea_len
, &ea_list
);
3359 if (!NT_STATUS_IS_OK(status
)) {
3363 if (!ea_list
|| (total_ea_len
> data_size
)) {
3365 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
3369 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
3373 case SMB2_FILE_FULL_EA_INFORMATION
:
3375 /* We have data_size bytes to put EA's into. */
3376 size_t total_ea_len
= 0;
3377 struct ea_list
*ea_file_list
= NULL
;
3379 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
3381 /*TODO: add filtering and index handling */
3384 get_ea_list_from_fsp(mem_ctx
,
3386 &total_ea_len
, &ea_file_list
);
3387 if (!NT_STATUS_IS_OK(status
)) {
3390 if (!ea_file_list
) {
3391 return NT_STATUS_NO_EAS_ON_FILE
;
3394 status
= fill_ea_chained_buffer(mem_ctx
,
3398 conn
, ea_file_list
);
3399 if (!NT_STATUS_IS_OK(status
)) {
3405 case SMB_FILE_BASIC_INFORMATION
:
3406 case SMB_QUERY_FILE_BASIC_INFO
:
3408 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
3409 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
3410 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
3412 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
3416 put_long_date_full_timespec(conn
->ts_res
,pdata
,&create_time_ts
);
3417 put_long_date_full_timespec(conn
->ts_res
,pdata
+8,&atime_ts
);
3418 put_long_date_full_timespec(conn
->ts_res
,pdata
+16,&mtime_ts
); /* write time */
3419 put_long_date_full_timespec(conn
->ts_res
,pdata
+24,&ctime_ts
); /* change time */
3420 SIVAL(pdata
,32,mode
);
3422 DEBUG(5,("SMB_QFBI - "));
3423 DEBUG(5,("create: %s ", ctime(&create_time
)));
3424 DEBUG(5,("access: %s ", ctime(&atime
)));
3425 DEBUG(5,("write: %s ", ctime(&mtime
)));
3426 DEBUG(5,("change: %s ", ctime(&c_time
)));
3427 DEBUG(5,("mode: %x\n", mode
));
3428 *fixed_portion
= data_size
;
3431 case SMB_FILE_STANDARD_INFORMATION
:
3432 case SMB_QUERY_FILE_STANDARD_INFO
:
3434 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
3436 SOFF_T(pdata
,0,allocation_size
);
3437 SOFF_T(pdata
,8,file_size
);
3438 SIVAL(pdata
,16,nlink
);
3439 SCVAL(pdata
,20,delete_pending
?1:0);
3440 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
3441 SSVAL(pdata
,22,0); /* Padding. */
3442 *fixed_portion
= 24;
3445 case SMB_FILE_EA_INFORMATION
:
3446 case SMB_QUERY_FILE_EA_INFO
:
3448 unsigned int ea_size
=
3449 estimate_ea_size(smb_fname
->fsp
);
3450 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
3453 SIVAL(pdata
,0,ea_size
);
3457 /* Get the 8.3 name - used if NT SMB was negotiated. */
3458 case SMB_QUERY_FILE_ALT_NAME_INFO
:
3459 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
3461 char mangled_name
[13];
3462 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
3463 if (!name_to_8_3(base_name
,mangled_name
,
3464 True
,conn
->params
)) {
3465 return NT_STATUS_NO_MEMORY
;
3467 status
= srvstr_push(dstart
, flags2
,
3468 pdata
+4, mangled_name
,
3469 PTR_DIFF(dend
, pdata
+4),
3471 if (!NT_STATUS_IS_OK(status
)) {
3474 data_size
= 4 + len
;
3480 case SMB_QUERY_FILE_NAME_INFO
:
3483 this must be *exactly* right for ACLs on mapped drives to work
3485 status
= srvstr_push(dstart
, flags2
,
3487 PTR_DIFF(dend
, pdata
+4),
3489 if (!NT_STATUS_IS_OK(status
)) {
3492 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
3493 data_size
= 4 + len
;
3498 case SMB_FILE_NORMALIZED_NAME_INFORMATION
:
3500 char *nfname
= NULL
;
3502 if (fsp
== NULL
|| !fsp
->conn
->sconn
->using_smb2
) {
3503 return NT_STATUS_INVALID_LEVEL
;
3506 nfname
= talloc_strdup(mem_ctx
, smb_fname
->base_name
);
3507 if (nfname
== NULL
) {
3508 return NT_STATUS_NO_MEMORY
;
3511 if (ISDOT(nfname
)) {
3514 string_replace(nfname
, '/', '\\');
3516 if (fsp_is_alternate_stream(fsp
)) {
3517 const char *s
= smb_fname
->stream_name
;
3518 const char *e
= NULL
;
3521 SMB_ASSERT(s
[0] != '\0');
3524 * smb_fname->stream_name is in form
3525 * of ':StrEam:$DATA', but we should only
3526 * append ':StrEam' here.
3529 e
= strchr(&s
[1], ':');
3535 nfname
= talloc_strndup_append(nfname
, s
, n
);
3536 if (nfname
== NULL
) {
3537 return NT_STATUS_NO_MEMORY
;
3541 status
= srvstr_push(dstart
, flags2
,
3543 PTR_DIFF(dend
, pdata
+4),
3545 if (!NT_STATUS_IS_OK(status
)) {
3548 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NORMALIZED_NAME_INFORMATION\n"));
3549 data_size
= 4 + len
;
3555 case SMB_FILE_ALLOCATION_INFORMATION
:
3556 case SMB_QUERY_FILE_ALLOCATION_INFO
:
3557 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
3559 SOFF_T(pdata
,0,allocation_size
);
3562 case SMB_FILE_END_OF_FILE_INFORMATION
:
3563 case SMB_QUERY_FILE_END_OF_FILEINFO
:
3564 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
3566 SOFF_T(pdata
,0,file_size
);
3569 case SMB_QUERY_FILE_ALL_INFO
:
3570 case SMB_FILE_ALL_INFORMATION
:
3572 unsigned int ea_size
=
3573 estimate_ea_size(smb_fname
->fsp
);
3574 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
3575 put_long_date_full_timespec(conn
->ts_res
,pdata
,&create_time_ts
);
3576 put_long_date_full_timespec(conn
->ts_res
,pdata
+8,&atime_ts
);
3577 put_long_date_full_timespec(conn
->ts_res
,pdata
+16,&mtime_ts
); /* write time */
3578 put_long_date_full_timespec(conn
->ts_res
,pdata
+24,&ctime_ts
); /* change time */
3579 SIVAL(pdata
,32,mode
);
3580 SIVAL(pdata
,36,0); /* padding. */
3582 SOFF_T(pdata
,0,allocation_size
);
3583 SOFF_T(pdata
,8,file_size
);
3584 SIVAL(pdata
,16,nlink
);
3585 SCVAL(pdata
,20,delete_pending
);
3586 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
3589 SIVAL(pdata
,0,ea_size
);
3590 pdata
+= 4; /* EA info */
3591 status
= srvstr_push(dstart
, flags2
,
3593 PTR_DIFF(dend
, pdata
+4),
3595 if (!NT_STATUS_IS_OK(status
)) {
3600 data_size
= PTR_DIFF(pdata
,(*ppdata
));
3601 *fixed_portion
= 10;
3605 case SMB2_FILE_ALL_INFORMATION
:
3607 unsigned int ea_size
=
3608 estimate_ea_size(smb_fname
->fsp
);
3609 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
3610 put_long_date_full_timespec(conn
->ts_res
,pdata
+0x00,&create_time_ts
);
3611 put_long_date_full_timespec(conn
->ts_res
,pdata
+0x08,&atime_ts
);
3612 put_long_date_full_timespec(conn
->ts_res
,pdata
+0x10,&mtime_ts
); /* write time */
3613 put_long_date_full_timespec(conn
->ts_res
,pdata
+0x18,&ctime_ts
); /* change time */
3614 SIVAL(pdata
, 0x20, mode
);
3615 SIVAL(pdata
, 0x24, 0); /* padding. */
3616 SBVAL(pdata
, 0x28, allocation_size
);
3617 SBVAL(pdata
, 0x30, file_size
);
3618 SIVAL(pdata
, 0x38, nlink
);
3619 SCVAL(pdata
, 0x3C, delete_pending
);
3620 SCVAL(pdata
, 0x3D, (mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
3621 SSVAL(pdata
, 0x3E, 0); /* padding */
3622 SBVAL(pdata
, 0x40, file_id
);
3623 SIVAL(pdata
, 0x48, ea_size
);
3624 SIVAL(pdata
, 0x4C, access_mask
);
3625 SBVAL(pdata
, 0x50, pos
);
3626 SIVAL(pdata
, 0x58, mode
); /*TODO: mode != mode fix this!!! */
3627 SIVAL(pdata
, 0x5C, 0); /* No alignment needed. */
3631 status
= srvstr_push(dstart
, flags2
,
3633 PTR_DIFF(dend
, pdata
+4),
3635 if (!NT_STATUS_IS_OK(status
)) {
3640 data_size
= PTR_DIFF(pdata
,(*ppdata
));
3641 *fixed_portion
= 104;
3644 case SMB_FILE_INTERNAL_INFORMATION
:
3646 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3647 SBVAL(pdata
, 0, file_id
);
3652 case SMB_FILE_ACCESS_INFORMATION
:
3653 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3654 SIVAL(pdata
, 0, access_mask
);
3659 case SMB_FILE_NAME_INFORMATION
:
3660 /* Pathname with leading '\'. */
3663 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
3664 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3665 SIVAL(pdata
,0,byte_len
);
3666 data_size
= 4 + byte_len
;
3670 case SMB_FILE_DISPOSITION_INFORMATION
:
3671 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3673 SCVAL(pdata
,0,delete_pending
);
3677 case SMB_FILE_POSITION_INFORMATION
:
3678 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3680 SOFF_T(pdata
,0,pos
);
3684 case SMB_FILE_MODE_INFORMATION
:
3685 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3686 SIVAL(pdata
,0,mode
);
3691 case SMB_FILE_ALIGNMENT_INFORMATION
:
3692 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3693 SIVAL(pdata
,0,0); /* No alignment needed. */
3699 * NT4 server just returns "invalid query" to this - if we try
3700 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
3703 /* The first statement above is false - verified using Thursby
3704 * client against NT4 -- gcolley.
3706 case SMB_QUERY_FILE_STREAM_INFO
:
3707 case SMB_FILE_STREAM_INFORMATION
: {
3708 unsigned int num_streams
= 0;
3709 struct stream_struct
*streams
= NULL
;
3711 DEBUG(10,("smbd_do_qfilepathinfo: "
3712 "SMB_FILE_STREAM_INFORMATION\n"));
3714 if (is_ntfs_stream_smb_fname(smb_fname
)) {
3715 return NT_STATUS_INVALID_PARAMETER
;
3718 status
= vfs_fstreaminfo(fsp
,
3723 if (!NT_STATUS_IS_OK(status
)) {
3724 DEBUG(10, ("could not get stream info: %s\n",
3725 nt_errstr(status
)));
3729 status
= marshall_stream_info(num_streams
, streams
,
3730 pdata
, max_data_bytes
,
3733 if (!NT_STATUS_IS_OK(status
)) {
3734 DEBUG(10, ("marshall_stream_info failed: %s\n",
3735 nt_errstr(status
)));
3736 TALLOC_FREE(streams
);
3740 TALLOC_FREE(streams
);
3742 *fixed_portion
= 32;
3746 case SMB_QUERY_COMPRESSION_INFO
:
3747 case SMB_FILE_COMPRESSION_INFORMATION
:
3748 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3749 SOFF_T(pdata
,0,file_size
);
3750 SIVAL(pdata
,8,0); /* ??? */
3751 SIVAL(pdata
,12,0); /* ??? */
3753 *fixed_portion
= 16;
3756 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
3757 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3758 put_long_date_full_timespec(conn
->ts_res
,pdata
,&create_time_ts
);
3759 put_long_date_full_timespec(conn
->ts_res
,pdata
+8,&atime_ts
);
3760 put_long_date_full_timespec(conn
->ts_res
,pdata
+16,&mtime_ts
); /* write time */
3761 put_long_date_full_timespec(conn
->ts_res
,pdata
+24,&ctime_ts
); /* change time */
3762 SOFF_T(pdata
,32,allocation_size
);
3763 SOFF_T(pdata
,40,file_size
);
3764 SIVAL(pdata
,48,mode
);
3765 SIVAL(pdata
,52,0); /* ??? */
3767 *fixed_portion
= 56;
3770 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
3771 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3772 SIVAL(pdata
,0,mode
);
3779 * SMB2 UNIX Extensions.
3781 case SMB2_FILE_POSIX_INFORMATION_INTERNAL
:
3783 uint8_t *buf
= NULL
;
3786 if (!(conn
->sconn
->using_smb2
)) {
3787 return NT_STATUS_INVALID_LEVEL
;
3789 if (!lp_smb3_unix_extensions()) {
3790 return NT_STATUS_INVALID_LEVEL
;
3793 return NT_STATUS_INVALID_HANDLE
;
3795 if (!(fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
)) {
3796 return NT_STATUS_INVALID_LEVEL
;
3799 /* Determine the size of the posix info context */
3800 plen
= store_smb2_posix_info(conn
,
3806 if (plen
== -1 || data_size
< plen
) {
3807 return NT_STATUS_INVALID_PARAMETER
;
3809 buf
= talloc_zero_size(mem_ctx
, plen
);
3811 return NT_STATUS_NO_MEMORY
;
3814 /* Store the context in buf */
3815 store_smb2_posix_info(conn
,
3821 memcpy(pdata
, buf
, plen
);
3827 return NT_STATUS_INVALID_LEVEL
;
3830 *pdata_size
= data_size
;
3831 return NT_STATUS_OK
;
3834 /****************************************************************************
3835 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3837 ****************************************************************************/
3839 NTSTATUS
hardlink_internals(TALLOC_CTX
*ctx
,
3840 connection_struct
*conn
,
3841 struct smb_request
*req
,
3842 bool overwrite_if_exists
,
3843 struct files_struct
*old_dirfsp
,
3844 const struct smb_filename
*smb_fname_old
,
3845 struct files_struct
*new_dirfsp
,
3846 struct smb_filename
*smb_fname_new
)
3848 NTSTATUS status
= NT_STATUS_OK
;
3851 struct smb_filename
*parent_fname_old
= NULL
;
3852 struct smb_filename
*base_name_old
= NULL
;
3853 struct smb_filename
*parent_fname_new
= NULL
;
3854 struct smb_filename
*base_name_new
= NULL
;
3856 /* source must already exist. */
3857 if (!VALID_STAT(smb_fname_old
->st
)) {
3858 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3862 /* No links from a directory. */
3863 if (S_ISDIR(smb_fname_old
->st
.st_ex_mode
)) {
3864 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
3868 /* Setting a hardlink to/from a stream isn't currently supported. */
3869 ok
= is_ntfs_stream_smb_fname(smb_fname_old
);
3871 DBG_DEBUG("Old name has streams\n");
3872 status
= NT_STATUS_INVALID_PARAMETER
;
3875 ok
= is_ntfs_stream_smb_fname(smb_fname_new
);
3877 DBG_DEBUG("New name has streams\n");
3878 status
= NT_STATUS_INVALID_PARAMETER
;
3882 status
= parent_pathref(talloc_tos(),
3887 if (!NT_STATUS_IS_OK(status
)) {
3891 status
= parent_pathref(talloc_tos(),
3896 if (!NT_STATUS_IS_OK(status
)) {
3900 if (VALID_STAT(smb_fname_new
->st
)) {
3901 if (overwrite_if_exists
) {
3902 if (S_ISDIR(smb_fname_new
->st
.st_ex_mode
)) {
3903 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
3906 status
= unlink_internals(conn
,
3908 FILE_ATTRIBUTE_NORMAL
,
3909 NULL
, /* new_dirfsp */
3911 if (!NT_STATUS_IS_OK(status
)) {
3915 /* Disallow if newname already exists. */
3916 status
= NT_STATUS_OBJECT_NAME_COLLISION
;
3921 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
3922 smb_fname_old
->base_name
, smb_fname_new
->base_name
));
3924 ret
= SMB_VFS_LINKAT(conn
,
3925 parent_fname_old
->fsp
,
3927 parent_fname_new
->fsp
,
3932 status
= map_nt_error_from_unix(errno
);
3933 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3934 nt_errstr(status
), smb_fname_old
->base_name
,
3935 smb_fname_new
->base_name
));
3940 TALLOC_FREE(parent_fname_old
);
3941 TALLOC_FREE(parent_fname_new
);
3945 /****************************************************************************
3946 Deal with setting the time from any of the setfilepathinfo functions.
3947 NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
3948 calling this function.
3949 ****************************************************************************/
3951 NTSTATUS
smb_set_file_time(connection_struct
*conn
,
3953 struct smb_filename
*smb_fname
,
3954 struct smb_file_time
*ft
,
3955 bool setting_write_time
)
3957 struct files_struct
*set_fsp
= NULL
;
3958 struct timeval_buf tbuf
[4];
3960 FILE_NOTIFY_CHANGE_LAST_ACCESS
3961 |FILE_NOTIFY_CHANGE_LAST_WRITE
3962 |FILE_NOTIFY_CHANGE_CREATION
;
3965 if (!VALID_STAT(smb_fname
->st
)) {
3966 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3971 return NT_STATUS_OK
;
3974 set_fsp
= metadata_fsp(fsp
);
3976 /* get some defaults (no modifications) if any info is zero or -1. */
3977 if (is_omit_timespec(&ft
->create_time
)) {
3978 action
&= ~FILE_NOTIFY_CHANGE_CREATION
;
3981 if (is_omit_timespec(&ft
->atime
)) {
3982 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
3985 if (is_omit_timespec(&ft
->mtime
)) {
3986 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
3989 if (!setting_write_time
) {
3990 /* ft->mtime comes from change time, not write time. */
3991 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
3994 /* Ensure the resolution is the correct for
3995 * what we can store on this filesystem. */
3997 round_timespec(conn
->ts_res
, &ft
->create_time
);
3998 round_timespec(conn
->ts_res
, &ft
->ctime
);
3999 round_timespec(conn
->ts_res
, &ft
->atime
);
4000 round_timespec(conn
->ts_res
, &ft
->mtime
);
4002 DBG_DEBUG("smb_set_filetime: actime: %s\n ",
4003 timespec_string_buf(&ft
->atime
, true, &tbuf
[0]));
4004 DBG_DEBUG("smb_set_filetime: modtime: %s\n ",
4005 timespec_string_buf(&ft
->mtime
, true, &tbuf
[1]));
4006 DBG_DEBUG("smb_set_filetime: ctime: %s\n ",
4007 timespec_string_buf(&ft
->ctime
, true, &tbuf
[2]));
4008 DBG_DEBUG("smb_set_file_time: createtime: %s\n ",
4009 timespec_string_buf(&ft
->create_time
, true, &tbuf
[3]));
4011 if (setting_write_time
) {
4013 * This was a Windows setfileinfo on an open file.
4014 * NT does this a lot. We also need to
4015 * set the time here, as it can be read by
4016 * FindFirst/FindNext and with the patch for bug #2045
4017 * in smbd/fileio.c it ensures that this timestamp is
4018 * kept sticky even after a write. We save the request
4019 * away and will set it on file close and after a write. JRA.
4022 DBG_DEBUG("setting pending modtime to %s\n",
4023 timespec_string_buf(&ft
->mtime
, true, &tbuf
[0]));
4025 if (set_fsp
!= NULL
) {
4026 set_sticky_write_time_fsp(set_fsp
, ft
->mtime
);
4028 set_sticky_write_time_path(
4029 vfs_file_id_from_sbuf(conn
, &smb_fname
->st
),
4034 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
4036 ret
= file_ntimes(conn
, set_fsp
, ft
);
4038 return map_nt_error_from_unix(errno
);
4041 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
,
4042 smb_fname
->base_name
);
4043 return NT_STATUS_OK
;
4046 /****************************************************************************
4047 Deal with setting the dosmode from any of the setfilepathinfo functions.
4048 NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
4049 done before calling this function.
4050 ****************************************************************************/
4052 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
4053 struct files_struct
*fsp
,
4056 struct files_struct
*dos_fsp
= NULL
;
4057 uint32_t current_dosmode
;
4060 if (!VALID_STAT(fsp
->fsp_name
->st
)) {
4061 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4064 dos_fsp
= metadata_fsp(fsp
);
4067 if (S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
4068 dosmode
|= FILE_ATTRIBUTE_DIRECTORY
;
4070 dosmode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
4074 DBG_DEBUG("dosmode: 0x%" PRIx32
"\n", dosmode
);
4076 /* check the mode isn't different, before changing it */
4078 return NT_STATUS_OK
;
4080 current_dosmode
= fdos_mode(dos_fsp
);
4081 if (dosmode
== current_dosmode
) {
4082 return NT_STATUS_OK
;
4085 DBG_DEBUG("file %s : setting dos mode 0x%" PRIx32
"\n",
4086 fsp_str_dbg(dos_fsp
), dosmode
);
4088 ret
= file_set_dosmode(conn
, dos_fsp
->fsp_name
, dosmode
, NULL
, false);
4090 DBG_WARNING("file_set_dosmode of %s failed: %s\n",
4091 fsp_str_dbg(dos_fsp
), strerror(errno
));
4092 return map_nt_error_from_unix(errno
);
4095 return NT_STATUS_OK
;
4098 /****************************************************************************
4099 Deal with setting the size from any of the setfilepathinfo functions.
4100 ****************************************************************************/
4102 NTSTATUS
smb_set_file_size(connection_struct
*conn
,
4103 struct smb_request
*req
,
4105 struct smb_filename
*smb_fname
,
4106 const SMB_STRUCT_STAT
*psbuf
,
4108 bool fail_after_createfile
)
4110 NTSTATUS status
= NT_STATUS_OK
;
4111 files_struct
*new_fsp
= NULL
;
4113 if (!VALID_STAT(*psbuf
)) {
4114 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4117 DBG_INFO("size: %"PRIu64
", file_size_stat=%"PRIu64
"\n",
4119 get_file_size_stat(psbuf
));
4121 if (size
== get_file_size_stat(psbuf
)) {
4123 return NT_STATUS_OK
;
4125 if (!fsp
->fsp_flags
.modified
) {
4126 return NT_STATUS_OK
;
4128 trigger_write_time_update_immediate(fsp
);
4129 return NT_STATUS_OK
;
4132 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
4133 smb_fname_str_dbg(smb_fname
), (double)size
));
4136 !fsp
->fsp_flags
.is_pathref
&&
4137 fsp_get_io_fd(fsp
) != -1)
4139 /* Handle based call. */
4140 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
4141 return NT_STATUS_ACCESS_DENIED
;
4144 if (vfs_set_filelen(fsp
, size
) == -1) {
4145 return map_nt_error_from_unix(errno
);
4147 trigger_write_time_update_immediate(fsp
);
4148 return NT_STATUS_OK
;
4151 status
= SMB_VFS_CREATE_FILE(
4155 smb_fname
, /* fname */
4156 FILE_WRITE_DATA
, /* access_mask */
4157 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
4159 FILE_OPEN
, /* create_disposition*/
4160 0, /* create_options */
4161 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
4162 0, /* oplock_request */
4164 0, /* allocation_size */
4165 0, /* private_flags */
4168 &new_fsp
, /* result */
4170 NULL
, NULL
); /* create context */
4172 if (!NT_STATUS_IS_OK(status
)) {
4173 /* NB. We check for open_was_deferred in the caller. */
4177 /* See RAW-SFILEINFO-END-OF-FILE */
4178 if (fail_after_createfile
) {
4179 close_file_free(req
, &new_fsp
, NORMAL_CLOSE
);
4180 return NT_STATUS_INVALID_LEVEL
;
4183 if (vfs_set_filelen(new_fsp
, size
) == -1) {
4184 status
= map_nt_error_from_unix(errno
);
4185 close_file_free(req
, &new_fsp
, NORMAL_CLOSE
);
4189 trigger_write_time_update_immediate(new_fsp
);
4190 close_file_free(req
, &new_fsp
, NORMAL_CLOSE
);
4191 return NT_STATUS_OK
;
4194 /****************************************************************************
4195 Deal with SMB_INFO_SET_EA.
4196 ****************************************************************************/
4198 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
4202 struct smb_filename
*smb_fname
)
4204 struct ea_list
*ea_list
= NULL
;
4205 TALLOC_CTX
*ctx
= NULL
;
4206 NTSTATUS status
= NT_STATUS_OK
;
4208 if (total_data
< 10) {
4210 /* OS/2 workplace shell seems to send SET_EA requests of "null"
4211 length. They seem to have no effect. Bug #3212. JRA */
4213 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
4214 /* We're done. We only get EA info in this call. */
4215 return NT_STATUS_OK
;
4218 return NT_STATUS_INVALID_PARAMETER
;
4221 if (IVAL(pdata
,0) > total_data
) {
4222 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
4223 IVAL(pdata
,0), (unsigned int)total_data
));
4224 return NT_STATUS_INVALID_PARAMETER
;
4228 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
4230 return NT_STATUS_INVALID_PARAMETER
;
4235 * The only way fsp can be NULL here is if
4236 * smb_fname points at a symlink and
4237 * and we're in POSIX context.
4238 * Ensure this is the case.
4240 * In this case we cannot set the EA.
4242 SMB_ASSERT(smb_fname
->flags
& SMB_FILENAME_POSIX_PATH
);
4243 return NT_STATUS_ACCESS_DENIED
;
4246 status
= set_ea(conn
, fsp
, ea_list
);
4251 /****************************************************************************
4252 Deal with SMB_FILE_FULL_EA_INFORMATION set.
4253 ****************************************************************************/
4255 static NTSTATUS
smb_set_file_full_ea_info(connection_struct
*conn
,
4260 struct ea_list
*ea_list
= NULL
;
4264 return NT_STATUS_INVALID_HANDLE
;
4267 if (!lp_ea_support(SNUM(conn
))) {
4268 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
4269 "EA's not supported.\n",
4270 (unsigned int)total_data
));
4271 return NT_STATUS_EAS_NOT_SUPPORTED
;
4274 if (total_data
< 10) {
4275 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
4277 (unsigned int)total_data
));
4278 return NT_STATUS_INVALID_PARAMETER
;
4281 ea_list
= read_nttrans_ea_list(talloc_tos(),
4286 return NT_STATUS_INVALID_PARAMETER
;
4289 status
= set_ea(conn
, fsp
, ea_list
);
4291 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
4292 smb_fname_str_dbg(fsp
->fsp_name
),
4293 nt_errstr(status
) ));
4299 /****************************************************************************
4300 Deal with SMB_SET_FILE_DISPOSITION_INFO.
4301 ****************************************************************************/
4303 NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
4307 struct smb_filename
*smb_fname
)
4309 NTSTATUS status
= NT_STATUS_OK
;
4310 bool delete_on_close
;
4311 uint32_t dosmode
= 0;
4313 if (total_data
< 1) {
4314 return NT_STATUS_INVALID_PARAMETER
;
4318 return NT_STATUS_INVALID_HANDLE
;
4321 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
4322 dosmode
= fdos_mode(fsp
);
4324 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
4325 "delete_on_close = %u\n",
4326 smb_fname_str_dbg(smb_fname
),
4327 (unsigned int)dosmode
,
4328 (unsigned int)delete_on_close
));
4330 if (delete_on_close
) {
4331 status
= can_set_delete_on_close(fsp
, dosmode
);
4332 if (!NT_STATUS_IS_OK(status
)) {
4337 /* The set is across all open files on this dev/inode pair. */
4338 if (!set_delete_on_close(fsp
, delete_on_close
,
4339 conn
->session_info
->security_token
,
4340 conn
->session_info
->unix_token
)) {
4341 return NT_STATUS_ACCESS_DENIED
;
4343 return NT_STATUS_OK
;
4346 /****************************************************************************
4347 Deal with SMB_FILE_POSITION_INFORMATION.
4348 ****************************************************************************/
4350 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
4355 uint64_t position_information
;
4357 if (total_data
< 8) {
4358 return NT_STATUS_INVALID_PARAMETER
;
4362 /* Ignore on pathname based set. */
4363 return NT_STATUS_OK
;
4366 position_information
= (uint64_t)IVAL(pdata
,0);
4367 position_information
|= (((uint64_t)IVAL(pdata
,4)) << 32);
4369 DEBUG(10,("smb_file_position_information: Set file position "
4370 "information for file %s to %.0f\n", fsp_str_dbg(fsp
),
4371 (double)position_information
));
4372 fh_set_position_information(fsp
->fh
, position_information
);
4373 return NT_STATUS_OK
;
4376 /****************************************************************************
4377 Deal with SMB_FILE_MODE_INFORMATION.
4378 ****************************************************************************/
4380 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
4386 if (total_data
< 4) {
4387 return NT_STATUS_INVALID_PARAMETER
;
4389 mode
= IVAL(pdata
,0);
4390 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
4391 return NT_STATUS_INVALID_PARAMETER
;
4393 return NT_STATUS_OK
;
4396 /****************************************************************************
4397 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
4398 ****************************************************************************/
4400 static NTSTATUS
smb2_file_rename_information(connection_struct
*conn
,
4401 struct smb_request
*req
,
4405 struct smb_filename
*smb_fname_src
)
4409 char *newname
= NULL
;
4410 struct files_struct
*dst_dirfsp
= NULL
;
4411 struct smb_filename
*smb_fname_dst
= NULL
;
4412 const char *dst_original_lcomp
= NULL
;
4413 uint32_t ucf_flags
= ucf_flags_from_smb_request(req
);
4414 NTSTATUS status
= NT_STATUS_OK
;
4415 TALLOC_CTX
*ctx
= talloc_tos();
4418 return NT_STATUS_INVALID_HANDLE
;
4421 if (total_data
< 20) {
4422 return NT_STATUS_INVALID_PARAMETER
;
4425 overwrite
= (CVAL(pdata
,0) ? True
: False
);
4426 len
= IVAL(pdata
,16);
4428 if (len
> (total_data
- 20) || (len
== 0)) {
4429 return NT_STATUS_INVALID_PARAMETER
;
4432 (void)srvstr_pull_talloc(ctx
,
4440 if (newname
== NULL
) {
4441 return NT_STATUS_INVALID_PARAMETER
;
4444 /* SMB2 rename paths are never DFS. */
4445 req
->flags2
&= ~FLAGS2_DFS_PATHNAMES
;
4446 ucf_flags
&= ~UCF_DFS_PATHNAME
;
4448 status
= check_path_syntax_smb2(newname
);
4449 if (!NT_STATUS_IS_OK(status
)) {
4453 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
4456 if (newname
[0] == ':') {
4457 /* Create an smb_fname to call rename_internals_fsp() with. */
4458 smb_fname_dst
= synthetic_smb_fname(talloc_tos(),
4459 fsp
->base_fsp
->fsp_name
->base_name
,
4462 fsp
->base_fsp
->fsp_name
->twrp
,
4463 fsp
->base_fsp
->fsp_name
->flags
);
4464 if (smb_fname_dst
== NULL
) {
4465 status
= NT_STATUS_NO_MEMORY
;
4469 status
= filename_convert_dirfsp(ctx
,
4473 0, /* Never a TWRP. */
4476 if (!NT_STATUS_IS_OK(status
)) {
4482 * Set the original last component, since
4483 * rename_internals_fsp() requires it.
4485 dst_original_lcomp
= get_original_lcomp(smb_fname_dst
,
4489 if (dst_original_lcomp
== NULL
) {
4490 status
= NT_STATUS_NO_MEMORY
;
4494 DEBUG(10,("smb2_file_rename_information: "
4495 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
4496 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
4497 smb_fname_str_dbg(smb_fname_dst
)));
4498 status
= rename_internals_fsp(conn
,
4500 NULL
, /* dst_dirfsp */
4503 (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
),
4507 TALLOC_FREE(smb_fname_dst
);
4511 static NTSTATUS
smb2_file_link_information(connection_struct
*conn
,
4512 struct smb_request
*req
,
4516 struct smb_filename
*smb_fname_src
)
4520 char *newname
= NULL
;
4521 struct files_struct
*dst_dirfsp
= NULL
;
4522 struct smb_filename
*smb_fname_dst
= NULL
;
4523 NTSTATUS status
= NT_STATUS_OK
;
4524 uint32_t ucf_flags
= ucf_flags_from_smb_request(req
);
4526 TALLOC_CTX
*ctx
= talloc_tos();
4529 return NT_STATUS_INVALID_HANDLE
;
4532 if (total_data
< 20) {
4533 return NT_STATUS_INVALID_PARAMETER
;
4536 overwrite
= (CVAL(pdata
,0) ? true : false);
4537 len
= IVAL(pdata
,16);
4539 if (len
> (total_data
- 20) || (len
== 0)) {
4540 return NT_STATUS_INVALID_PARAMETER
;
4543 ret
= srvstr_pull_talloc(ctx
,
4551 if (ret
== (size_t)-1 || newname
== NULL
) {
4552 return NT_STATUS_INVALID_PARAMETER
;
4555 /* SMB2 hardlink paths are never DFS. */
4556 req
->flags2
&= ~FLAGS2_DFS_PATHNAMES
;
4557 ucf_flags
&= ~UCF_DFS_PATHNAME
;
4559 status
= check_path_syntax_smb2(newname
);
4560 if (!NT_STATUS_IS_OK(status
)) {
4564 DBG_DEBUG("got name |%s|\n", newname
);
4566 status
= filename_convert_dirfsp(ctx
,
4573 if (!NT_STATUS_IS_OK(status
)) {
4577 if (fsp
->base_fsp
) {
4578 /* No stream names. */
4579 return NT_STATUS_NOT_SUPPORTED
;
4582 DBG_DEBUG("SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
4583 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
4584 smb_fname_str_dbg(smb_fname_dst
));
4585 status
= hardlink_internals(ctx
,
4589 NULL
, /* src_dirfsp */
4591 dst_dirfsp
, /* dst_dirfsp */
4594 TALLOC_FREE(smb_fname_dst
);
4598 static NTSTATUS
smb_file_link_information(connection_struct
*conn
,
4599 struct smb_request
*req
,
4603 struct smb_filename
*smb_fname_src
)
4607 char *newname
= NULL
;
4608 struct files_struct
*dst_dirfsp
= NULL
;
4609 struct smb_filename
*smb_fname_dst
= NULL
;
4610 NTSTATUS status
= NT_STATUS_OK
;
4611 uint32_t ucf_flags
= ucf_flags_from_smb_request(req
);
4612 NTTIME dst_twrp
= 0;
4613 TALLOC_CTX
*ctx
= talloc_tos();
4616 return NT_STATUS_INVALID_HANDLE
;
4619 if (total_data
< 20) {
4620 return NT_STATUS_INVALID_PARAMETER
;
4623 overwrite
= (CVAL(pdata
,0) ? true : false);
4624 len
= IVAL(pdata
,16);
4626 if (len
> (total_data
- 20) || (len
== 0)) {
4627 return NT_STATUS_INVALID_PARAMETER
;
4630 if (smb_fname_src
->flags
& SMB_FILENAME_POSIX_PATH
) {
4631 srvstr_get_path_posix(ctx
,
4639 ucf_flags
|= UCF_POSIX_PATHNAMES
;
4641 srvstr_get_path(ctx
,
4650 if (!NT_STATUS_IS_OK(status
)) {
4654 DEBUG(10,("smb_file_link_information: got name |%s|\n",
4657 if (ucf_flags
& UCF_GMT_PATHNAME
) {
4658 extract_snapshot_token(newname
, &dst_twrp
);
4660 status
= filename_convert_dirfsp(ctx
,
4667 if (!NT_STATUS_IS_OK(status
)) {
4671 if (fsp
->base_fsp
) {
4672 /* No stream names. */
4673 return NT_STATUS_NOT_SUPPORTED
;
4676 DEBUG(10,("smb_file_link_information: "
4677 "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
4678 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
4679 smb_fname_str_dbg(smb_fname_dst
)));
4680 status
= hardlink_internals(ctx
,
4684 NULL
, /* src_dirfsp */
4686 dst_dirfsp
, /* dst_dirfsp */
4689 TALLOC_FREE(smb_fname_dst
);
4694 /****************************************************************************
4695 Deal with SMB_FILE_RENAME_INFORMATION.
4696 ****************************************************************************/
4698 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
4699 struct smb_request
*req
,
4703 struct smb_filename
*smb_fname_src
)
4708 char *newname
= NULL
;
4709 struct files_struct
*dst_dirfsp
= NULL
;
4710 struct smb_filename
*smb_fname_dst
= NULL
;
4711 const char *dst_original_lcomp
= NULL
;
4712 NTSTATUS status
= NT_STATUS_OK
;
4714 TALLOC_CTX
*ctx
= talloc_tos();
4716 if (total_data
< 13) {
4717 return NT_STATUS_INVALID_PARAMETER
;
4720 overwrite
= (CVAL(pdata
,0) != 0);
4721 root_fid
= IVAL(pdata
,4);
4722 len
= IVAL(pdata
,8);
4724 if (len
> (total_data
- 12) || (len
== 0) || (root_fid
!= 0)) {
4725 return NT_STATUS_INVALID_PARAMETER
;
4728 if (req
->posix_pathnames
) {
4729 srvstr_get_path_posix(ctx
,
4738 srvstr_get_path(ctx
,
4747 if (!NT_STATUS_IS_OK(status
)) {
4751 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
4754 /* Check the new name has no '/' characters. */
4755 if (strchr_m(newname
, '/')) {
4756 return NT_STATUS_NOT_SUPPORTED
;
4759 if (fsp
&& fsp
->base_fsp
) {
4760 /* newname must be a stream name. */
4761 if (newname
[0] != ':') {
4762 return NT_STATUS_NOT_SUPPORTED
;
4765 /* Create an smb_fname to call rename_internals_fsp() with. */
4766 smb_fname_dst
= synthetic_smb_fname(talloc_tos(),
4767 fsp
->base_fsp
->fsp_name
->base_name
,
4770 fsp
->base_fsp
->fsp_name
->twrp
,
4771 fsp
->base_fsp
->fsp_name
->flags
);
4772 if (smb_fname_dst
== NULL
) {
4773 status
= NT_STATUS_NO_MEMORY
;
4778 * Get the original last component, since
4779 * rename_internals_fsp() requires it.
4781 dst_original_lcomp
= get_original_lcomp(smb_fname_dst
,
4785 if (dst_original_lcomp
== NULL
) {
4786 status
= NT_STATUS_NO_MEMORY
;
4792 * Build up an smb_fname_dst based on the filename passed in.
4793 * We basically just strip off the last component, and put on
4794 * the newname instead.
4796 char *base_name
= NULL
;
4797 uint32_t ucf_flags
= ucf_flags_from_smb_request(req
);
4798 NTTIME dst_twrp
= 0;
4800 /* newname must *not* be a stream name. */
4801 if (newname
[0] == ':') {
4802 return NT_STATUS_NOT_SUPPORTED
;
4806 * Strip off the last component (filename) of the path passed
4809 base_name
= talloc_strdup(ctx
, smb_fname_src
->base_name
);
4811 return NT_STATUS_NO_MEMORY
;
4813 p
= strrchr_m(base_name
, '/');
4817 base_name
= talloc_strdup(ctx
, "");
4819 return NT_STATUS_NO_MEMORY
;
4822 /* Append the new name. */
4823 base_name
= talloc_asprintf_append(base_name
,
4827 return NT_STATUS_NO_MEMORY
;
4830 if (ucf_flags
& UCF_GMT_PATHNAME
) {
4831 extract_snapshot_token(base_name
, &dst_twrp
);
4833 status
= filename_convert_dirfsp(ctx
,
4841 if (!NT_STATUS_IS_OK(status
)) {
4844 dst_original_lcomp
= get_original_lcomp(smb_fname_dst
,
4848 if (dst_original_lcomp
== NULL
) {
4849 status
= NT_STATUS_NO_MEMORY
;
4854 if (fsp
!= NULL
&& fsp
->fsp_flags
.is_fsa
) {
4855 DEBUG(10,("smb_file_rename_information: "
4856 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
4857 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
4858 smb_fname_str_dbg(smb_fname_dst
)));
4859 status
= rename_internals_fsp(conn
,
4867 DEBUG(10,("smb_file_rename_information: "
4868 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4869 smb_fname_str_dbg(smb_fname_src
),
4870 smb_fname_str_dbg(smb_fname_dst
)));
4871 status
= rename_internals(ctx
,
4874 NULL
, /* src_dirfsp */
4881 FILE_WRITE_ATTRIBUTES
);
4884 TALLOC_FREE(smb_fname_dst
);
4888 /****************************************************************************
4889 Deal with SMB_SET_FILE_BASIC_INFO.
4890 ****************************************************************************/
4892 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
4896 struct smb_filename
*smb_fname
)
4898 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
4899 struct smb_file_time ft
;
4900 uint32_t dosmode
= 0;
4901 NTSTATUS status
= NT_STATUS_OK
;
4903 init_smb_file_time(&ft
);
4905 if (total_data
< 36) {
4906 return NT_STATUS_INVALID_PARAMETER
;
4910 return NT_STATUS_INVALID_HANDLE
;
4913 status
= check_access_fsp(fsp
, FILE_WRITE_ATTRIBUTES
);
4914 if (!NT_STATUS_IS_OK(status
)) {
4918 /* Set the attributes */
4919 dosmode
= IVAL(pdata
,32);
4920 status
= smb_set_file_dosmode(conn
, fsp
, dosmode
);
4921 if (!NT_STATUS_IS_OK(status
)) {
4926 ft
.create_time
= pull_long_date_full_timespec(pdata
);
4929 ft
.atime
= pull_long_date_full_timespec(pdata
+8);
4932 ft
.mtime
= pull_long_date_full_timespec(pdata
+16);
4935 ft
.ctime
= pull_long_date_full_timespec(pdata
+24);
4937 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
4938 smb_fname_str_dbg(smb_fname
)));
4940 status
= smb_set_file_time(conn
, fsp
, smb_fname
, &ft
, true);
4941 if (!NT_STATUS_IS_OK(status
)) {
4945 if (fsp
->fsp_flags
.modified
) {
4946 trigger_write_time_update_immediate(fsp
);
4948 return NT_STATUS_OK
;
4951 /****************************************************************************
4952 Deal with SMB_INFO_STANDARD.
4953 ****************************************************************************/
4955 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
4959 struct smb_filename
*smb_fname
)
4962 struct smb_file_time ft
;
4964 init_smb_file_time(&ft
);
4966 if (total_data
< 12) {
4967 return NT_STATUS_INVALID_PARAMETER
;
4971 return NT_STATUS_INVALID_HANDLE
;
4975 ft
.create_time
= time_t_to_full_timespec(srv_make_unix_date2(pdata
));
4977 ft
.atime
= time_t_to_full_timespec(srv_make_unix_date2(pdata
+4));
4979 ft
.mtime
= time_t_to_full_timespec(srv_make_unix_date2(pdata
+8));
4981 DEBUG(10,("smb_set_info_standard: file %s\n",
4982 smb_fname_str_dbg(smb_fname
)));
4984 status
= check_access_fsp(fsp
, FILE_WRITE_ATTRIBUTES
);
4985 if (!NT_STATUS_IS_OK(status
)) {
4989 status
= smb_set_file_time(conn
, fsp
, smb_fname
, &ft
, true);
4990 if (!NT_STATUS_IS_OK(status
)) {
4994 if (fsp
->fsp_flags
.modified
) {
4995 trigger_write_time_update_immediate(fsp
);
4997 return NT_STATUS_OK
;
5000 /****************************************************************************
5001 Deal with SMB_SET_FILE_ALLOCATION_INFO.
5002 ****************************************************************************/
5004 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
5005 struct smb_request
*req
,
5009 struct smb_filename
*smb_fname
)
5011 uint64_t allocation_size
= 0;
5012 NTSTATUS status
= NT_STATUS_OK
;
5013 files_struct
*new_fsp
= NULL
;
5015 if (!VALID_STAT(smb_fname
->st
)) {
5016 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5019 if (total_data
< 8) {
5020 return NT_STATUS_INVALID_PARAMETER
;
5023 allocation_size
= (uint64_t)IVAL(pdata
,0);
5024 allocation_size
|= (((uint64_t)IVAL(pdata
,4)) << 32);
5025 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
5026 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
5027 (double)allocation_size
));
5029 if (allocation_size
) {
5030 allocation_size
= smb_roundup(conn
, allocation_size
);
5033 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
5034 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname
),
5035 (double)allocation_size
));
5038 !fsp
->fsp_flags
.is_pathref
&&
5039 fsp_get_io_fd(fsp
) != -1)
5041 /* Open file handle. */
5042 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
5043 return NT_STATUS_ACCESS_DENIED
;
5046 /* Only change if needed. */
5047 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
5048 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
5049 return map_nt_error_from_unix(errno
);
5052 /* But always update the time. */
5054 * This is equivalent to a write. Ensure it's seen immediately
5055 * if there are no pending writes.
5057 trigger_write_time_update_immediate(fsp
);
5058 return NT_STATUS_OK
;
5061 /* Pathname or stat or directory file. */
5062 status
= SMB_VFS_CREATE_FILE(
5066 smb_fname
, /* fname */
5067 FILE_WRITE_DATA
, /* access_mask */
5068 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5070 FILE_OPEN
, /* create_disposition*/
5071 0, /* create_options */
5072 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5073 0, /* oplock_request */
5075 0, /* allocation_size */
5076 0, /* private_flags */
5079 &new_fsp
, /* result */
5081 NULL
, NULL
); /* create context */
5083 if (!NT_STATUS_IS_OK(status
)) {
5084 /* NB. We check for open_was_deferred in the caller. */
5088 /* Only change if needed. */
5089 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
5090 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
5091 status
= map_nt_error_from_unix(errno
);
5092 close_file_free(req
, &new_fsp
, NORMAL_CLOSE
);
5097 /* Changing the allocation size should set the last mod time. */
5099 * This is equivalent to a write. Ensure it's seen immediately
5100 * if there are no pending writes.
5102 trigger_write_time_update_immediate(new_fsp
);
5103 close_file_free(req
, &new_fsp
, NORMAL_CLOSE
);
5104 return NT_STATUS_OK
;
5107 /****************************************************************************
5108 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
5109 ****************************************************************************/
5111 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
5112 struct smb_request
*req
,
5116 struct smb_filename
*smb_fname
,
5117 bool fail_after_createfile
)
5121 if (total_data
< 8) {
5122 return NT_STATUS_INVALID_PARAMETER
;
5125 size
= IVAL(pdata
,0);
5126 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
5127 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
5128 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
5131 return smb_set_file_size(conn
, req
,
5136 fail_after_createfile
);
5139 NTSTATUS
smbd_do_setfilepathinfo(connection_struct
*conn
,
5140 struct smb_request
*req
,
5141 TALLOC_CTX
*mem_ctx
,
5142 uint16_t info_level
,
5144 struct smb_filename
*smb_fname
,
5145 char **ppdata
, int total_data
,
5148 char *pdata
= *ppdata
;
5149 NTSTATUS status
= NT_STATUS_OK
;
5150 int data_return_size
= 0;
5154 DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
5155 "totdata=%d\n", smb_fname_str_dbg(smb_fname
),
5157 info_level
, total_data
));
5159 switch (info_level
) {
5161 case SMB_INFO_STANDARD
:
5163 status
= smb_set_info_standard(conn
,
5171 case SMB_INFO_SET_EA
:
5173 status
= smb_info_set_ea(conn
,
5181 case SMB_SET_FILE_BASIC_INFO
:
5182 case SMB_FILE_BASIC_INFORMATION
:
5184 status
= smb_set_file_basic_info(conn
,
5192 case SMB_FILE_ALLOCATION_INFORMATION
:
5193 case SMB_SET_FILE_ALLOCATION_INFO
:
5195 status
= smb_set_file_allocation_info(conn
, req
,
5203 case SMB_FILE_END_OF_FILE_INFORMATION
:
5204 case SMB_SET_FILE_END_OF_FILE_INFO
:
5207 * XP/Win7 both fail after the createfile with
5208 * SMB_SET_FILE_END_OF_FILE_INFO but not
5209 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
5210 * The level is known here, so pass it down
5214 (info_level
== SMB_SET_FILE_END_OF_FILE_INFO
);
5216 status
= smb_set_file_end_of_file_info(conn
, req
,
5225 case SMB_FILE_DISPOSITION_INFORMATION
:
5226 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
5229 /* JRA - We used to just ignore this on a path ?
5230 * Shouldn't this be invalid level on a pathname
5233 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
5234 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
5237 status
= smb_set_file_disposition_info(conn
,
5245 case SMB_FILE_POSITION_INFORMATION
:
5247 status
= smb_file_position_information(conn
,
5254 case SMB_FILE_FULL_EA_INFORMATION
:
5256 status
= smb_set_file_full_ea_info(conn
,
5263 /* From tridge Samba4 :
5264 * MODE_INFORMATION in setfileinfo (I have no
5265 * idea what "mode information" on a file is - it takes a value of 0,
5266 * 2, 4 or 6. What could it be?).
5269 case SMB_FILE_MODE_INFORMATION
:
5271 status
= smb_file_mode_information(conn
,
5277 /* [MS-SMB2] 3.3.5.21.1 states we MUST fail with STATUS_NOT_SUPPORTED. */
5278 case SMB_FILE_VALID_DATA_LENGTH_INFORMATION
:
5279 case SMB_FILE_SHORT_NAME_INFORMATION
:
5280 return NT_STATUS_NOT_SUPPORTED
;
5282 case SMB_FILE_RENAME_INFORMATION
:
5284 status
= smb_file_rename_information(conn
, req
,
5290 case SMB2_FILE_RENAME_INFORMATION_INTERNAL
:
5292 /* SMB2 rename information. */
5293 status
= smb2_file_rename_information(conn
, req
,
5299 case SMB_FILE_LINK_INFORMATION
:
5301 if (conn
->sconn
->using_smb2
) {
5302 status
= smb2_file_link_information(conn
,
5309 status
= smb_file_link_information(conn
,
5320 return NT_STATUS_INVALID_LEVEL
;
5323 if (!NT_STATUS_IS_OK(status
)) {
5327 *ret_data_size
= data_return_size
;
5328 return NT_STATUS_OK
;
5331 static uint32_t generate_volume_serial_number(
5332 const struct loadparm_substitution
*lp_sub
,
5335 int serial
= lp_volume_serial_number(snum
);
5336 return serial
!= -1 ? serial
:
5337 str_checksum(lp_servicename(talloc_tos(), lp_sub
, snum
)) ^
5338 (str_checksum(get_local_machine_name())<<16);