2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2007
5 Copyright (C) Stefan (metze) Metzmacher 2003
6 Copyright (C) Volker Lendecke 2005-2007
7 Copyright (C) Steve French 2005
8 Copyright (C) James Peach 2006-2007
10 Extensively modified by Andrew Tridgell, 1995
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "system/filesys.h"
29 #include "smbd/smbd.h"
30 #include "smbd/globals.h"
31 #include "../libcli/auth/libcli_auth.h"
32 #include "../librpc/gen_ndr/xattr.h"
33 #include "../librpc/gen_ndr/ndr_security.h"
34 #include "../librpc/gen_ndr/open_files.h"
35 #include "libcli/security/security.h"
38 #include "smbprofile.h"
39 #include "rpc_server/srv_pipe_hnd.h"
42 #define DIR_ENTRY_SAFETY_MARGIN 4096
44 static char *store_file_unix_basic(connection_struct
*conn
,
47 const SMB_STRUCT_STAT
*psbuf
);
49 static char *store_file_unix_basic_info2(connection_struct
*conn
,
52 const SMB_STRUCT_STAT
*psbuf
);
54 /********************************************************************
55 The canonical "check access" based on object handle or path function.
56 ********************************************************************/
58 NTSTATUS
check_access(connection_struct
*conn
,
60 const struct smb_filename
*smb_fname
,
64 if (!(fsp
->access_mask
& access_mask
)) {
65 return NT_STATUS_ACCESS_DENIED
;
68 NTSTATUS status
= smbd_check_access_rights(conn
,
72 if (!NT_STATUS_IS_OK(status
)) {
79 /********************************************************************
80 Roundup a value to the nearest allocation roundup size boundary.
81 Only do this for Windows clients.
82 ********************************************************************/
84 uint64_t smb_roundup(connection_struct
*conn
, uint64_t val
)
86 uint64_t rval
= lp_allocation_roundup_size(SNUM(conn
));
88 /* Only roundup for Windows clients. */
89 enum remote_arch_types ra_type
= get_remote_arch();
90 if (rval
&& (ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
91 val
= SMB_ROUNDUP(val
,rval
);
96 /********************************************************************
97 Create a 64 bit FileIndex. If the file is on the same device as
98 the root of the share, just return the 64-bit inode. If it isn't,
99 mangle as we used to do.
100 ********************************************************************/
102 uint64_t get_FileIndex(connection_struct
*conn
, const SMB_STRUCT_STAT
*psbuf
)
105 if (conn
->base_share_dev
== psbuf
->st_ex_dev
) {
106 return (uint64_t)psbuf
->st_ex_ino
;
108 file_index
= ((psbuf
->st_ex_ino
) & UINT32_MAX
); /* FileIndexLow */
109 file_index
|= ((uint64_t)((psbuf
->st_ex_dev
) & UINT32_MAX
)) << 32; /* FileIndexHigh */
113 /****************************************************************************
114 Utility functions for dealing with extended attributes.
115 ****************************************************************************/
117 /****************************************************************************
118 Refuse to allow clients to overwrite our private xattrs.
119 ****************************************************************************/
121 static bool samba_private_attr_name(const char *unix_ea_name
)
123 static const char * const prohibited_ea_names
[] = {
124 SAMBA_POSIX_INHERITANCE_EA_NAME
,
125 SAMBA_XATTR_DOS_ATTRIB
,
133 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
134 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
137 if (strncasecmp_m(unix_ea_name
, SAMBA_XATTR_DOSSTREAM_PREFIX
,
138 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX
)) == 0) {
144 /****************************************************************************
145 Get one EA value. Fill in a struct ea_struct.
146 ****************************************************************************/
148 NTSTATUS
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
149 files_struct
*fsp
, const char *fname
,
150 const char *ea_name
, struct ea_struct
*pea
)
152 /* Get the value of this xattr. Max size is 64k. */
153 size_t attr_size
= 256;
159 val
= talloc_realloc(mem_ctx
, val
, char, attr_size
);
161 return NT_STATUS_NO_MEMORY
;
164 if (fsp
&& fsp
->fh
->fd
!= -1) {
165 sizeret
= SMB_VFS_FGETXATTR(fsp
, ea_name
, val
, attr_size
);
167 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
170 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
176 return map_nt_error_from_unix(errno
);
179 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name
, (unsigned int)sizeret
));
180 dump_data(10, (uint8
*)val
, sizeret
);
183 if (strnequal(ea_name
, "user.", 5)) {
184 pea
->name
= talloc_strdup(mem_ctx
, &ea_name
[5]);
186 pea
->name
= talloc_strdup(mem_ctx
, ea_name
);
188 if (pea
->name
== NULL
) {
190 return NT_STATUS_NO_MEMORY
;
192 pea
->value
.data
= (unsigned char *)val
;
193 pea
->value
.length
= (size_t)sizeret
;
197 NTSTATUS
get_ea_names_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
198 files_struct
*fsp
, const char *fname
,
199 char ***pnames
, size_t *pnum_names
)
201 /* Get a list of all xattrs. Max namesize is 64k. */
202 size_t ea_namelist_size
= 1024;
203 char *ea_namelist
= NULL
;
208 ssize_t sizeret
= -1;
210 if (!lp_ea_support(SNUM(conn
))) {
219 * TALLOC the result early to get the talloc hierarchy right.
222 names
= talloc_array(mem_ctx
, char *, 1);
224 DEBUG(0, ("talloc failed\n"));
225 return NT_STATUS_NO_MEMORY
;
228 while (ea_namelist_size
<= 65536) {
230 ea_namelist
= talloc_realloc(
231 names
, ea_namelist
, char, ea_namelist_size
);
232 if (ea_namelist
== NULL
) {
233 DEBUG(0, ("talloc failed\n"));
235 return NT_STATUS_NO_MEMORY
;
238 if (fsp
&& fsp
->fh
->fd
!= -1) {
239 sizeret
= SMB_VFS_FLISTXATTR(fsp
, ea_namelist
,
242 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
,
246 if ((sizeret
== -1) && (errno
== ERANGE
)) {
247 ea_namelist_size
*= 2;
256 return map_nt_error_from_unix(errno
);
259 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
260 (unsigned int)sizeret
));
272 * Ensure the result is 0-terminated
275 if (ea_namelist
[sizeret
-1] != '\0') {
277 return NT_STATUS_INTERNAL_ERROR
;
285 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
289 tmp
= talloc_realloc(mem_ctx
, names
, char *, num_names
);
291 DEBUG(0, ("talloc failed\n"));
293 return NT_STATUS_NO_MEMORY
;
299 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
300 names
[num_names
++] = p
;
308 *pnum_names
= num_names
;
312 /****************************************************************************
313 Return a linked list of the total EA's. Plus the total size
314 ****************************************************************************/
316 static NTSTATUS
get_ea_list_from_file_path(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
317 const char *fname
, size_t *pea_total_len
, struct ea_list
**ea_list
)
319 /* Get a list of all xattrs. Max namesize is 64k. */
322 struct ea_list
*ea_list_head
= NULL
;
328 status
= get_ea_names_from_file(talloc_tos(), conn
, fsp
, fname
,
331 if (!NT_STATUS_IS_OK(status
)) {
335 if (num_names
== 0) {
340 for (i
=0; i
<num_names
; i
++) {
341 struct ea_list
*listp
;
344 if (strnequal(names
[i
], "system.", 7)
345 || samba_private_attr_name(names
[i
]))
348 listp
= talloc(mem_ctx
, struct ea_list
);
350 return NT_STATUS_NO_MEMORY
;
353 status
= get_ea_value(mem_ctx
, conn
, fsp
,
357 if (!NT_STATUS_IS_OK(status
)) {
361 if (listp
->ea
.value
.length
== 0) {
363 * We can never return a zero length EA.
364 * Windows reports the EA's as corrupted.
370 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
373 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
375 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
376 "= %u\n", (unsigned int)*pea_total_len
, dos_ea_name
,
377 (unsigned int)listp
->ea
.value
.length
));
379 DLIST_ADD_END(ea_list_head
, listp
, struct ea_list
*);
383 /* Add on 4 for total length. */
384 if (*pea_total_len
) {
388 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
389 (unsigned int)*pea_total_len
));
391 *ea_list
= ea_list_head
;
395 static NTSTATUS
get_ea_list_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
396 const struct smb_filename
*smb_fname
, size_t *pea_total_len
, struct ea_list
**ea_list
)
401 if (!lp_ea_support(SNUM(conn
))) {
405 if (is_ntfs_stream_smb_fname(smb_fname
)) {
406 return NT_STATUS_INVALID_PARAMETER
;
409 return get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, smb_fname
->base_name
, pea_total_len
, ea_list
);
412 /****************************************************************************
413 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
415 ****************************************************************************/
417 static unsigned int fill_ea_buffer(TALLOC_CTX
*mem_ctx
, char *pdata
, unsigned int total_data_size
,
418 connection_struct
*conn
, struct ea_list
*ea_list
)
420 unsigned int ret_data_size
= 4;
423 SMB_ASSERT(total_data_size
>= 4);
425 if (!lp_ea_support(SNUM(conn
))) {
430 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
433 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
434 dos_namelen
= strlen(dos_ea_name
);
435 if (dos_namelen
> 255 || dos_namelen
== 0) {
438 if (ea_list
->ea
.value
.length
> 65535) {
441 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
445 /* We know we have room. */
446 SCVAL(p
,0,ea_list
->ea
.flags
);
447 SCVAL(p
,1,dos_namelen
);
448 SSVAL(p
,2,ea_list
->ea
.value
.length
);
449 strlcpy(p
+4, dos_ea_name
, dos_namelen
+1);
450 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
452 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
453 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
456 ret_data_size
= PTR_DIFF(p
, pdata
);
457 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size
));
458 SIVAL(pdata
,0,ret_data_size
);
459 return ret_data_size
;
462 static NTSTATUS
fill_ea_chained_buffer(TALLOC_CTX
*mem_ctx
,
464 unsigned int total_data_size
,
465 unsigned int *ret_data_size
,
466 connection_struct
*conn
,
467 struct ea_list
*ea_list
)
469 uint8_t *p
= (uint8_t *)pdata
;
470 uint8_t *last_start
= NULL
;
471 bool do_store_data
= (pdata
!= NULL
);
475 if (!lp_ea_support(SNUM(conn
))) {
476 return NT_STATUS_NO_EAS_ON_FILE
;
479 for (; ea_list
; ea_list
= ea_list
->next
) {
484 if (last_start
!= NULL
&& do_store_data
) {
485 SIVAL(last_start
, 0, PTR_DIFF(p
, last_start
));
489 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
490 dos_namelen
= strlen(dos_ea_name
);
491 if (dos_namelen
> 255 || dos_namelen
== 0) {
492 return NT_STATUS_INTERNAL_ERROR
;
494 if (ea_list
->ea
.value
.length
> 65535) {
495 return NT_STATUS_INTERNAL_ERROR
;
498 this_size
= 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
501 size_t pad
= 4 - (this_size
% 4);
506 if (this_size
> total_data_size
) {
507 return NT_STATUS_INFO_LENGTH_MISMATCH
;
510 /* We know we have room. */
511 SIVAL(p
, 0x00, 0); /* next offset */
512 SCVAL(p
, 0x04, ea_list
->ea
.flags
);
513 SCVAL(p
, 0x05, dos_namelen
);
514 SSVAL(p
, 0x06, ea_list
->ea
.value
.length
);
515 strlcpy((char *)(p
+0x08), dos_ea_name
, dos_namelen
+1);
516 memcpy(p
+ 0x08 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
517 total_data_size
-= this_size
;
523 *ret_data_size
= PTR_DIFF(p
, pdata
);
524 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size
));
528 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const struct smb_filename
*smb_fname
)
530 size_t total_ea_len
= 0;
532 struct ea_list
*ea_list
= NULL
;
534 if (!lp_ea_support(SNUM(conn
))) {
537 mem_ctx
= talloc_stackframe();
539 /* If this is a stream fsp, then we need to instead find the
540 * estimated ea len from the main file, not the stream
541 * (streams cannot have EAs), but the estimate isn't just 0 in
543 if (is_ntfs_stream_smb_fname(smb_fname
)) {
546 (void)get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, smb_fname
->base_name
, &total_ea_len
, &ea_list
);
547 if(conn
->sconn
->using_smb2
) {
549 unsigned int ret_data_size
;
551 * We're going to be using fill_ea_chained_buffer() to
552 * marshall EA's - this size is significantly larger
553 * than the SMB1 buffer. Re-calculate the size without
556 status
= fill_ea_chained_buffer(mem_ctx
,
562 if (!NT_STATUS_IS_OK(status
)) {
565 total_ea_len
= ret_data_size
;
567 TALLOC_FREE(mem_ctx
);
571 /****************************************************************************
572 Ensure the EA name is case insensitive by matching any existing EA name.
573 ****************************************************************************/
575 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
578 TALLOC_CTX
*mem_ctx
= talloc_tos();
579 struct ea_list
*ea_list
;
580 NTSTATUS status
= get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
, &ea_list
);
581 if (!NT_STATUS_IS_OK(status
)) {
585 for (; ea_list
; ea_list
= ea_list
->next
) {
586 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
587 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
588 &unix_ea_name
[5], ea_list
->ea
.name
));
589 strlcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-5);
595 /****************************************************************************
596 Set or delete an extended attribute.
597 ****************************************************************************/
599 NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
,
600 const struct smb_filename
*smb_fname
, struct ea_list
*ea_list
)
605 if (!lp_ea_support(SNUM(conn
))) {
606 return NT_STATUS_EAS_NOT_SUPPORTED
;
609 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_EA
);
610 if (!NT_STATUS_IS_OK(status
)) {
614 /* Setting EAs on streams isn't supported. */
615 if (is_ntfs_stream_smb_fname(smb_fname
)) {
616 return NT_STATUS_INVALID_PARAMETER
;
619 fname
= smb_fname
->base_name
;
621 for (;ea_list
; ea_list
= ea_list
->next
) {
623 fstring unix_ea_name
;
625 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
626 fstrcat(unix_ea_name
, ea_list
->ea
.name
);
628 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
630 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, (unsigned int)ea_list
->ea
.value
.length
));
632 if (samba_private_attr_name(unix_ea_name
)) {
633 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
634 return NT_STATUS_ACCESS_DENIED
;
637 if (ea_list
->ea
.value
.length
== 0) {
638 /* Remove the attribute. */
639 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
640 DEBUG(10,("set_ea: deleting ea name %s on "
641 "file %s by file descriptor.\n",
642 unix_ea_name
, fsp_str_dbg(fsp
)));
643 ret
= SMB_VFS_FREMOVEXATTR(fsp
, unix_ea_name
);
645 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
646 unix_ea_name
, fname
));
647 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
650 /* Removing a non existent attribute always succeeds. */
651 if (ret
== -1 && errno
== ENOATTR
) {
652 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
658 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
659 DEBUG(10,("set_ea: setting ea name %s on file "
660 "%s by file descriptor.\n",
661 unix_ea_name
, fsp_str_dbg(fsp
)));
662 ret
= SMB_VFS_FSETXATTR(fsp
, unix_ea_name
,
663 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
665 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
666 unix_ea_name
, fname
));
667 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
,
668 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
674 if (errno
== ENOTSUP
) {
675 return NT_STATUS_EAS_NOT_SUPPORTED
;
678 return map_nt_error_from_unix(errno
);
684 /****************************************************************************
685 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
686 ****************************************************************************/
688 static struct ea_list
*read_ea_name_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
690 struct ea_list
*ea_list_head
= NULL
;
691 size_t converted_size
, offset
= 0;
693 while (offset
+ 2 < data_size
) {
694 struct ea_list
*eal
= talloc_zero(ctx
, struct ea_list
);
695 unsigned int namelen
= CVAL(pdata
,offset
);
697 offset
++; /* Go past the namelen byte. */
699 /* integer wrap paranioa. */
700 if ((offset
+ namelen
< offset
) || (offset
+ namelen
< namelen
) ||
701 (offset
> data_size
) || (namelen
> data_size
) ||
702 (offset
+ namelen
>= data_size
)) {
705 /* Ensure the name is null terminated. */
706 if (pdata
[offset
+ namelen
] != '\0') {
709 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, &pdata
[offset
],
711 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
712 "failed: %s", strerror(errno
)));
718 offset
+= (namelen
+ 1); /* Go past the name + terminating zero. */
719 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
720 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal
->ea
.name
));
726 /****************************************************************************
727 Read one EA list entry from the buffer.
728 ****************************************************************************/
730 struct ea_list
*read_ea_list_entry(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
, size_t *pbytes_used
)
732 struct ea_list
*eal
= talloc_zero(ctx
, struct ea_list
);
734 unsigned int namelen
;
735 size_t converted_size
;
745 eal
->ea
.flags
= CVAL(pdata
,0);
746 namelen
= CVAL(pdata
,1);
747 val_len
= SVAL(pdata
,2);
749 if (4 + namelen
+ 1 + val_len
> data_size
) {
753 /* Ensure the name is null terminated. */
754 if (pdata
[namelen
+ 4] != '\0') {
757 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, pdata
+ 4, &converted_size
)) {
758 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
765 eal
->ea
.value
= data_blob_talloc(eal
, NULL
, (size_t)val_len
+ 1);
766 if (!eal
->ea
.value
.data
) {
770 memcpy(eal
->ea
.value
.data
, pdata
+ 4 + namelen
+ 1, val_len
);
772 /* Ensure we're null terminated just in case we print the value. */
773 eal
->ea
.value
.data
[val_len
] = '\0';
774 /* But don't count the null. */
775 eal
->ea
.value
.length
--;
778 *pbytes_used
= 4 + namelen
+ 1 + val_len
;
781 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal
->ea
.name
));
782 dump_data(10, eal
->ea
.value
.data
, eal
->ea
.value
.length
);
787 /****************************************************************************
788 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
789 ****************************************************************************/
791 static struct ea_list
*read_ea_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
793 struct ea_list
*ea_list_head
= NULL
;
795 size_t bytes_used
= 0;
797 while (offset
< data_size
) {
798 struct ea_list
*eal
= read_ea_list_entry(ctx
, pdata
+ offset
, data_size
- offset
, &bytes_used
);
804 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
805 offset
+= bytes_used
;
811 /****************************************************************************
812 Count the total EA size needed.
813 ****************************************************************************/
815 static size_t ea_list_size(struct ea_list
*ealist
)
818 struct ea_list
*listp
;
821 for (listp
= ealist
; listp
; listp
= listp
->next
) {
822 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
823 ret
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
825 /* Add on 4 for total length. */
833 /****************************************************************************
834 Return a union of EA's from a file list and a list of names.
835 The TALLOC context for the two lists *MUST* be identical as we steal
836 memory from one list to add to another. JRA.
837 ****************************************************************************/
839 static struct ea_list
*ea_list_union(struct ea_list
*name_list
, struct ea_list
*file_list
, size_t *total_ea_len
)
841 struct ea_list
*nlistp
, *flistp
;
843 for (nlistp
= name_list
; nlistp
; nlistp
= nlistp
->next
) {
844 for (flistp
= file_list
; flistp
; flistp
= flistp
->next
) {
845 if (strequal(nlistp
->ea
.name
, flistp
->ea
.name
)) {
851 /* Copy the data from this entry. */
852 nlistp
->ea
.flags
= flistp
->ea
.flags
;
853 nlistp
->ea
.value
= flistp
->ea
.value
;
856 nlistp
->ea
.flags
= 0;
857 ZERO_STRUCT(nlistp
->ea
.value
);
861 *total_ea_len
= ea_list_size(name_list
);
865 /****************************************************************************
866 Send the required number of replies back.
867 We assume all fields other than the data fields are
868 set correctly for the type of call.
869 HACK ! Always assumes smb_setup field is zero.
870 ****************************************************************************/
872 void send_trans2_replies(connection_struct
*conn
,
873 struct smb_request
*req
,
880 /* As we are using a protocol > LANMAN1 then the max_send
881 variable must have been set in the sessetupX call.
882 This takes precedence over the max_xmit field in the
883 global struct. These different max_xmit variables should
884 be merged as this is now too confusing */
886 int data_to_send
= datasize
;
887 int params_to_send
= paramsize
;
889 const char *pp
= params
;
890 const char *pd
= pdata
;
891 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
892 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
893 int data_alignment_offset
= 0;
894 bool overflow
= False
;
895 struct smbd_server_connection
*sconn
= req
->sconn
;
896 int max_send
= sconn
->smb1
.sessions
.max_send
;
898 /* Modify the data_to_send and datasize and set the error if
899 we're trying to send more than max_data_bytes. We still send
900 the part of the packet(s) that fit. Strange, but needed
903 if (max_data_bytes
> 0 && datasize
> max_data_bytes
) {
904 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
905 max_data_bytes
, datasize
));
906 datasize
= data_to_send
= max_data_bytes
;
910 /* If there genuinely are no parameters or data to send just send the empty packet */
912 if(params_to_send
== 0 && data_to_send
== 0) {
913 reply_outbuf(req
, 10, 0);
914 show_msg((char *)req
->outbuf
);
915 if (!srv_send_smb(sconn
,
918 IS_CONN_ENCRYPTED(conn
),
920 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
922 TALLOC_FREE(req
->outbuf
);
926 /* When sending params and data ensure that both are nicely aligned */
927 /* Only do this alignment when there is also data to send - else
928 can cause NT redirector problems. */
930 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
931 data_alignment_offset
= 4 - (params_to_send
% 4);
933 /* Space is bufsize minus Netbios over TCP header minus SMB header */
934 /* The alignment_offset is to align the param bytes on an even byte
935 boundary. NT 4.0 Beta needs this to work correctly. */
937 useable_space
= max_send
- (smb_size
940 + data_alignment_offset
);
942 if (useable_space
< 0) {
943 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
944 "= %d!!!", useable_space
));
945 exit_server_cleanly("send_trans2_replies: Not enough space");
948 while (params_to_send
|| data_to_send
) {
949 /* Calculate whether we will totally or partially fill this packet */
951 total_sent_thistime
= params_to_send
+ data_to_send
;
953 /* We can never send more than useable_space */
955 * Note that 'useable_space' does not include the alignment offsets,
956 * but we must include the alignment offsets in the calculation of
957 * the length of the data we send over the wire, as the alignment offsets
958 * are sent here. Fix from Marc_Jacobsen@hp.com.
961 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
);
963 reply_outbuf(req
, 10, total_sent_thistime
+ alignment_offset
964 + data_alignment_offset
);
966 /* Set total params and data to be sent */
967 SSVAL(req
->outbuf
,smb_tprcnt
,paramsize
);
968 SSVAL(req
->outbuf
,smb_tdrcnt
,datasize
);
970 /* Calculate how many parameters and data we can fit into
971 * this packet. Parameters get precedence
974 params_sent_thistime
= MIN(params_to_send
,useable_space
);
975 data_sent_thistime
= useable_space
- params_sent_thistime
;
976 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
978 SSVAL(req
->outbuf
,smb_prcnt
, params_sent_thistime
);
980 /* smb_proff is the offset from the start of the SMB header to the
981 parameter bytes, however the first 4 bytes of outbuf are
982 the Netbios over TCP header. Thus use smb_base() to subtract
983 them from the calculation */
985 SSVAL(req
->outbuf
,smb_proff
,
986 ((smb_buf(req
->outbuf
)+alignment_offset
)
987 - smb_base(req
->outbuf
)));
989 if(params_sent_thistime
== 0)
990 SSVAL(req
->outbuf
,smb_prdisp
,0);
992 /* Absolute displacement of param bytes sent in this packet */
993 SSVAL(req
->outbuf
,smb_prdisp
,pp
- params
);
995 SSVAL(req
->outbuf
,smb_drcnt
, data_sent_thistime
);
996 if(data_sent_thistime
== 0) {
997 SSVAL(req
->outbuf
,smb_droff
,0);
998 SSVAL(req
->outbuf
,smb_drdisp
, 0);
1000 /* The offset of the data bytes is the offset of the
1001 parameter bytes plus the number of parameters being sent this time */
1002 SSVAL(req
->outbuf
, smb_droff
,
1003 ((smb_buf(req
->outbuf
)+alignment_offset
)
1004 - smb_base(req
->outbuf
))
1005 + params_sent_thistime
+ data_alignment_offset
);
1006 SSVAL(req
->outbuf
,smb_drdisp
, pd
- pdata
);
1009 /* Initialize the padding for alignment */
1011 if (alignment_offset
!= 0) {
1012 memset(smb_buf(req
->outbuf
), 0, alignment_offset
);
1015 /* Copy the param bytes into the packet */
1017 if(params_sent_thistime
) {
1018 memcpy((smb_buf(req
->outbuf
)+alignment_offset
), pp
,
1019 params_sent_thistime
);
1022 /* Copy in the data bytes */
1023 if(data_sent_thistime
) {
1024 if (data_alignment_offset
!= 0) {
1025 memset((smb_buf(req
->outbuf
)+alignment_offset
+
1026 params_sent_thistime
), 0,
1027 data_alignment_offset
);
1029 memcpy(smb_buf(req
->outbuf
)+alignment_offset
1030 +params_sent_thistime
+data_alignment_offset
,
1031 pd
,data_sent_thistime
);
1034 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
1035 params_sent_thistime
, data_sent_thistime
, useable_space
));
1036 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
1037 params_to_send
, data_to_send
, paramsize
, datasize
));
1040 error_packet_set((char *)req
->outbuf
,
1041 ERRDOS
,ERRbufferoverflow
,
1042 STATUS_BUFFER_OVERFLOW
,
1046 /* Send the packet */
1047 show_msg((char *)req
->outbuf
);
1048 if (!srv_send_smb(sconn
,
1049 (char *)req
->outbuf
,
1050 true, req
->seqnum
+1,
1051 IS_CONN_ENCRYPTED(conn
),
1053 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
1055 TALLOC_FREE(req
->outbuf
);
1057 pp
+= params_sent_thistime
;
1058 pd
+= data_sent_thistime
;
1060 params_to_send
-= params_sent_thistime
;
1061 data_to_send
-= data_sent_thistime
;
1064 if(params_to_send
< 0 || data_to_send
< 0) {
1065 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
1066 params_to_send
, data_to_send
));
1074 /****************************************************************************
1075 Reply to a TRANSACT2_OPEN.
1076 ****************************************************************************/
1078 static void call_trans2open(connection_struct
*conn
,
1079 struct smb_request
*req
,
1080 char **pparams
, int total_params
,
1081 char **ppdata
, int total_data
,
1082 unsigned int max_data_bytes
)
1084 struct smb_filename
*smb_fname
= NULL
;
1085 char *params
= *pparams
;
1086 char *pdata
= *ppdata
;
1089 bool oplock_request
;
1091 bool return_additional_info
;
1100 int fattr
=0,mtime
=0;
1101 SMB_INO_T inode
= 0;
1104 struct ea_list
*ea_list
= NULL
;
1109 uint32 create_disposition
;
1110 uint32 create_options
= 0;
1111 uint32_t private_flags
= 0;
1112 TALLOC_CTX
*ctx
= talloc_tos();
1115 * Ensure we have enough parameters to perform the operation.
1118 if (total_params
< 29) {
1119 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1123 flags
= SVAL(params
, 0);
1124 deny_mode
= SVAL(params
, 2);
1125 open_attr
= SVAL(params
,6);
1126 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
1127 if (oplock_request
) {
1128 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
1132 return_additional_info
= BITSETW(params
,0);
1133 open_sattr
= SVAL(params
, 4);
1134 open_time
= make_unix_date3(params
+8);
1136 open_ofun
= SVAL(params
,12);
1137 open_size
= IVAL(params
,14);
1138 pname
= ¶ms
[28];
1141 reply_nterror(req
, NT_STATUS_NETWORK_ACCESS_DENIED
);
1145 srvstr_get_path(ctx
, params
, req
->flags2
, &fname
, pname
,
1146 total_params
- 28, STR_TERMINATE
,
1148 if (!NT_STATUS_IS_OK(status
)) {
1149 reply_nterror(req
, status
);
1153 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1154 fname
, (unsigned int)deny_mode
, (unsigned int)open_attr
,
1155 (unsigned int)open_ofun
, open_size
));
1157 status
= filename_convert(ctx
,
1159 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1164 if (!NT_STATUS_IS_OK(status
)) {
1165 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1166 reply_botherror(req
,
1167 NT_STATUS_PATH_NOT_COVERED
,
1168 ERRSRV
, ERRbadpath
);
1171 reply_nterror(req
, status
);
1175 if (open_ofun
== 0) {
1176 reply_nterror(req
, NT_STATUS_OBJECT_NAME_COLLISION
);
1180 if (!map_open_params_to_ntcreate(smb_fname
->base_name
, deny_mode
,
1182 &access_mask
, &share_mode
,
1183 &create_disposition
,
1186 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1190 /* Any data in this call is an EA list. */
1191 if (total_data
&& (total_data
!= 4)) {
1192 if (total_data
< 10) {
1193 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1197 if (IVAL(pdata
,0) > total_data
) {
1198 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1199 IVAL(pdata
,0), (unsigned int)total_data
));
1200 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1204 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
1207 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1211 if (!lp_ea_support(SNUM(conn
))) {
1212 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
1217 status
= SMB_VFS_CREATE_FILE(
1220 0, /* root_dir_fid */
1221 smb_fname
, /* fname */
1222 access_mask
, /* access_mask */
1223 share_mode
, /* share_access */
1224 create_disposition
, /* create_disposition*/
1225 create_options
, /* create_options */
1226 open_attr
, /* file_attributes */
1227 oplock_request
, /* oplock_request */
1228 open_size
, /* allocation_size */
1231 ea_list
, /* ea_list */
1233 &smb_action
); /* psbuf */
1235 if (!NT_STATUS_IS_OK(status
)) {
1236 if (open_was_deferred(req
->sconn
, req
->mid
)) {
1237 /* We have re-scheduled this call. */
1240 reply_openerror(req
, status
);
1244 size
= get_file_size_stat(&smb_fname
->st
);
1245 fattr
= dos_mode(conn
, smb_fname
);
1246 mtime
= convert_timespec_to_time_t(smb_fname
->st
.st_ex_mtime
);
1247 inode
= smb_fname
->st
.st_ex_ino
;
1248 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
1249 close_file(req
, fsp
, ERROR_CLOSE
);
1250 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1254 /* Realloc the size of parameters and data we will return */
1255 *pparams
= (char *)SMB_REALLOC(*pparams
, 30);
1256 if(*pparams
== NULL
) {
1257 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1262 SSVAL(params
,0,fsp
->fnum
);
1263 SSVAL(params
,2,fattr
);
1264 srv_put_dos_date2(params
,4, mtime
);
1265 SIVAL(params
,8, (uint32
)size
);
1266 SSVAL(params
,12,deny_mode
);
1267 SSVAL(params
,14,0); /* open_type - file or directory. */
1268 SSVAL(params
,16,0); /* open_state - only valid for IPC device. */
1270 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1271 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1274 SSVAL(params
,18,smb_action
);
1277 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1279 SIVAL(params
,20,inode
);
1280 SSVAL(params
,24,0); /* Padding. */
1282 uint32 ea_size
= estimate_ea_size(conn
, fsp
,
1284 SIVAL(params
, 26, ea_size
);
1286 SIVAL(params
, 26, 0);
1289 /* Send the required number of replies */
1290 send_trans2_replies(conn
, req
, params
, 30, *ppdata
, 0, max_data_bytes
);
1292 TALLOC_FREE(smb_fname
);
1295 /*********************************************************
1296 Routine to check if a given string matches exactly.
1297 as a special case a mask of "." does NOT match. That
1298 is required for correct wildcard semantics
1299 Case can be significant or not.
1300 **********************************************************/
1302 static bool exact_match(bool has_wild
,
1303 bool case_sensitive
,
1307 if (mask
[0] == '.' && mask
[1] == 0) {
1315 if (case_sensitive
) {
1316 return strcmp(str
,mask
)==0;
1318 return strcasecmp_m(str
,mask
) == 0;
1322 /****************************************************************************
1323 Return the filetype for UNIX extensions.
1324 ****************************************************************************/
1326 static uint32
unix_filetype(mode_t mode
)
1329 return UNIX_TYPE_FILE
;
1330 else if(S_ISDIR(mode
))
1331 return UNIX_TYPE_DIR
;
1333 else if(S_ISLNK(mode
))
1334 return UNIX_TYPE_SYMLINK
;
1337 else if(S_ISCHR(mode
))
1338 return UNIX_TYPE_CHARDEV
;
1341 else if(S_ISBLK(mode
))
1342 return UNIX_TYPE_BLKDEV
;
1345 else if(S_ISFIFO(mode
))
1346 return UNIX_TYPE_FIFO
;
1349 else if(S_ISSOCK(mode
))
1350 return UNIX_TYPE_SOCKET
;
1353 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode
));
1354 return UNIX_TYPE_UNKNOWN
;
1357 /****************************************************************************
1358 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1359 ****************************************************************************/
1361 enum perm_type
{ PERM_NEW_FILE
, PERM_NEW_DIR
, PERM_EXISTING_FILE
, PERM_EXISTING_DIR
};
1363 static NTSTATUS
unix_perms_from_wire( connection_struct
*conn
,
1364 const SMB_STRUCT_STAT
*psbuf
,
1366 enum perm_type ptype
,
1371 if (perms
== SMB_MODE_NO_CHANGE
) {
1372 if (!VALID_STAT(*psbuf
)) {
1373 return NT_STATUS_INVALID_PARAMETER
;
1375 *ret_perms
= psbuf
->st_ex_mode
;
1376 return NT_STATUS_OK
;
1380 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
1381 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
1382 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
1383 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
1384 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
1385 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
1386 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
1387 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
1388 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
1390 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
1393 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
1396 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
1401 case PERM_EXISTING_FILE
:
1402 /* Apply mode mask */
1403 ret
&= lp_create_mask(SNUM(conn
));
1404 /* Add in force bits */
1405 ret
|= lp_force_create_mode(SNUM(conn
));
1408 case PERM_EXISTING_DIR
:
1409 ret
&= lp_dir_mask(SNUM(conn
));
1410 /* Add in force bits */
1411 ret
|= lp_force_dir_mode(SNUM(conn
));
1416 return NT_STATUS_OK
;
1419 /****************************************************************************
1420 Needed to show the msdfs symlinks as directories. Modifies psbuf
1421 to be a directory if it's a msdfs link.
1422 ****************************************************************************/
1424 static bool check_msdfs_link(connection_struct
*conn
,
1425 const char *pathname
,
1426 SMB_STRUCT_STAT
*psbuf
)
1428 int saved_errno
= errno
;
1429 if(lp_host_msdfs() &&
1430 lp_msdfs_root(SNUM(conn
)) &&
1431 is_msdfs_link(conn
, pathname
, psbuf
)) {
1433 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1436 psbuf
->st_ex_mode
= (psbuf
->st_ex_mode
& 0xFFF) | S_IFDIR
;
1437 errno
= saved_errno
;
1440 errno
= saved_errno
;
1445 /****************************************************************************
1446 Get a level dependent lanman2 dir entry.
1447 ****************************************************************************/
1449 struct smbd_dirptr_lanman2_state
{
1450 connection_struct
*conn
;
1451 uint32_t info_level
;
1452 bool check_mangled_names
;
1454 bool got_exact_match
;
1457 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX
*ctx
,
1463 struct smbd_dirptr_lanman2_state
*state
=
1464 (struct smbd_dirptr_lanman2_state
*)private_data
;
1466 char mangled_name
[13]; /* mangled 8.3 name. */
1470 /* Mangle fname if it's an illegal name. */
1471 if (mangle_must_mangle(dname
, state
->conn
->params
)) {
1472 ok
= name_to_8_3(dname
, mangled_name
,
1473 true, state
->conn
->params
);
1477 fname
= mangled_name
;
1482 got_match
= exact_match(state
->has_wild
,
1483 state
->conn
->case_sensitive
,
1485 state
->got_exact_match
= got_match
;
1487 got_match
= mask_match(fname
, mask
,
1488 state
->conn
->case_sensitive
);
1491 if(!got_match
&& state
->check_mangled_names
&&
1492 !mangle_is_8_3(fname
, false, state
->conn
->params
)) {
1494 * It turns out that NT matches wildcards against
1495 * both long *and* short names. This may explain some
1496 * of the wildcard wierdness from old DOS clients
1497 * that some people have been seeing.... JRA.
1499 /* Force the mangling into 8.3. */
1500 ok
= name_to_8_3(fname
, mangled_name
,
1501 false, state
->conn
->params
);
1506 got_match
= exact_match(state
->has_wild
,
1507 state
->conn
->case_sensitive
,
1508 mangled_name
, mask
);
1509 state
->got_exact_match
= got_match
;
1511 got_match
= mask_match(mangled_name
, mask
,
1512 state
->conn
->case_sensitive
);
1520 *_fname
= talloc_strdup(ctx
, fname
);
1521 if (*_fname
== NULL
) {
1528 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX
*ctx
,
1530 struct smb_filename
*smb_fname
,
1533 struct smbd_dirptr_lanman2_state
*state
=
1534 (struct smbd_dirptr_lanman2_state
*)private_data
;
1535 bool ms_dfs_link
= false;
1538 if (INFO_LEVEL_IS_UNIX(state
->info_level
)) {
1539 if (SMB_VFS_LSTAT(state
->conn
, smb_fname
) != 0) {
1540 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1541 "Couldn't lstat [%s] (%s)\n",
1542 smb_fname_str_dbg(smb_fname
),
1546 } else if (!VALID_STAT(smb_fname
->st
) &&
1547 SMB_VFS_STAT(state
->conn
, smb_fname
) != 0) {
1548 /* Needed to show the msdfs symlinks as
1551 ms_dfs_link
= check_msdfs_link(state
->conn
,
1552 smb_fname
->base_name
,
1555 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1556 "Couldn't stat [%s] (%s)\n",
1557 smb_fname_str_dbg(smb_fname
),
1564 mode
= dos_mode_msdfs(state
->conn
, smb_fname
);
1566 mode
= dos_mode(state
->conn
, smb_fname
);
1573 static bool smbd_marshall_dir_entry(TALLOC_CTX
*ctx
,
1574 connection_struct
*conn
,
1576 uint32_t info_level
,
1577 struct ea_list
*name_list
,
1578 bool check_mangled_names
,
1579 bool requires_resume_key
,
1582 const struct smb_filename
*smb_fname
,
1583 int space_remaining
,
1590 uint64_t *last_entry_off
)
1592 char *p
, *q
, *pdata
= *ppdata
;
1594 uint64_t file_size
= 0;
1595 uint64_t allocation_size
= 0;
1596 uint64_t file_index
= 0;
1598 struct timespec mdate_ts
, adate_ts
, cdate_ts
, create_date_ts
;
1599 time_t mdate
= (time_t)0, adate
= (time_t)0, create_date
= (time_t)0;
1601 char *last_entry_ptr
;
1606 *out_of_space
= false;
1608 ZERO_STRUCT(mdate_ts
);
1609 ZERO_STRUCT(adate_ts
);
1610 ZERO_STRUCT(create_date_ts
);
1611 ZERO_STRUCT(cdate_ts
);
1613 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
1614 file_size
= get_file_size_stat(&smb_fname
->st
);
1616 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, NULL
, &smb_fname
->st
);
1618 file_index
= get_FileIndex(conn
, &smb_fname
->st
);
1620 mdate_ts
= smb_fname
->st
.st_ex_mtime
;
1621 adate_ts
= smb_fname
->st
.st_ex_atime
;
1622 create_date_ts
= get_create_timespec(conn
, NULL
, smb_fname
);
1623 cdate_ts
= get_change_timespec(conn
, NULL
, smb_fname
);
1625 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1626 dos_filetime_timespec(&create_date_ts
);
1627 dos_filetime_timespec(&mdate_ts
);
1628 dos_filetime_timespec(&adate_ts
);
1629 dos_filetime_timespec(&cdate_ts
);
1632 create_date
= convert_timespec_to_time_t(create_date_ts
);
1633 mdate
= convert_timespec_to_time_t(mdate_ts
);
1634 adate
= convert_timespec_to_time_t(adate_ts
);
1636 /* align the record */
1637 SMB_ASSERT(align
>= 1);
1639 off
= (int)PTR_DIFF(pdata
, base_data
);
1640 pad
= (off
+ (align
-1)) & ~(align
-1);
1643 if (pad
&& pad
> space_remaining
) {
1644 *out_of_space
= true;
1645 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1646 "for padding (wanted %u, had %d)\n",
1649 return false; /* Not finished - just out of space */
1653 /* initialize padding to 0 */
1655 memset(pdata
, 0, pad
);
1657 space_remaining
-= pad
;
1659 DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1669 switch (info_level
) {
1670 case SMB_FIND_INFO_STANDARD
:
1671 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1672 if(requires_resume_key
) {
1676 srv_put_dos_date2(p
,0,create_date
);
1677 srv_put_dos_date2(p
,4,adate
);
1678 srv_put_dos_date2(p
,8,mdate
);
1679 SIVAL(p
,12,(uint32
)file_size
);
1680 SIVAL(p
,16,(uint32
)allocation_size
);
1684 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1685 p
+= ucs2_align(base_data
, p
, 0);
1687 len
= srvstr_push(base_data
, flags2
, p
,
1688 fname
, PTR_DIFF(end_data
, p
),
1690 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1692 SCVAL(nameptr
, -1, len
- 2);
1694 SCVAL(nameptr
, -1, 0);
1698 SCVAL(nameptr
, -1, len
- 1);
1700 SCVAL(nameptr
, -1, 0);
1706 case SMB_FIND_EA_SIZE
:
1707 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1708 if (requires_resume_key
) {
1712 srv_put_dos_date2(p
,0,create_date
);
1713 srv_put_dos_date2(p
,4,adate
);
1714 srv_put_dos_date2(p
,8,mdate
);
1715 SIVAL(p
,12,(uint32
)file_size
);
1716 SIVAL(p
,16,(uint32
)allocation_size
);
1719 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1721 SIVAL(p
,22,ea_size
); /* Extended attributes */
1725 len
= srvstr_push(base_data
, flags2
,
1726 p
, fname
, PTR_DIFF(end_data
, p
),
1727 STR_TERMINATE
| STR_NOALIGN
);
1728 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1741 SCVAL(nameptr
,0,len
);
1743 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1746 case SMB_FIND_EA_LIST
:
1748 struct ea_list
*file_list
= NULL
;
1752 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1756 if (requires_resume_key
) {
1760 srv_put_dos_date2(p
,0,create_date
);
1761 srv_put_dos_date2(p
,4,adate
);
1762 srv_put_dos_date2(p
,8,mdate
);
1763 SIVAL(p
,12,(uint32
)file_size
);
1764 SIVAL(p
,16,(uint32
)allocation_size
);
1766 p
+= 22; /* p now points to the EA area. */
1768 status
= get_ea_list_from_file(ctx
, conn
, NULL
,
1770 &ea_len
, &file_list
);
1771 if (!NT_STATUS_IS_OK(status
)) {
1774 name_list
= ea_list_union(name_list
, file_list
, &ea_len
);
1776 /* We need to determine if this entry will fit in the space available. */
1777 /* Max string size is 255 bytes. */
1778 if (PTR_DIFF(p
+ 255 + ea_len
,pdata
) > space_remaining
) {
1779 *out_of_space
= true;
1780 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1781 "(wanted %u, had %d)\n",
1782 (unsigned int)PTR_DIFF(p
+ 255 + ea_len
,pdata
),
1784 return False
; /* Not finished - just out of space */
1787 /* Push the ea_data followed by the name. */
1788 p
+= fill_ea_buffer(ctx
, p
, space_remaining
, conn
, name_list
);
1790 len
= srvstr_push(base_data
, flags2
,
1791 p
+ 1, fname
, PTR_DIFF(end_data
, p
+1),
1792 STR_TERMINATE
| STR_NOALIGN
);
1793 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1806 SCVAL(nameptr
,0,len
);
1808 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1812 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1813 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1814 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1816 SIVAL(p
,0,reskey
); p
+= 4;
1817 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1818 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1819 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1820 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1821 SOFF_T(p
,0,file_size
); p
+= 8;
1822 SOFF_T(p
,0,allocation_size
); p
+= 8;
1823 SIVAL(p
,0,mode
); p
+= 4;
1824 q
= p
; p
+= 4; /* q is placeholder for name length. */
1826 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1828 SIVAL(p
,0,ea_size
); /* Extended attributes */
1831 /* Clear the short name buffer. This is
1832 * IMPORTANT as not doing so will trigger
1833 * a Win2k client bug. JRA.
1835 if (!was_8_3
&& check_mangled_names
) {
1836 char mangled_name
[13]; /* mangled 8.3 name. */
1837 if (!name_to_8_3(fname
,mangled_name
,True
,
1839 /* Error - mangle failed ! */
1840 memset(mangled_name
,'\0',12);
1842 mangled_name
[12] = 0;
1843 len
= srvstr_push(base_data
, flags2
,
1844 p
+2, mangled_name
, 24,
1845 STR_UPPER
|STR_UNICODE
);
1847 memset(p
+ 2 + len
,'\0',24 - len
);
1854 len
= srvstr_push(base_data
, flags2
, p
,
1855 fname
, PTR_DIFF(end_data
, p
),
1856 STR_TERMINATE_ASCII
);
1860 len
= PTR_DIFF(p
, pdata
);
1861 pad
= (len
+ (align
-1)) & ~(align
-1);
1863 * offset to the next entry, the caller
1864 * will overwrite it for the last entry
1865 * that's why we always include the padding
1869 * set padding to zero
1872 memset(p
, 0, pad
- len
);
1879 case SMB_FIND_FILE_DIRECTORY_INFO
:
1880 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1882 SIVAL(p
,0,reskey
); p
+= 4;
1883 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1884 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1885 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1886 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1887 SOFF_T(p
,0,file_size
); p
+= 8;
1888 SOFF_T(p
,0,allocation_size
); p
+= 8;
1889 SIVAL(p
,0,mode
); p
+= 4;
1890 len
= srvstr_push(base_data
, flags2
,
1891 p
+ 4, fname
, PTR_DIFF(end_data
, p
+4),
1892 STR_TERMINATE_ASCII
);
1896 len
= PTR_DIFF(p
, pdata
);
1897 pad
= (len
+ (align
-1)) & ~(align
-1);
1899 * offset to the next entry, the caller
1900 * will overwrite it for the last entry
1901 * that's why we always include the padding
1905 * set padding to zero
1908 memset(p
, 0, pad
- len
);
1915 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1916 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1918 SIVAL(p
,0,reskey
); p
+= 4;
1919 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1920 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1921 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1922 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1923 SOFF_T(p
,0,file_size
); p
+= 8;
1924 SOFF_T(p
,0,allocation_size
); p
+= 8;
1925 SIVAL(p
,0,mode
); p
+= 4;
1926 q
= p
; p
+= 4; /* q is placeholder for name length. */
1928 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1930 SIVAL(p
,0,ea_size
); /* Extended attributes */
1933 len
= srvstr_push(base_data
, flags2
, p
,
1934 fname
, PTR_DIFF(end_data
, p
),
1935 STR_TERMINATE_ASCII
);
1939 len
= PTR_DIFF(p
, pdata
);
1940 pad
= (len
+ (align
-1)) & ~(align
-1);
1942 * offset to the next entry, the caller
1943 * will overwrite it for the last entry
1944 * that's why we always include the padding
1948 * set padding to zero
1951 memset(p
, 0, pad
- len
);
1958 case SMB_FIND_FILE_NAMES_INFO
:
1959 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1961 SIVAL(p
,0,reskey
); p
+= 4;
1963 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1964 acl on a dir (tridge) */
1965 len
= srvstr_push(base_data
, flags2
, p
,
1966 fname
, PTR_DIFF(end_data
, p
),
1967 STR_TERMINATE_ASCII
);
1971 len
= PTR_DIFF(p
, pdata
);
1972 pad
= (len
+ (align
-1)) & ~(align
-1);
1974 * offset to the next entry, the caller
1975 * will overwrite it for the last entry
1976 * that's why we always include the padding
1980 * set padding to zero
1983 memset(p
, 0, pad
- len
);
1990 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1991 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1993 SIVAL(p
,0,reskey
); p
+= 4;
1994 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1995 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1996 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1997 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1998 SOFF_T(p
,0,file_size
); p
+= 8;
1999 SOFF_T(p
,0,allocation_size
); p
+= 8;
2000 SIVAL(p
,0,mode
); p
+= 4;
2001 q
= p
; p
+= 4; /* q is placeholder for name length. */
2003 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
2005 SIVAL(p
,0,ea_size
); /* Extended attributes */
2008 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
2009 SBVAL(p
,0,file_index
); p
+= 8;
2010 len
= srvstr_push(base_data
, flags2
, p
,
2011 fname
, PTR_DIFF(end_data
, p
),
2012 STR_TERMINATE_ASCII
);
2016 len
= PTR_DIFF(p
, pdata
);
2017 pad
= (len
+ (align
-1)) & ~(align
-1);
2019 * offset to the next entry, the caller
2020 * will overwrite it for the last entry
2021 * that's why we always include the padding
2025 * set padding to zero
2028 memset(p
, 0, pad
- len
);
2035 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2036 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
2037 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
2039 SIVAL(p
,0,reskey
); p
+= 4;
2040 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
2041 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
2042 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
2043 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
2044 SOFF_T(p
,0,file_size
); p
+= 8;
2045 SOFF_T(p
,0,allocation_size
); p
+= 8;
2046 SIVAL(p
,0,mode
); p
+= 4;
2047 q
= p
; p
+= 4; /* q is placeholder for name length */
2049 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
2051 SIVAL(p
,0,ea_size
); /* Extended attributes */
2054 /* Clear the short name buffer. This is
2055 * IMPORTANT as not doing so will trigger
2056 * a Win2k client bug. JRA.
2058 if (!was_8_3
&& check_mangled_names
) {
2059 char mangled_name
[13]; /* mangled 8.3 name. */
2060 if (!name_to_8_3(fname
,mangled_name
,True
,
2062 /* Error - mangle failed ! */
2063 memset(mangled_name
,'\0',12);
2065 mangled_name
[12] = 0;
2066 len
= srvstr_push(base_data
, flags2
,
2067 p
+2, mangled_name
, 24,
2068 STR_UPPER
|STR_UNICODE
);
2071 memset(p
+ 2 + len
,'\0',24 - len
);
2078 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
2079 SBVAL(p
,0,file_index
); p
+= 8;
2080 len
= srvstr_push(base_data
, flags2
, p
,
2081 fname
, PTR_DIFF(end_data
, p
),
2082 STR_TERMINATE_ASCII
);
2086 len
= PTR_DIFF(p
, pdata
);
2087 pad
= (len
+ (align
-1)) & ~(align
-1);
2089 * offset to the next entry, the caller
2090 * will overwrite it for the last entry
2091 * that's why we always include the padding
2095 * set padding to zero
2098 memset(p
, 0, pad
- len
);
2105 /* CIFS UNIX Extension. */
2107 case SMB_FIND_FILE_UNIX
:
2108 case SMB_FIND_FILE_UNIX_INFO2
:
2110 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
2112 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2114 if (info_level
== SMB_FIND_FILE_UNIX
) {
2115 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2116 p
= store_file_unix_basic(conn
, p
,
2117 NULL
, &smb_fname
->st
);
2118 len
= srvstr_push(base_data
, flags2
, p
,
2119 fname
, PTR_DIFF(end_data
, p
),
2122 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2123 p
= store_file_unix_basic_info2(conn
, p
,
2124 NULL
, &smb_fname
->st
);
2127 len
= srvstr_push(base_data
, flags2
, p
, fname
,
2128 PTR_DIFF(end_data
, p
), 0);
2129 SIVAL(nameptr
, 0, len
);
2134 len
= PTR_DIFF(p
, pdata
);
2135 pad
= (len
+ (align
-1)) & ~(align
-1);
2137 * offset to the next entry, the caller
2138 * will overwrite it for the last entry
2139 * that's why we always include the padding
2143 * set padding to zero
2146 memset(p
, 0, pad
- len
);
2151 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2159 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
2160 *out_of_space
= true;
2161 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2162 "(wanted %u, had %d)\n",
2163 (unsigned int)PTR_DIFF(p
,pdata
),
2165 return false; /* Not finished - just out of space */
2168 /* Setup the last entry pointer, as an offset from base_data */
2169 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
2170 /* Advance the data pointer to the next slot */
2176 bool smbd_dirptr_lanman2_entry(TALLOC_CTX
*ctx
,
2177 connection_struct
*conn
,
2178 struct dptr_struct
*dirptr
,
2180 const char *path_mask
,
2183 int requires_resume_key
,
2191 int space_remaining
,
2193 bool *got_exact_match
,
2194 int *_last_entry_off
,
2195 struct ea_list
*name_list
)
2198 const char *mask
= NULL
;
2199 long prev_dirpos
= 0;
2202 struct smb_filename
*smb_fname
= NULL
;
2203 struct smbd_dirptr_lanman2_state state
;
2205 uint64_t last_entry_off
= 0;
2209 state
.info_level
= info_level
;
2210 state
.check_mangled_names
= lp_manglednames(conn
->params
);
2211 state
.has_wild
= dptr_has_wild(dirptr
);
2212 state
.got_exact_match
= false;
2214 *out_of_space
= false;
2215 *got_exact_match
= false;
2217 p
= strrchr_m(path_mask
,'/');
2228 ok
= smbd_dirptr_get_entry(ctx
,
2234 smbd_dirptr_lanman2_match_fn
,
2235 smbd_dirptr_lanman2_mode_fn
,
2245 *got_exact_match
= state
.got_exact_match
;
2247 ok
= smbd_marshall_dir_entry(ctx
,
2252 state
.check_mangled_names
,
2253 requires_resume_key
,
2266 TALLOC_FREE(smb_fname
);
2267 if (*out_of_space
) {
2268 dptr_SeekDir(dirptr
, prev_dirpos
);
2275 *_last_entry_off
= last_entry_off
;
2279 static bool get_lanman2_dir_entry(TALLOC_CTX
*ctx
,
2280 connection_struct
*conn
,
2281 struct dptr_struct
*dirptr
,
2283 const char *path_mask
,
2286 bool requires_resume_key
,
2292 int space_remaining
,
2294 bool *got_exact_match
,
2295 int *last_entry_off
,
2296 struct ea_list
*name_list
)
2299 const bool do_pad
= true;
2301 if (info_level
>= 1 && info_level
<= 3) {
2302 /* No alignment on earlier info levels. */
2306 return smbd_dirptr_lanman2_entry(ctx
, conn
, dirptr
, flags2
,
2307 path_mask
, dirtype
, info_level
,
2308 requires_resume_key
, dont_descend
, ask_sharemode
,
2310 ppdata
, base_data
, end_data
,
2312 out_of_space
, got_exact_match
,
2313 last_entry_off
, name_list
);
2316 /****************************************************************************
2317 Reply to a TRANS2_FINDFIRST.
2318 ****************************************************************************/
2320 static void call_trans2findfirst(connection_struct
*conn
,
2321 struct smb_request
*req
,
2322 char **pparams
, int total_params
,
2323 char **ppdata
, int total_data
,
2324 unsigned int max_data_bytes
)
2326 /* We must be careful here that we don't return more than the
2327 allowed number of data bytes. If this means returning fewer than
2328 maxentries then so be it. We assume that the redirector has
2329 enough room for the fixed number of parameter bytes it has
2331 struct smb_filename
*smb_dname
= NULL
;
2332 char *params
= *pparams
;
2333 char *pdata
= *ppdata
;
2337 uint16 findfirst_flags
;
2338 bool close_after_first
;
2340 bool requires_resume_key
;
2342 char *directory
= NULL
;
2345 int last_entry_off
=0;
2349 bool finished
= False
;
2350 bool dont_descend
= False
;
2351 bool out_of_space
= False
;
2352 int space_remaining
;
2353 bool mask_contains_wcard
= False
;
2354 struct ea_list
*ea_list
= NULL
;
2355 NTSTATUS ntstatus
= NT_STATUS_OK
;
2356 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2357 TALLOC_CTX
*ctx
= talloc_tos();
2358 struct dptr_struct
*dirptr
= NULL
;
2359 struct smbd_server_connection
*sconn
= req
->sconn
;
2360 uint32_t ucf_flags
= (UCF_SAVE_LCOMP
| UCF_ALWAYS_ALLOW_WCARD_LCOMP
);
2361 bool backup_priv
= false;
2363 if (total_params
< 13) {
2364 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2368 dirtype
= SVAL(params
,0);
2369 maxentries
= SVAL(params
,2);
2370 findfirst_flags
= SVAL(params
,4);
2371 close_after_first
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE
);
2372 close_if_end
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2373 requires_resume_key
= (findfirst_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2374 backup_priv
= ((findfirst_flags
& FLAG_TRANS2_FIND_BACKUP_INTENT
) &&
2375 security_token_has_privilege(get_current_nttok(conn
),
2378 info_level
= SVAL(params
,6);
2380 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2381 close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
2382 (unsigned int)dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
2384 info_level
, max_data_bytes
));
2387 /* W2K3 seems to treat zero as 1. */
2391 switch (info_level
) {
2392 case SMB_FIND_INFO_STANDARD
:
2393 case SMB_FIND_EA_SIZE
:
2394 case SMB_FIND_EA_LIST
:
2395 case SMB_FIND_FILE_DIRECTORY_INFO
:
2396 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2397 case SMB_FIND_FILE_NAMES_INFO
:
2398 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2399 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2400 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2402 case SMB_FIND_FILE_UNIX
:
2403 case SMB_FIND_FILE_UNIX_INFO2
:
2404 /* Always use filesystem for UNIX mtime query. */
2405 ask_sharemode
= false;
2406 if (!lp_unix_extensions()) {
2407 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2410 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
2413 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2417 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &directory
,
2418 params
+12, total_params
- 12,
2419 STR_TERMINATE
, &ntstatus
, &mask_contains_wcard
);
2420 if (!NT_STATUS_IS_OK(ntstatus
)) {
2421 reply_nterror(req
, ntstatus
);
2427 ntstatus
= filename_convert_with_privilege(ctx
,
2432 &mask_contains_wcard
,
2435 ntstatus
= filename_convert(ctx
, conn
,
2436 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2439 &mask_contains_wcard
,
2443 if (!NT_STATUS_IS_OK(ntstatus
)) {
2444 if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_PATH_NOT_COVERED
)) {
2445 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
2446 ERRSRV
, ERRbadpath
);
2449 reply_nterror(req
, ntstatus
);
2453 mask
= smb_dname
->original_lcomp
;
2455 directory
= smb_dname
->base_name
;
2457 p
= strrchr_m(directory
,'/');
2459 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2460 if((directory
[0] == '.') && (directory
[1] == '\0')) {
2461 mask
= talloc_strdup(ctx
,"*");
2463 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2466 mask_contains_wcard
= True
;
2472 if (p
== NULL
|| p
== directory
) {
2473 /* Ensure we don't have a directory name of "". */
2474 directory
= talloc_strdup(talloc_tos(), ".");
2476 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2481 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
2483 if (info_level
== SMB_FIND_EA_LIST
) {
2486 if (total_data
< 4) {
2487 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2491 ea_size
= IVAL(pdata
,0);
2492 if (ea_size
!= total_data
) {
2493 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2494 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2495 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2499 if (!lp_ea_support(SNUM(conn
))) {
2500 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2504 /* Pull out the list of names. */
2505 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2507 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2512 *ppdata
= (char *)SMB_REALLOC(
2513 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2514 if(*ppdata
== NULL
) {
2515 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2519 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2521 /* Realloc the params space */
2522 *pparams
= (char *)SMB_REALLOC(*pparams
, 10);
2523 if (*pparams
== NULL
) {
2524 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2529 /* Save the wildcard match and attribs we are using on this directory -
2530 needed as lanman2 assumes these are being saved between calls */
2532 ntstatus
= dptr_create(conn
,
2540 mask_contains_wcard
,
2544 if (!NT_STATUS_IS_OK(ntstatus
)) {
2545 reply_nterror(req
, ntstatus
);
2550 /* Remember this in case we have
2551 to do a findnext. */
2552 dptr_set_priv(dirptr
);
2555 dptr_num
= dptr_dnum(dirptr
);
2556 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num
, mask
, dirtype
));
2558 /* Initialize per TRANS2_FIND_FIRST operation data */
2559 dptr_init_search_op(dirptr
);
2561 /* We don't need to check for VOL here as this is returned by
2562 a different TRANS2 call. */
2564 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2565 directory
,lp_dontdescend(ctx
, SNUM(conn
))));
2566 if (in_list(directory
,lp_dontdescend(ctx
, SNUM(conn
)),conn
->case_sensitive
))
2567 dont_descend
= True
;
2570 space_remaining
= max_data_bytes
;
2571 out_of_space
= False
;
2573 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
2574 bool got_exact_match
= False
;
2576 /* this is a heuristic to avoid seeking the dirptr except when
2577 absolutely necessary. It allows for a filename of about 40 chars */
2578 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2579 out_of_space
= True
;
2582 finished
= !get_lanman2_dir_entry(ctx
,
2586 mask
,dirtype
,info_level
,
2587 requires_resume_key
,dont_descend
,
2590 space_remaining
, &out_of_space
,
2592 &last_entry_off
, ea_list
);
2595 if (finished
&& out_of_space
)
2598 if (!finished
&& !out_of_space
)
2602 * As an optimisation if we know we aren't looking
2603 * for a wildcard name (ie. the name matches the wildcard exactly)
2604 * then we can finish on any (first) match.
2605 * This speeds up large directory searches. JRA.
2611 /* Ensure space_remaining never goes -ve. */
2612 if (PTR_DIFF(p
,pdata
) > max_data_bytes
) {
2613 space_remaining
= 0;
2614 out_of_space
= true;
2616 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2620 /* Check if we can close the dirptr */
2621 if(close_after_first
|| (finished
&& close_if_end
)) {
2622 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
2623 dptr_close(sconn
, &dptr_num
);
2627 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2628 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2629 * the protocol level is less than NT1. Tested with smbclient. JRA.
2630 * This should fix the OS/2 client bug #2335.
2633 if(numentries
== 0) {
2634 dptr_close(sconn
, &dptr_num
);
2635 if (get_Protocol() < PROTOCOL_NT1
) {
2636 reply_force_doserror(req
, ERRDOS
, ERRnofiles
);
2639 reply_botherror(req
, NT_STATUS_NO_SUCH_FILE
,
2640 ERRDOS
, ERRbadfile
);
2645 /* At this point pdata points to numentries directory entries. */
2647 /* Set up the return parameter block */
2648 SSVAL(params
,0,dptr_num
);
2649 SSVAL(params
,2,numentries
);
2650 SSVAL(params
,4,finished
);
2651 SSVAL(params
,6,0); /* Never an EA error */
2652 SSVAL(params
,8,last_entry_off
);
2654 send_trans2_replies(conn
, req
, params
, 10, pdata
, PTR_DIFF(p
,pdata
),
2657 if ((! *directory
) && dptr_path(sconn
, dptr_num
)) {
2658 directory
= talloc_strdup(talloc_tos(),dptr_path(sconn
, dptr_num
));
2660 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2664 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2665 smb_fn_name(req
->cmd
),
2666 mask
, directory
, dirtype
, numentries
) );
2669 * Force a name mangle here to ensure that the
2670 * mask as an 8.3 name is top of the mangled cache.
2671 * The reasons for this are subtle. Don't remove
2672 * this code unless you know what you are doing
2673 * (see PR#13758). JRA.
2676 if(!mangle_is_8_3_wildcards( mask
, False
, conn
->params
)) {
2677 char mangled_name
[13];
2678 name_to_8_3(mask
, mangled_name
, True
, conn
->params
);
2686 TALLOC_FREE(smb_dname
);
2690 /****************************************************************************
2691 Reply to a TRANS2_FINDNEXT.
2692 ****************************************************************************/
2694 static void call_trans2findnext(connection_struct
*conn
,
2695 struct smb_request
*req
,
2696 char **pparams
, int total_params
,
2697 char **ppdata
, int total_data
,
2698 unsigned int max_data_bytes
)
2700 /* We must be careful here that we don't return more than the
2701 allowed number of data bytes. If this means returning fewer than
2702 maxentries then so be it. We assume that the redirector has
2703 enough room for the fixed number of parameter bytes it has
2705 char *params
= *pparams
;
2706 char *pdata
= *ppdata
;
2712 uint16 findnext_flags
;
2713 bool close_after_request
;
2715 bool requires_resume_key
;
2717 bool mask_contains_wcard
= False
;
2718 char *resume_name
= NULL
;
2719 const char *mask
= NULL
;
2720 const char *directory
= NULL
;
2724 int i
, last_entry_off
=0;
2725 bool finished
= False
;
2726 bool dont_descend
= False
;
2727 bool out_of_space
= False
;
2728 int space_remaining
;
2729 struct ea_list
*ea_list
= NULL
;
2730 NTSTATUS ntstatus
= NT_STATUS_OK
;
2731 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2732 TALLOC_CTX
*ctx
= talloc_tos();
2733 struct dptr_struct
*dirptr
;
2734 struct smbd_server_connection
*sconn
= req
->sconn
;
2735 bool backup_priv
= false;
2737 if (total_params
< 13) {
2738 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2742 dptr_num
= SVAL(params
,0);
2743 maxentries
= SVAL(params
,2);
2744 info_level
= SVAL(params
,4);
2745 resume_key
= IVAL(params
,6);
2746 findnext_flags
= SVAL(params
,10);
2747 close_after_request
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE
);
2748 close_if_end
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2749 requires_resume_key
= (findnext_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2750 continue_bit
= (findnext_flags
& FLAG_TRANS2_FIND_CONTINUE
);
2752 if (!continue_bit
) {
2753 /* We only need resume_name if continue_bit is zero. */
2754 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &resume_name
,
2756 total_params
- 12, STR_TERMINATE
, &ntstatus
,
2757 &mask_contains_wcard
);
2758 if (!NT_STATUS_IS_OK(ntstatus
)) {
2759 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2760 complain (it thinks we're asking for the directory above the shared
2761 path or an invalid name). Catch this as the resume name is only compared, never used in
2762 a file access. JRA. */
2763 srvstr_pull_talloc(ctx
, params
, req
->flags2
,
2764 &resume_name
, params
+12,
2768 if (!resume_name
|| !(ISDOT(resume_name
) || ISDOTDOT(resume_name
))) {
2769 reply_nterror(req
, ntstatus
);
2775 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2776 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2777 resume_key = %d resume name = %s continue=%d level = %d\n",
2778 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
2779 requires_resume_key
, resume_key
,
2780 resume_name
? resume_name
: "(NULL)", continue_bit
, info_level
));
2783 /* W2K3 seems to treat zero as 1. */
2787 switch (info_level
) {
2788 case SMB_FIND_INFO_STANDARD
:
2789 case SMB_FIND_EA_SIZE
:
2790 case SMB_FIND_EA_LIST
:
2791 case SMB_FIND_FILE_DIRECTORY_INFO
:
2792 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2793 case SMB_FIND_FILE_NAMES_INFO
:
2794 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2795 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2796 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2798 case SMB_FIND_FILE_UNIX
:
2799 case SMB_FIND_FILE_UNIX_INFO2
:
2800 /* Always use filesystem for UNIX mtime query. */
2801 ask_sharemode
= false;
2802 if (!lp_unix_extensions()) {
2803 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2808 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2812 if (info_level
== SMB_FIND_EA_LIST
) {
2815 if (total_data
< 4) {
2816 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2820 ea_size
= IVAL(pdata
,0);
2821 if (ea_size
!= total_data
) {
2822 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2823 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2824 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2828 if (!lp_ea_support(SNUM(conn
))) {
2829 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2833 /* Pull out the list of names. */
2834 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2836 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2841 *ppdata
= (char *)SMB_REALLOC(
2842 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2843 if(*ppdata
== NULL
) {
2844 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2849 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2851 /* Realloc the params space */
2852 *pparams
= (char *)SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
2853 if(*pparams
== NULL
) {
2854 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2860 /* Check that the dptr is valid */
2861 if(!(dirptr
= dptr_fetch_lanman2(sconn
, dptr_num
))) {
2862 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2866 directory
= dptr_path(sconn
, dptr_num
);
2868 /* Get the wildcard mask from the dptr */
2869 if((mask
= dptr_wcard(sconn
, dptr_num
))== NULL
) {
2870 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
2871 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2875 /* Get the attr mask from the dptr */
2876 dirtype
= dptr_attr(sconn
, dptr_num
);
2878 backup_priv
= dptr_get_priv(dirptr
);
2880 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
2881 "backup_priv = %d\n",
2882 dptr_num
, mask
, dirtype
,
2884 dptr_TellDir(dirptr
),
2887 /* Initialize per TRANS2_FIND_NEXT operation data */
2888 dptr_init_search_op(dirptr
);
2890 /* We don't need to check for VOL here as this is returned by
2891 a different TRANS2 call. */
2893 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2894 directory
,lp_dontdescend(ctx
, SNUM(conn
))));
2895 if (in_list(directory
,lp_dontdescend(ctx
, SNUM(conn
)),conn
->case_sensitive
))
2896 dont_descend
= True
;
2899 space_remaining
= max_data_bytes
;
2900 out_of_space
= False
;
2907 * Seek to the correct position. We no longer use the resume key but
2908 * depend on the last file name instead.
2911 if(!continue_bit
&& resume_name
&& *resume_name
) {
2914 long current_pos
= 0;
2916 * Remember, name_to_8_3 is called by
2917 * get_lanman2_dir_entry(), so the resume name
2918 * could be mangled. Ensure we check the unmangled name.
2921 if (mangle_is_mangled(resume_name
, conn
->params
)) {
2922 char *new_resume_name
= NULL
;
2923 mangle_lookup_name_from_8_3(ctx
,
2927 if (new_resume_name
) {
2928 resume_name
= new_resume_name
;
2933 * Fix for NT redirector problem triggered by resume key indexes
2934 * changing between directory scans. We now return a resume key of 0
2935 * and instead look for the filename to continue from (also given
2936 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2937 * findfirst/findnext (as is usual) then the directory pointer
2938 * should already be at the correct place.
2941 finished
= !dptr_SearchDir(dirptr
, resume_name
, ¤t_pos
, &st
);
2942 } /* end if resume_name && !continue_bit */
2944 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
2945 bool got_exact_match
= False
;
2947 /* this is a heuristic to avoid seeking the dirptr except when
2948 absolutely necessary. It allows for a filename of about 40 chars */
2949 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2950 out_of_space
= True
;
2953 finished
= !get_lanman2_dir_entry(ctx
,
2957 mask
,dirtype
,info_level
,
2958 requires_resume_key
,dont_descend
,
2961 space_remaining
, &out_of_space
,
2963 &last_entry_off
, ea_list
);
2966 if (finished
&& out_of_space
)
2969 if (!finished
&& !out_of_space
)
2973 * As an optimisation if we know we aren't looking
2974 * for a wildcard name (ie. the name matches the wildcard exactly)
2975 * then we can finish on any (first) match.
2976 * This speeds up large directory searches. JRA.
2982 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2985 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2986 smb_fn_name(req
->cmd
),
2987 mask
, directory
, dirtype
, numentries
) );
2989 /* Check if we can close the dirptr */
2990 if(close_after_request
|| (finished
&& close_if_end
)) {
2991 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
2992 dptr_close(sconn
, &dptr_num
); /* This frees up the saved mask */
2999 /* Set up the return parameter block */
3000 SSVAL(params
,0,numentries
);
3001 SSVAL(params
,2,finished
);
3002 SSVAL(params
,4,0); /* Never an EA error */
3003 SSVAL(params
,6,last_entry_off
);
3005 send_trans2_replies(conn
, req
, params
, 8, pdata
, PTR_DIFF(p
,pdata
),
3011 unsigned char *create_volume_objectid(connection_struct
*conn
, unsigned char objid
[16])
3013 E_md4hash(lp_servicename(talloc_tos(), SNUM(conn
)),objid
);
3017 static void samba_extended_info_version(struct smb_extended_info
*extended_info
)
3019 SMB_ASSERT(extended_info
!= NULL
);
3021 extended_info
->samba_magic
= SAMBA_EXTENDED_INFO_MAGIC
;
3022 extended_info
->samba_version
= ((SAMBA_VERSION_MAJOR
& 0xff) << 24)
3023 | ((SAMBA_VERSION_MINOR
& 0xff) << 16)
3024 | ((SAMBA_VERSION_RELEASE
& 0xff) << 8);
3025 #ifdef SAMBA_VERSION_REVISION
3026 extended_info
->samba_version
|= (tolower(*SAMBA_VERSION_REVISION
) - 'a' + 1) & 0xff;
3028 extended_info
->samba_subversion
= 0;
3029 #ifdef SAMBA_VERSION_RC_RELEASE
3030 extended_info
->samba_subversion
|= (SAMBA_VERSION_RC_RELEASE
& 0xff) << 24;
3032 #ifdef SAMBA_VERSION_PRE_RELEASE
3033 extended_info
->samba_subversion
|= (SAMBA_VERSION_PRE_RELEASE
& 0xff) << 16;
3036 #ifdef SAMBA_VERSION_VENDOR_PATCH
3037 extended_info
->samba_subversion
|= (SAMBA_VERSION_VENDOR_PATCH
& 0xffff);
3039 extended_info
->samba_gitcommitdate
= 0;
3040 #ifdef SAMBA_VERSION_COMMIT_TIME
3041 unix_to_nt_time(&extended_info
->samba_gitcommitdate
, SAMBA_VERSION_COMMIT_TIME
);
3044 memset(extended_info
->samba_version_string
, 0,
3045 sizeof(extended_info
->samba_version_string
));
3047 snprintf (extended_info
->samba_version_string
,
3048 sizeof(extended_info
->samba_version_string
),
3049 "%s", samba_version_string());
3052 NTSTATUS
smbd_do_qfsinfo(connection_struct
*conn
,
3053 TALLOC_CTX
*mem_ctx
,
3054 uint16_t info_level
,
3056 unsigned int max_data_bytes
,
3057 struct smb_filename
*fname
,
3061 char *pdata
, *end_data
;
3062 int data_len
= 0, len
;
3063 const char *vname
= volume_label(talloc_tos(), SNUM(conn
));
3064 int snum
= SNUM(conn
);
3065 char *fstype
= lp_fstype(talloc_tos(), SNUM(conn
));
3066 char *filename
= NULL
;
3067 uint32 additional_flags
= 0;
3068 struct smb_filename smb_fname
;
3071 if (fname
== NULL
|| fname
->base_name
== NULL
) {
3074 filename
= fname
->base_name
;
3078 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3079 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3080 "info level (0x%x) on IPC$.\n",
3081 (unsigned int)info_level
));
3082 return NT_STATUS_ACCESS_DENIED
;
3086 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level
));
3088 ZERO_STRUCT(smb_fname
);
3089 smb_fname
.base_name
= discard_const_p(char, filename
);
3091 if(SMB_VFS_STAT(conn
, &smb_fname
) != 0) {
3092 DEBUG(2,("stat of . failed (%s)\n", strerror(errno
)));
3093 return map_nt_error_from_unix(errno
);
3098 *ppdata
= (char *)SMB_REALLOC(
3099 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3100 if (*ppdata
== NULL
) {
3101 return NT_STATUS_NO_MEMORY
;
3105 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3106 end_data
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
3108 switch (info_level
) {
3109 case SMB_INFO_ALLOCATION
:
3111 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3113 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3114 return map_nt_error_from_unix(errno
);
3117 block_size
= lp_block_size(snum
);
3118 if (bsize
< block_size
) {
3119 uint64_t factor
= block_size
/bsize
;
3124 if (bsize
> block_size
) {
3125 uint64_t factor
= bsize
/block_size
;
3130 bytes_per_sector
= 512;
3131 sectors_per_unit
= bsize
/bytes_per_sector
;
3133 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3134 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_ex_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3135 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3137 SIVAL(pdata
,l1_idFileSystem
,st
.st_ex_dev
);
3138 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
3139 SIVAL(pdata
,l1_cUnit
,dsize
);
3140 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
3141 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
3145 case SMB_INFO_VOLUME
:
3146 /* Return volume name */
3148 * Add volume serial number - hash of a combination of
3149 * the called hostname and the service name.
3151 SIVAL(pdata
,0,str_checksum(lp_servicename(talloc_tos(), snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
3153 * Win2k3 and previous mess this up by sending a name length
3154 * one byte short. I believe only older clients (OS/2 Win9x) use
3155 * this call so try fixing this by adding a terminating null to
3156 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3160 pdata
+l2_vol_szVolLabel
, vname
,
3161 PTR_DIFF(end_data
, pdata
+l2_vol_szVolLabel
),
3162 STR_NOALIGN
|STR_TERMINATE
);
3163 SCVAL(pdata
,l2_vol_cch
,len
);
3164 data_len
= l2_vol_szVolLabel
+ len
;
3165 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
3166 (unsigned)convert_timespec_to_time_t(st
.st_ex_ctime
),
3170 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
3171 case SMB_FS_ATTRIBUTE_INFORMATION
:
3173 additional_flags
= 0;
3174 #if defined(HAVE_SYS_QUOTAS)
3175 additional_flags
|= FILE_VOLUME_QUOTAS
;
3178 if(lp_nt_acl_support(SNUM(conn
))) {
3179 additional_flags
|= FILE_PERSISTENT_ACLS
;
3182 /* Capabilities are filled in at connection time through STATVFS call */
3183 additional_flags
|= conn
->fs_capabilities
;
3184 additional_flags
|= lp_parm_int(conn
->params
->service
,
3185 "share", "fake_fscaps",
3188 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
3189 FILE_SUPPORTS_OBJECT_IDS
|FILE_UNICODE_ON_DISK
|
3190 additional_flags
); /* FS ATTRIBUTES */
3192 SIVAL(pdata
,4,255); /* Max filename component length */
3193 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3194 and will think we can't do long filenames */
3195 len
= srvstr_push(pdata
, flags2
, pdata
+12, fstype
,
3196 PTR_DIFF(end_data
, pdata
+12),
3199 data_len
= 12 + len
;
3202 case SMB_QUERY_FS_LABEL_INFO
:
3203 case SMB_FS_LABEL_INFORMATION
:
3204 len
= srvstr_push(pdata
, flags2
, pdata
+4, vname
,
3205 PTR_DIFF(end_data
, pdata
+4), 0);
3210 case SMB_QUERY_FS_VOLUME_INFO
:
3211 case SMB_FS_VOLUME_INFORMATION
:
3214 * Add volume serial number - hash of a combination of
3215 * the called hostname and the service name.
3217 SIVAL(pdata
,8,str_checksum(lp_servicename(talloc_tos(), snum
)) ^
3218 (str_checksum(get_local_machine_name())<<16));
3220 /* Max label len is 32 characters. */
3221 len
= srvstr_push(pdata
, flags2
, pdata
+18, vname
,
3222 PTR_DIFF(end_data
, pdata
+18),
3224 SIVAL(pdata
,12,len
);
3227 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3228 (int)strlen(vname
),vname
,
3229 lp_servicename(talloc_tos(), snum
)));
3232 case SMB_QUERY_FS_SIZE_INFO
:
3233 case SMB_FS_SIZE_INFORMATION
:
3235 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3237 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3238 return map_nt_error_from_unix(errno
);
3240 block_size
= lp_block_size(snum
);
3241 if (bsize
< block_size
) {
3242 uint64_t factor
= block_size
/bsize
;
3247 if (bsize
> block_size
) {
3248 uint64_t factor
= bsize
/block_size
;
3253 bytes_per_sector
= 512;
3254 sectors_per_unit
= bsize
/bytes_per_sector
;
3255 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3256 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3257 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3258 SBIG_UINT(pdata
,0,dsize
);
3259 SBIG_UINT(pdata
,8,dfree
);
3260 SIVAL(pdata
,16,sectors_per_unit
);
3261 SIVAL(pdata
,20,bytes_per_sector
);
3265 case SMB_FS_FULL_SIZE_INFORMATION
:
3267 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3269 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3270 return map_nt_error_from_unix(errno
);
3272 block_size
= lp_block_size(snum
);
3273 if (bsize
< block_size
) {
3274 uint64_t factor
= block_size
/bsize
;
3279 if (bsize
> block_size
) {
3280 uint64_t factor
= bsize
/block_size
;
3285 bytes_per_sector
= 512;
3286 sectors_per_unit
= bsize
/bytes_per_sector
;
3287 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3288 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3289 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3290 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
3291 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
3292 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
3293 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
3294 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
3298 case SMB_QUERY_FS_DEVICE_INFO
:
3299 case SMB_FS_DEVICE_INFORMATION
:
3301 uint32_t characteristics
= FILE_DEVICE_IS_MOUNTED
;
3303 if (!CAN_WRITE(conn
)) {
3304 characteristics
|= FILE_READ_ONLY_DEVICE
;
3307 SIVAL(pdata
,0,FILE_DEVICE_DISK
); /* dev type */
3308 SIVAL(pdata
,4,characteristics
);
3312 #ifdef HAVE_SYS_QUOTAS
3313 case SMB_FS_QUOTA_INFORMATION
:
3315 * what we have to send --metze:
3317 * Unknown1: 24 NULL bytes
3318 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3319 * Hard Quota Limit: 8 bytes seems like uint64_t or so
3320 * Quota Flags: 2 byte :
3321 * Unknown3: 6 NULL bytes
3325 * details for Quota Flags:
3327 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3328 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
3329 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3330 * 0x0001 Enable Quotas: enable quota for this fs
3334 /* we need to fake up a fsp here,
3335 * because its not send in this call
3338 SMB_NTQUOTA_STRUCT quotas
;
3341 ZERO_STRUCT(quotas
);
3344 fsp
.fnum
= FNUM_FIELD_INVALID
;
3347 if (get_current_uid(conn
) != 0) {
3348 DEBUG(0,("set_user_quota: access_denied "
3349 "service [%s] user [%s]\n",
3350 lp_servicename(talloc_tos(), SNUM(conn
)),
3351 conn
->session_info
->unix_info
->unix_name
));
3352 return NT_STATUS_ACCESS_DENIED
;
3355 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3356 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3357 return map_nt_error_from_unix(errno
);
3362 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3363 lp_servicename(talloc_tos(), SNUM(conn
))));
3365 /* Unknown1 24 NULL bytes*/
3366 SBIG_UINT(pdata
,0,(uint64_t)0);
3367 SBIG_UINT(pdata
,8,(uint64_t)0);
3368 SBIG_UINT(pdata
,16,(uint64_t)0);
3370 /* Default Soft Quota 8 bytes */
3371 SBIG_UINT(pdata
,24,quotas
.softlim
);
3373 /* Default Hard Quota 8 bytes */
3374 SBIG_UINT(pdata
,32,quotas
.hardlim
);
3376 /* Quota flag 2 bytes */
3377 SSVAL(pdata
,40,quotas
.qflags
);
3379 /* Unknown3 6 NULL bytes */
3385 #endif /* HAVE_SYS_QUOTAS */
3386 case SMB_FS_OBJECTID_INFORMATION
:
3388 unsigned char objid
[16];
3389 struct smb_extended_info extended_info
;
3390 memcpy(pdata
,create_volume_objectid(conn
, objid
),16);
3391 samba_extended_info_version (&extended_info
);
3392 SIVAL(pdata
,16,extended_info
.samba_magic
);
3393 SIVAL(pdata
,20,extended_info
.samba_version
);
3394 SIVAL(pdata
,24,extended_info
.samba_subversion
);
3395 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
3396 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
3402 * Query the version and capabilities of the CIFS UNIX extensions
3406 case SMB_QUERY_CIFS_UNIX_INFO
:
3408 bool large_write
= lp_min_receive_file_size() &&
3409 !srv_is_signing_active(conn
->sconn
);
3410 bool large_read
= !srv_is_signing_active(conn
->sconn
);
3411 int encrypt_caps
= 0;
3413 if (!lp_unix_extensions()) {
3414 return NT_STATUS_INVALID_LEVEL
;
3417 switch (conn
->encrypt_level
) {
3418 case SMB_SIGNING_OFF
:
3421 case SMB_SIGNING_IF_REQUIRED
:
3422 case SMB_SIGNING_DEFAULT
:
3423 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
;
3425 case SMB_SIGNING_REQUIRED
:
3426 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
|
3427 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP
;
3428 large_write
= false;
3434 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
3435 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
3437 /* We have POSIX ACLs, pathname, encryption,
3438 * large read/write, and locking capability. */
3440 SBIG_UINT(pdata
,4,((uint64_t)(
3441 CIFS_UNIX_POSIX_ACLS_CAP
|
3442 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
3443 CIFS_UNIX_FCNTL_LOCKS_CAP
|
3444 CIFS_UNIX_EXTATTR_CAP
|
3445 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
|
3447 (large_read
? CIFS_UNIX_LARGE_READ_CAP
: 0) |
3449 CIFS_UNIX_LARGE_WRITE_CAP
: 0))));
3453 case SMB_QUERY_POSIX_FS_INFO
:
3456 vfs_statvfs_struct svfs
;
3458 if (!lp_unix_extensions()) {
3459 return NT_STATUS_INVALID_LEVEL
;
3462 rc
= SMB_VFS_STATVFS(conn
, filename
, &svfs
);
3466 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
3467 SIVAL(pdata
,4,svfs
.BlockSize
);
3468 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
3469 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
3470 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
3471 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
3472 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
3473 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
3474 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3476 } else if (rc
== EOPNOTSUPP
) {
3477 return NT_STATUS_INVALID_LEVEL
;
3478 #endif /* EOPNOTSUPP */
3480 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3481 return NT_STATUS_DOS(ERRSRV
, ERRerror
);
3486 case SMB_QUERY_POSIX_WHOAMI
:
3492 if (!lp_unix_extensions()) {
3493 return NT_STATUS_INVALID_LEVEL
;
3496 if (max_data_bytes
< 40) {
3497 return NT_STATUS_BUFFER_TOO_SMALL
;
3500 if (security_session_user_level(conn
->session_info
, NULL
) < SECURITY_USER
) {
3501 flags
|= SMB_WHOAMI_GUEST
;
3504 /* NOTE: 8 bytes for UID/GID, irrespective of native
3505 * platform size. This matches
3506 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3508 data_len
= 4 /* flags */
3515 + 4 /* pad/reserved */
3516 + (conn
->session_info
->unix_token
->ngroups
* 8)
3518 + (conn
->session_info
->security_token
->num_sids
*
3522 SIVAL(pdata
, 0, flags
);
3523 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
3525 (uint64_t)conn
->session_info
->unix_token
->uid
);
3526 SBIG_UINT(pdata
, 16,
3527 (uint64_t)conn
->session_info
->unix_token
->gid
);
3530 if (data_len
>= max_data_bytes
) {
3531 /* Potential overflow, skip the GIDs and SIDs. */
3533 SIVAL(pdata
, 24, 0); /* num_groups */
3534 SIVAL(pdata
, 28, 0); /* num_sids */
3535 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
3536 SIVAL(pdata
, 36, 0); /* reserved */
3542 SIVAL(pdata
, 24, conn
->session_info
->unix_token
->ngroups
);
3543 SIVAL(pdata
, 28, conn
->session_info
->security_token
->num_sids
);
3545 /* We walk the SID list twice, but this call is fairly
3546 * infrequent, and I don't expect that it's performance
3547 * sensitive -- jpeach
3549 for (i
= 0, sid_bytes
= 0;
3550 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3551 sid_bytes
+= ndr_size_dom_sid(
3552 &conn
->session_info
->security_token
->sids
[i
],
3556 /* SID list byte count */
3557 SIVAL(pdata
, 32, sid_bytes
);
3559 /* 4 bytes pad/reserved - must be zero */
3560 SIVAL(pdata
, 36, 0);
3564 for (i
= 0; i
< conn
->session_info
->unix_token
->ngroups
; ++i
) {
3565 SBIG_UINT(pdata
, data_len
,
3566 (uint64_t)conn
->session_info
->unix_token
->groups
[i
]);
3572 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3573 int sid_len
= ndr_size_dom_sid(
3574 &conn
->session_info
->security_token
->sids
[i
],
3577 sid_linearize(pdata
+ data_len
, sid_len
,
3578 &conn
->session_info
->security_token
->sids
[i
]);
3579 data_len
+= sid_len
;
3585 case SMB_MAC_QUERY_FS_INFO
:
3587 * Thursby MAC extension... ONLY on NTFS filesystems
3588 * once we do streams then we don't need this
3590 if (strequal(lp_fstype(talloc_tos(), SNUM(conn
)),"NTFS")) {
3592 SIVAL(pdata
,84,0x100); /* Don't support mac... */
3597 return NT_STATUS_INVALID_LEVEL
;
3600 *ret_data_len
= data_len
;
3601 return NT_STATUS_OK
;
3604 /****************************************************************************
3605 Reply to a TRANS2_QFSINFO (query filesystem info).
3606 ****************************************************************************/
3608 static void call_trans2qfsinfo(connection_struct
*conn
,
3609 struct smb_request
*req
,
3610 char **pparams
, int total_params
,
3611 char **ppdata
, int total_data
,
3612 unsigned int max_data_bytes
)
3614 char *params
= *pparams
;
3615 uint16_t info_level
;
3619 if (total_params
< 2) {
3620 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3624 info_level
= SVAL(params
,0);
3626 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3627 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3628 DEBUG(0,("call_trans2qfsinfo: encryption required "
3629 "and info level 0x%x sent.\n",
3630 (unsigned int)info_level
));
3631 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3636 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
3638 status
= smbd_do_qfsinfo(conn
, req
,
3644 if (!NT_STATUS_IS_OK(status
)) {
3645 reply_nterror(req
, status
);
3649 send_trans2_replies(conn
, req
, params
, 0, *ppdata
, data_len
,
3652 DEBUG( 4, ( "%s info_level = %d\n",
3653 smb_fn_name(req
->cmd
), info_level
) );
3658 /****************************************************************************
3659 Reply to a TRANS2_SETFSINFO (set filesystem info).
3660 ****************************************************************************/
3662 static void call_trans2setfsinfo(connection_struct
*conn
,
3663 struct smb_request
*req
,
3664 char **pparams
, int total_params
,
3665 char **ppdata
, int total_data
,
3666 unsigned int max_data_bytes
)
3668 struct smbd_server_connection
*sconn
= req
->sconn
;
3669 char *pdata
= *ppdata
;
3670 char *params
= *pparams
;
3673 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
3674 lp_servicename(talloc_tos(), SNUM(conn
))));
3677 if (total_params
< 4) {
3678 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3680 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3684 info_level
= SVAL(params
,2);
3687 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
&&
3688 info_level
!= SMB_SET_CIFS_UNIX_INFO
) {
3689 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3690 "info level (0x%x) on IPC$.\n",
3691 (unsigned int)info_level
));
3692 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3697 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3698 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
) {
3699 DEBUG(0,("call_trans2setfsinfo: encryption required "
3700 "and info level 0x%x sent.\n",
3701 (unsigned int)info_level
));
3702 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3707 switch(info_level
) {
3708 case SMB_SET_CIFS_UNIX_INFO
:
3709 if (!lp_unix_extensions()) {
3710 DEBUG(2,("call_trans2setfsinfo: "
3711 "SMB_SET_CIFS_UNIX_INFO is invalid with "
3712 "unix extensions off\n"));
3714 NT_STATUS_INVALID_LEVEL
);
3718 /* There should be 12 bytes of capabilities set. */
3719 if (total_data
< 12) {
3722 NT_STATUS_INVALID_PARAMETER
);
3725 sconn
->smb1
.unix_info
.client_major
= SVAL(pdata
,0);
3726 sconn
->smb1
.unix_info
.client_minor
= SVAL(pdata
,2);
3727 sconn
->smb1
.unix_info
.client_cap_low
= IVAL(pdata
,4);
3728 sconn
->smb1
.unix_info
.client_cap_high
= IVAL(pdata
,8);
3729 /* Just print these values for now. */
3730 DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
3731 "major = %u, minor = %u cap_low = 0x%x, "
3733 (unsigned int)sconn
->
3734 smb1
.unix_info
.client_major
,
3735 (unsigned int)sconn
->
3736 smb1
.unix_info
.client_minor
,
3737 (unsigned int)sconn
->
3738 smb1
.unix_info
.client_cap_low
,
3739 (unsigned int)sconn
->
3740 smb1
.unix_info
.client_cap_high
));
3742 /* Here is where we must switch to posix pathname processing... */
3743 if (sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
3744 lp_set_posix_pathnames();
3745 mangle_change_to_posix();
3748 if ((sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_FCNTL_LOCKS_CAP
) &&
3749 !(sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)) {
3750 /* Client that knows how to do posix locks,
3751 * but not posix open/mkdir operations. Set a
3752 * default type for read/write checks. */
3754 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK
);
3759 case SMB_REQUEST_TRANSPORT_ENCRYPTION
:
3762 size_t param_len
= 0;
3763 size_t data_len
= total_data
;
3765 if (!lp_unix_extensions()) {
3768 NT_STATUS_INVALID_LEVEL
);
3772 if (lp_smb_encrypt(SNUM(conn
)) == SMB_SIGNING_OFF
) {
3775 NT_STATUS_NOT_SUPPORTED
);
3779 if (req
->sconn
->smb1
.echo_handler
.trusted_fde
) {
3780 DEBUG( 2,("call_trans2setfsinfo: "
3781 "request transport encryption disabled"
3782 "with 'fork echo handler = yes'\n"));
3785 NT_STATUS_NOT_SUPPORTED
);
3789 DEBUG( 4,("call_trans2setfsinfo: "
3790 "request transport encryption.\n"));
3792 status
= srv_request_encryption_setup(conn
,
3793 (unsigned char **)ppdata
,
3795 (unsigned char **)pparams
,
3798 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
3799 !NT_STATUS_IS_OK(status
)) {
3800 reply_nterror(req
, status
);
3804 send_trans2_replies(conn
, req
,
3811 if (NT_STATUS_IS_OK(status
)) {
3812 /* Server-side transport
3813 * encryption is now *on*. */
3814 status
= srv_encryption_start(conn
);
3815 if (!NT_STATUS_IS_OK(status
)) {
3816 char *reason
= talloc_asprintf(talloc_tos(),
3817 "Failure in setting "
3818 "up encrypted transport: %s",
3820 exit_server_cleanly(reason
);
3826 case SMB_FS_QUOTA_INFORMATION
:
3828 files_struct
*fsp
= NULL
;
3829 SMB_NTQUOTA_STRUCT quotas
;
3831 ZERO_STRUCT(quotas
);
3834 if ((get_current_uid(conn
) != 0) || !CAN_WRITE(conn
)) {
3835 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3836 lp_servicename(talloc_tos(), SNUM(conn
)),
3837 conn
->session_info
->unix_info
->unix_name
));
3838 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3842 /* note: normaly there're 48 bytes,
3843 * but we didn't use the last 6 bytes for now
3846 fsp
= file_fsp(req
, SVAL(params
,0));
3848 if (!check_fsp_ntquota_handle(conn
, req
,
3850 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3852 req
, NT_STATUS_INVALID_HANDLE
);
3856 if (total_data
< 42) {
3857 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3861 NT_STATUS_INVALID_PARAMETER
);
3865 /* unknown_1 24 NULL bytes in pdata*/
3867 /* the soft quotas 8 bytes (uint64_t)*/
3868 quotas
.softlim
= BVAL(pdata
,24);
3870 /* the hard quotas 8 bytes (uint64_t)*/
3871 quotas
.hardlim
= BVAL(pdata
,32);
3873 /* quota_flags 2 bytes **/
3874 quotas
.qflags
= SVAL(pdata
,40);
3876 /* unknown_2 6 NULL bytes follow*/
3878 /* now set the quotas */
3879 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3880 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3881 reply_nterror(req
, map_nt_error_from_unix(errno
));
3888 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3890 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
3896 * sending this reply works fine,
3897 * but I'm not sure it's the same
3898 * like windows do...
3901 reply_outbuf(req
, 10, 0);
3904 #if defined(HAVE_POSIX_ACLS)
3905 /****************************************************************************
3906 Utility function to count the number of entries in a POSIX acl.
3907 ****************************************************************************/
3909 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
3911 unsigned int ace_count
= 0;
3912 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3913 SMB_ACL_ENTRY_T entry
;
3915 while ( posix_acl
&& (sys_acl_get_entry(posix_acl
, entry_id
, &entry
) == 1)) {
3917 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3918 entry_id
= SMB_ACL_NEXT_ENTRY
;
3925 /****************************************************************************
3926 Utility function to marshall a POSIX acl into wire format.
3927 ****************************************************************************/
3929 static bool marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
3931 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3932 SMB_ACL_ENTRY_T entry
;
3934 while ( posix_acl
&& (sys_acl_get_entry(posix_acl
, entry_id
, &entry
) == 1)) {
3935 SMB_ACL_TAG_T tagtype
;
3936 SMB_ACL_PERMSET_T permset
;
3937 unsigned char perms
= 0;
3938 unsigned int own_grp
;
3941 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3942 entry_id
= SMB_ACL_NEXT_ENTRY
;
3945 if (sys_acl_get_tag_type(entry
, &tagtype
) == -1) {
3946 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3950 if (sys_acl_get_permset(entry
, &permset
) == -1) {
3951 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3955 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
3956 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
3957 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
3959 SCVAL(pdata
,1,perms
);
3962 case SMB_ACL_USER_OBJ
:
3963 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
3964 own_grp
= (unsigned int)pst
->st_ex_uid
;
3965 SIVAL(pdata
,2,own_grp
);
3970 uid_t
*puid
= (uid_t
*)sys_acl_get_qualifier(entry
);
3972 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3975 own_grp
= (unsigned int)*puid
;
3976 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
3977 SIVAL(pdata
,2,own_grp
);
3981 case SMB_ACL_GROUP_OBJ
:
3982 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
3983 own_grp
= (unsigned int)pst
->st_ex_gid
;
3984 SIVAL(pdata
,2,own_grp
);
3989 gid_t
*pgid
= (gid_t
*)sys_acl_get_qualifier(entry
);
3991 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3994 own_grp
= (unsigned int)*pgid
;
3995 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
3996 SIVAL(pdata
,2,own_grp
);
4001 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
4002 SIVAL(pdata
,2,0xFFFFFFFF);
4003 SIVAL(pdata
,6,0xFFFFFFFF);
4006 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
4007 SIVAL(pdata
,2,0xFFFFFFFF);
4008 SIVAL(pdata
,6,0xFFFFFFFF);
4011 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
4014 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
4021 /****************************************************************************
4022 Store the FILE_UNIX_BASIC info.
4023 ****************************************************************************/
4025 static char *store_file_unix_basic(connection_struct
*conn
,
4028 const SMB_STRUCT_STAT
*psbuf
)
4030 uint64_t file_index
= get_FileIndex(conn
, psbuf
);
4033 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
4034 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_ex_mode
));
4036 SOFF_T(pdata
,0,get_file_size_stat(psbuf
)); /* File size 64 Bit */
4039 SOFF_T(pdata
,0,SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
4042 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
, psbuf
->st_ex_ctime
); /* Change Time 64 Bit */
4043 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
+8, psbuf
->st_ex_atime
); /* Last access time 64 Bit */
4044 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
+16, psbuf
->st_ex_mtime
); /* Last modification time 64 Bit */
4047 SIVAL(pdata
,0,psbuf
->st_ex_uid
); /* user id for the owner */
4051 SIVAL(pdata
,0,psbuf
->st_ex_gid
); /* group id of owner */
4055 SIVAL(pdata
,0,unix_filetype(psbuf
->st_ex_mode
));
4058 if (S_ISBLK(psbuf
->st_ex_mode
) || S_ISCHR(psbuf
->st_ex_mode
)) {
4059 devno
= psbuf
->st_ex_rdev
;
4061 devno
= psbuf
->st_ex_dev
;
4064 SIVAL(pdata
,0,unix_dev_major(devno
)); /* Major device number if type is device */
4068 SIVAL(pdata
,0,unix_dev_minor(devno
)); /* Minor device number if type is device */
4072 SINO_T_VAL(pdata
,0,(SMB_INO_T
)file_index
); /* inode number */
4075 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_ex_mode
)); /* Standard UNIX file permissions */
4079 SIVAL(pdata
,0,psbuf
->st_ex_nlink
); /* number of hard links */
4086 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4087 * the chflags(2) (or equivalent) flags.
4089 * XXX: this really should be behind the VFS interface. To do this, we would
4090 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4091 * Each VFS module could then implement its own mapping as appropriate for the
4092 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4094 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
4098 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
4102 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
4106 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
4110 { UF_HIDDEN
, EXT_HIDDEN
},
4113 /* Do not remove. We need to guarantee that this array has at least one
4114 * entry to build on HP-UX.
4120 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4121 uint32
*smb_fflags
, uint32
*smb_fmask
)
4125 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4126 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
4127 if (psbuf
->st_ex_flags
& info2_flags_map
[i
].stat_fflag
) {
4128 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
4133 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4134 const uint32 smb_fflags
,
4135 const uint32 smb_fmask
,
4138 uint32 max_fmask
= 0;
4141 *stat_fflags
= psbuf
->st_ex_flags
;
4143 /* For each flags requested in smb_fmask, check the state of the
4144 * corresponding flag in smb_fflags and set or clear the matching
4148 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4149 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
4150 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
4151 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
4152 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
4154 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
4159 /* If smb_fmask is asking to set any bits that are not supported by
4160 * our flag mappings, we should fail.
4162 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
4170 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4171 * of file flags and birth (create) time.
4173 static char *store_file_unix_basic_info2(connection_struct
*conn
,
4176 const SMB_STRUCT_STAT
*psbuf
)
4178 uint32 file_flags
= 0;
4179 uint32 flags_mask
= 0;
4181 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4183 /* Create (birth) time 64 bit */
4184 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
, psbuf
->st_ex_btime
);
4187 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
4188 SIVAL(pdata
, 0, file_flags
); /* flags */
4189 SIVAL(pdata
, 4, flags_mask
); /* mask */
4195 static NTSTATUS
marshall_stream_info(unsigned int num_streams
,
4196 const struct stream_struct
*streams
,
4198 unsigned int max_data_bytes
,
4199 unsigned int *data_size
)
4202 unsigned int ofs
= 0;
4204 for (i
= 0; i
< num_streams
; i
++) {
4205 unsigned int next_offset
;
4207 smb_ucs2_t
*namebuf
;
4209 if (!push_ucs2_talloc(talloc_tos(), &namebuf
,
4210 streams
[i
].name
, &namelen
) ||
4213 return NT_STATUS_INVALID_PARAMETER
;
4217 * name_buf is now null-terminated, we need to marshall as not
4224 * We cannot overflow ...
4226 if ((ofs
+ 24 + namelen
) > max_data_bytes
) {
4227 DEBUG(10, ("refusing to overflow reply at stream %u\n",
4229 TALLOC_FREE(namebuf
);
4230 return STATUS_BUFFER_OVERFLOW
;
4233 SIVAL(data
, ofs
+4, namelen
);
4234 SOFF_T(data
, ofs
+8, streams
[i
].size
);
4235 SOFF_T(data
, ofs
+16, streams
[i
].alloc_size
);
4236 memcpy(data
+ofs
+24, namebuf
, namelen
);
4237 TALLOC_FREE(namebuf
);
4239 next_offset
= ofs
+ 24 + namelen
;
4241 if (i
== num_streams
-1) {
4242 SIVAL(data
, ofs
, 0);
4245 unsigned int align
= ndr_align_size(next_offset
, 8);
4247 if ((next_offset
+ align
) > max_data_bytes
) {
4248 DEBUG(10, ("refusing to overflow align "
4249 "reply at stream %u\n",
4251 TALLOC_FREE(namebuf
);
4252 return STATUS_BUFFER_OVERFLOW
;
4255 memset(data
+next_offset
, 0, align
);
4256 next_offset
+= align
;
4258 SIVAL(data
, ofs
, next_offset
- ofs
);
4265 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes
, ofs
));
4269 return NT_STATUS_OK
;
4272 /****************************************************************************
4273 Reply to a TRANSACT2_QFILEINFO on a PIPE !
4274 ****************************************************************************/
4276 static void call_trans2qpipeinfo(connection_struct
*conn
,
4277 struct smb_request
*req
,
4278 unsigned int tran_call
,
4279 char **pparams
, int total_params
,
4280 char **ppdata
, int total_data
,
4281 unsigned int max_data_bytes
)
4283 char *params
= *pparams
;
4284 char *pdata
= *ppdata
;
4285 unsigned int data_size
= 0;
4286 unsigned int param_size
= 2;
4291 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4295 if (total_params
< 4) {
4296 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4300 fsp
= file_fsp(req
, SVAL(params
,0));
4301 if (!fsp_is_np(fsp
)) {
4302 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
4306 info_level
= SVAL(params
,2);
4308 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
4309 if (*pparams
== NULL
) {
4310 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4315 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4316 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4317 if (*ppdata
== NULL
) {
4318 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4323 switch (info_level
) {
4324 case SMB_FILE_STANDARD_INFORMATION
:
4326 SOFF_T(pdata
,0,4096LL);
4333 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
4337 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
4343 NTSTATUS
smbd_do_qfilepathinfo(connection_struct
*conn
,
4344 TALLOC_CTX
*mem_ctx
,
4345 uint16_t info_level
,
4347 struct smb_filename
*smb_fname
,
4348 bool delete_pending
,
4349 struct timespec write_time_ts
,
4350 struct ea_list
*ea_list
,
4351 int lock_data_count
,
4354 unsigned int max_data_bytes
,
4356 unsigned int *pdata_size
)
4358 char *pdata
= *ppdata
;
4359 char *dstart
, *dend
;
4360 unsigned int data_size
;
4361 struct timespec create_time_ts
, mtime_ts
, atime_ts
, ctime_ts
;
4362 time_t create_time
, mtime
, atime
, c_time
;
4363 SMB_STRUCT_STAT
*psbuf
= &smb_fname
->st
;
4370 uint64_t file_size
= 0;
4372 uint64_t allocation_size
= 0;
4373 uint64_t file_index
= 0;
4374 uint32_t access_mask
= 0;
4376 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
4377 return NT_STATUS_INVALID_LEVEL
;
4380 DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
4381 smb_fname_str_dbg(smb_fname
),
4383 info_level
, max_data_bytes
));
4385 mode
= dos_mode(conn
, smb_fname
);
4386 nlink
= psbuf
->st_ex_nlink
;
4388 if (nlink
&& (mode
&FILE_ATTRIBUTE_DIRECTORY
)) {
4392 if ((nlink
> 0) && delete_pending
) {
4396 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4397 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4398 if (*ppdata
== NULL
) {
4399 return NT_STATUS_NO_MEMORY
;
4403 dend
= dstart
+ data_size
- 1;
4405 if (!null_timespec(write_time_ts
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
4406 update_stat_ex_mtime(psbuf
, write_time_ts
);
4409 create_time_ts
= get_create_timespec(conn
, fsp
, smb_fname
);
4410 mtime_ts
= psbuf
->st_ex_mtime
;
4411 atime_ts
= psbuf
->st_ex_atime
;
4412 ctime_ts
= get_change_timespec(conn
, fsp
, smb_fname
);
4414 if (lp_dos_filetime_resolution(SNUM(conn
))) {
4415 dos_filetime_timespec(&create_time_ts
);
4416 dos_filetime_timespec(&mtime_ts
);
4417 dos_filetime_timespec(&atime_ts
);
4418 dos_filetime_timespec(&ctime_ts
);
4421 create_time
= convert_timespec_to_time_t(create_time_ts
);
4422 mtime
= convert_timespec_to_time_t(mtime_ts
);
4423 atime
= convert_timespec_to_time_t(atime_ts
);
4424 c_time
= convert_timespec_to_time_t(ctime_ts
);
4426 p
= strrchr_m(smb_fname
->base_name
,'/');
4428 base_name
= smb_fname
->base_name
;
4432 /* NT expects the name to be in an exact form of the *full*
4433 filename. See the trans2 torture test */
4434 if (ISDOT(base_name
)) {
4435 dos_fname
= talloc_strdup(mem_ctx
, "\\");
4437 return NT_STATUS_NO_MEMORY
;
4440 dos_fname
= talloc_asprintf(mem_ctx
,
4442 smb_fname
->base_name
);
4444 return NT_STATUS_NO_MEMORY
;
4446 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4447 dos_fname
= talloc_asprintf(dos_fname
, "%s",
4448 smb_fname
->stream_name
);
4450 return NT_STATUS_NO_MEMORY
;
4454 string_replace(dos_fname
, '/', '\\');
4457 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, psbuf
);
4460 /* Do we have this path open ? */
4462 struct file_id fileid
= vfs_file_id_from_sbuf(conn
, psbuf
);
4463 fsp1
= file_find_di_first(conn
->sconn
, fileid
);
4464 if (fsp1
&& fsp1
->initial_allocation_size
) {
4465 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp1
, psbuf
);
4469 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
4470 file_size
= get_file_size_stat(psbuf
);
4474 pos
= fsp
->fh
->position_information
;
4478 access_mask
= fsp
->access_mask
;
4480 /* GENERIC_EXECUTE mapping from Windows */
4481 access_mask
= 0x12019F;
4484 /* This should be an index number - looks like
4487 I think this causes us to fail the IFSKIT
4488 BasicFileInformationTest. -tpot */
4489 file_index
= get_FileIndex(conn
, psbuf
);
4491 switch (info_level
) {
4492 case SMB_INFO_STANDARD
:
4493 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4495 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
4496 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
4497 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
4498 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
4499 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
4500 SSVAL(pdata
,l1_attrFile
,mode
);
4503 case SMB_INFO_QUERY_EA_SIZE
:
4505 unsigned int ea_size
=
4506 estimate_ea_size(conn
, fsp
,
4508 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4510 srv_put_dos_date2(pdata
,0,create_time
);
4511 srv_put_dos_date2(pdata
,4,atime
);
4512 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
4513 SIVAL(pdata
,12,(uint32
)file_size
);
4514 SIVAL(pdata
,16,(uint32
)allocation_size
);
4515 SSVAL(pdata
,20,mode
);
4516 SIVAL(pdata
,22,ea_size
);
4520 case SMB_INFO_IS_NAME_VALID
:
4521 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4523 /* os/2 needs this ? really ?*/
4524 return NT_STATUS_DOS(ERRDOS
, ERRbadfunc
);
4526 /* This is only reached for qpathinfo */
4530 case SMB_INFO_QUERY_EAS_FROM_LIST
:
4532 size_t total_ea_len
= 0;
4533 struct ea_list
*ea_file_list
= NULL
;
4534 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4537 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4539 &total_ea_len
, &ea_file_list
);
4540 if (!NT_STATUS_IS_OK(status
)) {
4544 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
4546 if (!ea_list
|| (total_ea_len
> data_size
)) {
4548 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4552 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4556 case SMB_INFO_QUERY_ALL_EAS
:
4558 /* We have data_size bytes to put EA's into. */
4559 size_t total_ea_len
= 0;
4560 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4562 status
= get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4564 &total_ea_len
, &ea_list
);
4565 if (!NT_STATUS_IS_OK(status
)) {
4569 if (!ea_list
|| (total_ea_len
> data_size
)) {
4571 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4575 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4579 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4581 /* This is FileFullEaInformation - 0xF which maps to
4582 * 1015 (decimal) in smbd_do_setfilepathinfo. */
4584 /* We have data_size bytes to put EA's into. */
4585 size_t total_ea_len
= 0;
4586 struct ea_list
*ea_file_list
= NULL
;
4588 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4590 /*TODO: add filtering and index handling */
4593 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4595 &total_ea_len
, &ea_file_list
);
4596 if (!NT_STATUS_IS_OK(status
)) {
4599 if (!ea_file_list
) {
4600 return NT_STATUS_NO_EAS_ON_FILE
;
4603 status
= fill_ea_chained_buffer(mem_ctx
,
4607 conn
, ea_file_list
);
4608 if (!NT_STATUS_IS_OK(status
)) {
4614 case SMB_FILE_BASIC_INFORMATION
:
4615 case SMB_QUERY_FILE_BASIC_INFO
:
4617 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
4618 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4619 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
4621 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4625 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4626 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4627 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4628 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4629 SIVAL(pdata
,32,mode
);
4631 DEBUG(5,("SMB_QFBI - "));
4632 DEBUG(5,("create: %s ", ctime(&create_time
)));
4633 DEBUG(5,("access: %s ", ctime(&atime
)));
4634 DEBUG(5,("write: %s ", ctime(&mtime
)));
4635 DEBUG(5,("change: %s ", ctime(&c_time
)));
4636 DEBUG(5,("mode: %x\n", mode
));
4639 case SMB_FILE_STANDARD_INFORMATION
:
4640 case SMB_QUERY_FILE_STANDARD_INFO
:
4642 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4644 SOFF_T(pdata
,0,allocation_size
);
4645 SOFF_T(pdata
,8,file_size
);
4646 SIVAL(pdata
,16,nlink
);
4647 SCVAL(pdata
,20,delete_pending
?1:0);
4648 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4649 SSVAL(pdata
,22,0); /* Padding. */
4652 case SMB_FILE_EA_INFORMATION
:
4653 case SMB_QUERY_FILE_EA_INFO
:
4655 unsigned int ea_size
=
4656 estimate_ea_size(conn
, fsp
, smb_fname
);
4657 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4659 SIVAL(pdata
,0,ea_size
);
4663 /* Get the 8.3 name - used if NT SMB was negotiated. */
4664 case SMB_QUERY_FILE_ALT_NAME_INFO
:
4665 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
4668 char mangled_name
[13];
4669 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4670 if (!name_to_8_3(base_name
,mangled_name
,
4671 True
,conn
->params
)) {
4672 return NT_STATUS_NO_MEMORY
;
4674 len
= srvstr_push(dstart
, flags2
,
4675 pdata
+4, mangled_name
,
4676 PTR_DIFF(dend
, pdata
+4),
4678 data_size
= 4 + len
;
4683 case SMB_QUERY_FILE_NAME_INFO
:
4687 this must be *exactly* right for ACLs on mapped drives to work
4689 len
= srvstr_push(dstart
, flags2
,
4691 PTR_DIFF(dend
, pdata
+4),
4693 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4694 data_size
= 4 + len
;
4699 case SMB_FILE_ALLOCATION_INFORMATION
:
4700 case SMB_QUERY_FILE_ALLOCATION_INFO
:
4701 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4703 SOFF_T(pdata
,0,allocation_size
);
4706 case SMB_FILE_END_OF_FILE_INFORMATION
:
4707 case SMB_QUERY_FILE_END_OF_FILEINFO
:
4708 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4710 SOFF_T(pdata
,0,file_size
);
4713 case SMB_QUERY_FILE_ALL_INFO
:
4714 case SMB_FILE_ALL_INFORMATION
:
4717 unsigned int ea_size
=
4718 estimate_ea_size(conn
, fsp
, smb_fname
);
4719 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4720 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4721 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4722 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4723 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4724 SIVAL(pdata
,32,mode
);
4725 SIVAL(pdata
,36,0); /* padding. */
4727 SOFF_T(pdata
,0,allocation_size
);
4728 SOFF_T(pdata
,8,file_size
);
4729 SIVAL(pdata
,16,nlink
);
4730 SCVAL(pdata
,20,delete_pending
);
4731 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4734 SIVAL(pdata
,0,ea_size
);
4735 pdata
+= 4; /* EA info */
4736 len
= srvstr_push(dstart
, flags2
,
4738 PTR_DIFF(dend
, pdata
+4),
4742 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4746 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4749 unsigned int ea_size
=
4750 estimate_ea_size(conn
, fsp
, smb_fname
);
4751 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4752 put_long_date_timespec(conn
->ts_res
,pdata
+0x00,create_time_ts
);
4753 put_long_date_timespec(conn
->ts_res
,pdata
+0x08,atime_ts
);
4754 put_long_date_timespec(conn
->ts_res
,pdata
+0x10,mtime_ts
); /* write time */
4755 put_long_date_timespec(conn
->ts_res
,pdata
+0x18,ctime_ts
); /* change time */
4756 SIVAL(pdata
, 0x20, mode
);
4757 SIVAL(pdata
, 0x24, 0); /* padding. */
4758 SBVAL(pdata
, 0x28, allocation_size
);
4759 SBVAL(pdata
, 0x30, file_size
);
4760 SIVAL(pdata
, 0x38, nlink
);
4761 SCVAL(pdata
, 0x3C, delete_pending
);
4762 SCVAL(pdata
, 0x3D, (mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4763 SSVAL(pdata
, 0x3E, 0); /* padding */
4764 SBVAL(pdata
, 0x40, file_index
);
4765 SIVAL(pdata
, 0x48, ea_size
);
4766 SIVAL(pdata
, 0x4C, access_mask
);
4767 SBVAL(pdata
, 0x50, pos
);
4768 SIVAL(pdata
, 0x58, mode
); /*TODO: mode != mode fix this!!! */
4769 SIVAL(pdata
, 0x5C, 0); /* No alignment needed. */
4773 len
= srvstr_push(dstart
, flags2
,
4775 PTR_DIFF(dend
, pdata
+4),
4779 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4782 case SMB_FILE_INTERNAL_INFORMATION
:
4784 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4785 SBVAL(pdata
, 0, file_index
);
4789 case SMB_FILE_ACCESS_INFORMATION
:
4790 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4791 SIVAL(pdata
, 0, access_mask
);
4795 case SMB_FILE_NAME_INFORMATION
:
4796 /* Pathname with leading '\'. */
4799 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
4800 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4801 SIVAL(pdata
,0,byte_len
);
4802 data_size
= 4 + byte_len
;
4806 case SMB_FILE_DISPOSITION_INFORMATION
:
4807 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4809 SCVAL(pdata
,0,delete_pending
);
4812 case SMB_FILE_POSITION_INFORMATION
:
4813 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4815 SOFF_T(pdata
,0,pos
);
4818 case SMB_FILE_MODE_INFORMATION
:
4819 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4820 SIVAL(pdata
,0,mode
);
4824 case SMB_FILE_ALIGNMENT_INFORMATION
:
4825 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4826 SIVAL(pdata
,0,0); /* No alignment needed. */
4831 * NT4 server just returns "invalid query" to this - if we try
4832 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4835 /* The first statement above is false - verified using Thursby
4836 * client against NT4 -- gcolley.
4838 case SMB_QUERY_FILE_STREAM_INFO
:
4839 case SMB_FILE_STREAM_INFORMATION
: {
4840 unsigned int num_streams
= 0;
4841 struct stream_struct
*streams
= NULL
;
4843 DEBUG(10,("smbd_do_qfilepathinfo: "
4844 "SMB_FILE_STREAM_INFORMATION\n"));
4846 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4847 return NT_STATUS_INVALID_PARAMETER
;
4850 status
= vfs_streaminfo(conn
, fsp
, smb_fname
->base_name
,
4851 talloc_tos(), &num_streams
, &streams
);
4853 if (!NT_STATUS_IS_OK(status
)) {
4854 DEBUG(10, ("could not get stream info: %s\n",
4855 nt_errstr(status
)));
4859 status
= marshall_stream_info(num_streams
, streams
,
4860 pdata
, max_data_bytes
,
4863 if (!NT_STATUS_IS_OK(status
)) {
4864 DEBUG(10, ("marshall_stream_info failed: %s\n",
4865 nt_errstr(status
)));
4866 TALLOC_FREE(streams
);
4870 TALLOC_FREE(streams
);
4874 case SMB_QUERY_COMPRESSION_INFO
:
4875 case SMB_FILE_COMPRESSION_INFORMATION
:
4876 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4877 SOFF_T(pdata
,0,file_size
);
4878 SIVAL(pdata
,8,0); /* ??? */
4879 SIVAL(pdata
,12,0); /* ??? */
4883 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
4884 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4885 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4886 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4887 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4888 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4889 SOFF_T(pdata
,32,allocation_size
);
4890 SOFF_T(pdata
,40,file_size
);
4891 SIVAL(pdata
,48,mode
);
4892 SIVAL(pdata
,52,0); /* ??? */
4896 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
4897 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4898 SIVAL(pdata
,0,mode
);
4904 * CIFS UNIX Extensions.
4907 case SMB_QUERY_FILE_UNIX_BASIC
:
4909 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4910 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4912 DEBUG(4,("smbd_do_qfilepathinfo: "
4913 "SMB_QUERY_FILE_UNIX_BASIC\n"));
4914 dump_data(4, (uint8_t *)(*ppdata
), data_size
);
4918 case SMB_QUERY_FILE_UNIX_INFO2
:
4920 pdata
= store_file_unix_basic_info2(conn
, pdata
, fsp
, psbuf
);
4921 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4925 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4927 for (i
=0; i
<100; i
++)
4928 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
4934 case SMB_QUERY_FILE_UNIX_LINK
:
4937 char *buffer
= talloc_array(mem_ctx
, char, PATH_MAX
+1);
4940 return NT_STATUS_NO_MEMORY
;
4943 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4945 if(!S_ISLNK(psbuf
->st_ex_mode
)) {
4946 return NT_STATUS_DOS(ERRSRV
, ERRbadlink
);
4949 return NT_STATUS_DOS(ERRDOS
, ERRbadlink
);
4951 len
= SMB_VFS_READLINK(conn
,
4952 smb_fname
->base_name
,
4955 return map_nt_error_from_unix(errno
);
4958 len
= srvstr_push(dstart
, flags2
,
4960 PTR_DIFF(dend
, pdata
),
4963 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4968 #if defined(HAVE_POSIX_ACLS)
4969 case SMB_QUERY_POSIX_ACL
:
4971 SMB_ACL_T file_acl
= NULL
;
4972 SMB_ACL_T def_acl
= NULL
;
4973 uint16 num_file_acls
= 0;
4974 uint16 num_def_acls
= 0;
4976 if (fsp
&& fsp
->fh
->fd
!= -1) {
4977 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
,
4981 SMB_VFS_SYS_ACL_GET_FILE(conn
,
4982 smb_fname
->base_name
,
4983 SMB_ACL_TYPE_ACCESS
,
4987 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
4988 DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4989 "not implemented on "
4990 "filesystem containing %s\n",
4991 smb_fname
->base_name
));
4992 return NT_STATUS_NOT_IMPLEMENTED
;
4995 if (S_ISDIR(psbuf
->st_ex_mode
)) {
4996 if (fsp
&& fsp
->is_directory
) {
4998 SMB_VFS_SYS_ACL_GET_FILE(
5000 fsp
->fsp_name
->base_name
,
5001 SMB_ACL_TYPE_DEFAULT
,
5005 SMB_VFS_SYS_ACL_GET_FILE(
5007 smb_fname
->base_name
,
5008 SMB_ACL_TYPE_DEFAULT
,
5011 def_acl
= free_empty_sys_acl(conn
, def_acl
);
5014 num_file_acls
= count_acl_entries(conn
, file_acl
);
5015 num_def_acls
= count_acl_entries(conn
, def_acl
);
5017 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
5018 DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
5020 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
5021 SMB_POSIX_ACL_HEADER_SIZE
) ));
5023 TALLOC_FREE(file_acl
);
5026 TALLOC_FREE(def_acl
);
5028 return NT_STATUS_BUFFER_TOO_SMALL
;
5031 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
5032 SSVAL(pdata
,2,num_file_acls
);
5033 SSVAL(pdata
,4,num_def_acls
);
5034 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, psbuf
, file_acl
)) {
5036 TALLOC_FREE(file_acl
);
5039 TALLOC_FREE(def_acl
);
5041 return NT_STATUS_INTERNAL_ERROR
;
5043 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), psbuf
, def_acl
)) {
5045 TALLOC_FREE(file_acl
);
5048 TALLOC_FREE(def_acl
);
5050 return NT_STATUS_INTERNAL_ERROR
;
5054 TALLOC_FREE(file_acl
);
5057 TALLOC_FREE(def_acl
);
5059 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
5065 case SMB_QUERY_POSIX_LOCK
:
5070 enum brl_type lock_type
;
5072 /* We need an open file with a real fd for this. */
5073 if (!fsp
|| fsp
->fh
->fd
== -1) {
5074 return NT_STATUS_INVALID_LEVEL
;
5077 if (lock_data_count
!= POSIX_LOCK_DATA_SIZE
) {
5078 return NT_STATUS_INVALID_PARAMETER
;
5081 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
5082 case POSIX_LOCK_TYPE_READ
:
5083 lock_type
= READ_LOCK
;
5085 case POSIX_LOCK_TYPE_WRITE
:
5086 lock_type
= WRITE_LOCK
;
5088 case POSIX_LOCK_TYPE_UNLOCK
:
5090 /* There's no point in asking for an unlock... */
5091 return NT_STATUS_INVALID_PARAMETER
;
5094 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
5095 #if defined(HAVE_LONGLONG)
5096 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
5097 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
5098 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
5099 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
5100 #else /* HAVE_LONGLONG */
5101 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
5102 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
5103 #endif /* HAVE_LONGLONG */
5105 status
= query_lock(fsp
,
5112 if (ERROR_WAS_LOCK_DENIED(status
)) {
5113 /* Here we need to report who has it locked... */
5114 data_size
= POSIX_LOCK_DATA_SIZE
;
5116 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, lock_type
);
5117 SSVAL(pdata
, POSIX_LOCK_FLAGS_OFFSET
, 0);
5118 SIVAL(pdata
, POSIX_LOCK_PID_OFFSET
, (uint32_t)smblctx
);
5119 #if defined(HAVE_LONGLONG)
5120 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, (uint32
)(offset
& 0xFFFFFFFF));
5121 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
+ 4, (uint32
)((offset
>> 32) & 0xFFFFFFFF));
5122 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, (uint32
)(count
& 0xFFFFFFFF));
5123 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
+ 4, (uint32
)((count
>> 32) & 0xFFFFFFFF));
5124 #else /* HAVE_LONGLONG */
5125 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, offset
);
5126 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, count
);
5127 #endif /* HAVE_LONGLONG */
5129 } else if (NT_STATUS_IS_OK(status
)) {
5130 /* For success we just return a copy of what we sent
5131 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5132 data_size
= POSIX_LOCK_DATA_SIZE
;
5133 memcpy(pdata
, lock_data
, POSIX_LOCK_DATA_SIZE
);
5134 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
5142 return NT_STATUS_INVALID_LEVEL
;
5145 *pdata_size
= data_size
;
5146 return NT_STATUS_OK
;
5149 /****************************************************************************
5150 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5151 file name or file id).
5152 ****************************************************************************/
5154 static void call_trans2qfilepathinfo(connection_struct
*conn
,
5155 struct smb_request
*req
,
5156 unsigned int tran_call
,
5157 char **pparams
, int total_params
,
5158 char **ppdata
, int total_data
,
5159 unsigned int max_data_bytes
)
5161 char *params
= *pparams
;
5162 char *pdata
= *ppdata
;
5164 unsigned int data_size
= 0;
5165 unsigned int param_size
= 2;
5166 struct smb_filename
*smb_fname
= NULL
;
5167 bool delete_pending
= False
;
5168 struct timespec write_time_ts
;
5169 files_struct
*fsp
= NULL
;
5170 struct file_id fileid
;
5171 struct ea_list
*ea_list
= NULL
;
5172 int lock_data_count
= 0;
5173 char *lock_data
= NULL
;
5174 NTSTATUS status
= NT_STATUS_OK
;
5177 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5181 ZERO_STRUCT(write_time_ts
);
5183 if (tran_call
== TRANSACT2_QFILEINFO
) {
5184 if (total_params
< 4) {
5185 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5190 call_trans2qpipeinfo(conn
, req
, tran_call
,
5191 pparams
, total_params
,
5197 fsp
= file_fsp(req
, SVAL(params
,0));
5198 info_level
= SVAL(params
,2);
5200 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
5202 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
5203 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5207 /* Initial check for valid fsp ptr. */
5208 if (!check_fsp_open(conn
, req
, fsp
)) {
5212 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
5214 if (!NT_STATUS_IS_OK(status
)) {
5215 reply_nterror(req
, status
);
5219 if(fsp
->fake_file_handle
) {
5221 * This is actually for the QUOTA_FAKE_FILE --metze
5224 /* We know this name is ok, it's already passed the checks. */
5226 } else if(fsp
->fh
->fd
== -1) {
5228 * This is actually a QFILEINFO on a directory
5229 * handle (returned from an NT SMB). NT5.0 seems
5230 * to do this call. JRA.
5233 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5234 /* Always do lstat for UNIX calls. */
5235 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5236 DEBUG(3,("call_trans2qfilepathinfo: "
5237 "SMB_VFS_LSTAT of %s failed "
5239 smb_fname_str_dbg(smb_fname
),
5242 map_nt_error_from_unix(errno
));
5245 } else if (SMB_VFS_STAT(conn
, smb_fname
)) {
5246 DEBUG(3,("call_trans2qfilepathinfo: "
5247 "SMB_VFS_STAT of %s failed (%s)\n",
5248 smb_fname_str_dbg(smb_fname
),
5251 map_nt_error_from_unix(errno
));
5255 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5256 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5259 * Original code - this is an open file.
5261 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
5262 DEBUG(3, ("fstat of %s failed (%s)\n",
5263 fsp_fnum_dbg(fsp
), strerror(errno
)));
5265 map_nt_error_from_unix(errno
));
5268 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5269 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5275 uint32_t ucf_flags
= 0;
5278 if (total_params
< 7) {
5279 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5283 info_level
= SVAL(params
,0);
5285 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
5287 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5288 if (!lp_unix_extensions()) {
5289 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5292 if (info_level
== SMB_QUERY_FILE_UNIX_BASIC
||
5293 info_level
== SMB_QUERY_FILE_UNIX_INFO2
||
5294 info_level
== SMB_QUERY_FILE_UNIX_LINK
) {
5295 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
5299 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
5301 STR_TERMINATE
, &status
);
5302 if (!NT_STATUS_IS_OK(status
)) {
5303 reply_nterror(req
, status
);
5307 status
= filename_convert(req
,
5309 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5314 if (!NT_STATUS_IS_OK(status
)) {
5315 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5316 reply_botherror(req
,
5317 NT_STATUS_PATH_NOT_COVERED
,
5318 ERRSRV
, ERRbadpath
);
5321 reply_nterror(req
, status
);
5325 /* If this is a stream, check if there is a delete_pending. */
5326 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5327 && is_ntfs_stream_smb_fname(smb_fname
)) {
5328 struct smb_filename
*smb_fname_base
= NULL
;
5330 /* Create an smb_filename with stream_name == NULL. */
5332 create_synthetic_smb_fname(talloc_tos(),
5333 smb_fname
->base_name
,
5336 if (!NT_STATUS_IS_OK(status
)) {
5337 reply_nterror(req
, status
);
5341 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5342 /* Always do lstat for UNIX calls. */
5343 if (SMB_VFS_LSTAT(conn
, smb_fname_base
) != 0) {
5344 DEBUG(3,("call_trans2qfilepathinfo: "
5345 "SMB_VFS_LSTAT of %s failed "
5347 smb_fname_str_dbg(smb_fname_base
),
5349 TALLOC_FREE(smb_fname_base
);
5351 map_nt_error_from_unix(errno
));
5355 if (SMB_VFS_STAT(conn
, smb_fname_base
) != 0) {
5356 DEBUG(3,("call_trans2qfilepathinfo: "
5357 "fileinfo of %s failed "
5359 smb_fname_str_dbg(smb_fname_base
),
5361 TALLOC_FREE(smb_fname_base
);
5363 map_nt_error_from_unix(errno
));
5368 status
= file_name_hash(conn
,
5369 smb_fname_str_dbg(smb_fname_base
),
5371 if (!NT_STATUS_IS_OK(status
)) {
5372 TALLOC_FREE(smb_fname_base
);
5373 reply_nterror(req
, status
);
5377 fileid
= vfs_file_id_from_sbuf(conn
,
5378 &smb_fname_base
->st
);
5379 TALLOC_FREE(smb_fname_base
);
5380 get_file_infos(fileid
, name_hash
, &delete_pending
, NULL
);
5381 if (delete_pending
) {
5382 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5387 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5388 /* Always do lstat for UNIX calls. */
5389 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5390 DEBUG(3,("call_trans2qfilepathinfo: "
5391 "SMB_VFS_LSTAT of %s failed (%s)\n",
5392 smb_fname_str_dbg(smb_fname
),
5395 map_nt_error_from_unix(errno
));
5400 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
5401 DEBUG(3,("call_trans2qfilepathinfo: "
5402 "SMB_VFS_STAT of %s failed (%s)\n",
5403 smb_fname_str_dbg(smb_fname
),
5406 map_nt_error_from_unix(errno
));
5411 status
= file_name_hash(conn
,
5412 smb_fname_str_dbg(smb_fname
),
5414 if (!NT_STATUS_IS_OK(status
)) {
5415 reply_nterror(req
, status
);
5419 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5420 get_file_infos(fileid
, name_hash
, &delete_pending
, &write_time_ts
);
5421 if (delete_pending
) {
5422 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5427 DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
5428 "total_data=%d\n", smb_fname_str_dbg(smb_fname
),
5430 info_level
,tran_call
,total_data
));
5432 /* Pull out any data sent here before we realloc. */
5433 switch (info_level
) {
5434 case SMB_INFO_QUERY_EAS_FROM_LIST
:
5436 /* Pull any EA list from the data portion. */
5439 if (total_data
< 4) {
5441 req
, NT_STATUS_INVALID_PARAMETER
);
5444 ea_size
= IVAL(pdata
,0);
5446 if (total_data
> 0 && ea_size
!= total_data
) {
5447 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5448 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
5450 req
, NT_STATUS_INVALID_PARAMETER
);
5454 if (!lp_ea_support(SNUM(conn
))) {
5455 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
5459 /* Pull out the list of names. */
5460 ea_list
= read_ea_name_list(req
, pdata
+ 4, ea_size
- 4);
5463 req
, NT_STATUS_INVALID_PARAMETER
);
5469 case SMB_QUERY_POSIX_LOCK
:
5471 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
5472 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
5476 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
5478 req
, NT_STATUS_INVALID_PARAMETER
);
5482 /* Copy the lock range data. */
5483 lock_data
= (char *)talloc_memdup(
5484 req
, pdata
, total_data
);
5486 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5489 lock_data_count
= total_data
;
5495 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
5496 if (*pparams
== NULL
) {
5497 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5504 * draft-leach-cifs-v1-spec-02.txt
5505 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5508 * The requested information is placed in the Data portion of the
5509 * transaction response. For the information levels greater than 0x100,
5510 * the transaction response has 1 parameter word which should be
5511 * ignored by the client.
5513 * However Windows only follows this rule for the IS_NAME_VALID call.
5515 switch (info_level
) {
5516 case SMB_INFO_IS_NAME_VALID
:
5521 if ((info_level
& 0xFF00) == 0xFF00) {
5523 * We use levels that start with 0xFF00
5524 * internally to represent SMB2 specific levels
5526 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5530 status
= smbd_do_qfilepathinfo(conn
, req
, info_level
,
5532 delete_pending
, write_time_ts
,
5534 lock_data_count
, lock_data
,
5535 req
->flags2
, max_data_bytes
,
5536 ppdata
, &data_size
);
5537 if (!NT_STATUS_IS_OK(status
)) {
5538 reply_nterror(req
, status
);
5542 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
5548 /****************************************************************************
5549 Set a hard link (called by UNIX extensions and by NT rename with HARD link
5551 ****************************************************************************/
5553 NTSTATUS
hardlink_internals(TALLOC_CTX
*ctx
,
5554 connection_struct
*conn
,
5555 struct smb_request
*req
,
5556 bool overwrite_if_exists
,
5557 const struct smb_filename
*smb_fname_old
,
5558 struct smb_filename
*smb_fname_new
)
5560 NTSTATUS status
= NT_STATUS_OK
;
5562 /* source must already exist. */
5563 if (!VALID_STAT(smb_fname_old
->st
)) {
5564 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5567 if (VALID_STAT(smb_fname_new
->st
)) {
5568 if (overwrite_if_exists
) {
5569 if (S_ISDIR(smb_fname_new
->st
.st_ex_mode
)) {
5570 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5572 status
= unlink_internals(conn
,
5574 FILE_ATTRIBUTE_NORMAL
,
5577 if (!NT_STATUS_IS_OK(status
)) {
5581 /* Disallow if newname already exists. */
5582 return NT_STATUS_OBJECT_NAME_COLLISION
;
5586 /* No links from a directory. */
5587 if (S_ISDIR(smb_fname_old
->st
.st_ex_mode
)) {
5588 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5591 /* Setting a hardlink to/from a stream isn't currently supported. */
5592 if (is_ntfs_stream_smb_fname(smb_fname_old
) ||
5593 is_ntfs_stream_smb_fname(smb_fname_new
)) {
5594 return NT_STATUS_INVALID_PARAMETER
;
5597 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5598 smb_fname_old
->base_name
, smb_fname_new
->base_name
));
5600 if (SMB_VFS_LINK(conn
, smb_fname_old
->base_name
,
5601 smb_fname_new
->base_name
) != 0) {
5602 status
= map_nt_error_from_unix(errno
);
5603 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5604 nt_errstr(status
), smb_fname_old
->base_name
,
5605 smb_fname_new
->base_name
));
5610 /****************************************************************************
5611 Deal with setting the time from any of the setfilepathinfo functions.
5612 NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
5613 calling this function.
5614 ****************************************************************************/
5616 NTSTATUS
smb_set_file_time(connection_struct
*conn
,
5618 const struct smb_filename
*smb_fname
,
5619 struct smb_file_time
*ft
,
5620 bool setting_write_time
)
5622 struct smb_filename smb_fname_base
;
5624 FILE_NOTIFY_CHANGE_LAST_ACCESS
5625 |FILE_NOTIFY_CHANGE_LAST_WRITE
5626 |FILE_NOTIFY_CHANGE_CREATION
;
5628 if (!VALID_STAT(smb_fname
->st
)) {
5629 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5632 /* get some defaults (no modifications) if any info is zero or -1. */
5633 if (null_timespec(ft
->create_time
)) {
5634 action
&= ~FILE_NOTIFY_CHANGE_CREATION
;
5637 if (null_timespec(ft
->atime
)) {
5638 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
5641 if (null_timespec(ft
->mtime
)) {
5642 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5645 if (!setting_write_time
) {
5646 /* ft->mtime comes from change time, not write time. */
5647 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5650 /* Ensure the resolution is the correct for
5651 * what we can store on this filesystem. */
5653 round_timespec(conn
->ts_res
, &ft
->create_time
);
5654 round_timespec(conn
->ts_res
, &ft
->ctime
);
5655 round_timespec(conn
->ts_res
, &ft
->atime
);
5656 round_timespec(conn
->ts_res
, &ft
->mtime
);
5658 DEBUG(5,("smb_set_filetime: actime: %s\n ",
5659 time_to_asc(convert_timespec_to_time_t(ft
->atime
))));
5660 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5661 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5662 DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5663 time_to_asc(convert_timespec_to_time_t(ft
->ctime
))));
5664 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5665 time_to_asc(convert_timespec_to_time_t(ft
->create_time
))));
5667 if (setting_write_time
) {
5669 * This was a Windows setfileinfo on an open file.
5670 * NT does this a lot. We also need to
5671 * set the time here, as it can be read by
5672 * FindFirst/FindNext and with the patch for bug #2045
5673 * in smbd/fileio.c it ensures that this timestamp is
5674 * kept sticky even after a write. We save the request
5675 * away and will set it on file close and after a write. JRA.
5678 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5679 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5682 if (fsp
->base_fsp
) {
5683 set_sticky_write_time_fsp(fsp
->base_fsp
,
5686 set_sticky_write_time_fsp(fsp
, ft
->mtime
);
5689 set_sticky_write_time_path(
5690 vfs_file_id_from_sbuf(conn
, &smb_fname
->st
),
5695 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5697 /* Always call ntimes on the base, even if a stream was passed in. */
5698 smb_fname_base
= *smb_fname
;
5699 smb_fname_base
.stream_name
= NULL
;
5701 if(file_ntimes(conn
, &smb_fname_base
, ft
)!=0) {
5702 return map_nt_error_from_unix(errno
);
5705 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
,
5706 smb_fname
->base_name
);
5707 return NT_STATUS_OK
;
5710 /****************************************************************************
5711 Deal with setting the dosmode from any of the setfilepathinfo functions.
5712 NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
5713 done before calling this function.
5714 ****************************************************************************/
5716 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
5717 const struct smb_filename
*smb_fname
,
5720 struct smb_filename
*smb_fname_base
= NULL
;
5723 if (!VALID_STAT(smb_fname
->st
)) {
5724 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5727 /* Always operate on the base_name, even if a stream was passed in. */
5728 status
= create_synthetic_smb_fname(talloc_tos(), smb_fname
->base_name
,
5729 NULL
, &smb_fname
->st
,
5731 if (!NT_STATUS_IS_OK(status
)) {
5736 if (S_ISDIR(smb_fname_base
->st
.st_ex_mode
)) {
5737 dosmode
|= FILE_ATTRIBUTE_DIRECTORY
;
5739 dosmode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
5743 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode
));
5745 /* check the mode isn't different, before changing it */
5746 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, smb_fname_base
))) {
5747 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5748 "0x%x\n", smb_fname_str_dbg(smb_fname_base
),
5749 (unsigned int)dosmode
));
5751 if(file_set_dosmode(conn
, smb_fname_base
, dosmode
, NULL
,
5753 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5755 smb_fname_str_dbg(smb_fname_base
),
5757 status
= map_nt_error_from_unix(errno
);
5761 status
= NT_STATUS_OK
;
5763 TALLOC_FREE(smb_fname_base
);
5767 /****************************************************************************
5768 Deal with setting the size from any of the setfilepathinfo functions.
5769 ****************************************************************************/
5771 static NTSTATUS
smb_set_file_size(connection_struct
*conn
,
5772 struct smb_request
*req
,
5774 const struct smb_filename
*smb_fname
,
5775 const SMB_STRUCT_STAT
*psbuf
,
5777 bool fail_after_createfile
)
5779 NTSTATUS status
= NT_STATUS_OK
;
5780 struct smb_filename
*smb_fname_tmp
= NULL
;
5781 files_struct
*new_fsp
= NULL
;
5783 if (!VALID_STAT(*psbuf
)) {
5784 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5787 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size
));
5789 if (size
== get_file_size_stat(psbuf
)) {
5790 return NT_STATUS_OK
;
5793 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5794 smb_fname_str_dbg(smb_fname
), (double)size
));
5796 if (fsp
&& fsp
->fh
->fd
!= -1) {
5797 /* Handle based call. */
5798 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
5799 return NT_STATUS_ACCESS_DENIED
;
5802 if (vfs_set_filelen(fsp
, size
) == -1) {
5803 return map_nt_error_from_unix(errno
);
5805 trigger_write_time_update_immediate(fsp
);
5806 return NT_STATUS_OK
;
5809 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
5810 if (!NT_STATUS_IS_OK(status
)) {
5814 smb_fname_tmp
->st
= *psbuf
;
5816 status
= SMB_VFS_CREATE_FILE(
5819 0, /* root_dir_fid */
5820 smb_fname_tmp
, /* fname */
5821 FILE_WRITE_DATA
, /* access_mask */
5822 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5824 FILE_OPEN
, /* create_disposition*/
5825 0, /* create_options */
5826 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5827 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
5828 0, /* allocation_size */
5829 0, /* private_flags */
5832 &new_fsp
, /* result */
5835 TALLOC_FREE(smb_fname_tmp
);
5837 if (!NT_STATUS_IS_OK(status
)) {
5838 /* NB. We check for open_was_deferred in the caller. */
5842 /* See RAW-SFILEINFO-END-OF-FILE */
5843 if (fail_after_createfile
) {
5844 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5845 return NT_STATUS_INVALID_LEVEL
;
5848 if (vfs_set_filelen(new_fsp
, size
) == -1) {
5849 status
= map_nt_error_from_unix(errno
);
5850 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5854 trigger_write_time_update_immediate(new_fsp
);
5855 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5856 return NT_STATUS_OK
;
5859 /****************************************************************************
5860 Deal with SMB_INFO_SET_EA.
5861 ****************************************************************************/
5863 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
5867 const struct smb_filename
*smb_fname
)
5869 struct ea_list
*ea_list
= NULL
;
5870 TALLOC_CTX
*ctx
= NULL
;
5871 NTSTATUS status
= NT_STATUS_OK
;
5873 if (total_data
< 10) {
5875 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5876 length. They seem to have no effect. Bug #3212. JRA */
5878 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
5879 /* We're done. We only get EA info in this call. */
5880 return NT_STATUS_OK
;
5883 return NT_STATUS_INVALID_PARAMETER
;
5886 if (IVAL(pdata
,0) > total_data
) {
5887 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5888 IVAL(pdata
,0), (unsigned int)total_data
));
5889 return NT_STATUS_INVALID_PARAMETER
;
5893 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
5895 return NT_STATUS_INVALID_PARAMETER
;
5898 status
= set_ea(conn
, fsp
, smb_fname
, ea_list
);
5903 /****************************************************************************
5904 Deal with SMB_FILE_FULL_EA_INFORMATION set.
5905 ****************************************************************************/
5907 static NTSTATUS
smb_set_file_full_ea_info(connection_struct
*conn
,
5912 struct ea_list
*ea_list
= NULL
;
5916 return NT_STATUS_INVALID_HANDLE
;
5919 if (!lp_ea_support(SNUM(conn
))) {
5920 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5921 "EA's not supported.\n",
5922 (unsigned int)total_data
));
5923 return NT_STATUS_EAS_NOT_SUPPORTED
;
5926 if (total_data
< 10) {
5927 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5929 (unsigned int)total_data
));
5930 return NT_STATUS_INVALID_PARAMETER
;
5933 ea_list
= read_nttrans_ea_list(talloc_tos(),
5938 return NT_STATUS_INVALID_PARAMETER
;
5941 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
5943 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5944 smb_fname_str_dbg(fsp
->fsp_name
),
5945 nt_errstr(status
) ));
5951 /****************************************************************************
5952 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5953 ****************************************************************************/
5955 static NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
5959 struct smb_filename
*smb_fname
)
5961 NTSTATUS status
= NT_STATUS_OK
;
5962 bool delete_on_close
;
5965 if (total_data
< 1) {
5966 return NT_STATUS_INVALID_PARAMETER
;
5970 return NT_STATUS_INVALID_HANDLE
;
5973 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
5974 dosmode
= dos_mode(conn
, smb_fname
);
5976 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5977 "delete_on_close = %u\n",
5978 smb_fname_str_dbg(smb_fname
),
5979 (unsigned int)dosmode
,
5980 (unsigned int)delete_on_close
));
5982 if (delete_on_close
) {
5983 status
= can_set_delete_on_close(fsp
, dosmode
);
5984 if (!NT_STATUS_IS_OK(status
)) {
5989 /* The set is across all open files on this dev/inode pair. */
5990 if (!set_delete_on_close(fsp
, delete_on_close
,
5991 conn
->session_info
->security_token
,
5992 conn
->session_info
->unix_token
)) {
5993 return NT_STATUS_ACCESS_DENIED
;
5995 return NT_STATUS_OK
;
5998 /****************************************************************************
5999 Deal with SMB_FILE_POSITION_INFORMATION.
6000 ****************************************************************************/
6002 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
6007 uint64_t position_information
;
6009 if (total_data
< 8) {
6010 return NT_STATUS_INVALID_PARAMETER
;
6014 /* Ignore on pathname based set. */
6015 return NT_STATUS_OK
;
6018 position_information
= (uint64_t)IVAL(pdata
,0);
6019 position_information
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6021 DEBUG(10,("smb_file_position_information: Set file position "
6022 "information for file %s to %.0f\n", fsp_str_dbg(fsp
),
6023 (double)position_information
));
6024 fsp
->fh
->position_information
= position_information
;
6025 return NT_STATUS_OK
;
6028 /****************************************************************************
6029 Deal with SMB_FILE_MODE_INFORMATION.
6030 ****************************************************************************/
6032 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
6038 if (total_data
< 4) {
6039 return NT_STATUS_INVALID_PARAMETER
;
6041 mode
= IVAL(pdata
,0);
6042 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
6043 return NT_STATUS_INVALID_PARAMETER
;
6045 return NT_STATUS_OK
;
6048 /****************************************************************************
6049 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
6050 ****************************************************************************/
6052 static NTSTATUS
smb_set_file_unix_link(connection_struct
*conn
,
6053 struct smb_request
*req
,
6056 const struct smb_filename
*smb_fname
)
6058 char *link_target
= NULL
;
6059 const char *newname
= smb_fname
->base_name
;
6060 TALLOC_CTX
*ctx
= talloc_tos();
6062 /* Set a symbolic link. */
6063 /* Don't allow this if follow links is false. */
6065 if (total_data
== 0) {
6066 return NT_STATUS_INVALID_PARAMETER
;
6069 if (!lp_symlinks(SNUM(conn
))) {
6070 return NT_STATUS_ACCESS_DENIED
;
6073 srvstr_pull_talloc(ctx
, pdata
, req
->flags2
, &link_target
, pdata
,
6074 total_data
, STR_TERMINATE
);
6077 return NT_STATUS_INVALID_PARAMETER
;
6080 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
6081 newname
, link_target
));
6083 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0) {
6084 return map_nt_error_from_unix(errno
);
6087 return NT_STATUS_OK
;
6090 /****************************************************************************
6091 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
6092 ****************************************************************************/
6094 static NTSTATUS
smb_set_file_unix_hlink(connection_struct
*conn
,
6095 struct smb_request
*req
,
6096 const char *pdata
, int total_data
,
6097 struct smb_filename
*smb_fname_new
)
6099 char *oldname
= NULL
;
6100 struct smb_filename
*smb_fname_old
= NULL
;
6101 TALLOC_CTX
*ctx
= talloc_tos();
6102 NTSTATUS status
= NT_STATUS_OK
;
6104 /* Set a hard link. */
6105 if (total_data
== 0) {
6106 return NT_STATUS_INVALID_PARAMETER
;
6109 srvstr_get_path(ctx
, pdata
, req
->flags2
, &oldname
, pdata
,
6110 total_data
, STR_TERMINATE
, &status
);
6111 if (!NT_STATUS_IS_OK(status
)) {
6115 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6116 smb_fname_str_dbg(smb_fname_new
), oldname
));
6118 status
= filename_convert(ctx
,
6120 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6125 if (!NT_STATUS_IS_OK(status
)) {
6129 return hardlink_internals(ctx
, conn
, req
, false,
6130 smb_fname_old
, smb_fname_new
);
6133 /****************************************************************************
6134 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6135 ****************************************************************************/
6137 static NTSTATUS
smb2_file_rename_information(connection_struct
*conn
,
6138 struct smb_request
*req
,
6142 struct smb_filename
*smb_fname_src
)
6146 char *newname
= NULL
;
6147 struct smb_filename
*smb_fname_dst
= NULL
;
6148 NTSTATUS status
= NT_STATUS_OK
;
6149 TALLOC_CTX
*ctx
= talloc_tos();
6152 return NT_STATUS_INVALID_HANDLE
;
6155 if (total_data
< 20) {
6156 return NT_STATUS_INVALID_PARAMETER
;
6159 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6160 len
= IVAL(pdata
,16);
6162 if (len
> (total_data
- 20) || (len
== 0)) {
6163 return NT_STATUS_INVALID_PARAMETER
;
6166 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6167 &pdata
[20], len
, STR_TERMINATE
,
6169 if (!NT_STATUS_IS_OK(status
)) {
6173 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
6176 status
= filename_convert(ctx
,
6178 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6183 if (!NT_STATUS_IS_OK(status
)) {
6187 if (fsp
->base_fsp
) {
6188 /* newname must be a stream name. */
6189 if (newname
[0] != ':') {
6190 return NT_STATUS_NOT_SUPPORTED
;
6193 /* Create an smb_fname to call rename_internals_fsp() with. */
6194 status
= create_synthetic_smb_fname(talloc_tos(),
6195 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6197 if (!NT_STATUS_IS_OK(status
)) {
6202 * Set the original last component, since
6203 * rename_internals_fsp() requires it.
6205 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6207 if (smb_fname_dst
->original_lcomp
== NULL
) {
6208 status
= NT_STATUS_NO_MEMORY
;
6214 DEBUG(10,("smb2_file_rename_information: "
6215 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6216 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6217 smb_fname_str_dbg(smb_fname_dst
)));
6218 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6219 (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
),
6223 TALLOC_FREE(smb_fname_dst
);
6227 static NTSTATUS
smb_file_link_information(connection_struct
*conn
,
6228 struct smb_request
*req
,
6232 struct smb_filename
*smb_fname_src
)
6236 char *newname
= NULL
;
6237 struct smb_filename
*smb_fname_dst
= NULL
;
6238 NTSTATUS status
= NT_STATUS_OK
;
6239 TALLOC_CTX
*ctx
= talloc_tos();
6242 return NT_STATUS_INVALID_HANDLE
;
6245 if (total_data
< 20) {
6246 return NT_STATUS_INVALID_PARAMETER
;
6249 overwrite
= (CVAL(pdata
,0) ? true : false);
6250 len
= IVAL(pdata
,16);
6252 if (len
> (total_data
- 20) || (len
== 0)) {
6253 return NT_STATUS_INVALID_PARAMETER
;
6256 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6257 &pdata
[20], len
, STR_TERMINATE
,
6259 if (!NT_STATUS_IS_OK(status
)) {
6263 DEBUG(10,("smb_file_link_information: got name |%s|\n",
6266 status
= filename_convert(ctx
,
6268 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6273 if (!NT_STATUS_IS_OK(status
)) {
6277 if (fsp
->base_fsp
) {
6278 /* No stream names. */
6279 return NT_STATUS_NOT_SUPPORTED
;
6282 DEBUG(10,("smb_file_link_information: "
6283 "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
6284 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6285 smb_fname_str_dbg(smb_fname_dst
)));
6286 status
= hardlink_internals(ctx
,
6293 TALLOC_FREE(smb_fname_dst
);
6297 /****************************************************************************
6298 Deal with SMB_FILE_RENAME_INFORMATION.
6299 ****************************************************************************/
6301 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
6302 struct smb_request
*req
,
6306 struct smb_filename
*smb_fname_src
)
6311 char *newname
= NULL
;
6312 struct smb_filename
*smb_fname_dst
= NULL
;
6313 bool dest_has_wcard
= False
;
6314 NTSTATUS status
= NT_STATUS_OK
;
6316 TALLOC_CTX
*ctx
= talloc_tos();
6318 if (total_data
< 13) {
6319 return NT_STATUS_INVALID_PARAMETER
;
6322 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6323 root_fid
= IVAL(pdata
,4);
6324 len
= IVAL(pdata
,8);
6326 if (len
> (total_data
- 12) || (len
== 0) || (root_fid
!= 0)) {
6327 return NT_STATUS_INVALID_PARAMETER
;
6330 srvstr_get_path_wcard(ctx
, pdata
, req
->flags2
, &newname
, &pdata
[12],
6333 if (!NT_STATUS_IS_OK(status
)) {
6337 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6340 status
= resolve_dfspath_wcard(ctx
, conn
,
6341 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6344 !conn
->sconn
->using_smb2
,
6347 if (!NT_STATUS_IS_OK(status
)) {
6351 /* Check the new name has no '/' characters. */
6352 if (strchr_m(newname
, '/')) {
6353 return NT_STATUS_NOT_SUPPORTED
;
6356 if (fsp
&& fsp
->base_fsp
) {
6357 /* newname must be a stream name. */
6358 if (newname
[0] != ':') {
6359 return NT_STATUS_NOT_SUPPORTED
;
6362 /* Create an smb_fname to call rename_internals_fsp() with. */
6363 status
= create_synthetic_smb_fname(talloc_tos(),
6364 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6366 if (!NT_STATUS_IS_OK(status
)) {
6371 * Set the original last component, since
6372 * rename_internals_fsp() requires it.
6374 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6376 if (smb_fname_dst
->original_lcomp
== NULL
) {
6377 status
= NT_STATUS_NO_MEMORY
;
6383 * Build up an smb_fname_dst based on the filename passed in.
6384 * We basically just strip off the last component, and put on
6385 * the newname instead.
6387 char *base_name
= NULL
;
6389 /* newname must *not* be a stream name. */
6390 if (newname
[0] == ':') {
6391 return NT_STATUS_NOT_SUPPORTED
;
6395 * Strip off the last component (filename) of the path passed
6398 base_name
= talloc_strdup(ctx
, smb_fname_src
->base_name
);
6400 return NT_STATUS_NO_MEMORY
;
6402 p
= strrchr_m(base_name
, '/');
6406 base_name
= talloc_strdup(ctx
, "");
6408 return NT_STATUS_NO_MEMORY
;
6411 /* Append the new name. */
6412 base_name
= talloc_asprintf_append(base_name
,
6416 return NT_STATUS_NO_MEMORY
;
6419 status
= unix_convert(ctx
, conn
, base_name
, &smb_fname_dst
,
6422 UCF_ALWAYS_ALLOW_WCARD_LCOMP
:
6425 /* If an error we expect this to be
6426 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6428 if (!NT_STATUS_IS_OK(status
)) {
6429 if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND
,
6433 /* Create an smb_fname to call rename_internals_fsp() */
6434 status
= create_synthetic_smb_fname(ctx
,
6438 if (!NT_STATUS_IS_OK(status
)) {
6445 DEBUG(10,("smb_file_rename_information: "
6446 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6447 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6448 smb_fname_str_dbg(smb_fname_dst
)));
6449 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
, 0,
6452 DEBUG(10,("smb_file_rename_information: "
6453 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6454 smb_fname_str_dbg(smb_fname_src
),
6455 smb_fname_str_dbg(smb_fname_dst
)));
6456 status
= rename_internals(ctx
, conn
, req
, smb_fname_src
,
6457 smb_fname_dst
, 0, overwrite
, false,
6459 FILE_WRITE_ATTRIBUTES
);
6462 TALLOC_FREE(smb_fname_dst
);
6466 /****************************************************************************
6467 Deal with SMB_SET_POSIX_ACL.
6468 ****************************************************************************/
6470 #if defined(HAVE_POSIX_ACLS)
6471 static NTSTATUS
smb_set_posix_acl(connection_struct
*conn
,
6475 const struct smb_filename
*smb_fname
)
6477 uint16 posix_acl_version
;
6478 uint16 num_file_acls
;
6479 uint16 num_def_acls
;
6480 bool valid_file_acls
= True
;
6481 bool valid_def_acls
= True
;
6483 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
6484 return NT_STATUS_INVALID_PARAMETER
;
6486 posix_acl_version
= SVAL(pdata
,0);
6487 num_file_acls
= SVAL(pdata
,2);
6488 num_def_acls
= SVAL(pdata
,4);
6490 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6491 valid_file_acls
= False
;
6495 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6496 valid_def_acls
= False
;
6500 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
6501 return NT_STATUS_INVALID_PARAMETER
;
6504 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
6505 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
6506 return NT_STATUS_INVALID_PARAMETER
;
6509 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6510 smb_fname
? smb_fname_str_dbg(smb_fname
) : fsp_str_dbg(fsp
),
6511 (unsigned int)num_file_acls
,
6512 (unsigned int)num_def_acls
));
6514 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
,
6515 smb_fname
->base_name
, num_file_acls
,
6516 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
6517 return map_nt_error_from_unix(errno
);
6520 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
,
6521 smb_fname
->base_name
, &smb_fname
->st
, num_def_acls
,
6522 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
6523 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
6524 return map_nt_error_from_unix(errno
);
6526 return NT_STATUS_OK
;
6530 /****************************************************************************
6531 Deal with SMB_SET_POSIX_LOCK.
6532 ****************************************************************************/
6534 static NTSTATUS
smb_set_posix_lock(connection_struct
*conn
,
6535 struct smb_request
*req
,
6543 bool blocking_lock
= False
;
6544 enum brl_type lock_type
;
6546 NTSTATUS status
= NT_STATUS_OK
;
6548 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
6549 return NT_STATUS_INVALID_HANDLE
;
6552 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
6553 return NT_STATUS_INVALID_PARAMETER
;
6556 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
6557 case POSIX_LOCK_TYPE_READ
:
6558 lock_type
= READ_LOCK
;
6560 case POSIX_LOCK_TYPE_WRITE
:
6561 /* Return the right POSIX-mappable error code for files opened read-only. */
6562 if (!fsp
->can_write
) {
6563 return NT_STATUS_INVALID_HANDLE
;
6565 lock_type
= WRITE_LOCK
;
6567 case POSIX_LOCK_TYPE_UNLOCK
:
6568 lock_type
= UNLOCK_LOCK
;
6571 return NT_STATUS_INVALID_PARAMETER
;
6574 if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_NOWAIT
) {
6575 blocking_lock
= False
;
6576 } else if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_WAIT
) {
6577 blocking_lock
= True
;
6579 return NT_STATUS_INVALID_PARAMETER
;
6582 if (!lp_blocking_locks(SNUM(conn
))) {
6583 blocking_lock
= False
;
6586 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
6587 #if defined(HAVE_LONGLONG)
6588 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
6589 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
6590 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
6591 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
6592 #else /* HAVE_LONGLONG */
6593 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
6594 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
6595 #endif /* HAVE_LONGLONG */
6597 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6598 "smblctx = %llu, count = %.0f, offset = %.0f\n",
6600 (unsigned int)lock_type
,
6601 (unsigned long long)smblctx
,
6605 if (lock_type
== UNLOCK_LOCK
) {
6606 status
= do_unlock(req
->sconn
->msg_ctx
,
6613 uint64_t block_smblctx
;
6615 struct byte_range_lock
*br_lck
= do_lock(req
->sconn
->msg_ctx
,
6627 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
6629 * A blocking lock was requested. Package up
6630 * this smb into a queued request and push it
6631 * onto the blocking lock queue.
6633 if(push_blocking_lock_request(br_lck
,
6636 -1, /* infinite timeout. */
6644 TALLOC_FREE(br_lck
);
6648 TALLOC_FREE(br_lck
);
6654 /****************************************************************************
6655 Deal with SMB_SET_FILE_BASIC_INFO.
6656 ****************************************************************************/
6658 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
6662 const struct smb_filename
*smb_fname
)
6664 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6665 struct smb_file_time ft
;
6667 NTSTATUS status
= NT_STATUS_OK
;
6671 if (total_data
< 36) {
6672 return NT_STATUS_INVALID_PARAMETER
;
6675 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_ATTRIBUTES
);
6676 if (!NT_STATUS_IS_OK(status
)) {
6680 /* Set the attributes */
6681 dosmode
= IVAL(pdata
,32);
6682 status
= smb_set_file_dosmode(conn
, smb_fname
, dosmode
);
6683 if (!NT_STATUS_IS_OK(status
)) {
6688 ft
.create_time
= interpret_long_date(pdata
);
6691 ft
.atime
= interpret_long_date(pdata
+8);
6694 ft
.mtime
= interpret_long_date(pdata
+16);
6697 ft
.ctime
= interpret_long_date(pdata
+24);
6699 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6700 smb_fname_str_dbg(smb_fname
)));
6702 return smb_set_file_time(conn
, fsp
, smb_fname
, &ft
,
6706 /****************************************************************************
6707 Deal with SMB_INFO_STANDARD.
6708 ****************************************************************************/
6710 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
6714 const struct smb_filename
*smb_fname
)
6717 struct smb_file_time ft
;
6721 if (total_data
< 12) {
6722 return NT_STATUS_INVALID_PARAMETER
;
6726 ft
.create_time
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
));
6728 ft
.atime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+4));
6730 ft
.mtime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+8));
6732 DEBUG(10,("smb_set_info_standard: file %s\n",
6733 smb_fname_str_dbg(smb_fname
)));
6735 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_ATTRIBUTES
);
6736 if (!NT_STATUS_IS_OK(status
)) {
6740 return smb_set_file_time(conn
,
6747 /****************************************************************************
6748 Deal with SMB_SET_FILE_ALLOCATION_INFO.
6749 ****************************************************************************/
6751 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
6752 struct smb_request
*req
,
6756 struct smb_filename
*smb_fname
)
6758 uint64_t allocation_size
= 0;
6759 NTSTATUS status
= NT_STATUS_OK
;
6760 files_struct
*new_fsp
= NULL
;
6762 if (!VALID_STAT(smb_fname
->st
)) {
6763 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6766 if (total_data
< 8) {
6767 return NT_STATUS_INVALID_PARAMETER
;
6770 allocation_size
= (uint64_t)IVAL(pdata
,0);
6771 allocation_size
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6772 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6773 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6774 (double)allocation_size
));
6776 if (allocation_size
) {
6777 allocation_size
= smb_roundup(conn
, allocation_size
);
6780 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6781 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname
),
6782 (double)allocation_size
));
6784 if (fsp
&& fsp
->fh
->fd
!= -1) {
6785 /* Open file handle. */
6786 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6787 return NT_STATUS_ACCESS_DENIED
;
6790 /* Only change if needed. */
6791 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6792 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
6793 return map_nt_error_from_unix(errno
);
6796 /* But always update the time. */
6798 * This is equivalent to a write. Ensure it's seen immediately
6799 * if there are no pending writes.
6801 trigger_write_time_update_immediate(fsp
);
6802 return NT_STATUS_OK
;
6805 /* Pathname or stat or directory file. */
6806 status
= SMB_VFS_CREATE_FILE(
6809 0, /* root_dir_fid */
6810 smb_fname
, /* fname */
6811 FILE_WRITE_DATA
, /* access_mask */
6812 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
6814 FILE_OPEN
, /* create_disposition*/
6815 0, /* create_options */
6816 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
6817 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
6818 0, /* allocation_size */
6819 0, /* private_flags */
6822 &new_fsp
, /* result */
6825 if (!NT_STATUS_IS_OK(status
)) {
6826 /* NB. We check for open_was_deferred in the caller. */
6830 /* Only change if needed. */
6831 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6832 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
6833 status
= map_nt_error_from_unix(errno
);
6834 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6839 /* Changing the allocation size should set the last mod time. */
6841 * This is equivalent to a write. Ensure it's seen immediately
6842 * if there are no pending writes.
6844 trigger_write_time_update_immediate(new_fsp
);
6846 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6847 return NT_STATUS_OK
;
6850 /****************************************************************************
6851 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6852 ****************************************************************************/
6854 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
6855 struct smb_request
*req
,
6859 const struct smb_filename
*smb_fname
,
6860 bool fail_after_createfile
)
6864 if (total_data
< 8) {
6865 return NT_STATUS_INVALID_PARAMETER
;
6868 size
= IVAL(pdata
,0);
6869 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
6870 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6871 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6874 return smb_set_file_size(conn
, req
,
6879 fail_after_createfile
);
6882 /****************************************************************************
6883 Allow a UNIX info mknod.
6884 ****************************************************************************/
6886 static NTSTATUS
smb_unix_mknod(connection_struct
*conn
,
6889 const struct smb_filename
*smb_fname
)
6891 uint32 file_type
= IVAL(pdata
,56);
6892 #if defined(HAVE_MAKEDEV)
6893 uint32 dev_major
= IVAL(pdata
,60);
6894 uint32 dev_minor
= IVAL(pdata
,68);
6896 SMB_DEV_T dev
= (SMB_DEV_T
)0;
6897 uint32 raw_unixmode
= IVAL(pdata
,84);
6901 if (total_data
< 100) {
6902 return NT_STATUS_INVALID_PARAMETER
;
6905 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6906 PERM_NEW_FILE
, &unixmode
);
6907 if (!NT_STATUS_IS_OK(status
)) {
6911 #if defined(HAVE_MAKEDEV)
6912 dev
= makedev(dev_major
, dev_minor
);
6915 switch (file_type
) {
6916 #if defined(S_IFIFO)
6917 case UNIX_TYPE_FIFO
:
6918 unixmode
|= S_IFIFO
;
6921 #if defined(S_IFSOCK)
6922 case UNIX_TYPE_SOCKET
:
6923 unixmode
|= S_IFSOCK
;
6926 #if defined(S_IFCHR)
6927 case UNIX_TYPE_CHARDEV
:
6928 unixmode
|= S_IFCHR
;
6931 #if defined(S_IFBLK)
6932 case UNIX_TYPE_BLKDEV
:
6933 unixmode
|= S_IFBLK
;
6937 return NT_STATUS_INVALID_PARAMETER
;
6940 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6941 "%.0f mode 0%o for file %s\n", (double)dev
,
6942 (unsigned int)unixmode
, smb_fname_str_dbg(smb_fname
)));
6944 /* Ok - do the mknod. */
6945 if (SMB_VFS_MKNOD(conn
, smb_fname
->base_name
, unixmode
, dev
) != 0) {
6946 return map_nt_error_from_unix(errno
);
6949 /* If any of the other "set" calls fail we
6950 * don't want to end up with a half-constructed mknod.
6953 if (lp_inherit_perms(SNUM(conn
))) {
6955 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
,
6957 return NT_STATUS_NO_MEMORY
;
6959 inherit_access_posix_acl(conn
, parent
, smb_fname
->base_name
,
6961 TALLOC_FREE(parent
);
6964 return NT_STATUS_OK
;
6967 /****************************************************************************
6968 Deal with SMB_SET_FILE_UNIX_BASIC.
6969 ****************************************************************************/
6971 static NTSTATUS
smb_set_file_unix_basic(connection_struct
*conn
,
6972 struct smb_request
*req
,
6976 const struct smb_filename
*smb_fname
)
6978 struct smb_file_time ft
;
6979 uint32 raw_unixmode
;
6982 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
6983 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
6984 NTSTATUS status
= NT_STATUS_OK
;
6985 bool delete_on_fail
= False
;
6986 enum perm_type ptype
;
6987 files_struct
*all_fsps
= NULL
;
6988 bool modify_mtime
= true;
6990 struct smb_filename
*smb_fname_tmp
= NULL
;
6991 SMB_STRUCT_STAT sbuf
;
6995 if (total_data
< 100) {
6996 return NT_STATUS_INVALID_PARAMETER
;
6999 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
7000 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
7001 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
7002 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
7005 ft
.atime
= interpret_long_date(pdata
+24); /* access_time */
7006 ft
.mtime
= interpret_long_date(pdata
+32); /* modification_time */
7007 set_owner
= (uid_t
)IVAL(pdata
,40);
7008 set_grp
= (gid_t
)IVAL(pdata
,48);
7009 raw_unixmode
= IVAL(pdata
,84);
7011 if (VALID_STAT(smb_fname
->st
)) {
7012 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
7013 ptype
= PERM_EXISTING_DIR
;
7015 ptype
= PERM_EXISTING_FILE
;
7018 ptype
= PERM_NEW_FILE
;
7021 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7023 if (!NT_STATUS_IS_OK(status
)) {
7027 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
7028 "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
7029 smb_fname_str_dbg(smb_fname
), (double)size
,
7030 (unsigned int)set_owner
, (unsigned int)set_grp
,
7031 (int)raw_unixmode
));
7033 sbuf
= smb_fname
->st
;
7035 if (!VALID_STAT(sbuf
)) {
7037 * The only valid use of this is to create character and block
7038 * devices, and named pipes. This is deprecated (IMHO) and
7039 * a new info level should be used for mknod. JRA.
7042 status
= smb_unix_mknod(conn
,
7046 if (!NT_STATUS_IS_OK(status
)) {
7050 status
= copy_smb_filename(talloc_tos(), smb_fname
,
7052 if (!NT_STATUS_IS_OK(status
)) {
7056 if (SMB_VFS_STAT(conn
, smb_fname_tmp
) != 0) {
7057 status
= map_nt_error_from_unix(errno
);
7058 TALLOC_FREE(smb_fname_tmp
);
7059 SMB_VFS_UNLINK(conn
, smb_fname
);
7063 sbuf
= smb_fname_tmp
->st
;
7064 smb_fname
= smb_fname_tmp
;
7066 /* Ensure we don't try and change anything else. */
7067 raw_unixmode
= SMB_MODE_NO_CHANGE
;
7068 size
= get_file_size_stat(&sbuf
);
7069 ft
.atime
= sbuf
.st_ex_atime
;
7070 ft
.mtime
= sbuf
.st_ex_mtime
;
7072 * We continue here as we might want to change the
7075 delete_on_fail
= True
;
7079 /* Horrible backwards compatibility hack as an old server bug
7080 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
7084 size
= get_file_size_stat(&sbuf
);
7089 * Deal with the UNIX specific mode set.
7092 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
7093 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7094 "setting mode 0%o for file %s\n",
7095 (unsigned int)unixmode
,
7096 smb_fname_str_dbg(smb_fname
)));
7097 if (SMB_VFS_CHMOD(conn
, smb_fname
->base_name
, unixmode
) != 0) {
7098 return map_nt_error_from_unix(errno
);
7103 * Deal with the UNIX specific uid set.
7106 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) &&
7107 (sbuf
.st_ex_uid
!= set_owner
)) {
7110 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7111 "changing owner %u for path %s\n",
7112 (unsigned int)set_owner
,
7113 smb_fname_str_dbg(smb_fname
)));
7115 if (S_ISLNK(sbuf
.st_ex_mode
)) {
7116 ret
= SMB_VFS_LCHOWN(conn
, smb_fname
->base_name
,
7117 set_owner
, (gid_t
)-1);
7119 ret
= SMB_VFS_CHOWN(conn
, smb_fname
->base_name
,
7120 set_owner
, (gid_t
)-1);
7124 status
= map_nt_error_from_unix(errno
);
7125 if (delete_on_fail
) {
7126 SMB_VFS_UNLINK(conn
, smb_fname
);
7133 * Deal with the UNIX specific gid set.
7136 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) &&
7137 (sbuf
.st_ex_gid
!= set_grp
)) {
7138 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7139 "changing group %u for file %s\n",
7140 (unsigned int)set_owner
,
7141 smb_fname_str_dbg(smb_fname
)));
7142 if (SMB_VFS_CHOWN(conn
, smb_fname
->base_name
, (uid_t
)-1,
7144 status
= map_nt_error_from_unix(errno
);
7145 if (delete_on_fail
) {
7146 SMB_VFS_UNLINK(conn
, smb_fname
);
7152 /* Deal with any size changes. */
7154 status
= smb_set_file_size(conn
, req
,
7160 if (!NT_STATUS_IS_OK(status
)) {
7164 /* Deal with any time changes. */
7165 if (null_timespec(ft
.mtime
) && null_timespec(ft
.atime
)) {
7166 /* No change, don't cancel anything. */
7170 id
= vfs_file_id_from_sbuf(conn
, &sbuf
);
7171 for(all_fsps
= file_find_di_first(conn
->sconn
, id
); all_fsps
;
7172 all_fsps
= file_find_di_next(all_fsps
)) {
7174 * We're setting the time explicitly for UNIX.
7175 * Cancel any pending changes over all handles.
7177 all_fsps
->update_write_time_on_close
= false;
7178 TALLOC_FREE(all_fsps
->update_write_time_event
);
7182 * Override the "setting_write_time"
7183 * parameter here as it almost does what
7184 * we need. Just remember if we modified
7185 * mtime and send the notify ourselves.
7187 if (null_timespec(ft
.mtime
)) {
7188 modify_mtime
= false;
7191 status
= smb_set_file_time(conn
,
7197 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
7198 FILE_NOTIFY_CHANGE_LAST_WRITE
, smb_fname
->base_name
);
7203 /****************************************************************************
7204 Deal with SMB_SET_FILE_UNIX_INFO2.
7205 ****************************************************************************/
7207 static NTSTATUS
smb_set_file_unix_info2(connection_struct
*conn
,
7208 struct smb_request
*req
,
7212 const struct smb_filename
*smb_fname
)
7218 if (total_data
< 116) {
7219 return NT_STATUS_INVALID_PARAMETER
;
7222 /* Start by setting all the fields that are common between UNIX_BASIC
7225 status
= smb_set_file_unix_basic(conn
, req
, pdata
, total_data
,
7227 if (!NT_STATUS_IS_OK(status
)) {
7231 smb_fflags
= IVAL(pdata
, 108);
7232 smb_fmask
= IVAL(pdata
, 112);
7234 /* NB: We should only attempt to alter the file flags if the client
7235 * sends a non-zero mask.
7237 if (smb_fmask
!= 0) {
7238 int stat_fflags
= 0;
7240 if (!map_info2_flags_to_sbuf(&smb_fname
->st
, smb_fflags
,
7241 smb_fmask
, &stat_fflags
)) {
7242 /* Client asked to alter a flag we don't understand. */
7243 return NT_STATUS_INVALID_PARAMETER
;
7246 if (fsp
&& fsp
->fh
->fd
!= -1) {
7247 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
7248 return NT_STATUS_NOT_SUPPORTED
;
7250 if (SMB_VFS_CHFLAGS(conn
, smb_fname
->base_name
,
7251 stat_fflags
) != 0) {
7252 return map_nt_error_from_unix(errno
);
7257 /* XXX: need to add support for changing the create_time here. You
7258 * can do this for paths on Darwin with setattrlist(2). The right way
7259 * to hook this up is probably by extending the VFS utimes interface.
7262 return NT_STATUS_OK
;
7265 /****************************************************************************
7266 Create a directory with POSIX semantics.
7267 ****************************************************************************/
7269 static NTSTATUS
smb_posix_mkdir(connection_struct
*conn
,
7270 struct smb_request
*req
,
7273 struct smb_filename
*smb_fname
,
7274 int *pdata_return_size
)
7276 NTSTATUS status
= NT_STATUS_OK
;
7277 uint32 raw_unixmode
= 0;
7278 uint32 mod_unixmode
= 0;
7279 mode_t unixmode
= (mode_t
)0;
7280 files_struct
*fsp
= NULL
;
7281 uint16 info_level_return
= 0;
7283 char *pdata
= *ppdata
;
7285 if (total_data
< 18) {
7286 return NT_STATUS_INVALID_PARAMETER
;
7289 raw_unixmode
= IVAL(pdata
,8);
7290 /* Next 4 bytes are not yet defined. */
7292 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7293 PERM_NEW_DIR
, &unixmode
);
7294 if (!NT_STATUS_IS_OK(status
)) {
7298 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7300 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7301 smb_fname_str_dbg(smb_fname
), (unsigned int)unixmode
));
7303 status
= SMB_VFS_CREATE_FILE(
7306 0, /* root_dir_fid */
7307 smb_fname
, /* fname */
7308 FILE_READ_ATTRIBUTES
, /* access_mask */
7309 FILE_SHARE_NONE
, /* share_access */
7310 FILE_CREATE
, /* create_disposition*/
7311 FILE_DIRECTORY_FILE
, /* create_options */
7312 mod_unixmode
, /* file_attributes */
7313 0, /* oplock_request */
7314 0, /* allocation_size */
7315 0, /* private_flags */
7321 if (NT_STATUS_IS_OK(status
)) {
7322 close_file(req
, fsp
, NORMAL_CLOSE
);
7325 info_level_return
= SVAL(pdata
,16);
7327 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7328 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7329 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7330 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7332 *pdata_return_size
= 12;
7335 /* Realloc the data size */
7336 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7337 if (*ppdata
== NULL
) {
7338 *pdata_return_size
= 0;
7339 return NT_STATUS_NO_MEMORY
;
7343 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7344 SSVAL(pdata
,2,0); /* No fnum. */
7345 SIVAL(pdata
,4,info
); /* Was directory created. */
7347 switch (info_level_return
) {
7348 case SMB_QUERY_FILE_UNIX_BASIC
:
7349 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7350 SSVAL(pdata
,10,0); /* Padding. */
7351 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7354 case SMB_QUERY_FILE_UNIX_INFO2
:
7355 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7356 SSVAL(pdata
,10,0); /* Padding. */
7357 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7361 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7362 SSVAL(pdata
,10,0); /* Padding. */
7369 /****************************************************************************
7370 Open/Create a file with POSIX semantics.
7371 ****************************************************************************/
7373 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7374 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7376 static NTSTATUS
smb_posix_open(connection_struct
*conn
,
7377 struct smb_request
*req
,
7380 struct smb_filename
*smb_fname
,
7381 int *pdata_return_size
)
7383 bool extended_oplock_granted
= False
;
7384 char *pdata
= *ppdata
;
7386 uint32 wire_open_mode
= 0;
7387 uint32 raw_unixmode
= 0;
7388 uint32 mod_unixmode
= 0;
7389 uint32 create_disp
= 0;
7390 uint32 access_mask
= 0;
7391 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
7392 NTSTATUS status
= NT_STATUS_OK
;
7393 mode_t unixmode
= (mode_t
)0;
7394 files_struct
*fsp
= NULL
;
7395 int oplock_request
= 0;
7397 uint16 info_level_return
= 0;
7399 if (total_data
< 18) {
7400 return NT_STATUS_INVALID_PARAMETER
;
7403 flags
= IVAL(pdata
,0);
7404 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
7405 if (oplock_request
) {
7406 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
7409 wire_open_mode
= IVAL(pdata
,4);
7411 if (wire_open_mode
== (SMB_O_CREAT
|SMB_O_DIRECTORY
)) {
7412 return smb_posix_mkdir(conn
, req
,
7419 switch (wire_open_mode
& SMB_ACCMODE
) {
7421 access_mask
= SMB_O_RDONLY_MAPPING
;
7424 access_mask
= SMB_O_WRONLY_MAPPING
;
7427 access_mask
= (SMB_O_RDONLY_MAPPING
|
7428 SMB_O_WRONLY_MAPPING
);
7431 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7432 (unsigned int)wire_open_mode
));
7433 return NT_STATUS_INVALID_PARAMETER
;
7436 wire_open_mode
&= ~SMB_ACCMODE
;
7438 /* First take care of O_CREAT|O_EXCL interactions. */
7439 switch (wire_open_mode
& (SMB_O_CREAT
| SMB_O_EXCL
)) {
7440 case (SMB_O_CREAT
| SMB_O_EXCL
):
7441 /* File exists fail. File not exist create. */
7442 create_disp
= FILE_CREATE
;
7445 /* File exists open. File not exist create. */
7446 create_disp
= FILE_OPEN_IF
;
7449 /* O_EXCL on its own without O_CREAT is undefined.
7450 We deliberately ignore it as some versions of
7451 Linux CIFSFS can send a bare O_EXCL on the
7452 wire which other filesystems in the kernel
7453 ignore. See bug 9519 for details. */
7458 /* File exists open. File not exist fail. */
7459 create_disp
= FILE_OPEN
;
7462 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7463 (unsigned int)wire_open_mode
));
7464 return NT_STATUS_INVALID_PARAMETER
;
7467 /* Next factor in the effects of O_TRUNC. */
7468 wire_open_mode
&= ~(SMB_O_CREAT
| SMB_O_EXCL
);
7470 if (wire_open_mode
& SMB_O_TRUNC
) {
7471 switch (create_disp
) {
7473 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7474 /* Leave create_disp alone as
7475 (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7477 /* File exists fail. File not exist create. */
7480 /* SMB_O_CREAT | SMB_O_TRUNC */
7481 /* File exists overwrite. File not exist create. */
7482 create_disp
= FILE_OVERWRITE_IF
;
7486 /* File exists overwrite. File not exist fail. */
7487 create_disp
= FILE_OVERWRITE
;
7490 /* Cannot get here. */
7491 smb_panic("smb_posix_open: logic error");
7492 return NT_STATUS_INVALID_PARAMETER
;
7496 raw_unixmode
= IVAL(pdata
,8);
7497 /* Next 4 bytes are not yet defined. */
7499 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7500 (VALID_STAT(smb_fname
->st
) ?
7501 PERM_EXISTING_FILE
: PERM_NEW_FILE
),
7504 if (!NT_STATUS_IS_OK(status
)) {
7508 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7510 if (wire_open_mode
& SMB_O_SYNC
) {
7511 create_options
|= FILE_WRITE_THROUGH
;
7513 if (wire_open_mode
& SMB_O_APPEND
) {
7514 access_mask
|= FILE_APPEND_DATA
;
7516 if (wire_open_mode
& SMB_O_DIRECT
) {
7517 mod_unixmode
|= FILE_FLAG_NO_BUFFERING
;
7520 if ((wire_open_mode
& SMB_O_DIRECTORY
) ||
7521 VALID_STAT_OF_DIR(smb_fname
->st
)) {
7522 if (access_mask
!= SMB_O_RDONLY_MAPPING
) {
7523 return NT_STATUS_FILE_IS_A_DIRECTORY
;
7525 create_options
&= ~FILE_NON_DIRECTORY_FILE
;
7526 create_options
|= FILE_DIRECTORY_FILE
;
7529 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7530 smb_fname_str_dbg(smb_fname
),
7531 (unsigned int)wire_open_mode
,
7532 (unsigned int)unixmode
));
7534 status
= SMB_VFS_CREATE_FILE(
7537 0, /* root_dir_fid */
7538 smb_fname
, /* fname */
7539 access_mask
, /* access_mask */
7540 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7542 create_disp
, /* create_disposition*/
7543 create_options
, /* create_options */
7544 mod_unixmode
, /* file_attributes */
7545 oplock_request
, /* oplock_request */
7546 0, /* allocation_size */
7547 0, /* private_flags */
7553 if (!NT_STATUS_IS_OK(status
)) {
7557 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
7558 extended_oplock_granted
= True
;
7561 if(oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
7562 extended_oplock_granted
= True
;
7565 info_level_return
= SVAL(pdata
,16);
7567 /* Allocate the correct return size. */
7569 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7570 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7571 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7572 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7574 *pdata_return_size
= 12;
7577 /* Realloc the data size */
7578 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7579 if (*ppdata
== NULL
) {
7580 close_file(req
, fsp
, ERROR_CLOSE
);
7581 *pdata_return_size
= 0;
7582 return NT_STATUS_NO_MEMORY
;
7586 if (extended_oplock_granted
) {
7587 if (flags
& REQUEST_BATCH_OPLOCK
) {
7588 SSVAL(pdata
,0, BATCH_OPLOCK_RETURN
);
7590 SSVAL(pdata
,0, EXCLUSIVE_OPLOCK_RETURN
);
7592 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
7593 SSVAL(pdata
,0, LEVEL_II_OPLOCK_RETURN
);
7595 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7598 SSVAL(pdata
,2,fsp
->fnum
);
7599 SIVAL(pdata
,4,info
); /* Was file created etc. */
7601 switch (info_level_return
) {
7602 case SMB_QUERY_FILE_UNIX_BASIC
:
7603 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7604 SSVAL(pdata
,10,0); /* padding. */
7605 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7608 case SMB_QUERY_FILE_UNIX_INFO2
:
7609 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7610 SSVAL(pdata
,10,0); /* padding. */
7611 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7615 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7616 SSVAL(pdata
,10,0); /* padding. */
7619 return NT_STATUS_OK
;
7622 /****************************************************************************
7623 Delete a file with POSIX semantics.
7624 ****************************************************************************/
7626 static NTSTATUS
smb_posix_unlink(connection_struct
*conn
,
7627 struct smb_request
*req
,
7630 struct smb_filename
*smb_fname
)
7632 NTSTATUS status
= NT_STATUS_OK
;
7633 files_struct
*fsp
= NULL
;
7637 int create_options
= 0;
7639 struct share_mode_lock
*lck
= NULL
;
7641 if (total_data
< 2) {
7642 return NT_STATUS_INVALID_PARAMETER
;
7645 flags
= SVAL(pdata
,0);
7647 if (!VALID_STAT(smb_fname
->st
)) {
7648 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
7651 if ((flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) &&
7652 !VALID_STAT_OF_DIR(smb_fname
->st
)) {
7653 return NT_STATUS_NOT_A_DIRECTORY
;
7656 DEBUG(10,("smb_posix_unlink: %s %s\n",
7657 (flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) ? "directory" : "file",
7658 smb_fname_str_dbg(smb_fname
)));
7660 if (VALID_STAT_OF_DIR(smb_fname
->st
)) {
7661 create_options
|= FILE_DIRECTORY_FILE
;
7664 status
= SMB_VFS_CREATE_FILE(
7667 0, /* root_dir_fid */
7668 smb_fname
, /* fname */
7669 DELETE_ACCESS
, /* access_mask */
7670 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7672 FILE_OPEN
, /* create_disposition*/
7673 create_options
, /* create_options */
7674 FILE_FLAG_POSIX_SEMANTICS
|0777, /* file_attributes */
7675 0, /* oplock_request */
7676 0, /* allocation_size */
7677 0, /* private_flags */
7683 if (!NT_STATUS_IS_OK(status
)) {
7688 * Don't lie to client. If we can't really delete due to
7689 * non-POSIX opens return SHARING_VIOLATION.
7692 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
7694 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7695 "lock for file %s\n", fsp_str_dbg(fsp
)));
7696 close_file(req
, fsp
, NORMAL_CLOSE
);
7697 return NT_STATUS_INVALID_PARAMETER
;
7701 * See if others still have the file open. If this is the case, then
7702 * don't delete. If all opens are POSIX delete we can set the delete
7703 * on close disposition.
7705 for (i
=0; i
<lck
->data
->num_share_modes
; i
++) {
7706 struct share_mode_entry
*e
= &lck
->data
->share_modes
[i
];
7707 if (is_valid_share_mode_entry(e
)) {
7708 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
7711 if (share_mode_stale_pid(lck
->data
, i
)) {
7714 /* Fail with sharing violation. */
7716 close_file(req
, fsp
, NORMAL_CLOSE
);
7717 return NT_STATUS_SHARING_VIOLATION
;
7722 * Set the delete on close.
7724 status
= smb_set_file_disposition_info(conn
,
7732 if (!NT_STATUS_IS_OK(status
)) {
7733 close_file(req
, fsp
, NORMAL_CLOSE
);
7736 return close_file(req
, fsp
, NORMAL_CLOSE
);
7739 NTSTATUS
smbd_do_setfilepathinfo(connection_struct
*conn
,
7740 struct smb_request
*req
,
7741 TALLOC_CTX
*mem_ctx
,
7742 uint16_t info_level
,
7744 struct smb_filename
*smb_fname
,
7745 char **ppdata
, int total_data
,
7748 char *pdata
= *ppdata
;
7749 NTSTATUS status
= NT_STATUS_OK
;
7750 int data_return_size
= 0;
7754 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
7755 return NT_STATUS_INVALID_LEVEL
;
7758 if (!CAN_WRITE(conn
)) {
7759 /* Allow POSIX opens. The open path will deny
7760 * any non-readonly opens. */
7761 if (info_level
!= SMB_POSIX_PATH_OPEN
) {
7762 return NT_STATUS_DOS(ERRSRV
, ERRaccess
);
7766 DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
7767 "totdata=%d\n", smb_fname_str_dbg(smb_fname
),
7769 info_level
, total_data
));
7771 switch (info_level
) {
7773 case SMB_INFO_STANDARD
:
7775 status
= smb_set_info_standard(conn
,
7783 case SMB_INFO_SET_EA
:
7785 status
= smb_info_set_ea(conn
,
7793 case SMB_SET_FILE_BASIC_INFO
:
7794 case SMB_FILE_BASIC_INFORMATION
:
7796 status
= smb_set_file_basic_info(conn
,
7804 case SMB_FILE_ALLOCATION_INFORMATION
:
7805 case SMB_SET_FILE_ALLOCATION_INFO
:
7807 status
= smb_set_file_allocation_info(conn
, req
,
7815 case SMB_FILE_END_OF_FILE_INFORMATION
:
7816 case SMB_SET_FILE_END_OF_FILE_INFO
:
7819 * XP/Win7 both fail after the createfile with
7820 * SMB_SET_FILE_END_OF_FILE_INFO but not
7821 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7822 * The level is known here, so pass it down
7826 (info_level
== SMB_SET_FILE_END_OF_FILE_INFO
);
7828 status
= smb_set_file_end_of_file_info(conn
, req
,
7837 case SMB_FILE_DISPOSITION_INFORMATION
:
7838 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
7841 /* JRA - We used to just ignore this on a path ?
7842 * Shouldn't this be invalid level on a pathname
7845 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
7846 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
7849 status
= smb_set_file_disposition_info(conn
,
7857 case SMB_FILE_POSITION_INFORMATION
:
7859 status
= smb_file_position_information(conn
,
7866 case SMB_FILE_FULL_EA_INFORMATION
:
7868 status
= smb_set_file_full_ea_info(conn
,
7875 /* From tridge Samba4 :
7876 * MODE_INFORMATION in setfileinfo (I have no
7877 * idea what "mode information" on a file is - it takes a value of 0,
7878 * 2, 4 or 6. What could it be?).
7881 case SMB_FILE_MODE_INFORMATION
:
7883 status
= smb_file_mode_information(conn
,
7890 * CIFS UNIX extensions.
7893 case SMB_SET_FILE_UNIX_BASIC
:
7895 status
= smb_set_file_unix_basic(conn
, req
,
7903 case SMB_SET_FILE_UNIX_INFO2
:
7905 status
= smb_set_file_unix_info2(conn
, req
,
7913 case SMB_SET_FILE_UNIX_LINK
:
7916 /* We must have a pathname for this. */
7917 return NT_STATUS_INVALID_LEVEL
;
7919 status
= smb_set_file_unix_link(conn
, req
, pdata
,
7920 total_data
, smb_fname
);
7924 case SMB_SET_FILE_UNIX_HLINK
:
7927 /* We must have a pathname for this. */
7928 return NT_STATUS_INVALID_LEVEL
;
7930 status
= smb_set_file_unix_hlink(conn
, req
,
7936 case SMB_FILE_RENAME_INFORMATION
:
7938 status
= smb_file_rename_information(conn
, req
,
7944 case SMB2_FILE_RENAME_INFORMATION_INTERNAL
:
7946 /* SMB2 rename information. */
7947 status
= smb2_file_rename_information(conn
, req
,
7953 case SMB_FILE_LINK_INFORMATION
:
7955 status
= smb_file_link_information(conn
, req
,
7961 #if defined(HAVE_POSIX_ACLS)
7962 case SMB_SET_POSIX_ACL
:
7964 status
= smb_set_posix_acl(conn
,
7973 case SMB_SET_POSIX_LOCK
:
7976 return NT_STATUS_INVALID_LEVEL
;
7978 status
= smb_set_posix_lock(conn
, req
,
7979 pdata
, total_data
, fsp
);
7983 case SMB_POSIX_PATH_OPEN
:
7986 /* We must have a pathname for this. */
7987 return NT_STATUS_INVALID_LEVEL
;
7990 status
= smb_posix_open(conn
, req
,
7998 case SMB_POSIX_PATH_UNLINK
:
8001 /* We must have a pathname for this. */
8002 return NT_STATUS_INVALID_LEVEL
;
8005 status
= smb_posix_unlink(conn
, req
,
8013 return NT_STATUS_INVALID_LEVEL
;
8016 if (!NT_STATUS_IS_OK(status
)) {
8020 *ret_data_size
= data_return_size
;
8021 return NT_STATUS_OK
;
8024 /****************************************************************************
8025 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
8026 ****************************************************************************/
8028 static void call_trans2setfilepathinfo(connection_struct
*conn
,
8029 struct smb_request
*req
,
8030 unsigned int tran_call
,
8031 char **pparams
, int total_params
,
8032 char **ppdata
, int total_data
,
8033 unsigned int max_data_bytes
)
8035 char *params
= *pparams
;
8036 char *pdata
= *ppdata
;
8038 struct smb_filename
*smb_fname
= NULL
;
8039 files_struct
*fsp
= NULL
;
8040 NTSTATUS status
= NT_STATUS_OK
;
8041 int data_return_size
= 0;
8044 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8048 if (tran_call
== TRANSACT2_SETFILEINFO
) {
8049 if (total_params
< 4) {
8050 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8054 fsp
= file_fsp(req
, SVAL(params
,0));
8055 /* Basic check for non-null fsp. */
8056 if (!check_fsp_open(conn
, req
, fsp
)) {
8059 info_level
= SVAL(params
,2);
8061 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
8063 if (!NT_STATUS_IS_OK(status
)) {
8064 reply_nterror(req
, status
);
8068 if(fsp
->fh
->fd
== -1) {
8070 * This is actually a SETFILEINFO on a directory
8071 * handle (returned from an NT SMB). NT5.0 seems
8072 * to do this call. JRA.
8074 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8075 /* Always do lstat for UNIX calls. */
8076 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
8077 DEBUG(3,("call_trans2setfilepathinfo: "
8078 "SMB_VFS_LSTAT of %s failed "
8080 smb_fname_str_dbg(smb_fname
),
8082 reply_nterror(req
, map_nt_error_from_unix(errno
));
8086 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
8087 DEBUG(3,("call_trans2setfilepathinfo: "
8088 "fileinfo of %s failed (%s)\n",
8089 smb_fname_str_dbg(smb_fname
),
8091 reply_nterror(req
, map_nt_error_from_unix(errno
));
8095 } else if (fsp
->print_file
) {
8097 * Doing a DELETE_ON_CLOSE should cancel a print job.
8099 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
8100 fsp
->fh
->private_options
|= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE
;
8102 DEBUG(3,("call_trans2setfilepathinfo: "
8103 "Cancelling print job (%s)\n",
8107 send_trans2_replies(conn
, req
, params
, 2,
8113 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
8118 * Original code - this is an open file.
8120 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
8121 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8122 "of %s failed (%s)\n", fsp_fnum_dbg(fsp
),
8124 reply_nterror(req
, map_nt_error_from_unix(errno
));
8130 uint32_t ucf_flags
= 0;
8133 if (total_params
< 7) {
8134 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8138 info_level
= SVAL(params
,0);
8139 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
8140 total_params
- 6, STR_TERMINATE
,
8142 if (!NT_STATUS_IS_OK(status
)) {
8143 reply_nterror(req
, status
);
8147 if (info_level
== SMB_SET_FILE_UNIX_BASIC
||
8148 info_level
== SMB_SET_FILE_UNIX_INFO2
||
8149 info_level
== SMB_FILE_RENAME_INFORMATION
||
8150 info_level
== SMB_POSIX_PATH_UNLINK
) {
8151 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
8154 status
= filename_convert(req
, conn
,
8155 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8160 if (!NT_STATUS_IS_OK(status
)) {
8161 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8162 reply_botherror(req
,
8163 NT_STATUS_PATH_NOT_COVERED
,
8164 ERRSRV
, ERRbadpath
);
8167 reply_nterror(req
, status
);
8171 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8173 * For CIFS UNIX extensions the target name may not exist.
8176 /* Always do lstat for UNIX calls. */
8177 SMB_VFS_LSTAT(conn
, smb_fname
);
8179 } else if (!VALID_STAT(smb_fname
->st
) &&
8180 SMB_VFS_STAT(conn
, smb_fname
)) {
8181 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8183 smb_fname_str_dbg(smb_fname
),
8185 reply_nterror(req
, map_nt_error_from_unix(errno
));
8190 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
8191 "totdata=%d\n", tran_call
, smb_fname_str_dbg(smb_fname
),
8193 info_level
,total_data
));
8195 /* Realloc the parameter size */
8196 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8197 if (*pparams
== NULL
) {
8198 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8205 status
= smbd_do_setfilepathinfo(conn
, req
, req
,
8211 if (!NT_STATUS_IS_OK(status
)) {
8212 if (open_was_deferred(req
->sconn
, req
->mid
)) {
8213 /* We have re-scheduled this call. */
8216 if (blocking_lock_was_deferred_smb1(req
->sconn
, req
->mid
)) {
8217 /* We have re-scheduled this call. */
8220 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8221 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
8222 ERRSRV
, ERRbadpath
);
8225 if (info_level
== SMB_POSIX_PATH_OPEN
) {
8226 reply_openerror(req
, status
);
8230 reply_nterror(req
, status
);
8234 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, data_return_size
,
8240 /****************************************************************************
8241 Reply to a TRANS2_MKDIR (make directory with extended attributes).
8242 ****************************************************************************/
8244 static void call_trans2mkdir(connection_struct
*conn
, struct smb_request
*req
,
8245 char **pparams
, int total_params
,
8246 char **ppdata
, int total_data
,
8247 unsigned int max_data_bytes
)
8249 struct smb_filename
*smb_dname
= NULL
;
8250 char *params
= *pparams
;
8251 char *pdata
= *ppdata
;
8252 char *directory
= NULL
;
8253 NTSTATUS status
= NT_STATUS_OK
;
8254 struct ea_list
*ea_list
= NULL
;
8255 TALLOC_CTX
*ctx
= talloc_tos();
8257 if (!CAN_WRITE(conn
)) {
8258 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8262 if (total_params
< 5) {
8263 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8267 srvstr_get_path(ctx
, params
, req
->flags2
, &directory
, ¶ms
[4],
8268 total_params
- 4, STR_TERMINATE
,
8270 if (!NT_STATUS_IS_OK(status
)) {
8271 reply_nterror(req
, status
);
8275 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
8277 status
= filename_convert(ctx
,
8279 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8285 if (!NT_STATUS_IS_OK(status
)) {
8286 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8287 reply_botherror(req
,
8288 NT_STATUS_PATH_NOT_COVERED
,
8289 ERRSRV
, ERRbadpath
);
8292 reply_nterror(req
, status
);
8297 * OS/2 workplace shell seems to send SET_EA requests of "null"
8298 * length (4 bytes containing IVAL 4).
8299 * They seem to have no effect. Bug #3212. JRA.
8302 if (total_data
&& (total_data
!= 4)) {
8303 /* Any data in this call is an EA list. */
8304 if (total_data
< 10) {
8305 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8309 if (IVAL(pdata
,0) > total_data
) {
8310 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8311 IVAL(pdata
,0), (unsigned int)total_data
));
8312 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8316 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
8319 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8323 if (!lp_ea_support(SNUM(conn
))) {
8324 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
8328 /* If total_data == 4 Windows doesn't care what values
8329 * are placed in that field, it just ignores them.
8330 * The System i QNTC IBM SMB client puts bad values here,
8331 * so ignore them. */
8333 status
= create_directory(conn
, req
, smb_dname
);
8335 if (!NT_STATUS_IS_OK(status
)) {
8336 reply_nterror(req
, status
);
8340 /* Try and set any given EA. */
8342 status
= set_ea(conn
, NULL
, smb_dname
, ea_list
);
8343 if (!NT_STATUS_IS_OK(status
)) {
8344 reply_nterror(req
, status
);
8349 /* Realloc the parameter and data sizes */
8350 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8351 if(*pparams
== NULL
) {
8352 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8359 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, 0, max_data_bytes
);
8362 TALLOC_FREE(smb_dname
);
8366 /****************************************************************************
8367 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8368 We don't actually do this - we just send a null response.
8369 ****************************************************************************/
8371 static void call_trans2findnotifyfirst(connection_struct
*conn
,
8372 struct smb_request
*req
,
8373 char **pparams
, int total_params
,
8374 char **ppdata
, int total_data
,
8375 unsigned int max_data_bytes
)
8377 char *params
= *pparams
;
8380 if (total_params
< 6) {
8381 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8385 info_level
= SVAL(params
,4);
8386 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
8388 switch (info_level
) {
8393 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
8397 /* Realloc the parameter and data sizes */
8398 *pparams
= (char *)SMB_REALLOC(*pparams
,6);
8399 if (*pparams
== NULL
) {
8400 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8405 SSVAL(params
,0,fnf_handle
);
8406 SSVAL(params
,2,0); /* No changes */
8407 SSVAL(params
,4,0); /* No EA errors */
8414 send_trans2_replies(conn
, req
, params
, 6, *ppdata
, 0, max_data_bytes
);
8419 /****************************************************************************
8420 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
8421 changes). Currently this does nothing.
8422 ****************************************************************************/
8424 static void call_trans2findnotifynext(connection_struct
*conn
,
8425 struct smb_request
*req
,
8426 char **pparams
, int total_params
,
8427 char **ppdata
, int total_data
,
8428 unsigned int max_data_bytes
)
8430 char *params
= *pparams
;
8432 DEBUG(3,("call_trans2findnotifynext\n"));
8434 /* Realloc the parameter and data sizes */
8435 *pparams
= (char *)SMB_REALLOC(*pparams
,4);
8436 if (*pparams
== NULL
) {
8437 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8442 SSVAL(params
,0,0); /* No changes */
8443 SSVAL(params
,2,0); /* No EA errors */
8445 send_trans2_replies(conn
, req
, params
, 4, *ppdata
, 0, max_data_bytes
);
8450 /****************************************************************************
8451 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8452 ****************************************************************************/
8454 static void call_trans2getdfsreferral(connection_struct
*conn
,
8455 struct smb_request
*req
,
8456 char **pparams
, int total_params
,
8457 char **ppdata
, int total_data
,
8458 unsigned int max_data_bytes
)
8460 char *params
= *pparams
;
8461 char *pathname
= NULL
;
8463 int max_referral_level
;
8464 NTSTATUS status
= NT_STATUS_OK
;
8465 TALLOC_CTX
*ctx
= talloc_tos();
8467 DEBUG(10,("call_trans2getdfsreferral\n"));
8469 if (total_params
< 3) {
8470 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8474 max_referral_level
= SVAL(params
,0);
8476 if(!lp_host_msdfs()) {
8477 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8481 srvstr_pull_talloc(ctx
, params
, req
->flags2
, &pathname
, ¶ms
[2],
8482 total_params
- 2, STR_TERMINATE
);
8484 reply_nterror(req
, NT_STATUS_NOT_FOUND
);
8487 if((reply_size
= setup_dfs_referral(conn
, pathname
, max_referral_level
,
8488 ppdata
,&status
)) < 0) {
8489 reply_nterror(req
, status
);
8493 SSVAL((discard_const_p(uint8_t, req
->inbuf
)), smb_flg2
,
8494 SVAL(req
->inbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
8495 send_trans2_replies(conn
, req
,0,0,*ppdata
,reply_size
, max_data_bytes
);
8500 #define LMCAT_SPL 0x53
8501 #define LMFUNC_GETJOBID 0x60
8503 /****************************************************************************
8504 Reply to a TRANS2_IOCTL - used for OS/2 printing.
8505 ****************************************************************************/
8507 static void call_trans2ioctl(connection_struct
*conn
,
8508 struct smb_request
*req
,
8509 char **pparams
, int total_params
,
8510 char **ppdata
, int total_data
,
8511 unsigned int max_data_bytes
)
8513 char *pdata
= *ppdata
;
8514 files_struct
*fsp
= file_fsp(req
, SVAL(req
->vwv
+15, 0));
8516 /* check for an invalid fid before proceeding */
8519 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8523 if ((SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8524 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8525 *ppdata
= (char *)SMB_REALLOC(*ppdata
, 32);
8526 if (*ppdata
== NULL
) {
8527 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8532 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8533 CAN ACCEPT THIS IN UNICODE. JRA. */
8536 SSVAL(pdata
, 0, print_spool_rap_jobid(fsp
->print_file
));
8538 srvstr_push(pdata
, req
->flags2
, pdata
+ 2,
8539 lp_netbios_name(), 15,
8540 STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
8541 srvstr_push(pdata
, req
->flags2
, pdata
+18,
8542 lp_servicename(talloc_tos(), SNUM(conn
)), 13,
8543 STR_ASCII
|STR_TERMINATE
); /* Service name */
8544 send_trans2_replies(conn
, req
, *pparams
, 0, *ppdata
, 32,
8549 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8550 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8553 /****************************************************************************
8554 Reply to a SMBfindclose (stop trans2 directory search).
8555 ****************************************************************************/
8557 void reply_findclose(struct smb_request
*req
)
8560 struct smbd_server_connection
*sconn
= req
->sconn
;
8562 START_PROFILE(SMBfindclose
);
8565 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8566 END_PROFILE(SMBfindclose
);
8570 dptr_num
= SVALS(req
->vwv
+0, 0);
8572 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
8574 dptr_close(sconn
, &dptr_num
);
8576 reply_outbuf(req
, 0, 0);
8578 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
8580 END_PROFILE(SMBfindclose
);
8584 /****************************************************************************
8585 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8586 ****************************************************************************/
8588 void reply_findnclose(struct smb_request
*req
)
8592 START_PROFILE(SMBfindnclose
);
8595 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8596 END_PROFILE(SMBfindnclose
);
8600 dptr_num
= SVAL(req
->vwv
+0, 0);
8602 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
8604 /* We never give out valid handles for a
8605 findnotifyfirst - so any dptr_num is ok here.
8608 reply_outbuf(req
, 0, 0);
8610 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
8612 END_PROFILE(SMBfindnclose
);
8616 static void handle_trans2(connection_struct
*conn
, struct smb_request
*req
,
8617 struct trans_state
*state
)
8619 if (get_Protocol() >= PROTOCOL_NT1
) {
8620 req
->flags2
|= 0x40; /* IS_LONG_NAME */
8621 SSVAL((discard_const_p(uint8_t, req
->inbuf
)),smb_flg2
,req
->flags2
);
8624 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
8625 if (state
->call
!= TRANSACT2_QFSINFO
&&
8626 state
->call
!= TRANSACT2_SETFSINFO
) {
8627 DEBUG(0,("handle_trans2: encryption required "
8629 (unsigned int)state
->call
));
8630 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8635 SMB_PERFCOUNT_SET_SUBOP(&req
->pcd
, state
->call
);
8637 /* Now we must call the relevant TRANS2 function */
8638 switch(state
->call
) {
8639 case TRANSACT2_OPEN
:
8641 START_PROFILE(Trans2_open
);
8642 call_trans2open(conn
, req
,
8643 &state
->param
, state
->total_param
,
8644 &state
->data
, state
->total_data
,
8645 state
->max_data_return
);
8646 END_PROFILE(Trans2_open
);
8650 case TRANSACT2_FINDFIRST
:
8652 START_PROFILE(Trans2_findfirst
);
8653 call_trans2findfirst(conn
, req
,
8654 &state
->param
, state
->total_param
,
8655 &state
->data
, state
->total_data
,
8656 state
->max_data_return
);
8657 END_PROFILE(Trans2_findfirst
);
8661 case TRANSACT2_FINDNEXT
:
8663 START_PROFILE(Trans2_findnext
);
8664 call_trans2findnext(conn
, req
,
8665 &state
->param
, state
->total_param
,
8666 &state
->data
, state
->total_data
,
8667 state
->max_data_return
);
8668 END_PROFILE(Trans2_findnext
);
8672 case TRANSACT2_QFSINFO
:
8674 START_PROFILE(Trans2_qfsinfo
);
8675 call_trans2qfsinfo(conn
, req
,
8676 &state
->param
, state
->total_param
,
8677 &state
->data
, state
->total_data
,
8678 state
->max_data_return
);
8679 END_PROFILE(Trans2_qfsinfo
);
8683 case TRANSACT2_SETFSINFO
:
8685 START_PROFILE(Trans2_setfsinfo
);
8686 call_trans2setfsinfo(conn
, req
,
8687 &state
->param
, state
->total_param
,
8688 &state
->data
, state
->total_data
,
8689 state
->max_data_return
);
8690 END_PROFILE(Trans2_setfsinfo
);
8694 case TRANSACT2_QPATHINFO
:
8695 case TRANSACT2_QFILEINFO
:
8697 START_PROFILE(Trans2_qpathinfo
);
8698 call_trans2qfilepathinfo(conn
, req
, state
->call
,
8699 &state
->param
, state
->total_param
,
8700 &state
->data
, state
->total_data
,
8701 state
->max_data_return
);
8702 END_PROFILE(Trans2_qpathinfo
);
8706 case TRANSACT2_SETPATHINFO
:
8707 case TRANSACT2_SETFILEINFO
:
8709 START_PROFILE(Trans2_setpathinfo
);
8710 call_trans2setfilepathinfo(conn
, req
, state
->call
,
8711 &state
->param
, state
->total_param
,
8712 &state
->data
, state
->total_data
,
8713 state
->max_data_return
);
8714 END_PROFILE(Trans2_setpathinfo
);
8718 case TRANSACT2_FINDNOTIFYFIRST
:
8720 START_PROFILE(Trans2_findnotifyfirst
);
8721 call_trans2findnotifyfirst(conn
, req
,
8722 &state
->param
, state
->total_param
,
8723 &state
->data
, state
->total_data
,
8724 state
->max_data_return
);
8725 END_PROFILE(Trans2_findnotifyfirst
);
8729 case TRANSACT2_FINDNOTIFYNEXT
:
8731 START_PROFILE(Trans2_findnotifynext
);
8732 call_trans2findnotifynext(conn
, req
,
8733 &state
->param
, state
->total_param
,
8734 &state
->data
, state
->total_data
,
8735 state
->max_data_return
);
8736 END_PROFILE(Trans2_findnotifynext
);
8740 case TRANSACT2_MKDIR
:
8742 START_PROFILE(Trans2_mkdir
);
8743 call_trans2mkdir(conn
, req
,
8744 &state
->param
, state
->total_param
,
8745 &state
->data
, state
->total_data
,
8746 state
->max_data_return
);
8747 END_PROFILE(Trans2_mkdir
);
8751 case TRANSACT2_GET_DFS_REFERRAL
:
8753 START_PROFILE(Trans2_get_dfs_referral
);
8754 call_trans2getdfsreferral(conn
, req
,
8755 &state
->param
, state
->total_param
,
8756 &state
->data
, state
->total_data
,
8757 state
->max_data_return
);
8758 END_PROFILE(Trans2_get_dfs_referral
);
8762 case TRANSACT2_IOCTL
:
8764 START_PROFILE(Trans2_ioctl
);
8765 call_trans2ioctl(conn
, req
,
8766 &state
->param
, state
->total_param
,
8767 &state
->data
, state
->total_data
,
8768 state
->max_data_return
);
8769 END_PROFILE(Trans2_ioctl
);
8774 /* Error in request */
8775 DEBUG(2,("Unknown request %d in trans2 call\n", state
->call
));
8776 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8780 /****************************************************************************
8781 Reply to a SMBtrans2.
8782 ****************************************************************************/
8784 void reply_trans2(struct smb_request
*req
)
8786 connection_struct
*conn
= req
->conn
;
8791 unsigned int tran_call
;
8792 struct trans_state
*state
;
8795 START_PROFILE(SMBtrans2
);
8797 if (req
->wct
< 14) {
8798 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8799 END_PROFILE(SMBtrans2
);
8803 dsoff
= SVAL(req
->vwv
+12, 0);
8804 dscnt
= SVAL(req
->vwv
+11, 0);
8805 psoff
= SVAL(req
->vwv
+10, 0);
8806 pscnt
= SVAL(req
->vwv
+9, 0);
8807 tran_call
= SVAL(req
->vwv
+14, 0);
8809 result
= allow_new_trans(conn
->pending_trans
, req
->mid
);
8810 if (!NT_STATUS_IS_OK(result
)) {
8811 DEBUG(2, ("Got invalid trans2 request: %s\n",
8812 nt_errstr(result
)));
8813 reply_nterror(req
, result
);
8814 END_PROFILE(SMBtrans2
);
8819 switch (tran_call
) {
8820 /* List the allowed trans2 calls on IPC$ */
8821 case TRANSACT2_OPEN
:
8822 case TRANSACT2_GET_DFS_REFERRAL
:
8823 case TRANSACT2_QFILEINFO
:
8824 case TRANSACT2_QFSINFO
:
8825 case TRANSACT2_SETFSINFO
:
8828 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8829 END_PROFILE(SMBtrans2
);
8834 if ((state
= talloc(conn
, struct trans_state
)) == NULL
) {
8835 DEBUG(0, ("talloc failed\n"));
8836 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8837 END_PROFILE(SMBtrans2
);
8841 state
->cmd
= SMBtrans2
;
8843 state
->mid
= req
->mid
;
8844 state
->vuid
= req
->vuid
;
8845 state
->setup_count
= SVAL(req
->vwv
+13, 0);
8846 state
->setup
= NULL
;
8847 state
->total_param
= SVAL(req
->vwv
+0, 0);
8848 state
->param
= NULL
;
8849 state
->total_data
= SVAL(req
->vwv
+1, 0);
8851 state
->max_param_return
= SVAL(req
->vwv
+2, 0);
8852 state
->max_data_return
= SVAL(req
->vwv
+3, 0);
8853 state
->max_setup_return
= SVAL(req
->vwv
+4, 0);
8854 state
->close_on_completion
= BITSETW(req
->vwv
+5, 0);
8855 state
->one_way
= BITSETW(req
->vwv
+5, 1);
8857 state
->call
= tran_call
;
8859 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8860 is so as a sanity check */
8861 if (state
->setup_count
!= 1) {
8863 * Need to have rc=0 for ioctl to get job id for OS/2.
8864 * Network printing will fail if function is not successful.
8865 * Similar function in reply.c will be used if protocol
8866 * is LANMAN1.0 instead of LM1.2X002.
8867 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
8868 * outbuf doesn't have to be set(only job id is used).
8870 if ( (state
->setup_count
== 4)
8871 && (tran_call
== TRANSACT2_IOCTL
)
8872 && (SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8873 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8874 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8876 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state
->setup_count
));
8877 DEBUG(2,("Transaction is %d\n",tran_call
));
8879 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8880 END_PROFILE(SMBtrans2
);
8885 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
8888 if (state
->total_data
) {
8890 if (trans_oob(state
->total_data
, 0, dscnt
)
8891 || trans_oob(smb_len(req
->inbuf
), dsoff
, dscnt
)) {
8895 /* Can't use talloc here, the core routines do realloc on the
8896 * params and data. */
8897 state
->data
= (char *)SMB_MALLOC(state
->total_data
);
8898 if (state
->data
== NULL
) {
8899 DEBUG(0,("reply_trans2: data malloc fail for %u "
8900 "bytes !\n", (unsigned int)state
->total_data
));
8902 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8903 END_PROFILE(SMBtrans2
);
8907 memcpy(state
->data
,smb_base(req
->inbuf
)+dsoff
,dscnt
);
8910 if (state
->total_param
) {
8912 if (trans_oob(state
->total_param
, 0, pscnt
)
8913 || trans_oob(smb_len(req
->inbuf
), psoff
, pscnt
)) {
8917 /* Can't use talloc here, the core routines do realloc on the
8918 * params and data. */
8919 state
->param
= (char *)SMB_MALLOC(state
->total_param
);
8920 if (state
->param
== NULL
) {
8921 DEBUG(0,("reply_trans: param malloc fail for %u "
8922 "bytes !\n", (unsigned int)state
->total_param
));
8923 SAFE_FREE(state
->data
);
8925 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8926 END_PROFILE(SMBtrans2
);
8930 memcpy(state
->param
,smb_base(req
->inbuf
)+psoff
,pscnt
);
8933 state
->received_data
= dscnt
;
8934 state
->received_param
= pscnt
;
8936 if ((state
->received_param
== state
->total_param
) &&
8937 (state
->received_data
== state
->total_data
)) {
8939 handle_trans2(conn
, req
, state
);
8941 SAFE_FREE(state
->data
);
8942 SAFE_FREE(state
->param
);
8944 END_PROFILE(SMBtrans2
);
8948 DLIST_ADD(conn
->pending_trans
, state
);
8950 /* We need to send an interim response then receive the rest
8951 of the parameter/data bytes */
8952 reply_outbuf(req
, 0, 0);
8953 show_msg((char *)req
->outbuf
);
8954 END_PROFILE(SMBtrans2
);
8959 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8960 SAFE_FREE(state
->data
);
8961 SAFE_FREE(state
->param
);
8963 END_PROFILE(SMBtrans2
);
8964 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8968 /****************************************************************************
8969 Reply to a SMBtranss2
8970 ****************************************************************************/
8972 void reply_transs2(struct smb_request
*req
)
8974 connection_struct
*conn
= req
->conn
;
8975 unsigned int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
8976 struct trans_state
*state
;
8978 START_PROFILE(SMBtranss2
);
8980 show_msg((const char *)req
->inbuf
);
8982 /* Windows clients expect all replies to
8983 a transact secondary (SMBtranss2 0x33)
8984 to have a command code of transact
8985 (SMBtrans2 0x32). See bug #8989
8986 and also [MS-CIFS] section 2.2.4.47.2
8989 req
->cmd
= SMBtrans2
;
8992 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8993 END_PROFILE(SMBtranss2
);
8997 for (state
= conn
->pending_trans
; state
!= NULL
;
8998 state
= state
->next
) {
8999 if (state
->mid
== req
->mid
) {
9004 if ((state
== NULL
) || (state
->cmd
!= SMBtrans2
)) {
9005 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9006 END_PROFILE(SMBtranss2
);
9010 /* Revise state->total_param and state->total_data in case they have
9011 changed downwards */
9013 if (SVAL(req
->vwv
+0, 0) < state
->total_param
)
9014 state
->total_param
= SVAL(req
->vwv
+0, 0);
9015 if (SVAL(req
->vwv
+1, 0) < state
->total_data
)
9016 state
->total_data
= SVAL(req
->vwv
+1, 0);
9018 pcnt
= SVAL(req
->vwv
+2, 0);
9019 poff
= SVAL(req
->vwv
+3, 0);
9020 pdisp
= SVAL(req
->vwv
+4, 0);
9022 dcnt
= SVAL(req
->vwv
+5, 0);
9023 doff
= SVAL(req
->vwv
+6, 0);
9024 ddisp
= SVAL(req
->vwv
+7, 0);
9026 state
->received_param
+= pcnt
;
9027 state
->received_data
+= dcnt
;
9029 if ((state
->received_data
> state
->total_data
) ||
9030 (state
->received_param
> state
->total_param
))
9034 if (trans_oob(state
->total_param
, pdisp
, pcnt
)
9035 || trans_oob(smb_len(req
->inbuf
), poff
, pcnt
)) {
9038 memcpy(state
->param
+pdisp
,smb_base(req
->inbuf
)+poff
,pcnt
);
9042 if (trans_oob(state
->total_data
, ddisp
, dcnt
)
9043 || trans_oob(smb_len(req
->inbuf
), doff
, dcnt
)) {
9046 memcpy(state
->data
+ddisp
, smb_base(req
->inbuf
)+doff
,dcnt
);
9049 if ((state
->received_param
< state
->total_param
) ||
9050 (state
->received_data
< state
->total_data
)) {
9051 END_PROFILE(SMBtranss2
);
9055 handle_trans2(conn
, req
, state
);
9057 DLIST_REMOVE(conn
->pending_trans
, state
);
9058 SAFE_FREE(state
->data
);
9059 SAFE_FREE(state
->param
);
9062 END_PROFILE(SMBtranss2
);
9067 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
9068 DLIST_REMOVE(conn
->pending_trans
, state
);
9069 SAFE_FREE(state
->data
);
9070 SAFE_FREE(state
->param
);
9072 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9073 END_PROFILE(SMBtranss2
);