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(listp
, conn
, fsp
,
357 if (!NT_STATUS_IS_OK(status
)) {
362 if (listp
->ea
.value
.length
== 0) {
364 * We can never return a zero length EA.
365 * Windows reports the EA's as corrupted.
371 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
374 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
376 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
377 "= %u\n", (unsigned int)*pea_total_len
, dos_ea_name
,
378 (unsigned int)listp
->ea
.value
.length
));
380 DLIST_ADD_END(ea_list_head
, listp
, struct ea_list
*);
384 /* Add on 4 for total length. */
385 if (*pea_total_len
) {
389 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
390 (unsigned int)*pea_total_len
));
392 *ea_list
= ea_list_head
;
396 static NTSTATUS
get_ea_list_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
397 const struct smb_filename
*smb_fname
, size_t *pea_total_len
, struct ea_list
**ea_list
)
402 if (!lp_ea_support(SNUM(conn
))) {
406 if (is_ntfs_stream_smb_fname(smb_fname
)) {
407 return NT_STATUS_INVALID_PARAMETER
;
410 return get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, smb_fname
->base_name
, pea_total_len
, ea_list
);
413 /****************************************************************************
414 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
416 ****************************************************************************/
418 static unsigned int fill_ea_buffer(TALLOC_CTX
*mem_ctx
, char *pdata
, unsigned int total_data_size
,
419 connection_struct
*conn
, struct ea_list
*ea_list
)
421 unsigned int ret_data_size
= 4;
424 SMB_ASSERT(total_data_size
>= 4);
426 if (!lp_ea_support(SNUM(conn
))) {
431 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
434 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
435 dos_namelen
= strlen(dos_ea_name
);
436 if (dos_namelen
> 255 || dos_namelen
== 0) {
439 if (ea_list
->ea
.value
.length
> 65535) {
442 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
446 /* We know we have room. */
447 SCVAL(p
,0,ea_list
->ea
.flags
);
448 SCVAL(p
,1,dos_namelen
);
449 SSVAL(p
,2,ea_list
->ea
.value
.length
);
450 strlcpy(p
+4, dos_ea_name
, dos_namelen
+1);
451 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
453 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
454 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
457 ret_data_size
= PTR_DIFF(p
, pdata
);
458 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size
));
459 SIVAL(pdata
,0,ret_data_size
);
460 return ret_data_size
;
463 static NTSTATUS
fill_ea_chained_buffer(TALLOC_CTX
*mem_ctx
,
465 unsigned int total_data_size
,
466 unsigned int *ret_data_size
,
467 connection_struct
*conn
,
468 struct ea_list
*ea_list
)
470 uint8_t *p
= (uint8_t *)pdata
;
471 uint8_t *last_start
= NULL
;
472 bool do_store_data
= (pdata
!= NULL
);
476 if (!lp_ea_support(SNUM(conn
))) {
477 return NT_STATUS_NO_EAS_ON_FILE
;
480 for (; ea_list
; ea_list
= ea_list
->next
) {
486 if (last_start
!= NULL
&& do_store_data
) {
487 SIVAL(last_start
, 0, PTR_DIFF(p
, last_start
));
491 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
492 dos_namelen
= strlen(dos_ea_name
);
493 if (dos_namelen
> 255 || dos_namelen
== 0) {
494 return NT_STATUS_INTERNAL_ERROR
;
496 if (ea_list
->ea
.value
.length
> 65535) {
497 return NT_STATUS_INTERNAL_ERROR
;
500 this_size
= 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
503 pad
= (4 - (this_size
% 4)) % 4;
508 if (this_size
> total_data_size
) {
509 return NT_STATUS_INFO_LENGTH_MISMATCH
;
512 /* We know we have room. */
513 SIVAL(p
, 0x00, 0); /* next offset */
514 SCVAL(p
, 0x04, ea_list
->ea
.flags
);
515 SCVAL(p
, 0x05, dos_namelen
);
516 SSVAL(p
, 0x06, ea_list
->ea
.value
.length
);
517 strlcpy((char *)(p
+0x08), dos_ea_name
, dos_namelen
+1);
518 memcpy(p
+ 0x08 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
520 memset(p
+ 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
,
524 total_data_size
-= this_size
;
530 *ret_data_size
= PTR_DIFF(p
, pdata
);
531 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size
));
535 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const struct smb_filename
*smb_fname
)
537 size_t total_ea_len
= 0;
539 struct ea_list
*ea_list
= NULL
;
541 if (!lp_ea_support(SNUM(conn
))) {
544 mem_ctx
= talloc_stackframe();
546 /* If this is a stream fsp, then we need to instead find the
547 * estimated ea len from the main file, not the stream
548 * (streams cannot have EAs), but the estimate isn't just 0 in
550 if (is_ntfs_stream_smb_fname(smb_fname
)) {
553 (void)get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, smb_fname
->base_name
, &total_ea_len
, &ea_list
);
554 if(conn
->sconn
->using_smb2
) {
556 unsigned int ret_data_size
;
558 * We're going to be using fill_ea_chained_buffer() to
559 * marshall EA's - this size is significantly larger
560 * than the SMB1 buffer. Re-calculate the size without
563 status
= fill_ea_chained_buffer(mem_ctx
,
569 if (!NT_STATUS_IS_OK(status
)) {
572 total_ea_len
= ret_data_size
;
574 TALLOC_FREE(mem_ctx
);
578 /****************************************************************************
579 Ensure the EA name is case insensitive by matching any existing EA name.
580 ****************************************************************************/
582 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
585 TALLOC_CTX
*mem_ctx
= talloc_tos();
586 struct ea_list
*ea_list
;
587 NTSTATUS status
= get_ea_list_from_file_path(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
, &ea_list
);
588 if (!NT_STATUS_IS_OK(status
)) {
592 for (; ea_list
; ea_list
= ea_list
->next
) {
593 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
594 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
595 &unix_ea_name
[5], ea_list
->ea
.name
));
596 strlcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-5);
602 /****************************************************************************
603 Set or delete an extended attribute.
604 ****************************************************************************/
606 NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
,
607 const struct smb_filename
*smb_fname
, struct ea_list
*ea_list
)
612 if (!lp_ea_support(SNUM(conn
))) {
613 return NT_STATUS_EAS_NOT_SUPPORTED
;
616 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_EA
);
617 if (!NT_STATUS_IS_OK(status
)) {
621 /* Setting EAs on streams isn't supported. */
622 if (is_ntfs_stream_smb_fname(smb_fname
)) {
623 return NT_STATUS_INVALID_PARAMETER
;
626 fname
= smb_fname
->base_name
;
628 for (;ea_list
; ea_list
= ea_list
->next
) {
630 fstring unix_ea_name
;
632 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
633 fstrcat(unix_ea_name
, ea_list
->ea
.name
);
635 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
637 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, (unsigned int)ea_list
->ea
.value
.length
));
639 if (samba_private_attr_name(unix_ea_name
)) {
640 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
641 return NT_STATUS_ACCESS_DENIED
;
644 if (ea_list
->ea
.value
.length
== 0) {
645 /* Remove the attribute. */
646 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
647 DEBUG(10,("set_ea: deleting ea name %s on "
648 "file %s by file descriptor.\n",
649 unix_ea_name
, fsp_str_dbg(fsp
)));
650 ret
= SMB_VFS_FREMOVEXATTR(fsp
, unix_ea_name
);
652 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
653 unix_ea_name
, fname
));
654 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
657 /* Removing a non existent attribute always succeeds. */
658 if (ret
== -1 && errno
== ENOATTR
) {
659 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
665 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
666 DEBUG(10,("set_ea: setting ea name %s on file "
667 "%s by file descriptor.\n",
668 unix_ea_name
, fsp_str_dbg(fsp
)));
669 ret
= SMB_VFS_FSETXATTR(fsp
, unix_ea_name
,
670 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
672 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
673 unix_ea_name
, fname
));
674 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
,
675 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
681 if (errno
== ENOTSUP
) {
682 return NT_STATUS_EAS_NOT_SUPPORTED
;
685 return map_nt_error_from_unix(errno
);
691 /****************************************************************************
692 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
693 ****************************************************************************/
695 static struct ea_list
*read_ea_name_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
697 struct ea_list
*ea_list_head
= NULL
;
698 size_t converted_size
, offset
= 0;
700 while (offset
+ 2 < data_size
) {
701 struct ea_list
*eal
= talloc_zero(ctx
, struct ea_list
);
702 unsigned int namelen
= CVAL(pdata
,offset
);
704 offset
++; /* Go past the namelen byte. */
706 /* integer wrap paranioa. */
707 if ((offset
+ namelen
< offset
) || (offset
+ namelen
< namelen
) ||
708 (offset
> data_size
) || (namelen
> data_size
) ||
709 (offset
+ namelen
>= data_size
)) {
712 /* Ensure the name is null terminated. */
713 if (pdata
[offset
+ namelen
] != '\0') {
716 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, &pdata
[offset
],
718 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
719 "failed: %s", strerror(errno
)));
725 offset
+= (namelen
+ 1); /* Go past the name + terminating zero. */
726 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
727 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal
->ea
.name
));
733 /****************************************************************************
734 Read one EA list entry from the buffer.
735 ****************************************************************************/
737 struct ea_list
*read_ea_list_entry(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
, size_t *pbytes_used
)
739 struct ea_list
*eal
= talloc_zero(ctx
, struct ea_list
);
741 unsigned int namelen
;
742 size_t converted_size
;
752 eal
->ea
.flags
= CVAL(pdata
,0);
753 namelen
= CVAL(pdata
,1);
754 val_len
= SVAL(pdata
,2);
756 if (4 + namelen
+ 1 + val_len
> data_size
) {
760 /* Ensure the name is null terminated. */
761 if (pdata
[namelen
+ 4] != '\0') {
764 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, pdata
+ 4, &converted_size
)) {
765 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
772 eal
->ea
.value
= data_blob_talloc(eal
, NULL
, (size_t)val_len
+ 1);
773 if (!eal
->ea
.value
.data
) {
777 memcpy(eal
->ea
.value
.data
, pdata
+ 4 + namelen
+ 1, val_len
);
779 /* Ensure we're null terminated just in case we print the value. */
780 eal
->ea
.value
.data
[val_len
] = '\0';
781 /* But don't count the null. */
782 eal
->ea
.value
.length
--;
785 *pbytes_used
= 4 + namelen
+ 1 + val_len
;
788 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal
->ea
.name
));
789 dump_data(10, eal
->ea
.value
.data
, eal
->ea
.value
.length
);
794 /****************************************************************************
795 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
796 ****************************************************************************/
798 static struct ea_list
*read_ea_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
800 struct ea_list
*ea_list_head
= NULL
;
802 size_t bytes_used
= 0;
804 while (offset
< data_size
) {
805 struct ea_list
*eal
= read_ea_list_entry(ctx
, pdata
+ offset
, data_size
- offset
, &bytes_used
);
811 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
812 offset
+= bytes_used
;
818 /****************************************************************************
819 Count the total EA size needed.
820 ****************************************************************************/
822 static size_t ea_list_size(struct ea_list
*ealist
)
825 struct ea_list
*listp
;
828 for (listp
= ealist
; listp
; listp
= listp
->next
) {
829 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
830 ret
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
832 /* Add on 4 for total length. */
840 /****************************************************************************
841 Return a union of EA's from a file list and a list of names.
842 The TALLOC context for the two lists *MUST* be identical as we steal
843 memory from one list to add to another. JRA.
844 ****************************************************************************/
846 static struct ea_list
*ea_list_union(struct ea_list
*name_list
, struct ea_list
*file_list
, size_t *total_ea_len
)
848 struct ea_list
*nlistp
, *flistp
;
850 for (nlistp
= name_list
; nlistp
; nlistp
= nlistp
->next
) {
851 for (flistp
= file_list
; flistp
; flistp
= flistp
->next
) {
852 if (strequal(nlistp
->ea
.name
, flistp
->ea
.name
)) {
858 /* Copy the data from this entry. */
859 nlistp
->ea
.flags
= flistp
->ea
.flags
;
860 nlistp
->ea
.value
= flistp
->ea
.value
;
863 nlistp
->ea
.flags
= 0;
864 ZERO_STRUCT(nlistp
->ea
.value
);
868 *total_ea_len
= ea_list_size(name_list
);
872 /****************************************************************************
873 Send the required number of replies back.
874 We assume all fields other than the data fields are
875 set correctly for the type of call.
876 HACK ! Always assumes smb_setup field is zero.
877 ****************************************************************************/
879 void send_trans2_replies(connection_struct
*conn
,
880 struct smb_request
*req
,
887 /* As we are using a protocol > LANMAN1 then the max_send
888 variable must have been set in the sessetupX call.
889 This takes precedence over the max_xmit field in the
890 global struct. These different max_xmit variables should
891 be merged as this is now too confusing */
893 int data_to_send
= datasize
;
894 int params_to_send
= paramsize
;
896 const char *pp
= params
;
897 const char *pd
= pdata
;
898 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
899 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
900 int data_alignment_offset
= 0;
901 bool overflow
= False
;
902 struct smbd_server_connection
*sconn
= req
->sconn
;
903 int max_send
= sconn
->smb1
.sessions
.max_send
;
905 /* Modify the data_to_send and datasize and set the error if
906 we're trying to send more than max_data_bytes. We still send
907 the part of the packet(s) that fit. Strange, but needed
910 if (max_data_bytes
> 0 && datasize
> max_data_bytes
) {
911 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
912 max_data_bytes
, datasize
));
913 datasize
= data_to_send
= max_data_bytes
;
917 /* If there genuinely are no parameters or data to send just send the empty packet */
919 if(params_to_send
== 0 && data_to_send
== 0) {
920 reply_outbuf(req
, 10, 0);
921 show_msg((char *)req
->outbuf
);
922 if (!srv_send_smb(sconn
,
925 IS_CONN_ENCRYPTED(conn
),
927 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
929 TALLOC_FREE(req
->outbuf
);
933 /* When sending params and data ensure that both are nicely aligned */
934 /* Only do this alignment when there is also data to send - else
935 can cause NT redirector problems. */
937 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
938 data_alignment_offset
= 4 - (params_to_send
% 4);
940 /* Space is bufsize minus Netbios over TCP header minus SMB header */
941 /* The alignment_offset is to align the param bytes on an even byte
942 boundary. NT 4.0 Beta needs this to work correctly. */
944 useable_space
= max_send
- (smb_size
947 + data_alignment_offset
);
949 if (useable_space
< 0) {
950 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
951 "= %d!!!", useable_space
));
952 exit_server_cleanly("send_trans2_replies: Not enough space");
955 while (params_to_send
|| data_to_send
) {
956 /* Calculate whether we will totally or partially fill this packet */
958 total_sent_thistime
= params_to_send
+ data_to_send
;
960 /* We can never send more than useable_space */
962 * Note that 'useable_space' does not include the alignment offsets,
963 * but we must include the alignment offsets in the calculation of
964 * the length of the data we send over the wire, as the alignment offsets
965 * are sent here. Fix from Marc_Jacobsen@hp.com.
968 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
);
970 reply_outbuf(req
, 10, total_sent_thistime
+ alignment_offset
971 + data_alignment_offset
);
973 /* Set total params and data to be sent */
974 SSVAL(req
->outbuf
,smb_tprcnt
,paramsize
);
975 SSVAL(req
->outbuf
,smb_tdrcnt
,datasize
);
977 /* Calculate how many parameters and data we can fit into
978 * this packet. Parameters get precedence
981 params_sent_thistime
= MIN(params_to_send
,useable_space
);
982 data_sent_thistime
= useable_space
- params_sent_thistime
;
983 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
985 SSVAL(req
->outbuf
,smb_prcnt
, params_sent_thistime
);
987 /* smb_proff is the offset from the start of the SMB header to the
988 parameter bytes, however the first 4 bytes of outbuf are
989 the Netbios over TCP header. Thus use smb_base() to subtract
990 them from the calculation */
992 SSVAL(req
->outbuf
,smb_proff
,
993 ((smb_buf(req
->outbuf
)+alignment_offset
)
994 - smb_base(req
->outbuf
)));
996 if(params_sent_thistime
== 0)
997 SSVAL(req
->outbuf
,smb_prdisp
,0);
999 /* Absolute displacement of param bytes sent in this packet */
1000 SSVAL(req
->outbuf
,smb_prdisp
,pp
- params
);
1002 SSVAL(req
->outbuf
,smb_drcnt
, data_sent_thistime
);
1003 if(data_sent_thistime
== 0) {
1004 SSVAL(req
->outbuf
,smb_droff
,0);
1005 SSVAL(req
->outbuf
,smb_drdisp
, 0);
1007 /* The offset of the data bytes is the offset of the
1008 parameter bytes plus the number of parameters being sent this time */
1009 SSVAL(req
->outbuf
, smb_droff
,
1010 ((smb_buf(req
->outbuf
)+alignment_offset
)
1011 - smb_base(req
->outbuf
))
1012 + params_sent_thistime
+ data_alignment_offset
);
1013 SSVAL(req
->outbuf
,smb_drdisp
, pd
- pdata
);
1016 /* Initialize the padding for alignment */
1018 if (alignment_offset
!= 0) {
1019 memset(smb_buf(req
->outbuf
), 0, alignment_offset
);
1022 /* Copy the param bytes into the packet */
1024 if(params_sent_thistime
) {
1025 memcpy((smb_buf(req
->outbuf
)+alignment_offset
), pp
,
1026 params_sent_thistime
);
1029 /* Copy in the data bytes */
1030 if(data_sent_thistime
) {
1031 if (data_alignment_offset
!= 0) {
1032 memset((smb_buf(req
->outbuf
)+alignment_offset
+
1033 params_sent_thistime
), 0,
1034 data_alignment_offset
);
1036 memcpy(smb_buf(req
->outbuf
)+alignment_offset
1037 +params_sent_thistime
+data_alignment_offset
,
1038 pd
,data_sent_thistime
);
1041 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
1042 params_sent_thistime
, data_sent_thistime
, useable_space
));
1043 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
1044 params_to_send
, data_to_send
, paramsize
, datasize
));
1047 error_packet_set((char *)req
->outbuf
,
1048 ERRDOS
,ERRbufferoverflow
,
1049 STATUS_BUFFER_OVERFLOW
,
1053 /* Send the packet */
1054 show_msg((char *)req
->outbuf
);
1055 if (!srv_send_smb(sconn
,
1056 (char *)req
->outbuf
,
1057 true, req
->seqnum
+1,
1058 IS_CONN_ENCRYPTED(conn
),
1060 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
1062 TALLOC_FREE(req
->outbuf
);
1064 pp
+= params_sent_thistime
;
1065 pd
+= data_sent_thistime
;
1067 params_to_send
-= params_sent_thistime
;
1068 data_to_send
-= data_sent_thistime
;
1071 if(params_to_send
< 0 || data_to_send
< 0) {
1072 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
1073 params_to_send
, data_to_send
));
1081 /****************************************************************************
1082 Reply to a TRANSACT2_OPEN.
1083 ****************************************************************************/
1085 static void call_trans2open(connection_struct
*conn
,
1086 struct smb_request
*req
,
1087 char **pparams
, int total_params
,
1088 char **ppdata
, int total_data
,
1089 unsigned int max_data_bytes
)
1091 struct smb_filename
*smb_fname
= NULL
;
1092 char *params
= *pparams
;
1093 char *pdata
= *ppdata
;
1096 bool oplock_request
;
1098 bool return_additional_info
;
1107 int fattr
=0,mtime
=0;
1108 SMB_INO_T inode
= 0;
1111 struct ea_list
*ea_list
= NULL
;
1116 uint32 create_disposition
;
1117 uint32 create_options
= 0;
1118 uint32_t private_flags
= 0;
1119 TALLOC_CTX
*ctx
= talloc_tos();
1122 * Ensure we have enough parameters to perform the operation.
1125 if (total_params
< 29) {
1126 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1130 flags
= SVAL(params
, 0);
1131 deny_mode
= SVAL(params
, 2);
1132 open_attr
= SVAL(params
,6);
1133 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
1134 if (oplock_request
) {
1135 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
1139 return_additional_info
= BITSETW(params
,0);
1140 open_sattr
= SVAL(params
, 4);
1141 open_time
= make_unix_date3(params
+8);
1143 open_ofun
= SVAL(params
,12);
1144 open_size
= IVAL(params
,14);
1145 pname
= ¶ms
[28];
1148 reply_nterror(req
, NT_STATUS_NETWORK_ACCESS_DENIED
);
1152 srvstr_get_path(ctx
, params
, req
->flags2
, &fname
, pname
,
1153 total_params
- 28, STR_TERMINATE
,
1155 if (!NT_STATUS_IS_OK(status
)) {
1156 reply_nterror(req
, status
);
1160 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1161 fname
, (unsigned int)deny_mode
, (unsigned int)open_attr
,
1162 (unsigned int)open_ofun
, open_size
));
1164 status
= filename_convert(ctx
,
1166 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1171 if (!NT_STATUS_IS_OK(status
)) {
1172 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1173 reply_botherror(req
,
1174 NT_STATUS_PATH_NOT_COVERED
,
1175 ERRSRV
, ERRbadpath
);
1178 reply_nterror(req
, status
);
1182 if (open_ofun
== 0) {
1183 reply_nterror(req
, NT_STATUS_OBJECT_NAME_COLLISION
);
1187 if (!map_open_params_to_ntcreate(smb_fname
->base_name
, deny_mode
,
1189 &access_mask
, &share_mode
,
1190 &create_disposition
,
1193 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1197 /* Any data in this call is an EA list. */
1198 if (total_data
&& (total_data
!= 4)) {
1199 if (total_data
< 10) {
1200 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1204 if (IVAL(pdata
,0) > total_data
) {
1205 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1206 IVAL(pdata
,0), (unsigned int)total_data
));
1207 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1211 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
1214 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1218 if (!lp_ea_support(SNUM(conn
))) {
1219 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
1224 status
= SMB_VFS_CREATE_FILE(
1227 0, /* root_dir_fid */
1228 smb_fname
, /* fname */
1229 access_mask
, /* access_mask */
1230 share_mode
, /* share_access */
1231 create_disposition
, /* create_disposition*/
1232 create_options
, /* create_options */
1233 open_attr
, /* file_attributes */
1234 oplock_request
, /* oplock_request */
1235 open_size
, /* allocation_size */
1238 ea_list
, /* ea_list */
1240 &smb_action
); /* psbuf */
1242 if (!NT_STATUS_IS_OK(status
)) {
1243 if (open_was_deferred(req
->sconn
, req
->mid
)) {
1244 /* We have re-scheduled this call. */
1247 reply_openerror(req
, status
);
1251 size
= get_file_size_stat(&smb_fname
->st
);
1252 fattr
= dos_mode(conn
, smb_fname
);
1253 mtime
= convert_timespec_to_time_t(smb_fname
->st
.st_ex_mtime
);
1254 inode
= smb_fname
->st
.st_ex_ino
;
1255 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
1256 close_file(req
, fsp
, ERROR_CLOSE
);
1257 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1261 /* Realloc the size of parameters and data we will return */
1262 *pparams
= (char *)SMB_REALLOC(*pparams
, 30);
1263 if(*pparams
== NULL
) {
1264 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1269 SSVAL(params
,0,fsp
->fnum
);
1270 SSVAL(params
,2,fattr
);
1271 srv_put_dos_date2(params
,4, mtime
);
1272 SIVAL(params
,8, (uint32
)size
);
1273 SSVAL(params
,12,deny_mode
);
1274 SSVAL(params
,14,0); /* open_type - file or directory. */
1275 SSVAL(params
,16,0); /* open_state - only valid for IPC device. */
1277 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1278 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1281 SSVAL(params
,18,smb_action
);
1284 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1286 SIVAL(params
,20,inode
);
1287 SSVAL(params
,24,0); /* Padding. */
1289 uint32 ea_size
= estimate_ea_size(conn
, fsp
,
1291 SIVAL(params
, 26, ea_size
);
1293 SIVAL(params
, 26, 0);
1296 /* Send the required number of replies */
1297 send_trans2_replies(conn
, req
, params
, 30, *ppdata
, 0, max_data_bytes
);
1299 TALLOC_FREE(smb_fname
);
1302 /*********************************************************
1303 Routine to check if a given string matches exactly.
1304 as a special case a mask of "." does NOT match. That
1305 is required for correct wildcard semantics
1306 Case can be significant or not.
1307 **********************************************************/
1309 static bool exact_match(bool has_wild
,
1310 bool case_sensitive
,
1314 if (mask
[0] == '.' && mask
[1] == 0) {
1322 if (case_sensitive
) {
1323 return strcmp(str
,mask
)==0;
1325 return strcasecmp_m(str
,mask
) == 0;
1329 /****************************************************************************
1330 Return the filetype for UNIX extensions.
1331 ****************************************************************************/
1333 static uint32
unix_filetype(mode_t mode
)
1336 return UNIX_TYPE_FILE
;
1337 else if(S_ISDIR(mode
))
1338 return UNIX_TYPE_DIR
;
1340 else if(S_ISLNK(mode
))
1341 return UNIX_TYPE_SYMLINK
;
1344 else if(S_ISCHR(mode
))
1345 return UNIX_TYPE_CHARDEV
;
1348 else if(S_ISBLK(mode
))
1349 return UNIX_TYPE_BLKDEV
;
1352 else if(S_ISFIFO(mode
))
1353 return UNIX_TYPE_FIFO
;
1356 else if(S_ISSOCK(mode
))
1357 return UNIX_TYPE_SOCKET
;
1360 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode
));
1361 return UNIX_TYPE_UNKNOWN
;
1364 /****************************************************************************
1365 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1366 ****************************************************************************/
1368 enum perm_type
{ PERM_NEW_FILE
, PERM_NEW_DIR
, PERM_EXISTING_FILE
, PERM_EXISTING_DIR
};
1370 static NTSTATUS
unix_perms_from_wire( connection_struct
*conn
,
1371 const SMB_STRUCT_STAT
*psbuf
,
1373 enum perm_type ptype
,
1378 if (perms
== SMB_MODE_NO_CHANGE
) {
1379 if (!VALID_STAT(*psbuf
)) {
1380 return NT_STATUS_INVALID_PARAMETER
;
1382 *ret_perms
= psbuf
->st_ex_mode
;
1383 return NT_STATUS_OK
;
1387 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
1388 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
1389 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
1390 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
1391 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
1392 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
1393 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
1394 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
1395 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
1397 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
1400 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
1403 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
1408 case PERM_EXISTING_FILE
:
1409 /* Apply mode mask */
1410 ret
&= lp_create_mask(SNUM(conn
));
1411 /* Add in force bits */
1412 ret
|= lp_force_create_mode(SNUM(conn
));
1415 case PERM_EXISTING_DIR
:
1416 ret
&= lp_dir_mask(SNUM(conn
));
1417 /* Add in force bits */
1418 ret
|= lp_force_dir_mode(SNUM(conn
));
1423 return NT_STATUS_OK
;
1426 /****************************************************************************
1427 Needed to show the msdfs symlinks as directories. Modifies psbuf
1428 to be a directory if it's a msdfs link.
1429 ****************************************************************************/
1431 static bool check_msdfs_link(connection_struct
*conn
,
1432 const char *pathname
,
1433 SMB_STRUCT_STAT
*psbuf
)
1435 int saved_errno
= errno
;
1436 if(lp_host_msdfs() &&
1437 lp_msdfs_root(SNUM(conn
)) &&
1438 is_msdfs_link(conn
, pathname
, psbuf
)) {
1440 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1443 psbuf
->st_ex_mode
= (psbuf
->st_ex_mode
& 0xFFF) | S_IFDIR
;
1444 errno
= saved_errno
;
1447 errno
= saved_errno
;
1452 /****************************************************************************
1453 Get a level dependent lanman2 dir entry.
1454 ****************************************************************************/
1456 struct smbd_dirptr_lanman2_state
{
1457 connection_struct
*conn
;
1458 uint32_t info_level
;
1459 bool check_mangled_names
;
1461 bool got_exact_match
;
1464 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX
*ctx
,
1470 struct smbd_dirptr_lanman2_state
*state
=
1471 (struct smbd_dirptr_lanman2_state
*)private_data
;
1473 char mangled_name
[13]; /* mangled 8.3 name. */
1477 /* Mangle fname if it's an illegal name. */
1478 if (mangle_must_mangle(dname
, state
->conn
->params
)) {
1479 ok
= name_to_8_3(dname
, mangled_name
,
1480 true, state
->conn
->params
);
1484 fname
= mangled_name
;
1489 got_match
= exact_match(state
->has_wild
,
1490 state
->conn
->case_sensitive
,
1492 state
->got_exact_match
= got_match
;
1494 got_match
= mask_match(fname
, mask
,
1495 state
->conn
->case_sensitive
);
1498 if(!got_match
&& state
->check_mangled_names
&&
1499 !mangle_is_8_3(fname
, false, state
->conn
->params
)) {
1501 * It turns out that NT matches wildcards against
1502 * both long *and* short names. This may explain some
1503 * of the wildcard wierdness from old DOS clients
1504 * that some people have been seeing.... JRA.
1506 /* Force the mangling into 8.3. */
1507 ok
= name_to_8_3(fname
, mangled_name
,
1508 false, state
->conn
->params
);
1513 got_match
= exact_match(state
->has_wild
,
1514 state
->conn
->case_sensitive
,
1515 mangled_name
, mask
);
1516 state
->got_exact_match
= got_match
;
1518 got_match
= mask_match(mangled_name
, mask
,
1519 state
->conn
->case_sensitive
);
1527 *_fname
= talloc_strdup(ctx
, fname
);
1528 if (*_fname
== NULL
) {
1535 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX
*ctx
,
1537 struct smb_filename
*smb_fname
,
1540 struct smbd_dirptr_lanman2_state
*state
=
1541 (struct smbd_dirptr_lanman2_state
*)private_data
;
1542 bool ms_dfs_link
= false;
1545 if (INFO_LEVEL_IS_UNIX(state
->info_level
)) {
1546 if (SMB_VFS_LSTAT(state
->conn
, smb_fname
) != 0) {
1547 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1548 "Couldn't lstat [%s] (%s)\n",
1549 smb_fname_str_dbg(smb_fname
),
1553 } else if (!VALID_STAT(smb_fname
->st
) &&
1554 SMB_VFS_STAT(state
->conn
, smb_fname
) != 0) {
1555 /* Needed to show the msdfs symlinks as
1558 ms_dfs_link
= check_msdfs_link(state
->conn
,
1559 smb_fname
->base_name
,
1562 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1563 "Couldn't stat [%s] (%s)\n",
1564 smb_fname_str_dbg(smb_fname
),
1571 mode
= dos_mode_msdfs(state
->conn
, smb_fname
);
1573 mode
= dos_mode(state
->conn
, smb_fname
);
1580 static bool smbd_marshall_dir_entry(TALLOC_CTX
*ctx
,
1581 connection_struct
*conn
,
1583 uint32_t info_level
,
1584 struct ea_list
*name_list
,
1585 bool check_mangled_names
,
1586 bool requires_resume_key
,
1589 const struct smb_filename
*smb_fname
,
1590 int space_remaining
,
1597 uint64_t *last_entry_off
)
1599 char *p
, *q
, *pdata
= *ppdata
;
1601 uint64_t file_size
= 0;
1602 uint64_t allocation_size
= 0;
1603 uint64_t file_index
= 0;
1605 struct timespec mdate_ts
, adate_ts
, cdate_ts
, create_date_ts
;
1606 time_t mdate
= (time_t)0, adate
= (time_t)0, create_date
= (time_t)0;
1608 char *last_entry_ptr
;
1613 *out_of_space
= false;
1615 ZERO_STRUCT(mdate_ts
);
1616 ZERO_STRUCT(adate_ts
);
1617 ZERO_STRUCT(create_date_ts
);
1618 ZERO_STRUCT(cdate_ts
);
1620 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
1621 file_size
= get_file_size_stat(&smb_fname
->st
);
1623 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, NULL
, &smb_fname
->st
);
1625 file_index
= get_FileIndex(conn
, &smb_fname
->st
);
1627 mdate_ts
= smb_fname
->st
.st_ex_mtime
;
1628 adate_ts
= smb_fname
->st
.st_ex_atime
;
1629 create_date_ts
= get_create_timespec(conn
, NULL
, smb_fname
);
1630 cdate_ts
= get_change_timespec(conn
, NULL
, smb_fname
);
1632 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1633 dos_filetime_timespec(&create_date_ts
);
1634 dos_filetime_timespec(&mdate_ts
);
1635 dos_filetime_timespec(&adate_ts
);
1636 dos_filetime_timespec(&cdate_ts
);
1639 create_date
= convert_timespec_to_time_t(create_date_ts
);
1640 mdate
= convert_timespec_to_time_t(mdate_ts
);
1641 adate
= convert_timespec_to_time_t(adate_ts
);
1643 /* align the record */
1644 SMB_ASSERT(align
>= 1);
1646 off
= (int)PTR_DIFF(pdata
, base_data
);
1647 pad
= (off
+ (align
-1)) & ~(align
-1);
1650 if (pad
&& pad
> space_remaining
) {
1651 *out_of_space
= true;
1652 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1653 "for padding (wanted %u, had %d)\n",
1656 return false; /* Not finished - just out of space */
1660 /* initialize padding to 0 */
1662 memset(pdata
, 0, pad
);
1664 space_remaining
-= pad
;
1666 DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1676 switch (info_level
) {
1677 case SMB_FIND_INFO_STANDARD
:
1678 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1679 if(requires_resume_key
) {
1683 srv_put_dos_date2(p
,0,create_date
);
1684 srv_put_dos_date2(p
,4,adate
);
1685 srv_put_dos_date2(p
,8,mdate
);
1686 SIVAL(p
,12,(uint32
)file_size
);
1687 SIVAL(p
,16,(uint32
)allocation_size
);
1691 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1692 p
+= ucs2_align(base_data
, p
, 0);
1694 len
= srvstr_push(base_data
, flags2
, p
,
1695 fname
, PTR_DIFF(end_data
, p
),
1697 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1699 SCVAL(nameptr
, -1, len
- 2);
1701 SCVAL(nameptr
, -1, 0);
1705 SCVAL(nameptr
, -1, len
- 1);
1707 SCVAL(nameptr
, -1, 0);
1713 case SMB_FIND_EA_SIZE
:
1714 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1715 if (requires_resume_key
) {
1719 srv_put_dos_date2(p
,0,create_date
);
1720 srv_put_dos_date2(p
,4,adate
);
1721 srv_put_dos_date2(p
,8,mdate
);
1722 SIVAL(p
,12,(uint32
)file_size
);
1723 SIVAL(p
,16,(uint32
)allocation_size
);
1726 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1728 SIVAL(p
,22,ea_size
); /* Extended attributes */
1732 len
= srvstr_push(base_data
, flags2
,
1733 p
, fname
, PTR_DIFF(end_data
, p
),
1734 STR_TERMINATE
| STR_NOALIGN
);
1735 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1748 SCVAL(nameptr
,0,len
);
1750 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1753 case SMB_FIND_EA_LIST
:
1755 struct ea_list
*file_list
= NULL
;
1759 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1763 if (requires_resume_key
) {
1767 srv_put_dos_date2(p
,0,create_date
);
1768 srv_put_dos_date2(p
,4,adate
);
1769 srv_put_dos_date2(p
,8,mdate
);
1770 SIVAL(p
,12,(uint32
)file_size
);
1771 SIVAL(p
,16,(uint32
)allocation_size
);
1773 p
+= 22; /* p now points to the EA area. */
1775 status
= get_ea_list_from_file(ctx
, conn
, NULL
,
1777 &ea_len
, &file_list
);
1778 if (!NT_STATUS_IS_OK(status
)) {
1781 name_list
= ea_list_union(name_list
, file_list
, &ea_len
);
1783 /* We need to determine if this entry will fit in the space available. */
1784 /* Max string size is 255 bytes. */
1785 if (PTR_DIFF(p
+ 255 + ea_len
,pdata
) > space_remaining
) {
1786 *out_of_space
= true;
1787 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1788 "(wanted %u, had %d)\n",
1789 (unsigned int)PTR_DIFF(p
+ 255 + ea_len
,pdata
),
1791 return False
; /* Not finished - just out of space */
1794 /* Push the ea_data followed by the name. */
1795 p
+= fill_ea_buffer(ctx
, p
, space_remaining
, conn
, name_list
);
1797 len
= srvstr_push(base_data
, flags2
,
1798 p
+ 1, fname
, PTR_DIFF(end_data
, p
+1),
1799 STR_TERMINATE
| STR_NOALIGN
);
1800 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1813 SCVAL(nameptr
,0,len
);
1815 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1819 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1820 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1821 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1823 SIVAL(p
,0,reskey
); p
+= 4;
1824 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1825 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1826 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1827 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1828 SOFF_T(p
,0,file_size
); p
+= 8;
1829 SOFF_T(p
,0,allocation_size
); p
+= 8;
1830 SIVAL(p
,0,mode
); p
+= 4;
1831 q
= p
; p
+= 4; /* q is placeholder for name length. */
1833 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1835 SIVAL(p
,0,ea_size
); /* Extended attributes */
1838 /* Clear the short name buffer. This is
1839 * IMPORTANT as not doing so will trigger
1840 * a Win2k client bug. JRA.
1842 if (!was_8_3
&& check_mangled_names
) {
1843 char mangled_name
[13]; /* mangled 8.3 name. */
1844 if (!name_to_8_3(fname
,mangled_name
,True
,
1846 /* Error - mangle failed ! */
1847 memset(mangled_name
,'\0',12);
1849 mangled_name
[12] = 0;
1850 len
= srvstr_push(base_data
, flags2
,
1851 p
+2, mangled_name
, 24,
1852 STR_UPPER
|STR_UNICODE
);
1854 memset(p
+ 2 + len
,'\0',24 - len
);
1861 len
= srvstr_push(base_data
, flags2
, p
,
1862 fname
, PTR_DIFF(end_data
, p
),
1863 STR_TERMINATE_ASCII
);
1867 len
= PTR_DIFF(p
, pdata
);
1868 pad
= (len
+ (align
-1)) & ~(align
-1);
1870 * offset to the next entry, the caller
1871 * will overwrite it for the last entry
1872 * that's why we always include the padding
1876 * set padding to zero
1879 memset(p
, 0, pad
- len
);
1886 case SMB_FIND_FILE_DIRECTORY_INFO
:
1887 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1889 SIVAL(p
,0,reskey
); p
+= 4;
1890 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1891 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1892 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1893 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1894 SOFF_T(p
,0,file_size
); p
+= 8;
1895 SOFF_T(p
,0,allocation_size
); p
+= 8;
1896 SIVAL(p
,0,mode
); p
+= 4;
1897 len
= srvstr_push(base_data
, flags2
,
1898 p
+ 4, fname
, PTR_DIFF(end_data
, p
+4),
1899 STR_TERMINATE_ASCII
);
1903 len
= PTR_DIFF(p
, pdata
);
1904 pad
= (len
+ (align
-1)) & ~(align
-1);
1906 * offset to the next entry, the caller
1907 * will overwrite it for the last entry
1908 * that's why we always include the padding
1912 * set padding to zero
1915 memset(p
, 0, pad
- len
);
1922 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1923 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1925 SIVAL(p
,0,reskey
); p
+= 4;
1926 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1927 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1928 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1929 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1930 SOFF_T(p
,0,file_size
); p
+= 8;
1931 SOFF_T(p
,0,allocation_size
); p
+= 8;
1932 SIVAL(p
,0,mode
); p
+= 4;
1933 q
= p
; p
+= 4; /* q is placeholder for name length. */
1935 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1937 SIVAL(p
,0,ea_size
); /* Extended attributes */
1940 len
= srvstr_push(base_data
, flags2
, p
,
1941 fname
, PTR_DIFF(end_data
, p
),
1942 STR_TERMINATE_ASCII
);
1946 len
= PTR_DIFF(p
, pdata
);
1947 pad
= (len
+ (align
-1)) & ~(align
-1);
1949 * offset to the next entry, the caller
1950 * will overwrite it for the last entry
1951 * that's why we always include the padding
1955 * set padding to zero
1958 memset(p
, 0, pad
- len
);
1965 case SMB_FIND_FILE_NAMES_INFO
:
1966 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1968 SIVAL(p
,0,reskey
); p
+= 4;
1970 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1971 acl on a dir (tridge) */
1972 len
= srvstr_push(base_data
, flags2
, p
,
1973 fname
, PTR_DIFF(end_data
, p
),
1974 STR_TERMINATE_ASCII
);
1978 len
= PTR_DIFF(p
, pdata
);
1979 pad
= (len
+ (align
-1)) & ~(align
-1);
1981 * offset to the next entry, the caller
1982 * will overwrite it for the last entry
1983 * that's why we always include the padding
1987 * set padding to zero
1990 memset(p
, 0, pad
- len
);
1997 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1998 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
2000 SIVAL(p
,0,reskey
); p
+= 4;
2001 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
2002 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
2003 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
2004 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
2005 SOFF_T(p
,0,file_size
); p
+= 8;
2006 SOFF_T(p
,0,allocation_size
); p
+= 8;
2007 SIVAL(p
,0,mode
); p
+= 4;
2008 q
= p
; p
+= 4; /* q is placeholder for name length. */
2010 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
2012 SIVAL(p
,0,ea_size
); /* Extended attributes */
2015 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
2016 SBVAL(p
,0,file_index
); p
+= 8;
2017 len
= srvstr_push(base_data
, flags2
, p
,
2018 fname
, PTR_DIFF(end_data
, p
),
2019 STR_TERMINATE_ASCII
);
2023 len
= PTR_DIFF(p
, pdata
);
2024 pad
= (len
+ (align
-1)) & ~(align
-1);
2026 * offset to the next entry, the caller
2027 * will overwrite it for the last entry
2028 * that's why we always include the padding
2032 * set padding to zero
2035 memset(p
, 0, pad
- len
);
2042 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2043 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
2044 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
2046 SIVAL(p
,0,reskey
); p
+= 4;
2047 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
2048 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
2049 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
2050 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
2051 SOFF_T(p
,0,file_size
); p
+= 8;
2052 SOFF_T(p
,0,allocation_size
); p
+= 8;
2053 SIVAL(p
,0,mode
); p
+= 4;
2054 q
= p
; p
+= 4; /* q is placeholder for name length */
2056 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
2058 SIVAL(p
,0,ea_size
); /* Extended attributes */
2061 /* Clear the short name buffer. This is
2062 * IMPORTANT as not doing so will trigger
2063 * a Win2k client bug. JRA.
2065 if (!was_8_3
&& check_mangled_names
) {
2066 char mangled_name
[13]; /* mangled 8.3 name. */
2067 if (!name_to_8_3(fname
,mangled_name
,True
,
2069 /* Error - mangle failed ! */
2070 memset(mangled_name
,'\0',12);
2072 mangled_name
[12] = 0;
2073 len
= srvstr_push(base_data
, flags2
,
2074 p
+2, mangled_name
, 24,
2075 STR_UPPER
|STR_UNICODE
);
2078 memset(p
+ 2 + len
,'\0',24 - len
);
2085 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
2086 SBVAL(p
,0,file_index
); p
+= 8;
2087 len
= srvstr_push(base_data
, flags2
, p
,
2088 fname
, PTR_DIFF(end_data
, p
),
2089 STR_TERMINATE_ASCII
);
2093 len
= PTR_DIFF(p
, pdata
);
2094 pad
= (len
+ (align
-1)) & ~(align
-1);
2096 * offset to the next entry, the caller
2097 * will overwrite it for the last entry
2098 * that's why we always include the padding
2102 * set padding to zero
2105 memset(p
, 0, pad
- len
);
2112 /* CIFS UNIX Extension. */
2114 case SMB_FIND_FILE_UNIX
:
2115 case SMB_FIND_FILE_UNIX_INFO2
:
2117 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
2119 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2121 if (info_level
== SMB_FIND_FILE_UNIX
) {
2122 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2123 p
= store_file_unix_basic(conn
, p
,
2124 NULL
, &smb_fname
->st
);
2125 len
= srvstr_push(base_data
, flags2
, p
,
2126 fname
, PTR_DIFF(end_data
, p
),
2129 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2130 p
= store_file_unix_basic_info2(conn
, p
,
2131 NULL
, &smb_fname
->st
);
2134 len
= srvstr_push(base_data
, flags2
, p
, fname
,
2135 PTR_DIFF(end_data
, p
), 0);
2136 SIVAL(nameptr
, 0, len
);
2141 len
= PTR_DIFF(p
, pdata
);
2142 pad
= (len
+ (align
-1)) & ~(align
-1);
2144 * offset to the next entry, the caller
2145 * will overwrite it for the last entry
2146 * that's why we always include the padding
2150 * set padding to zero
2153 memset(p
, 0, pad
- len
);
2158 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2166 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
2167 *out_of_space
= true;
2168 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2169 "(wanted %u, had %d)\n",
2170 (unsigned int)PTR_DIFF(p
,pdata
),
2172 return false; /* Not finished - just out of space */
2175 /* Setup the last entry pointer, as an offset from base_data */
2176 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
2177 /* Advance the data pointer to the next slot */
2183 bool smbd_dirptr_lanman2_entry(TALLOC_CTX
*ctx
,
2184 connection_struct
*conn
,
2185 struct dptr_struct
*dirptr
,
2187 const char *path_mask
,
2190 int requires_resume_key
,
2198 int space_remaining
,
2200 bool *got_exact_match
,
2201 int *_last_entry_off
,
2202 struct ea_list
*name_list
)
2205 const char *mask
= NULL
;
2206 long prev_dirpos
= 0;
2209 struct smb_filename
*smb_fname
= NULL
;
2210 struct smbd_dirptr_lanman2_state state
;
2212 uint64_t last_entry_off
= 0;
2216 state
.info_level
= info_level
;
2217 state
.check_mangled_names
= lp_manglednames(conn
->params
);
2218 state
.has_wild
= dptr_has_wild(dirptr
);
2219 state
.got_exact_match
= false;
2221 *out_of_space
= false;
2222 *got_exact_match
= false;
2224 p
= strrchr_m(path_mask
,'/');
2235 ok
= smbd_dirptr_get_entry(ctx
,
2241 smbd_dirptr_lanman2_match_fn
,
2242 smbd_dirptr_lanman2_mode_fn
,
2252 *got_exact_match
= state
.got_exact_match
;
2254 ok
= smbd_marshall_dir_entry(ctx
,
2259 state
.check_mangled_names
,
2260 requires_resume_key
,
2273 TALLOC_FREE(smb_fname
);
2274 if (*out_of_space
) {
2275 dptr_SeekDir(dirptr
, prev_dirpos
);
2282 *_last_entry_off
= last_entry_off
;
2286 static bool get_lanman2_dir_entry(TALLOC_CTX
*ctx
,
2287 connection_struct
*conn
,
2288 struct dptr_struct
*dirptr
,
2290 const char *path_mask
,
2293 bool requires_resume_key
,
2299 int space_remaining
,
2301 bool *got_exact_match
,
2302 int *last_entry_off
,
2303 struct ea_list
*name_list
)
2306 const bool do_pad
= true;
2308 if (info_level
>= 1 && info_level
<= 3) {
2309 /* No alignment on earlier info levels. */
2313 return smbd_dirptr_lanman2_entry(ctx
, conn
, dirptr
, flags2
,
2314 path_mask
, dirtype
, info_level
,
2315 requires_resume_key
, dont_descend
, ask_sharemode
,
2317 ppdata
, base_data
, end_data
,
2319 out_of_space
, got_exact_match
,
2320 last_entry_off
, name_list
);
2323 /****************************************************************************
2324 Reply to a TRANS2_FINDFIRST.
2325 ****************************************************************************/
2327 static void call_trans2findfirst(connection_struct
*conn
,
2328 struct smb_request
*req
,
2329 char **pparams
, int total_params
,
2330 char **ppdata
, int total_data
,
2331 unsigned int max_data_bytes
)
2333 /* We must be careful here that we don't return more than the
2334 allowed number of data bytes. If this means returning fewer than
2335 maxentries then so be it. We assume that the redirector has
2336 enough room for the fixed number of parameter bytes it has
2338 struct smb_filename
*smb_dname
= NULL
;
2339 char *params
= *pparams
;
2340 char *pdata
= *ppdata
;
2344 uint16 findfirst_flags
;
2345 bool close_after_first
;
2347 bool requires_resume_key
;
2349 char *directory
= NULL
;
2352 int last_entry_off
=0;
2356 bool finished
= False
;
2357 bool dont_descend
= False
;
2358 bool out_of_space
= False
;
2359 int space_remaining
;
2360 bool mask_contains_wcard
= False
;
2361 struct ea_list
*ea_list
= NULL
;
2362 NTSTATUS ntstatus
= NT_STATUS_OK
;
2363 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2364 TALLOC_CTX
*ctx
= talloc_tos();
2365 struct dptr_struct
*dirptr
= NULL
;
2366 struct smbd_server_connection
*sconn
= req
->sconn
;
2367 uint32_t ucf_flags
= (UCF_SAVE_LCOMP
| UCF_ALWAYS_ALLOW_WCARD_LCOMP
);
2368 bool backup_priv
= false;
2370 if (total_params
< 13) {
2371 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2375 dirtype
= SVAL(params
,0);
2376 maxentries
= SVAL(params
,2);
2377 findfirst_flags
= SVAL(params
,4);
2378 close_after_first
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE
);
2379 close_if_end
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2380 requires_resume_key
= (findfirst_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2381 backup_priv
= ((findfirst_flags
& FLAG_TRANS2_FIND_BACKUP_INTENT
) &&
2382 security_token_has_privilege(get_current_nttok(conn
),
2385 info_level
= SVAL(params
,6);
2387 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2388 close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
2389 (unsigned int)dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
2391 info_level
, max_data_bytes
));
2394 /* W2K3 seems to treat zero as 1. */
2398 switch (info_level
) {
2399 case SMB_FIND_INFO_STANDARD
:
2400 case SMB_FIND_EA_SIZE
:
2401 case SMB_FIND_EA_LIST
:
2402 case SMB_FIND_FILE_DIRECTORY_INFO
:
2403 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2404 case SMB_FIND_FILE_NAMES_INFO
:
2405 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2406 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2407 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2409 case SMB_FIND_FILE_UNIX
:
2410 case SMB_FIND_FILE_UNIX_INFO2
:
2411 /* Always use filesystem for UNIX mtime query. */
2412 ask_sharemode
= false;
2413 if (!lp_unix_extensions()) {
2414 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2417 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
2420 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2424 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &directory
,
2425 params
+12, total_params
- 12,
2426 STR_TERMINATE
, &ntstatus
, &mask_contains_wcard
);
2427 if (!NT_STATUS_IS_OK(ntstatus
)) {
2428 reply_nterror(req
, ntstatus
);
2434 ntstatus
= filename_convert_with_privilege(ctx
,
2439 &mask_contains_wcard
,
2442 ntstatus
= filename_convert(ctx
, conn
,
2443 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2446 &mask_contains_wcard
,
2450 if (!NT_STATUS_IS_OK(ntstatus
)) {
2451 if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_PATH_NOT_COVERED
)) {
2452 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
2453 ERRSRV
, ERRbadpath
);
2456 reply_nterror(req
, ntstatus
);
2460 mask
= smb_dname
->original_lcomp
;
2462 directory
= smb_dname
->base_name
;
2464 p
= strrchr_m(directory
,'/');
2466 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2467 if((directory
[0] == '.') && (directory
[1] == '\0')) {
2468 mask
= talloc_strdup(ctx
,"*");
2470 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2473 mask_contains_wcard
= True
;
2479 if (p
== NULL
|| p
== directory
) {
2480 /* Ensure we don't have a directory name of "". */
2481 directory
= talloc_strdup(talloc_tos(), ".");
2483 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2488 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
2490 if (info_level
== SMB_FIND_EA_LIST
) {
2493 if (total_data
< 4) {
2494 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2498 ea_size
= IVAL(pdata
,0);
2499 if (ea_size
!= total_data
) {
2500 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2501 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2502 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2506 if (!lp_ea_support(SNUM(conn
))) {
2507 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2511 /* Pull out the list of names. */
2512 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2514 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2519 *ppdata
= (char *)SMB_REALLOC(
2520 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2521 if(*ppdata
== NULL
) {
2522 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2526 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2528 /* Realloc the params space */
2529 *pparams
= (char *)SMB_REALLOC(*pparams
, 10);
2530 if (*pparams
== NULL
) {
2531 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2536 /* Save the wildcard match and attribs we are using on this directory -
2537 needed as lanman2 assumes these are being saved between calls */
2539 ntstatus
= dptr_create(conn
,
2547 mask_contains_wcard
,
2551 if (!NT_STATUS_IS_OK(ntstatus
)) {
2552 reply_nterror(req
, ntstatus
);
2557 /* Remember this in case we have
2558 to do a findnext. */
2559 dptr_set_priv(dirptr
);
2562 dptr_num
= dptr_dnum(dirptr
);
2563 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num
, mask
, dirtype
));
2565 /* Initialize per TRANS2_FIND_FIRST operation data */
2566 dptr_init_search_op(dirptr
);
2568 /* We don't need to check for VOL here as this is returned by
2569 a different TRANS2 call. */
2571 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2572 directory
,lp_dontdescend(ctx
, SNUM(conn
))));
2573 if (in_list(directory
,lp_dontdescend(ctx
, SNUM(conn
)),conn
->case_sensitive
))
2574 dont_descend
= True
;
2577 space_remaining
= max_data_bytes
;
2578 out_of_space
= False
;
2580 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
2581 bool got_exact_match
= False
;
2583 /* this is a heuristic to avoid seeking the dirptr except when
2584 absolutely necessary. It allows for a filename of about 40 chars */
2585 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2586 out_of_space
= True
;
2589 finished
= !get_lanman2_dir_entry(ctx
,
2593 mask
,dirtype
,info_level
,
2594 requires_resume_key
,dont_descend
,
2597 space_remaining
, &out_of_space
,
2599 &last_entry_off
, ea_list
);
2602 if (finished
&& out_of_space
)
2605 if (!finished
&& !out_of_space
)
2609 * As an optimisation if we know we aren't looking
2610 * for a wildcard name (ie. the name matches the wildcard exactly)
2611 * then we can finish on any (first) match.
2612 * This speeds up large directory searches. JRA.
2618 /* Ensure space_remaining never goes -ve. */
2619 if (PTR_DIFF(p
,pdata
) > max_data_bytes
) {
2620 space_remaining
= 0;
2621 out_of_space
= true;
2623 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2627 /* Check if we can close the dirptr */
2628 if(close_after_first
|| (finished
&& close_if_end
)) {
2629 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
2630 dptr_close(sconn
, &dptr_num
);
2634 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2635 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2636 * the protocol level is less than NT1. Tested with smbclient. JRA.
2637 * This should fix the OS/2 client bug #2335.
2640 if(numentries
== 0) {
2641 dptr_close(sconn
, &dptr_num
);
2642 if (get_Protocol() < PROTOCOL_NT1
) {
2643 reply_force_doserror(req
, ERRDOS
, ERRnofiles
);
2646 reply_botherror(req
, NT_STATUS_NO_SUCH_FILE
,
2647 ERRDOS
, ERRbadfile
);
2652 /* At this point pdata points to numentries directory entries. */
2654 /* Set up the return parameter block */
2655 SSVAL(params
,0,dptr_num
);
2656 SSVAL(params
,2,numentries
);
2657 SSVAL(params
,4,finished
);
2658 SSVAL(params
,6,0); /* Never an EA error */
2659 SSVAL(params
,8,last_entry_off
);
2661 send_trans2_replies(conn
, req
, params
, 10, pdata
, PTR_DIFF(p
,pdata
),
2664 if ((! *directory
) && dptr_path(sconn
, dptr_num
)) {
2665 directory
= talloc_strdup(talloc_tos(),dptr_path(sconn
, dptr_num
));
2667 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2671 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2672 smb_fn_name(req
->cmd
),
2673 mask
, directory
, dirtype
, numentries
) );
2676 * Force a name mangle here to ensure that the
2677 * mask as an 8.3 name is top of the mangled cache.
2678 * The reasons for this are subtle. Don't remove
2679 * this code unless you know what you are doing
2680 * (see PR#13758). JRA.
2683 if(!mangle_is_8_3_wildcards( mask
, False
, conn
->params
)) {
2684 char mangled_name
[13];
2685 name_to_8_3(mask
, mangled_name
, True
, conn
->params
);
2693 TALLOC_FREE(smb_dname
);
2697 /****************************************************************************
2698 Reply to a TRANS2_FINDNEXT.
2699 ****************************************************************************/
2701 static void call_trans2findnext(connection_struct
*conn
,
2702 struct smb_request
*req
,
2703 char **pparams
, int total_params
,
2704 char **ppdata
, int total_data
,
2705 unsigned int max_data_bytes
)
2707 /* We must be careful here that we don't return more than the
2708 allowed number of data bytes. If this means returning fewer than
2709 maxentries then so be it. We assume that the redirector has
2710 enough room for the fixed number of parameter bytes it has
2712 char *params
= *pparams
;
2713 char *pdata
= *ppdata
;
2719 uint16 findnext_flags
;
2720 bool close_after_request
;
2722 bool requires_resume_key
;
2724 bool mask_contains_wcard
= False
;
2725 char *resume_name
= NULL
;
2726 const char *mask
= NULL
;
2727 const char *directory
= NULL
;
2731 int i
, last_entry_off
=0;
2732 bool finished
= False
;
2733 bool dont_descend
= False
;
2734 bool out_of_space
= False
;
2735 int space_remaining
;
2736 struct ea_list
*ea_list
= NULL
;
2737 NTSTATUS ntstatus
= NT_STATUS_OK
;
2738 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2739 TALLOC_CTX
*ctx
= talloc_tos();
2740 struct dptr_struct
*dirptr
;
2741 struct smbd_server_connection
*sconn
= req
->sconn
;
2742 bool backup_priv
= false;
2744 if (total_params
< 13) {
2745 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2749 dptr_num
= SVAL(params
,0);
2750 maxentries
= SVAL(params
,2);
2751 info_level
= SVAL(params
,4);
2752 resume_key
= IVAL(params
,6);
2753 findnext_flags
= SVAL(params
,10);
2754 close_after_request
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE
);
2755 close_if_end
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2756 requires_resume_key
= (findnext_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2757 continue_bit
= (findnext_flags
& FLAG_TRANS2_FIND_CONTINUE
);
2759 if (!continue_bit
) {
2760 /* We only need resume_name if continue_bit is zero. */
2761 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &resume_name
,
2763 total_params
- 12, STR_TERMINATE
, &ntstatus
,
2764 &mask_contains_wcard
);
2765 if (!NT_STATUS_IS_OK(ntstatus
)) {
2766 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2767 complain (it thinks we're asking for the directory above the shared
2768 path or an invalid name). Catch this as the resume name is only compared, never used in
2769 a file access. JRA. */
2770 srvstr_pull_talloc(ctx
, params
, req
->flags2
,
2771 &resume_name
, params
+12,
2775 if (!resume_name
|| !(ISDOT(resume_name
) || ISDOTDOT(resume_name
))) {
2776 reply_nterror(req
, ntstatus
);
2782 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2783 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2784 resume_key = %d resume name = %s continue=%d level = %d\n",
2785 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
2786 requires_resume_key
, resume_key
,
2787 resume_name
? resume_name
: "(NULL)", continue_bit
, info_level
));
2790 /* W2K3 seems to treat zero as 1. */
2794 switch (info_level
) {
2795 case SMB_FIND_INFO_STANDARD
:
2796 case SMB_FIND_EA_SIZE
:
2797 case SMB_FIND_EA_LIST
:
2798 case SMB_FIND_FILE_DIRECTORY_INFO
:
2799 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2800 case SMB_FIND_FILE_NAMES_INFO
:
2801 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2802 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2803 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2805 case SMB_FIND_FILE_UNIX
:
2806 case SMB_FIND_FILE_UNIX_INFO2
:
2807 /* Always use filesystem for UNIX mtime query. */
2808 ask_sharemode
= false;
2809 if (!lp_unix_extensions()) {
2810 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2815 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2819 if (info_level
== SMB_FIND_EA_LIST
) {
2822 if (total_data
< 4) {
2823 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2827 ea_size
= IVAL(pdata
,0);
2828 if (ea_size
!= total_data
) {
2829 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2830 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2831 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2835 if (!lp_ea_support(SNUM(conn
))) {
2836 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2840 /* Pull out the list of names. */
2841 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2843 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2848 *ppdata
= (char *)SMB_REALLOC(
2849 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2850 if(*ppdata
== NULL
) {
2851 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2856 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2858 /* Realloc the params space */
2859 *pparams
= (char *)SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
2860 if(*pparams
== NULL
) {
2861 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2867 /* Check that the dptr is valid */
2868 if(!(dirptr
= dptr_fetch_lanman2(sconn
, dptr_num
))) {
2869 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2873 directory
= dptr_path(sconn
, dptr_num
);
2875 /* Get the wildcard mask from the dptr */
2876 if((mask
= dptr_wcard(sconn
, dptr_num
))== NULL
) {
2877 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
2878 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2882 /* Get the attr mask from the dptr */
2883 dirtype
= dptr_attr(sconn
, dptr_num
);
2885 backup_priv
= dptr_get_priv(dirptr
);
2887 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
2888 "backup_priv = %d\n",
2889 dptr_num
, mask
, dirtype
,
2891 dptr_TellDir(dirptr
),
2894 /* Initialize per TRANS2_FIND_NEXT operation data */
2895 dptr_init_search_op(dirptr
);
2897 /* We don't need to check for VOL here as this is returned by
2898 a different TRANS2 call. */
2900 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2901 directory
,lp_dontdescend(ctx
, SNUM(conn
))));
2902 if (in_list(directory
,lp_dontdescend(ctx
, SNUM(conn
)),conn
->case_sensitive
))
2903 dont_descend
= True
;
2906 space_remaining
= max_data_bytes
;
2907 out_of_space
= False
;
2914 * Seek to the correct position. We no longer use the resume key but
2915 * depend on the last file name instead.
2918 if(!continue_bit
&& resume_name
&& *resume_name
) {
2921 long current_pos
= 0;
2923 * Remember, name_to_8_3 is called by
2924 * get_lanman2_dir_entry(), so the resume name
2925 * could be mangled. Ensure we check the unmangled name.
2928 if (mangle_is_mangled(resume_name
, conn
->params
)) {
2929 char *new_resume_name
= NULL
;
2930 mangle_lookup_name_from_8_3(ctx
,
2934 if (new_resume_name
) {
2935 resume_name
= new_resume_name
;
2940 * Fix for NT redirector problem triggered by resume key indexes
2941 * changing between directory scans. We now return a resume key of 0
2942 * and instead look for the filename to continue from (also given
2943 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2944 * findfirst/findnext (as is usual) then the directory pointer
2945 * should already be at the correct place.
2948 finished
= !dptr_SearchDir(dirptr
, resume_name
, ¤t_pos
, &st
);
2949 } /* end if resume_name && !continue_bit */
2951 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
2952 bool got_exact_match
= False
;
2954 /* this is a heuristic to avoid seeking the dirptr except when
2955 absolutely necessary. It allows for a filename of about 40 chars */
2956 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2957 out_of_space
= True
;
2960 finished
= !get_lanman2_dir_entry(ctx
,
2964 mask
,dirtype
,info_level
,
2965 requires_resume_key
,dont_descend
,
2968 space_remaining
, &out_of_space
,
2970 &last_entry_off
, ea_list
);
2973 if (finished
&& out_of_space
)
2976 if (!finished
&& !out_of_space
)
2980 * As an optimisation if we know we aren't looking
2981 * for a wildcard name (ie. the name matches the wildcard exactly)
2982 * then we can finish on any (first) match.
2983 * This speeds up large directory searches. JRA.
2989 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2992 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2993 smb_fn_name(req
->cmd
),
2994 mask
, directory
, dirtype
, numentries
) );
2996 /* Check if we can close the dirptr */
2997 if(close_after_request
|| (finished
&& close_if_end
)) {
2998 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
2999 dptr_close(sconn
, &dptr_num
); /* This frees up the saved mask */
3006 /* Set up the return parameter block */
3007 SSVAL(params
,0,numentries
);
3008 SSVAL(params
,2,finished
);
3009 SSVAL(params
,4,0); /* Never an EA error */
3010 SSVAL(params
,6,last_entry_off
);
3012 send_trans2_replies(conn
, req
, params
, 8, pdata
, PTR_DIFF(p
,pdata
),
3018 unsigned char *create_volume_objectid(connection_struct
*conn
, unsigned char objid
[16])
3020 E_md4hash(lp_servicename(talloc_tos(), SNUM(conn
)),objid
);
3024 static void samba_extended_info_version(struct smb_extended_info
*extended_info
)
3026 SMB_ASSERT(extended_info
!= NULL
);
3028 extended_info
->samba_magic
= SAMBA_EXTENDED_INFO_MAGIC
;
3029 extended_info
->samba_version
= ((SAMBA_VERSION_MAJOR
& 0xff) << 24)
3030 | ((SAMBA_VERSION_MINOR
& 0xff) << 16)
3031 | ((SAMBA_VERSION_RELEASE
& 0xff) << 8);
3032 #ifdef SAMBA_VERSION_REVISION
3033 extended_info
->samba_version
|= (tolower(*SAMBA_VERSION_REVISION
) - 'a' + 1) & 0xff;
3035 extended_info
->samba_subversion
= 0;
3036 #ifdef SAMBA_VERSION_RC_RELEASE
3037 extended_info
->samba_subversion
|= (SAMBA_VERSION_RC_RELEASE
& 0xff) << 24;
3039 #ifdef SAMBA_VERSION_PRE_RELEASE
3040 extended_info
->samba_subversion
|= (SAMBA_VERSION_PRE_RELEASE
& 0xff) << 16;
3043 #ifdef SAMBA_VERSION_VENDOR_PATCH
3044 extended_info
->samba_subversion
|= (SAMBA_VERSION_VENDOR_PATCH
& 0xffff);
3046 extended_info
->samba_gitcommitdate
= 0;
3047 #ifdef SAMBA_VERSION_COMMIT_TIME
3048 unix_to_nt_time(&extended_info
->samba_gitcommitdate
, SAMBA_VERSION_COMMIT_TIME
);
3051 memset(extended_info
->samba_version_string
, 0,
3052 sizeof(extended_info
->samba_version_string
));
3054 snprintf (extended_info
->samba_version_string
,
3055 sizeof(extended_info
->samba_version_string
),
3056 "%s", samba_version_string());
3059 NTSTATUS
smbd_do_qfsinfo(connection_struct
*conn
,
3060 TALLOC_CTX
*mem_ctx
,
3061 uint16_t info_level
,
3063 unsigned int max_data_bytes
,
3064 struct smb_filename
*fname
,
3068 char *pdata
, *end_data
;
3069 int data_len
= 0, len
;
3070 const char *vname
= volume_label(talloc_tos(), SNUM(conn
));
3071 int snum
= SNUM(conn
);
3072 char *fstype
= lp_fstype(talloc_tos(), SNUM(conn
));
3073 char *filename
= NULL
;
3074 uint32 additional_flags
= 0;
3075 struct smb_filename smb_fname
;
3078 if (fname
== NULL
|| fname
->base_name
== NULL
) {
3081 filename
= fname
->base_name
;
3085 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3086 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3087 "info level (0x%x) on IPC$.\n",
3088 (unsigned int)info_level
));
3089 return NT_STATUS_ACCESS_DENIED
;
3093 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level
));
3095 ZERO_STRUCT(smb_fname
);
3096 smb_fname
.base_name
= discard_const_p(char, filename
);
3098 if(SMB_VFS_STAT(conn
, &smb_fname
) != 0) {
3099 DEBUG(2,("stat of . failed (%s)\n", strerror(errno
)));
3100 return map_nt_error_from_unix(errno
);
3105 *ppdata
= (char *)SMB_REALLOC(
3106 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3107 if (*ppdata
== NULL
) {
3108 return NT_STATUS_NO_MEMORY
;
3112 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3113 end_data
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
3115 switch (info_level
) {
3116 case SMB_INFO_ALLOCATION
:
3118 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3120 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3121 return map_nt_error_from_unix(errno
);
3124 block_size
= lp_block_size(snum
);
3125 if (bsize
< block_size
) {
3126 uint64_t factor
= block_size
/bsize
;
3131 if (bsize
> block_size
) {
3132 uint64_t factor
= bsize
/block_size
;
3137 bytes_per_sector
= 512;
3138 sectors_per_unit
= bsize
/bytes_per_sector
;
3140 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3141 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_ex_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3142 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3144 SIVAL(pdata
,l1_idFileSystem
,st
.st_ex_dev
);
3145 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
3146 SIVAL(pdata
,l1_cUnit
,dsize
);
3147 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
3148 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
3152 case SMB_INFO_VOLUME
:
3153 /* Return volume name */
3155 * Add volume serial number - hash of a combination of
3156 * the called hostname and the service name.
3158 SIVAL(pdata
,0,str_checksum(lp_servicename(talloc_tos(), snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
3160 * Win2k3 and previous mess this up by sending a name length
3161 * one byte short. I believe only older clients (OS/2 Win9x) use
3162 * this call so try fixing this by adding a terminating null to
3163 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3167 pdata
+l2_vol_szVolLabel
, vname
,
3168 PTR_DIFF(end_data
, pdata
+l2_vol_szVolLabel
),
3169 STR_NOALIGN
|STR_TERMINATE
);
3170 SCVAL(pdata
,l2_vol_cch
,len
);
3171 data_len
= l2_vol_szVolLabel
+ len
;
3172 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
3173 (unsigned)convert_timespec_to_time_t(st
.st_ex_ctime
),
3177 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
3178 case SMB_FS_ATTRIBUTE_INFORMATION
:
3180 additional_flags
= 0;
3181 #if defined(HAVE_SYS_QUOTAS)
3182 additional_flags
|= FILE_VOLUME_QUOTAS
;
3185 if(lp_nt_acl_support(SNUM(conn
))) {
3186 additional_flags
|= FILE_PERSISTENT_ACLS
;
3189 /* Capabilities are filled in at connection time through STATVFS call */
3190 additional_flags
|= conn
->fs_capabilities
;
3191 additional_flags
|= lp_parm_int(conn
->params
->service
,
3192 "share", "fake_fscaps",
3195 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
3196 FILE_SUPPORTS_OBJECT_IDS
|FILE_UNICODE_ON_DISK
|
3197 additional_flags
); /* FS ATTRIBUTES */
3199 SIVAL(pdata
,4,255); /* Max filename component length */
3200 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3201 and will think we can't do long filenames */
3202 len
= srvstr_push(pdata
, flags2
, pdata
+12, fstype
,
3203 PTR_DIFF(end_data
, pdata
+12),
3206 data_len
= 12 + len
;
3209 case SMB_QUERY_FS_LABEL_INFO
:
3210 case SMB_FS_LABEL_INFORMATION
:
3211 len
= srvstr_push(pdata
, flags2
, pdata
+4, vname
,
3212 PTR_DIFF(end_data
, pdata
+4), 0);
3217 case SMB_QUERY_FS_VOLUME_INFO
:
3218 case SMB_FS_VOLUME_INFORMATION
:
3221 * Add volume serial number - hash of a combination of
3222 * the called hostname and the service name.
3224 SIVAL(pdata
,8,str_checksum(lp_servicename(talloc_tos(), snum
)) ^
3225 (str_checksum(get_local_machine_name())<<16));
3227 /* Max label len is 32 characters. */
3228 len
= srvstr_push(pdata
, flags2
, pdata
+18, vname
,
3229 PTR_DIFF(end_data
, pdata
+18),
3231 SIVAL(pdata
,12,len
);
3234 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3235 (int)strlen(vname
),vname
,
3236 lp_servicename(talloc_tos(), snum
)));
3239 case SMB_QUERY_FS_SIZE_INFO
:
3240 case SMB_FS_SIZE_INFORMATION
:
3242 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3244 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3245 return map_nt_error_from_unix(errno
);
3247 block_size
= lp_block_size(snum
);
3248 if (bsize
< block_size
) {
3249 uint64_t factor
= block_size
/bsize
;
3254 if (bsize
> block_size
) {
3255 uint64_t factor
= bsize
/block_size
;
3260 bytes_per_sector
= 512;
3261 sectors_per_unit
= bsize
/bytes_per_sector
;
3262 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3263 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3264 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3265 SBIG_UINT(pdata
,0,dsize
);
3266 SBIG_UINT(pdata
,8,dfree
);
3267 SIVAL(pdata
,16,sectors_per_unit
);
3268 SIVAL(pdata
,20,bytes_per_sector
);
3272 case SMB_FS_FULL_SIZE_INFORMATION
:
3274 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3276 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3277 return map_nt_error_from_unix(errno
);
3279 block_size
= lp_block_size(snum
);
3280 if (bsize
< block_size
) {
3281 uint64_t factor
= block_size
/bsize
;
3286 if (bsize
> block_size
) {
3287 uint64_t factor
= bsize
/block_size
;
3292 bytes_per_sector
= 512;
3293 sectors_per_unit
= bsize
/bytes_per_sector
;
3294 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3295 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3296 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3297 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
3298 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
3299 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
3300 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
3301 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
3305 case SMB_QUERY_FS_DEVICE_INFO
:
3306 case SMB_FS_DEVICE_INFORMATION
:
3308 uint32_t characteristics
= FILE_DEVICE_IS_MOUNTED
;
3310 if (!CAN_WRITE(conn
)) {
3311 characteristics
|= FILE_READ_ONLY_DEVICE
;
3314 SIVAL(pdata
,0,FILE_DEVICE_DISK
); /* dev type */
3315 SIVAL(pdata
,4,characteristics
);
3319 #ifdef HAVE_SYS_QUOTAS
3320 case SMB_FS_QUOTA_INFORMATION
:
3322 * what we have to send --metze:
3324 * Unknown1: 24 NULL bytes
3325 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3326 * Hard Quota Limit: 8 bytes seems like uint64_t or so
3327 * Quota Flags: 2 byte :
3328 * Unknown3: 6 NULL bytes
3332 * details for Quota Flags:
3334 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3335 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
3336 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3337 * 0x0001 Enable Quotas: enable quota for this fs
3341 /* we need to fake up a fsp here,
3342 * because its not send in this call
3345 SMB_NTQUOTA_STRUCT quotas
;
3348 ZERO_STRUCT(quotas
);
3351 fsp
.fnum
= FNUM_FIELD_INVALID
;
3354 if (get_current_uid(conn
) != 0) {
3355 DEBUG(0,("set_user_quota: access_denied "
3356 "service [%s] user [%s]\n",
3357 lp_servicename(talloc_tos(), SNUM(conn
)),
3358 conn
->session_info
->unix_info
->unix_name
));
3359 return NT_STATUS_ACCESS_DENIED
;
3362 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3363 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3364 return map_nt_error_from_unix(errno
);
3369 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3370 lp_servicename(talloc_tos(), SNUM(conn
))));
3372 /* Unknown1 24 NULL bytes*/
3373 SBIG_UINT(pdata
,0,(uint64_t)0);
3374 SBIG_UINT(pdata
,8,(uint64_t)0);
3375 SBIG_UINT(pdata
,16,(uint64_t)0);
3377 /* Default Soft Quota 8 bytes */
3378 SBIG_UINT(pdata
,24,quotas
.softlim
);
3380 /* Default Hard Quota 8 bytes */
3381 SBIG_UINT(pdata
,32,quotas
.hardlim
);
3383 /* Quota flag 2 bytes */
3384 SSVAL(pdata
,40,quotas
.qflags
);
3386 /* Unknown3 6 NULL bytes */
3392 #endif /* HAVE_SYS_QUOTAS */
3393 case SMB_FS_OBJECTID_INFORMATION
:
3395 unsigned char objid
[16];
3396 struct smb_extended_info extended_info
;
3397 memcpy(pdata
,create_volume_objectid(conn
, objid
),16);
3398 samba_extended_info_version (&extended_info
);
3399 SIVAL(pdata
,16,extended_info
.samba_magic
);
3400 SIVAL(pdata
,20,extended_info
.samba_version
);
3401 SIVAL(pdata
,24,extended_info
.samba_subversion
);
3402 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
3403 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
3409 * Query the version and capabilities of the CIFS UNIX extensions
3413 case SMB_QUERY_CIFS_UNIX_INFO
:
3415 bool large_write
= lp_min_receive_file_size() &&
3416 !srv_is_signing_active(conn
->sconn
);
3417 bool large_read
= !srv_is_signing_active(conn
->sconn
);
3418 int encrypt_caps
= 0;
3420 if (!lp_unix_extensions()) {
3421 return NT_STATUS_INVALID_LEVEL
;
3424 switch (conn
->encrypt_level
) {
3425 case SMB_SIGNING_OFF
:
3428 case SMB_SIGNING_IF_REQUIRED
:
3429 case SMB_SIGNING_DEFAULT
:
3430 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
;
3432 case SMB_SIGNING_REQUIRED
:
3433 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
|
3434 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP
;
3435 large_write
= false;
3441 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
3442 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
3444 /* We have POSIX ACLs, pathname, encryption,
3445 * large read/write, and locking capability. */
3447 SBIG_UINT(pdata
,4,((uint64_t)(
3448 CIFS_UNIX_POSIX_ACLS_CAP
|
3449 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
3450 CIFS_UNIX_FCNTL_LOCKS_CAP
|
3451 CIFS_UNIX_EXTATTR_CAP
|
3452 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
|
3454 (large_read
? CIFS_UNIX_LARGE_READ_CAP
: 0) |
3456 CIFS_UNIX_LARGE_WRITE_CAP
: 0))));
3460 case SMB_QUERY_POSIX_FS_INFO
:
3463 vfs_statvfs_struct svfs
;
3465 if (!lp_unix_extensions()) {
3466 return NT_STATUS_INVALID_LEVEL
;
3469 rc
= SMB_VFS_STATVFS(conn
, filename
, &svfs
);
3473 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
3474 SIVAL(pdata
,4,svfs
.BlockSize
);
3475 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
3476 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
3477 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
3478 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
3479 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
3480 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
3481 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3483 } else if (rc
== EOPNOTSUPP
) {
3484 return NT_STATUS_INVALID_LEVEL
;
3485 #endif /* EOPNOTSUPP */
3487 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3488 return NT_STATUS_DOS(ERRSRV
, ERRerror
);
3493 case SMB_QUERY_POSIX_WHOAMI
:
3499 if (!lp_unix_extensions()) {
3500 return NT_STATUS_INVALID_LEVEL
;
3503 if (max_data_bytes
< 40) {
3504 return NT_STATUS_BUFFER_TOO_SMALL
;
3507 if (security_session_user_level(conn
->session_info
, NULL
) < SECURITY_USER
) {
3508 flags
|= SMB_WHOAMI_GUEST
;
3511 /* NOTE: 8 bytes for UID/GID, irrespective of native
3512 * platform size. This matches
3513 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3515 data_len
= 4 /* flags */
3522 + 4 /* pad/reserved */
3523 + (conn
->session_info
->unix_token
->ngroups
* 8)
3525 + (conn
->session_info
->security_token
->num_sids
*
3529 SIVAL(pdata
, 0, flags
);
3530 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
3532 (uint64_t)conn
->session_info
->unix_token
->uid
);
3533 SBIG_UINT(pdata
, 16,
3534 (uint64_t)conn
->session_info
->unix_token
->gid
);
3537 if (data_len
>= max_data_bytes
) {
3538 /* Potential overflow, skip the GIDs and SIDs. */
3540 SIVAL(pdata
, 24, 0); /* num_groups */
3541 SIVAL(pdata
, 28, 0); /* num_sids */
3542 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
3543 SIVAL(pdata
, 36, 0); /* reserved */
3549 SIVAL(pdata
, 24, conn
->session_info
->unix_token
->ngroups
);
3550 SIVAL(pdata
, 28, conn
->session_info
->security_token
->num_sids
);
3552 /* We walk the SID list twice, but this call is fairly
3553 * infrequent, and I don't expect that it's performance
3554 * sensitive -- jpeach
3556 for (i
= 0, sid_bytes
= 0;
3557 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3558 sid_bytes
+= ndr_size_dom_sid(
3559 &conn
->session_info
->security_token
->sids
[i
],
3563 /* SID list byte count */
3564 SIVAL(pdata
, 32, sid_bytes
);
3566 /* 4 bytes pad/reserved - must be zero */
3567 SIVAL(pdata
, 36, 0);
3571 for (i
= 0; i
< conn
->session_info
->unix_token
->ngroups
; ++i
) {
3572 SBIG_UINT(pdata
, data_len
,
3573 (uint64_t)conn
->session_info
->unix_token
->groups
[i
]);
3579 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3580 int sid_len
= ndr_size_dom_sid(
3581 &conn
->session_info
->security_token
->sids
[i
],
3584 sid_linearize(pdata
+ data_len
, sid_len
,
3585 &conn
->session_info
->security_token
->sids
[i
]);
3586 data_len
+= sid_len
;
3592 case SMB_MAC_QUERY_FS_INFO
:
3594 * Thursby MAC extension... ONLY on NTFS filesystems
3595 * once we do streams then we don't need this
3597 if (strequal(lp_fstype(talloc_tos(), SNUM(conn
)),"NTFS")) {
3599 SIVAL(pdata
,84,0x100); /* Don't support mac... */
3604 return NT_STATUS_INVALID_LEVEL
;
3607 *ret_data_len
= data_len
;
3608 return NT_STATUS_OK
;
3611 /****************************************************************************
3612 Reply to a TRANS2_QFSINFO (query filesystem info).
3613 ****************************************************************************/
3615 static void call_trans2qfsinfo(connection_struct
*conn
,
3616 struct smb_request
*req
,
3617 char **pparams
, int total_params
,
3618 char **ppdata
, int total_data
,
3619 unsigned int max_data_bytes
)
3621 char *params
= *pparams
;
3622 uint16_t info_level
;
3626 if (total_params
< 2) {
3627 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3631 info_level
= SVAL(params
,0);
3633 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3634 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3635 DEBUG(0,("call_trans2qfsinfo: encryption required "
3636 "and info level 0x%x sent.\n",
3637 (unsigned int)info_level
));
3638 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3643 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
3645 status
= smbd_do_qfsinfo(conn
, req
,
3651 if (!NT_STATUS_IS_OK(status
)) {
3652 reply_nterror(req
, status
);
3656 send_trans2_replies(conn
, req
, params
, 0, *ppdata
, data_len
,
3659 DEBUG( 4, ( "%s info_level = %d\n",
3660 smb_fn_name(req
->cmd
), info_level
) );
3665 /****************************************************************************
3666 Reply to a TRANS2_SETFSINFO (set filesystem info).
3667 ****************************************************************************/
3669 static void call_trans2setfsinfo(connection_struct
*conn
,
3670 struct smb_request
*req
,
3671 char **pparams
, int total_params
,
3672 char **ppdata
, int total_data
,
3673 unsigned int max_data_bytes
)
3675 struct smbd_server_connection
*sconn
= req
->sconn
;
3676 char *pdata
= *ppdata
;
3677 char *params
= *pparams
;
3680 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
3681 lp_servicename(talloc_tos(), SNUM(conn
))));
3684 if (total_params
< 4) {
3685 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3687 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3691 info_level
= SVAL(params
,2);
3694 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
&&
3695 info_level
!= SMB_SET_CIFS_UNIX_INFO
) {
3696 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3697 "info level (0x%x) on IPC$.\n",
3698 (unsigned int)info_level
));
3699 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3704 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3705 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
) {
3706 DEBUG(0,("call_trans2setfsinfo: encryption required "
3707 "and info level 0x%x sent.\n",
3708 (unsigned int)info_level
));
3709 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3714 switch(info_level
) {
3715 case SMB_SET_CIFS_UNIX_INFO
:
3716 if (!lp_unix_extensions()) {
3717 DEBUG(2,("call_trans2setfsinfo: "
3718 "SMB_SET_CIFS_UNIX_INFO is invalid with "
3719 "unix extensions off\n"));
3721 NT_STATUS_INVALID_LEVEL
);
3725 /* There should be 12 bytes of capabilities set. */
3726 if (total_data
< 12) {
3729 NT_STATUS_INVALID_PARAMETER
);
3732 sconn
->smb1
.unix_info
.client_major
= SVAL(pdata
,0);
3733 sconn
->smb1
.unix_info
.client_minor
= SVAL(pdata
,2);
3734 sconn
->smb1
.unix_info
.client_cap_low
= IVAL(pdata
,4);
3735 sconn
->smb1
.unix_info
.client_cap_high
= IVAL(pdata
,8);
3736 /* Just print these values for now. */
3737 DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
3738 "major = %u, minor = %u cap_low = 0x%x, "
3740 (unsigned int)sconn
->
3741 smb1
.unix_info
.client_major
,
3742 (unsigned int)sconn
->
3743 smb1
.unix_info
.client_minor
,
3744 (unsigned int)sconn
->
3745 smb1
.unix_info
.client_cap_low
,
3746 (unsigned int)sconn
->
3747 smb1
.unix_info
.client_cap_high
));
3749 /* Here is where we must switch to posix pathname processing... */
3750 if (sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
3751 lp_set_posix_pathnames();
3752 mangle_change_to_posix();
3755 if ((sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_FCNTL_LOCKS_CAP
) &&
3756 !(sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)) {
3757 /* Client that knows how to do posix locks,
3758 * but not posix open/mkdir operations. Set a
3759 * default type for read/write checks. */
3761 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK
);
3766 case SMB_REQUEST_TRANSPORT_ENCRYPTION
:
3769 size_t param_len
= 0;
3770 size_t data_len
= total_data
;
3772 if (!lp_unix_extensions()) {
3775 NT_STATUS_INVALID_LEVEL
);
3779 if (lp_smb_encrypt(SNUM(conn
)) == SMB_SIGNING_OFF
) {
3782 NT_STATUS_NOT_SUPPORTED
);
3786 if (req
->sconn
->smb1
.echo_handler
.trusted_fde
) {
3787 DEBUG( 2,("call_trans2setfsinfo: "
3788 "request transport encryption disabled"
3789 "with 'fork echo handler = yes'\n"));
3792 NT_STATUS_NOT_SUPPORTED
);
3796 DEBUG( 4,("call_trans2setfsinfo: "
3797 "request transport encryption.\n"));
3799 status
= srv_request_encryption_setup(conn
,
3800 (unsigned char **)ppdata
,
3802 (unsigned char **)pparams
,
3805 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
3806 !NT_STATUS_IS_OK(status
)) {
3807 reply_nterror(req
, status
);
3811 send_trans2_replies(conn
, req
,
3818 if (NT_STATUS_IS_OK(status
)) {
3819 /* Server-side transport
3820 * encryption is now *on*. */
3821 status
= srv_encryption_start(conn
);
3822 if (!NT_STATUS_IS_OK(status
)) {
3823 char *reason
= talloc_asprintf(talloc_tos(),
3824 "Failure in setting "
3825 "up encrypted transport: %s",
3827 exit_server_cleanly(reason
);
3833 case SMB_FS_QUOTA_INFORMATION
:
3835 files_struct
*fsp
= NULL
;
3836 SMB_NTQUOTA_STRUCT quotas
;
3838 ZERO_STRUCT(quotas
);
3841 if ((get_current_uid(conn
) != 0) || !CAN_WRITE(conn
)) {
3842 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3843 lp_servicename(talloc_tos(), SNUM(conn
)),
3844 conn
->session_info
->unix_info
->unix_name
));
3845 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3849 /* note: normaly there're 48 bytes,
3850 * but we didn't use the last 6 bytes for now
3853 fsp
= file_fsp(req
, SVAL(params
,0));
3855 if (!check_fsp_ntquota_handle(conn
, req
,
3857 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3859 req
, NT_STATUS_INVALID_HANDLE
);
3863 if (total_data
< 42) {
3864 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3868 NT_STATUS_INVALID_PARAMETER
);
3872 /* unknown_1 24 NULL bytes in pdata*/
3874 /* the soft quotas 8 bytes (uint64_t)*/
3875 quotas
.softlim
= BVAL(pdata
,24);
3877 /* the hard quotas 8 bytes (uint64_t)*/
3878 quotas
.hardlim
= BVAL(pdata
,32);
3880 /* quota_flags 2 bytes **/
3881 quotas
.qflags
= SVAL(pdata
,40);
3883 /* unknown_2 6 NULL bytes follow*/
3885 /* now set the quotas */
3886 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3887 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn
))));
3888 reply_nterror(req
, map_nt_error_from_unix(errno
));
3895 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3897 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
3903 * sending this reply works fine,
3904 * but I'm not sure it's the same
3905 * like windows do...
3908 reply_outbuf(req
, 10, 0);
3911 #if defined(HAVE_POSIX_ACLS)
3912 /****************************************************************************
3913 Utility function to count the number of entries in a POSIX acl.
3914 ****************************************************************************/
3916 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
3918 unsigned int ace_count
= 0;
3919 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3920 SMB_ACL_ENTRY_T entry
;
3922 while ( posix_acl
&& (sys_acl_get_entry(posix_acl
, entry_id
, &entry
) == 1)) {
3924 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3925 entry_id
= SMB_ACL_NEXT_ENTRY
;
3932 /****************************************************************************
3933 Utility function to marshall a POSIX acl into wire format.
3934 ****************************************************************************/
3936 static bool marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
3938 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3939 SMB_ACL_ENTRY_T entry
;
3941 while ( posix_acl
&& (sys_acl_get_entry(posix_acl
, entry_id
, &entry
) == 1)) {
3942 SMB_ACL_TAG_T tagtype
;
3943 SMB_ACL_PERMSET_T permset
;
3944 unsigned char perms
= 0;
3945 unsigned int own_grp
;
3948 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3949 entry_id
= SMB_ACL_NEXT_ENTRY
;
3952 if (sys_acl_get_tag_type(entry
, &tagtype
) == -1) {
3953 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3957 if (sys_acl_get_permset(entry
, &permset
) == -1) {
3958 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3962 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
3963 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
3964 perms
|= (sys_acl_get_perm(permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
3966 SCVAL(pdata
,1,perms
);
3969 case SMB_ACL_USER_OBJ
:
3970 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
3971 own_grp
= (unsigned int)pst
->st_ex_uid
;
3972 SIVAL(pdata
,2,own_grp
);
3977 uid_t
*puid
= (uid_t
*)sys_acl_get_qualifier(entry
);
3979 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3982 own_grp
= (unsigned int)*puid
;
3983 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
3984 SIVAL(pdata
,2,own_grp
);
3988 case SMB_ACL_GROUP_OBJ
:
3989 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
3990 own_grp
= (unsigned int)pst
->st_ex_gid
;
3991 SIVAL(pdata
,2,own_grp
);
3996 gid_t
*pgid
= (gid_t
*)sys_acl_get_qualifier(entry
);
3998 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
4001 own_grp
= (unsigned int)*pgid
;
4002 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
4003 SIVAL(pdata
,2,own_grp
);
4008 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
4009 SIVAL(pdata
,2,0xFFFFFFFF);
4010 SIVAL(pdata
,6,0xFFFFFFFF);
4013 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
4014 SIVAL(pdata
,2,0xFFFFFFFF);
4015 SIVAL(pdata
,6,0xFFFFFFFF);
4018 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
4021 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
4028 /****************************************************************************
4029 Store the FILE_UNIX_BASIC info.
4030 ****************************************************************************/
4032 static char *store_file_unix_basic(connection_struct
*conn
,
4035 const SMB_STRUCT_STAT
*psbuf
)
4037 uint64_t file_index
= get_FileIndex(conn
, psbuf
);
4040 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
4041 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_ex_mode
));
4043 SOFF_T(pdata
,0,get_file_size_stat(psbuf
)); /* File size 64 Bit */
4046 SOFF_T(pdata
,0,SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
4049 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
, psbuf
->st_ex_ctime
); /* Change Time 64 Bit */
4050 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
+8, psbuf
->st_ex_atime
); /* Last access time 64 Bit */
4051 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
+16, psbuf
->st_ex_mtime
); /* Last modification time 64 Bit */
4054 SIVAL(pdata
,0,psbuf
->st_ex_uid
); /* user id for the owner */
4058 SIVAL(pdata
,0,psbuf
->st_ex_gid
); /* group id of owner */
4062 SIVAL(pdata
,0,unix_filetype(psbuf
->st_ex_mode
));
4065 if (S_ISBLK(psbuf
->st_ex_mode
) || S_ISCHR(psbuf
->st_ex_mode
)) {
4066 devno
= psbuf
->st_ex_rdev
;
4068 devno
= psbuf
->st_ex_dev
;
4071 SIVAL(pdata
,0,unix_dev_major(devno
)); /* Major device number if type is device */
4075 SIVAL(pdata
,0,unix_dev_minor(devno
)); /* Minor device number if type is device */
4079 SINO_T_VAL(pdata
,0,(SMB_INO_T
)file_index
); /* inode number */
4082 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_ex_mode
)); /* Standard UNIX file permissions */
4086 SIVAL(pdata
,0,psbuf
->st_ex_nlink
); /* number of hard links */
4093 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4094 * the chflags(2) (or equivalent) flags.
4096 * XXX: this really should be behind the VFS interface. To do this, we would
4097 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4098 * Each VFS module could then implement its own mapping as appropriate for the
4099 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4101 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
4105 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
4109 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
4113 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
4117 { UF_HIDDEN
, EXT_HIDDEN
},
4120 /* Do not remove. We need to guarantee that this array has at least one
4121 * entry to build on HP-UX.
4127 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4128 uint32
*smb_fflags
, uint32
*smb_fmask
)
4132 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4133 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
4134 if (psbuf
->st_ex_flags
& info2_flags_map
[i
].stat_fflag
) {
4135 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
4140 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4141 const uint32 smb_fflags
,
4142 const uint32 smb_fmask
,
4145 uint32 max_fmask
= 0;
4148 *stat_fflags
= psbuf
->st_ex_flags
;
4150 /* For each flags requested in smb_fmask, check the state of the
4151 * corresponding flag in smb_fflags and set or clear the matching
4155 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4156 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
4157 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
4158 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
4159 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
4161 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
4166 /* If smb_fmask is asking to set any bits that are not supported by
4167 * our flag mappings, we should fail.
4169 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
4177 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4178 * of file flags and birth (create) time.
4180 static char *store_file_unix_basic_info2(connection_struct
*conn
,
4183 const SMB_STRUCT_STAT
*psbuf
)
4185 uint32 file_flags
= 0;
4186 uint32 flags_mask
= 0;
4188 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4190 /* Create (birth) time 64 bit */
4191 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
, psbuf
->st_ex_btime
);
4194 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
4195 SIVAL(pdata
, 0, file_flags
); /* flags */
4196 SIVAL(pdata
, 4, flags_mask
); /* mask */
4202 static NTSTATUS
marshall_stream_info(unsigned int num_streams
,
4203 const struct stream_struct
*streams
,
4205 unsigned int max_data_bytes
,
4206 unsigned int *data_size
)
4209 unsigned int ofs
= 0;
4211 for (i
= 0; i
< num_streams
; i
++) {
4212 unsigned int next_offset
;
4214 smb_ucs2_t
*namebuf
;
4216 if (!push_ucs2_talloc(talloc_tos(), &namebuf
,
4217 streams
[i
].name
, &namelen
) ||
4220 return NT_STATUS_INVALID_PARAMETER
;
4224 * name_buf is now null-terminated, we need to marshall as not
4231 * We cannot overflow ...
4233 if ((ofs
+ 24 + namelen
) > max_data_bytes
) {
4234 DEBUG(10, ("refusing to overflow reply at stream %u\n",
4236 TALLOC_FREE(namebuf
);
4237 return STATUS_BUFFER_OVERFLOW
;
4240 SIVAL(data
, ofs
+4, namelen
);
4241 SOFF_T(data
, ofs
+8, streams
[i
].size
);
4242 SOFF_T(data
, ofs
+16, streams
[i
].alloc_size
);
4243 memcpy(data
+ofs
+24, namebuf
, namelen
);
4244 TALLOC_FREE(namebuf
);
4246 next_offset
= ofs
+ 24 + namelen
;
4248 if (i
== num_streams
-1) {
4249 SIVAL(data
, ofs
, 0);
4252 unsigned int align
= ndr_align_size(next_offset
, 8);
4254 if ((next_offset
+ align
) > max_data_bytes
) {
4255 DEBUG(10, ("refusing to overflow align "
4256 "reply at stream %u\n",
4258 TALLOC_FREE(namebuf
);
4259 return STATUS_BUFFER_OVERFLOW
;
4262 memset(data
+next_offset
, 0, align
);
4263 next_offset
+= align
;
4265 SIVAL(data
, ofs
, next_offset
- ofs
);
4272 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes
, ofs
));
4276 return NT_STATUS_OK
;
4279 /****************************************************************************
4280 Reply to a TRANSACT2_QFILEINFO on a PIPE !
4281 ****************************************************************************/
4283 static void call_trans2qpipeinfo(connection_struct
*conn
,
4284 struct smb_request
*req
,
4285 unsigned int tran_call
,
4286 char **pparams
, int total_params
,
4287 char **ppdata
, int total_data
,
4288 unsigned int max_data_bytes
)
4290 char *params
= *pparams
;
4291 char *pdata
= *ppdata
;
4292 unsigned int data_size
= 0;
4293 unsigned int param_size
= 2;
4298 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4302 if (total_params
< 4) {
4303 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4307 fsp
= file_fsp(req
, SVAL(params
,0));
4308 if (!fsp_is_np(fsp
)) {
4309 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
4313 info_level
= SVAL(params
,2);
4315 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
4316 if (*pparams
== NULL
) {
4317 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4322 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4323 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4324 if (*ppdata
== NULL
) {
4325 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4330 switch (info_level
) {
4331 case SMB_FILE_STANDARD_INFORMATION
:
4333 SOFF_T(pdata
,0,4096LL);
4340 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
4344 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
4350 NTSTATUS
smbd_do_qfilepathinfo(connection_struct
*conn
,
4351 TALLOC_CTX
*mem_ctx
,
4352 uint16_t info_level
,
4354 struct smb_filename
*smb_fname
,
4355 bool delete_pending
,
4356 struct timespec write_time_ts
,
4357 struct ea_list
*ea_list
,
4358 int lock_data_count
,
4361 unsigned int max_data_bytes
,
4363 unsigned int *pdata_size
)
4365 char *pdata
= *ppdata
;
4366 char *dstart
, *dend
;
4367 unsigned int data_size
;
4368 struct timespec create_time_ts
, mtime_ts
, atime_ts
, ctime_ts
;
4369 time_t create_time
, mtime
, atime
, c_time
;
4370 SMB_STRUCT_STAT
*psbuf
= &smb_fname
->st
;
4377 uint64_t file_size
= 0;
4379 uint64_t allocation_size
= 0;
4380 uint64_t file_index
= 0;
4381 uint32_t access_mask
= 0;
4383 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
4384 return NT_STATUS_INVALID_LEVEL
;
4387 DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
4388 smb_fname_str_dbg(smb_fname
),
4390 info_level
, max_data_bytes
));
4392 mode
= dos_mode(conn
, smb_fname
);
4393 nlink
= psbuf
->st_ex_nlink
;
4395 if (nlink
&& (mode
&FILE_ATTRIBUTE_DIRECTORY
)) {
4399 if ((nlink
> 0) && delete_pending
) {
4403 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4404 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4405 if (*ppdata
== NULL
) {
4406 return NT_STATUS_NO_MEMORY
;
4410 dend
= dstart
+ data_size
- 1;
4412 if (!null_timespec(write_time_ts
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
4413 update_stat_ex_mtime(psbuf
, write_time_ts
);
4416 create_time_ts
= get_create_timespec(conn
, fsp
, smb_fname
);
4417 mtime_ts
= psbuf
->st_ex_mtime
;
4418 atime_ts
= psbuf
->st_ex_atime
;
4419 ctime_ts
= get_change_timespec(conn
, fsp
, smb_fname
);
4421 if (lp_dos_filetime_resolution(SNUM(conn
))) {
4422 dos_filetime_timespec(&create_time_ts
);
4423 dos_filetime_timespec(&mtime_ts
);
4424 dos_filetime_timespec(&atime_ts
);
4425 dos_filetime_timespec(&ctime_ts
);
4428 create_time
= convert_timespec_to_time_t(create_time_ts
);
4429 mtime
= convert_timespec_to_time_t(mtime_ts
);
4430 atime
= convert_timespec_to_time_t(atime_ts
);
4431 c_time
= convert_timespec_to_time_t(ctime_ts
);
4433 p
= strrchr_m(smb_fname
->base_name
,'/');
4435 base_name
= smb_fname
->base_name
;
4439 /* NT expects the name to be in an exact form of the *full*
4440 filename. See the trans2 torture test */
4441 if (ISDOT(base_name
)) {
4442 dos_fname
= talloc_strdup(mem_ctx
, "\\");
4444 return NT_STATUS_NO_MEMORY
;
4447 dos_fname
= talloc_asprintf(mem_ctx
,
4449 smb_fname
->base_name
);
4451 return NT_STATUS_NO_MEMORY
;
4453 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4454 dos_fname
= talloc_asprintf(dos_fname
, "%s",
4455 smb_fname
->stream_name
);
4457 return NT_STATUS_NO_MEMORY
;
4461 string_replace(dos_fname
, '/', '\\');
4464 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, psbuf
);
4467 /* Do we have this path open ? */
4469 struct file_id fileid
= vfs_file_id_from_sbuf(conn
, psbuf
);
4470 fsp1
= file_find_di_first(conn
->sconn
, fileid
);
4471 if (fsp1
&& fsp1
->initial_allocation_size
) {
4472 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp1
, psbuf
);
4476 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
4477 file_size
= get_file_size_stat(psbuf
);
4481 pos
= fsp
->fh
->position_information
;
4485 access_mask
= fsp
->access_mask
;
4487 /* GENERIC_EXECUTE mapping from Windows */
4488 access_mask
= 0x12019F;
4491 /* This should be an index number - looks like
4494 I think this causes us to fail the IFSKIT
4495 BasicFileInformationTest. -tpot */
4496 file_index
= get_FileIndex(conn
, psbuf
);
4498 switch (info_level
) {
4499 case SMB_INFO_STANDARD
:
4500 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4502 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
4503 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
4504 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
4505 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
4506 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
4507 SSVAL(pdata
,l1_attrFile
,mode
);
4510 case SMB_INFO_QUERY_EA_SIZE
:
4512 unsigned int ea_size
=
4513 estimate_ea_size(conn
, fsp
,
4515 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4517 srv_put_dos_date2(pdata
,0,create_time
);
4518 srv_put_dos_date2(pdata
,4,atime
);
4519 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
4520 SIVAL(pdata
,12,(uint32
)file_size
);
4521 SIVAL(pdata
,16,(uint32
)allocation_size
);
4522 SSVAL(pdata
,20,mode
);
4523 SIVAL(pdata
,22,ea_size
);
4527 case SMB_INFO_IS_NAME_VALID
:
4528 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4530 /* os/2 needs this ? really ?*/
4531 return NT_STATUS_DOS(ERRDOS
, ERRbadfunc
);
4533 /* This is only reached for qpathinfo */
4537 case SMB_INFO_QUERY_EAS_FROM_LIST
:
4539 size_t total_ea_len
= 0;
4540 struct ea_list
*ea_file_list
= NULL
;
4541 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4544 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4546 &total_ea_len
, &ea_file_list
);
4547 if (!NT_STATUS_IS_OK(status
)) {
4551 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
4553 if (!ea_list
|| (total_ea_len
> data_size
)) {
4555 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4559 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4563 case SMB_INFO_QUERY_ALL_EAS
:
4565 /* We have data_size bytes to put EA's into. */
4566 size_t total_ea_len
= 0;
4567 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4569 status
= get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4571 &total_ea_len
, &ea_list
);
4572 if (!NT_STATUS_IS_OK(status
)) {
4576 if (!ea_list
|| (total_ea_len
> data_size
)) {
4578 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4582 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4586 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4588 /* This is FileFullEaInformation - 0xF which maps to
4589 * 1015 (decimal) in smbd_do_setfilepathinfo. */
4591 /* We have data_size bytes to put EA's into. */
4592 size_t total_ea_len
= 0;
4593 struct ea_list
*ea_file_list
= NULL
;
4595 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4597 /*TODO: add filtering and index handling */
4600 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4602 &total_ea_len
, &ea_file_list
);
4603 if (!NT_STATUS_IS_OK(status
)) {
4606 if (!ea_file_list
) {
4607 return NT_STATUS_NO_EAS_ON_FILE
;
4610 status
= fill_ea_chained_buffer(mem_ctx
,
4614 conn
, ea_file_list
);
4615 if (!NT_STATUS_IS_OK(status
)) {
4621 case SMB_FILE_BASIC_INFORMATION
:
4622 case SMB_QUERY_FILE_BASIC_INFO
:
4624 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
4625 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4626 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
4628 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4632 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4633 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4634 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4635 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4636 SIVAL(pdata
,32,mode
);
4638 DEBUG(5,("SMB_QFBI - "));
4639 DEBUG(5,("create: %s ", ctime(&create_time
)));
4640 DEBUG(5,("access: %s ", ctime(&atime
)));
4641 DEBUG(5,("write: %s ", ctime(&mtime
)));
4642 DEBUG(5,("change: %s ", ctime(&c_time
)));
4643 DEBUG(5,("mode: %x\n", mode
));
4646 case SMB_FILE_STANDARD_INFORMATION
:
4647 case SMB_QUERY_FILE_STANDARD_INFO
:
4649 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4651 SOFF_T(pdata
,0,allocation_size
);
4652 SOFF_T(pdata
,8,file_size
);
4653 SIVAL(pdata
,16,nlink
);
4654 SCVAL(pdata
,20,delete_pending
?1:0);
4655 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4656 SSVAL(pdata
,22,0); /* Padding. */
4659 case SMB_FILE_EA_INFORMATION
:
4660 case SMB_QUERY_FILE_EA_INFO
:
4662 unsigned int ea_size
=
4663 estimate_ea_size(conn
, fsp
, smb_fname
);
4664 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4666 SIVAL(pdata
,0,ea_size
);
4670 /* Get the 8.3 name - used if NT SMB was negotiated. */
4671 case SMB_QUERY_FILE_ALT_NAME_INFO
:
4672 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
4675 char mangled_name
[13];
4676 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4677 if (!name_to_8_3(base_name
,mangled_name
,
4678 True
,conn
->params
)) {
4679 return NT_STATUS_NO_MEMORY
;
4681 len
= srvstr_push(dstart
, flags2
,
4682 pdata
+4, mangled_name
,
4683 PTR_DIFF(dend
, pdata
+4),
4685 data_size
= 4 + len
;
4690 case SMB_QUERY_FILE_NAME_INFO
:
4694 this must be *exactly* right for ACLs on mapped drives to work
4696 len
= srvstr_push(dstart
, flags2
,
4698 PTR_DIFF(dend
, pdata
+4),
4700 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4701 data_size
= 4 + len
;
4706 case SMB_FILE_ALLOCATION_INFORMATION
:
4707 case SMB_QUERY_FILE_ALLOCATION_INFO
:
4708 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4710 SOFF_T(pdata
,0,allocation_size
);
4713 case SMB_FILE_END_OF_FILE_INFORMATION
:
4714 case SMB_QUERY_FILE_END_OF_FILEINFO
:
4715 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4717 SOFF_T(pdata
,0,file_size
);
4720 case SMB_QUERY_FILE_ALL_INFO
:
4721 case SMB_FILE_ALL_INFORMATION
:
4724 unsigned int ea_size
=
4725 estimate_ea_size(conn
, fsp
, smb_fname
);
4726 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4727 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4728 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4729 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4730 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4731 SIVAL(pdata
,32,mode
);
4732 SIVAL(pdata
,36,0); /* padding. */
4734 SOFF_T(pdata
,0,allocation_size
);
4735 SOFF_T(pdata
,8,file_size
);
4736 SIVAL(pdata
,16,nlink
);
4737 SCVAL(pdata
,20,delete_pending
);
4738 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4741 SIVAL(pdata
,0,ea_size
);
4742 pdata
+= 4; /* EA info */
4743 len
= srvstr_push(dstart
, flags2
,
4745 PTR_DIFF(dend
, pdata
+4),
4749 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4753 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4756 unsigned int ea_size
=
4757 estimate_ea_size(conn
, fsp
, smb_fname
);
4758 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4759 put_long_date_timespec(conn
->ts_res
,pdata
+0x00,create_time_ts
);
4760 put_long_date_timespec(conn
->ts_res
,pdata
+0x08,atime_ts
);
4761 put_long_date_timespec(conn
->ts_res
,pdata
+0x10,mtime_ts
); /* write time */
4762 put_long_date_timespec(conn
->ts_res
,pdata
+0x18,ctime_ts
); /* change time */
4763 SIVAL(pdata
, 0x20, mode
);
4764 SIVAL(pdata
, 0x24, 0); /* padding. */
4765 SBVAL(pdata
, 0x28, allocation_size
);
4766 SBVAL(pdata
, 0x30, file_size
);
4767 SIVAL(pdata
, 0x38, nlink
);
4768 SCVAL(pdata
, 0x3C, delete_pending
);
4769 SCVAL(pdata
, 0x3D, (mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4770 SSVAL(pdata
, 0x3E, 0); /* padding */
4771 SBVAL(pdata
, 0x40, file_index
);
4772 SIVAL(pdata
, 0x48, ea_size
);
4773 SIVAL(pdata
, 0x4C, access_mask
);
4774 SBVAL(pdata
, 0x50, pos
);
4775 SIVAL(pdata
, 0x58, mode
); /*TODO: mode != mode fix this!!! */
4776 SIVAL(pdata
, 0x5C, 0); /* No alignment needed. */
4780 len
= srvstr_push(dstart
, flags2
,
4782 PTR_DIFF(dend
, pdata
+4),
4786 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4789 case SMB_FILE_INTERNAL_INFORMATION
:
4791 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4792 SBVAL(pdata
, 0, file_index
);
4796 case SMB_FILE_ACCESS_INFORMATION
:
4797 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4798 SIVAL(pdata
, 0, access_mask
);
4802 case SMB_FILE_NAME_INFORMATION
:
4803 /* Pathname with leading '\'. */
4806 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
4807 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4808 SIVAL(pdata
,0,byte_len
);
4809 data_size
= 4 + byte_len
;
4813 case SMB_FILE_DISPOSITION_INFORMATION
:
4814 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4816 SCVAL(pdata
,0,delete_pending
);
4819 case SMB_FILE_POSITION_INFORMATION
:
4820 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4822 SOFF_T(pdata
,0,pos
);
4825 case SMB_FILE_MODE_INFORMATION
:
4826 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4827 SIVAL(pdata
,0,mode
);
4831 case SMB_FILE_ALIGNMENT_INFORMATION
:
4832 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4833 SIVAL(pdata
,0,0); /* No alignment needed. */
4838 * NT4 server just returns "invalid query" to this - if we try
4839 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4842 /* The first statement above is false - verified using Thursby
4843 * client against NT4 -- gcolley.
4845 case SMB_QUERY_FILE_STREAM_INFO
:
4846 case SMB_FILE_STREAM_INFORMATION
: {
4847 unsigned int num_streams
= 0;
4848 struct stream_struct
*streams
= NULL
;
4850 DEBUG(10,("smbd_do_qfilepathinfo: "
4851 "SMB_FILE_STREAM_INFORMATION\n"));
4853 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4854 return NT_STATUS_INVALID_PARAMETER
;
4857 status
= vfs_streaminfo(conn
, fsp
, smb_fname
->base_name
,
4858 talloc_tos(), &num_streams
, &streams
);
4860 if (!NT_STATUS_IS_OK(status
)) {
4861 DEBUG(10, ("could not get stream info: %s\n",
4862 nt_errstr(status
)));
4866 status
= marshall_stream_info(num_streams
, streams
,
4867 pdata
, max_data_bytes
,
4870 if (!NT_STATUS_IS_OK(status
)) {
4871 DEBUG(10, ("marshall_stream_info failed: %s\n",
4872 nt_errstr(status
)));
4873 TALLOC_FREE(streams
);
4877 TALLOC_FREE(streams
);
4881 case SMB_QUERY_COMPRESSION_INFO
:
4882 case SMB_FILE_COMPRESSION_INFORMATION
:
4883 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4884 SOFF_T(pdata
,0,file_size
);
4885 SIVAL(pdata
,8,0); /* ??? */
4886 SIVAL(pdata
,12,0); /* ??? */
4890 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
4891 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4892 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4893 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4894 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4895 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4896 SOFF_T(pdata
,32,allocation_size
);
4897 SOFF_T(pdata
,40,file_size
);
4898 SIVAL(pdata
,48,mode
);
4899 SIVAL(pdata
,52,0); /* ??? */
4903 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
4904 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4905 SIVAL(pdata
,0,mode
);
4911 * CIFS UNIX Extensions.
4914 case SMB_QUERY_FILE_UNIX_BASIC
:
4916 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4917 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4919 DEBUG(4,("smbd_do_qfilepathinfo: "
4920 "SMB_QUERY_FILE_UNIX_BASIC\n"));
4921 dump_data(4, (uint8_t *)(*ppdata
), data_size
);
4925 case SMB_QUERY_FILE_UNIX_INFO2
:
4927 pdata
= store_file_unix_basic_info2(conn
, pdata
, fsp
, psbuf
);
4928 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4932 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4934 for (i
=0; i
<100; i
++)
4935 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
4941 case SMB_QUERY_FILE_UNIX_LINK
:
4944 char *buffer
= talloc_array(mem_ctx
, char, PATH_MAX
+1);
4947 return NT_STATUS_NO_MEMORY
;
4950 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4952 if(!S_ISLNK(psbuf
->st_ex_mode
)) {
4953 return NT_STATUS_DOS(ERRSRV
, ERRbadlink
);
4956 return NT_STATUS_DOS(ERRDOS
, ERRbadlink
);
4958 len
= SMB_VFS_READLINK(conn
,
4959 smb_fname
->base_name
,
4962 return map_nt_error_from_unix(errno
);
4965 len
= srvstr_push(dstart
, flags2
,
4967 PTR_DIFF(dend
, pdata
),
4970 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4975 #if defined(HAVE_POSIX_ACLS)
4976 case SMB_QUERY_POSIX_ACL
:
4978 SMB_ACL_T file_acl
= NULL
;
4979 SMB_ACL_T def_acl
= NULL
;
4980 uint16 num_file_acls
= 0;
4981 uint16 num_def_acls
= 0;
4983 if (fsp
&& fsp
->fh
->fd
!= -1) {
4984 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
,
4988 SMB_VFS_SYS_ACL_GET_FILE(conn
,
4989 smb_fname
->base_name
,
4990 SMB_ACL_TYPE_ACCESS
,
4994 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
4995 DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4996 "not implemented on "
4997 "filesystem containing %s\n",
4998 smb_fname
->base_name
));
4999 return NT_STATUS_NOT_IMPLEMENTED
;
5002 if (S_ISDIR(psbuf
->st_ex_mode
)) {
5003 if (fsp
&& fsp
->is_directory
) {
5005 SMB_VFS_SYS_ACL_GET_FILE(
5007 fsp
->fsp_name
->base_name
,
5008 SMB_ACL_TYPE_DEFAULT
,
5012 SMB_VFS_SYS_ACL_GET_FILE(
5014 smb_fname
->base_name
,
5015 SMB_ACL_TYPE_DEFAULT
,
5018 def_acl
= free_empty_sys_acl(conn
, def_acl
);
5021 num_file_acls
= count_acl_entries(conn
, file_acl
);
5022 num_def_acls
= count_acl_entries(conn
, def_acl
);
5024 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
5025 DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
5027 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
5028 SMB_POSIX_ACL_HEADER_SIZE
) ));
5030 TALLOC_FREE(file_acl
);
5033 TALLOC_FREE(def_acl
);
5035 return NT_STATUS_BUFFER_TOO_SMALL
;
5038 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
5039 SSVAL(pdata
,2,num_file_acls
);
5040 SSVAL(pdata
,4,num_def_acls
);
5041 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, psbuf
, file_acl
)) {
5043 TALLOC_FREE(file_acl
);
5046 TALLOC_FREE(def_acl
);
5048 return NT_STATUS_INTERNAL_ERROR
;
5050 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), psbuf
, def_acl
)) {
5052 TALLOC_FREE(file_acl
);
5055 TALLOC_FREE(def_acl
);
5057 return NT_STATUS_INTERNAL_ERROR
;
5061 TALLOC_FREE(file_acl
);
5064 TALLOC_FREE(def_acl
);
5066 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
5072 case SMB_QUERY_POSIX_LOCK
:
5077 enum brl_type lock_type
;
5079 /* We need an open file with a real fd for this. */
5080 if (!fsp
|| fsp
->fh
->fd
== -1) {
5081 return NT_STATUS_INVALID_LEVEL
;
5084 if (lock_data_count
!= POSIX_LOCK_DATA_SIZE
) {
5085 return NT_STATUS_INVALID_PARAMETER
;
5088 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
5089 case POSIX_LOCK_TYPE_READ
:
5090 lock_type
= READ_LOCK
;
5092 case POSIX_LOCK_TYPE_WRITE
:
5093 lock_type
= WRITE_LOCK
;
5095 case POSIX_LOCK_TYPE_UNLOCK
:
5097 /* There's no point in asking for an unlock... */
5098 return NT_STATUS_INVALID_PARAMETER
;
5101 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
5102 #if defined(HAVE_LONGLONG)
5103 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
5104 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
5105 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
5106 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
5107 #else /* HAVE_LONGLONG */
5108 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
5109 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
5110 #endif /* HAVE_LONGLONG */
5112 status
= query_lock(fsp
,
5119 if (ERROR_WAS_LOCK_DENIED(status
)) {
5120 /* Here we need to report who has it locked... */
5121 data_size
= POSIX_LOCK_DATA_SIZE
;
5123 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, lock_type
);
5124 SSVAL(pdata
, POSIX_LOCK_FLAGS_OFFSET
, 0);
5125 SIVAL(pdata
, POSIX_LOCK_PID_OFFSET
, (uint32_t)smblctx
);
5126 #if defined(HAVE_LONGLONG)
5127 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, (uint32
)(offset
& 0xFFFFFFFF));
5128 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
+ 4, (uint32
)((offset
>> 32) & 0xFFFFFFFF));
5129 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, (uint32
)(count
& 0xFFFFFFFF));
5130 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
+ 4, (uint32
)((count
>> 32) & 0xFFFFFFFF));
5131 #else /* HAVE_LONGLONG */
5132 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, offset
);
5133 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, count
);
5134 #endif /* HAVE_LONGLONG */
5136 } else if (NT_STATUS_IS_OK(status
)) {
5137 /* For success we just return a copy of what we sent
5138 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5139 data_size
= POSIX_LOCK_DATA_SIZE
;
5140 memcpy(pdata
, lock_data
, POSIX_LOCK_DATA_SIZE
);
5141 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
5149 return NT_STATUS_INVALID_LEVEL
;
5152 *pdata_size
= data_size
;
5153 return NT_STATUS_OK
;
5156 /****************************************************************************
5157 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5158 file name or file id).
5159 ****************************************************************************/
5161 static void call_trans2qfilepathinfo(connection_struct
*conn
,
5162 struct smb_request
*req
,
5163 unsigned int tran_call
,
5164 char **pparams
, int total_params
,
5165 char **ppdata
, int total_data
,
5166 unsigned int max_data_bytes
)
5168 char *params
= *pparams
;
5169 char *pdata
= *ppdata
;
5171 unsigned int data_size
= 0;
5172 unsigned int param_size
= 2;
5173 struct smb_filename
*smb_fname
= NULL
;
5174 bool delete_pending
= False
;
5175 struct timespec write_time_ts
;
5176 files_struct
*fsp
= NULL
;
5177 struct file_id fileid
;
5178 struct ea_list
*ea_list
= NULL
;
5179 int lock_data_count
= 0;
5180 char *lock_data
= NULL
;
5181 NTSTATUS status
= NT_STATUS_OK
;
5184 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5188 ZERO_STRUCT(write_time_ts
);
5190 if (tran_call
== TRANSACT2_QFILEINFO
) {
5191 if (total_params
< 4) {
5192 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5197 call_trans2qpipeinfo(conn
, req
, tran_call
,
5198 pparams
, total_params
,
5204 fsp
= file_fsp(req
, SVAL(params
,0));
5205 info_level
= SVAL(params
,2);
5207 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
5209 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
5210 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5214 /* Initial check for valid fsp ptr. */
5215 if (!check_fsp_open(conn
, req
, fsp
)) {
5219 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
5221 if (!NT_STATUS_IS_OK(status
)) {
5222 reply_nterror(req
, status
);
5226 if(fsp
->fake_file_handle
) {
5228 * This is actually for the QUOTA_FAKE_FILE --metze
5231 /* We know this name is ok, it's already passed the checks. */
5233 } else if(fsp
->fh
->fd
== -1) {
5235 * This is actually a QFILEINFO on a directory
5236 * handle (returned from an NT SMB). NT5.0 seems
5237 * to do this call. JRA.
5240 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5241 /* Always do lstat for UNIX calls. */
5242 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5243 DEBUG(3,("call_trans2qfilepathinfo: "
5244 "SMB_VFS_LSTAT of %s failed "
5246 smb_fname_str_dbg(smb_fname
),
5249 map_nt_error_from_unix(errno
));
5252 } else if (SMB_VFS_STAT(conn
, smb_fname
)) {
5253 DEBUG(3,("call_trans2qfilepathinfo: "
5254 "SMB_VFS_STAT of %s failed (%s)\n",
5255 smb_fname_str_dbg(smb_fname
),
5258 map_nt_error_from_unix(errno
));
5262 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5263 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5266 * Original code - this is an open file.
5268 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
5269 DEBUG(3, ("fstat of %s failed (%s)\n",
5270 fsp_fnum_dbg(fsp
), strerror(errno
)));
5272 map_nt_error_from_unix(errno
));
5275 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5276 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5282 uint32_t ucf_flags
= 0;
5285 if (total_params
< 7) {
5286 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5290 info_level
= SVAL(params
,0);
5292 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
5294 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5295 if (!lp_unix_extensions()) {
5296 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5299 if (info_level
== SMB_QUERY_FILE_UNIX_BASIC
||
5300 info_level
== SMB_QUERY_FILE_UNIX_INFO2
||
5301 info_level
== SMB_QUERY_FILE_UNIX_LINK
) {
5302 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
5306 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
5308 STR_TERMINATE
, &status
);
5309 if (!NT_STATUS_IS_OK(status
)) {
5310 reply_nterror(req
, status
);
5314 status
= filename_convert(req
,
5316 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5321 if (!NT_STATUS_IS_OK(status
)) {
5322 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5323 reply_botherror(req
,
5324 NT_STATUS_PATH_NOT_COVERED
,
5325 ERRSRV
, ERRbadpath
);
5328 reply_nterror(req
, status
);
5332 /* If this is a stream, check if there is a delete_pending. */
5333 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5334 && is_ntfs_stream_smb_fname(smb_fname
)) {
5335 struct smb_filename
*smb_fname_base
= NULL
;
5337 /* Create an smb_filename with stream_name == NULL. */
5339 create_synthetic_smb_fname(talloc_tos(),
5340 smb_fname
->base_name
,
5343 if (!NT_STATUS_IS_OK(status
)) {
5344 reply_nterror(req
, status
);
5348 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5349 /* Always do lstat for UNIX calls. */
5350 if (SMB_VFS_LSTAT(conn
, smb_fname_base
) != 0) {
5351 DEBUG(3,("call_trans2qfilepathinfo: "
5352 "SMB_VFS_LSTAT of %s failed "
5354 smb_fname_str_dbg(smb_fname_base
),
5356 TALLOC_FREE(smb_fname_base
);
5358 map_nt_error_from_unix(errno
));
5362 if (SMB_VFS_STAT(conn
, smb_fname_base
) != 0) {
5363 DEBUG(3,("call_trans2qfilepathinfo: "
5364 "fileinfo of %s failed "
5366 smb_fname_str_dbg(smb_fname_base
),
5368 TALLOC_FREE(smb_fname_base
);
5370 map_nt_error_from_unix(errno
));
5375 status
= file_name_hash(conn
,
5376 smb_fname_str_dbg(smb_fname_base
),
5378 if (!NT_STATUS_IS_OK(status
)) {
5379 TALLOC_FREE(smb_fname_base
);
5380 reply_nterror(req
, status
);
5384 fileid
= vfs_file_id_from_sbuf(conn
,
5385 &smb_fname_base
->st
);
5386 TALLOC_FREE(smb_fname_base
);
5387 get_file_infos(fileid
, name_hash
, &delete_pending
, NULL
);
5388 if (delete_pending
) {
5389 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5394 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5395 /* Always do lstat for UNIX calls. */
5396 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5397 DEBUG(3,("call_trans2qfilepathinfo: "
5398 "SMB_VFS_LSTAT of %s failed (%s)\n",
5399 smb_fname_str_dbg(smb_fname
),
5402 map_nt_error_from_unix(errno
));
5407 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
5408 DEBUG(3,("call_trans2qfilepathinfo: "
5409 "SMB_VFS_STAT of %s failed (%s)\n",
5410 smb_fname_str_dbg(smb_fname
),
5413 map_nt_error_from_unix(errno
));
5418 status
= file_name_hash(conn
,
5419 smb_fname_str_dbg(smb_fname
),
5421 if (!NT_STATUS_IS_OK(status
)) {
5422 reply_nterror(req
, status
);
5426 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5427 get_file_infos(fileid
, name_hash
, &delete_pending
, &write_time_ts
);
5428 if (delete_pending
) {
5429 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5434 DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
5435 "total_data=%d\n", smb_fname_str_dbg(smb_fname
),
5437 info_level
,tran_call
,total_data
));
5439 /* Pull out any data sent here before we realloc. */
5440 switch (info_level
) {
5441 case SMB_INFO_QUERY_EAS_FROM_LIST
:
5443 /* Pull any EA list from the data portion. */
5446 if (total_data
< 4) {
5448 req
, NT_STATUS_INVALID_PARAMETER
);
5451 ea_size
= IVAL(pdata
,0);
5453 if (total_data
> 0 && ea_size
!= total_data
) {
5454 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5455 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
5457 req
, NT_STATUS_INVALID_PARAMETER
);
5461 if (!lp_ea_support(SNUM(conn
))) {
5462 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
5466 /* Pull out the list of names. */
5467 ea_list
= read_ea_name_list(req
, pdata
+ 4, ea_size
- 4);
5470 req
, NT_STATUS_INVALID_PARAMETER
);
5476 case SMB_QUERY_POSIX_LOCK
:
5478 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
5479 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
5483 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
5485 req
, NT_STATUS_INVALID_PARAMETER
);
5489 /* Copy the lock range data. */
5490 lock_data
= (char *)talloc_memdup(
5491 req
, pdata
, total_data
);
5493 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5496 lock_data_count
= total_data
;
5502 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
5503 if (*pparams
== NULL
) {
5504 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5511 * draft-leach-cifs-v1-spec-02.txt
5512 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5515 * The requested information is placed in the Data portion of the
5516 * transaction response. For the information levels greater than 0x100,
5517 * the transaction response has 1 parameter word which should be
5518 * ignored by the client.
5520 * However Windows only follows this rule for the IS_NAME_VALID call.
5522 switch (info_level
) {
5523 case SMB_INFO_IS_NAME_VALID
:
5528 if ((info_level
& 0xFF00) == 0xFF00) {
5530 * We use levels that start with 0xFF00
5531 * internally to represent SMB2 specific levels
5533 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5537 status
= smbd_do_qfilepathinfo(conn
, req
, info_level
,
5539 delete_pending
, write_time_ts
,
5541 lock_data_count
, lock_data
,
5542 req
->flags2
, max_data_bytes
,
5543 ppdata
, &data_size
);
5544 if (!NT_STATUS_IS_OK(status
)) {
5545 reply_nterror(req
, status
);
5549 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
5555 /****************************************************************************
5556 Set a hard link (called by UNIX extensions and by NT rename with HARD link
5558 ****************************************************************************/
5560 NTSTATUS
hardlink_internals(TALLOC_CTX
*ctx
,
5561 connection_struct
*conn
,
5562 struct smb_request
*req
,
5563 bool overwrite_if_exists
,
5564 const struct smb_filename
*smb_fname_old
,
5565 struct smb_filename
*smb_fname_new
)
5567 NTSTATUS status
= NT_STATUS_OK
;
5569 /* source must already exist. */
5570 if (!VALID_STAT(smb_fname_old
->st
)) {
5571 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5574 if (VALID_STAT(smb_fname_new
->st
)) {
5575 if (overwrite_if_exists
) {
5576 if (S_ISDIR(smb_fname_new
->st
.st_ex_mode
)) {
5577 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5579 status
= unlink_internals(conn
,
5581 FILE_ATTRIBUTE_NORMAL
,
5584 if (!NT_STATUS_IS_OK(status
)) {
5588 /* Disallow if newname already exists. */
5589 return NT_STATUS_OBJECT_NAME_COLLISION
;
5593 /* No links from a directory. */
5594 if (S_ISDIR(smb_fname_old
->st
.st_ex_mode
)) {
5595 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5598 /* Setting a hardlink to/from a stream isn't currently supported. */
5599 if (is_ntfs_stream_smb_fname(smb_fname_old
) ||
5600 is_ntfs_stream_smb_fname(smb_fname_new
)) {
5601 return NT_STATUS_INVALID_PARAMETER
;
5604 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5605 smb_fname_old
->base_name
, smb_fname_new
->base_name
));
5607 if (SMB_VFS_LINK(conn
, smb_fname_old
->base_name
,
5608 smb_fname_new
->base_name
) != 0) {
5609 status
= map_nt_error_from_unix(errno
);
5610 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5611 nt_errstr(status
), smb_fname_old
->base_name
,
5612 smb_fname_new
->base_name
));
5617 /****************************************************************************
5618 Deal with setting the time from any of the setfilepathinfo functions.
5619 NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
5620 calling this function.
5621 ****************************************************************************/
5623 NTSTATUS
smb_set_file_time(connection_struct
*conn
,
5625 const struct smb_filename
*smb_fname
,
5626 struct smb_file_time
*ft
,
5627 bool setting_write_time
)
5629 struct smb_filename smb_fname_base
;
5631 FILE_NOTIFY_CHANGE_LAST_ACCESS
5632 |FILE_NOTIFY_CHANGE_LAST_WRITE
5633 |FILE_NOTIFY_CHANGE_CREATION
;
5635 if (!VALID_STAT(smb_fname
->st
)) {
5636 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5639 /* get some defaults (no modifications) if any info is zero or -1. */
5640 if (null_timespec(ft
->create_time
)) {
5641 action
&= ~FILE_NOTIFY_CHANGE_CREATION
;
5644 if (null_timespec(ft
->atime
)) {
5645 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
5648 if (null_timespec(ft
->mtime
)) {
5649 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5652 if (!setting_write_time
) {
5653 /* ft->mtime comes from change time, not write time. */
5654 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5657 /* Ensure the resolution is the correct for
5658 * what we can store on this filesystem. */
5660 round_timespec(conn
->ts_res
, &ft
->create_time
);
5661 round_timespec(conn
->ts_res
, &ft
->ctime
);
5662 round_timespec(conn
->ts_res
, &ft
->atime
);
5663 round_timespec(conn
->ts_res
, &ft
->mtime
);
5665 DEBUG(5,("smb_set_filetime: actime: %s\n ",
5666 time_to_asc(convert_timespec_to_time_t(ft
->atime
))));
5667 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5668 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5669 DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5670 time_to_asc(convert_timespec_to_time_t(ft
->ctime
))));
5671 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5672 time_to_asc(convert_timespec_to_time_t(ft
->create_time
))));
5674 if (setting_write_time
) {
5676 * This was a Windows setfileinfo on an open file.
5677 * NT does this a lot. We also need to
5678 * set the time here, as it can be read by
5679 * FindFirst/FindNext and with the patch for bug #2045
5680 * in smbd/fileio.c it ensures that this timestamp is
5681 * kept sticky even after a write. We save the request
5682 * away and will set it on file close and after a write. JRA.
5685 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5686 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5689 if (fsp
->base_fsp
) {
5690 set_sticky_write_time_fsp(fsp
->base_fsp
,
5693 set_sticky_write_time_fsp(fsp
, ft
->mtime
);
5696 set_sticky_write_time_path(
5697 vfs_file_id_from_sbuf(conn
, &smb_fname
->st
),
5702 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5704 /* Always call ntimes on the base, even if a stream was passed in. */
5705 smb_fname_base
= *smb_fname
;
5706 smb_fname_base
.stream_name
= NULL
;
5708 if(file_ntimes(conn
, &smb_fname_base
, ft
)!=0) {
5709 return map_nt_error_from_unix(errno
);
5712 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
,
5713 smb_fname
->base_name
);
5714 return NT_STATUS_OK
;
5717 /****************************************************************************
5718 Deal with setting the dosmode from any of the setfilepathinfo functions.
5719 NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
5720 done before calling this function.
5721 ****************************************************************************/
5723 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
5724 const struct smb_filename
*smb_fname
,
5727 struct smb_filename
*smb_fname_base
= NULL
;
5730 if (!VALID_STAT(smb_fname
->st
)) {
5731 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5734 /* Always operate on the base_name, even if a stream was passed in. */
5735 status
= create_synthetic_smb_fname(talloc_tos(), smb_fname
->base_name
,
5736 NULL
, &smb_fname
->st
,
5738 if (!NT_STATUS_IS_OK(status
)) {
5743 if (S_ISDIR(smb_fname_base
->st
.st_ex_mode
)) {
5744 dosmode
|= FILE_ATTRIBUTE_DIRECTORY
;
5746 dosmode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
5750 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode
));
5752 /* check the mode isn't different, before changing it */
5753 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, smb_fname_base
))) {
5754 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5755 "0x%x\n", smb_fname_str_dbg(smb_fname_base
),
5756 (unsigned int)dosmode
));
5758 if(file_set_dosmode(conn
, smb_fname_base
, dosmode
, NULL
,
5760 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5762 smb_fname_str_dbg(smb_fname_base
),
5764 status
= map_nt_error_from_unix(errno
);
5768 status
= NT_STATUS_OK
;
5770 TALLOC_FREE(smb_fname_base
);
5774 /****************************************************************************
5775 Deal with setting the size from any of the setfilepathinfo functions.
5776 ****************************************************************************/
5778 static NTSTATUS
smb_set_file_size(connection_struct
*conn
,
5779 struct smb_request
*req
,
5781 const struct smb_filename
*smb_fname
,
5782 const SMB_STRUCT_STAT
*psbuf
,
5784 bool fail_after_createfile
)
5786 NTSTATUS status
= NT_STATUS_OK
;
5787 struct smb_filename
*smb_fname_tmp
= NULL
;
5788 files_struct
*new_fsp
= NULL
;
5790 if (!VALID_STAT(*psbuf
)) {
5791 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5794 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size
));
5796 if (size
== get_file_size_stat(psbuf
)) {
5797 return NT_STATUS_OK
;
5800 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5801 smb_fname_str_dbg(smb_fname
), (double)size
));
5803 if (fsp
&& fsp
->fh
->fd
!= -1) {
5804 /* Handle based call. */
5805 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
5806 return NT_STATUS_ACCESS_DENIED
;
5809 if (vfs_set_filelen(fsp
, size
) == -1) {
5810 return map_nt_error_from_unix(errno
);
5812 trigger_write_time_update_immediate(fsp
);
5813 return NT_STATUS_OK
;
5816 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
5817 if (!NT_STATUS_IS_OK(status
)) {
5821 smb_fname_tmp
->st
= *psbuf
;
5823 status
= SMB_VFS_CREATE_FILE(
5826 0, /* root_dir_fid */
5827 smb_fname_tmp
, /* fname */
5828 FILE_WRITE_DATA
, /* access_mask */
5829 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5831 FILE_OPEN
, /* create_disposition*/
5832 0, /* create_options */
5833 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5834 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
5835 0, /* allocation_size */
5836 0, /* private_flags */
5839 &new_fsp
, /* result */
5842 TALLOC_FREE(smb_fname_tmp
);
5844 if (!NT_STATUS_IS_OK(status
)) {
5845 /* NB. We check for open_was_deferred in the caller. */
5849 /* See RAW-SFILEINFO-END-OF-FILE */
5850 if (fail_after_createfile
) {
5851 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5852 return NT_STATUS_INVALID_LEVEL
;
5855 if (vfs_set_filelen(new_fsp
, size
) == -1) {
5856 status
= map_nt_error_from_unix(errno
);
5857 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5861 trigger_write_time_update_immediate(new_fsp
);
5862 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5863 return NT_STATUS_OK
;
5866 /****************************************************************************
5867 Deal with SMB_INFO_SET_EA.
5868 ****************************************************************************/
5870 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
5874 const struct smb_filename
*smb_fname
)
5876 struct ea_list
*ea_list
= NULL
;
5877 TALLOC_CTX
*ctx
= NULL
;
5878 NTSTATUS status
= NT_STATUS_OK
;
5880 if (total_data
< 10) {
5882 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5883 length. They seem to have no effect. Bug #3212. JRA */
5885 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
5886 /* We're done. We only get EA info in this call. */
5887 return NT_STATUS_OK
;
5890 return NT_STATUS_INVALID_PARAMETER
;
5893 if (IVAL(pdata
,0) > total_data
) {
5894 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5895 IVAL(pdata
,0), (unsigned int)total_data
));
5896 return NT_STATUS_INVALID_PARAMETER
;
5900 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
5902 return NT_STATUS_INVALID_PARAMETER
;
5905 status
= set_ea(conn
, fsp
, smb_fname
, ea_list
);
5910 /****************************************************************************
5911 Deal with SMB_FILE_FULL_EA_INFORMATION set.
5912 ****************************************************************************/
5914 static NTSTATUS
smb_set_file_full_ea_info(connection_struct
*conn
,
5919 struct ea_list
*ea_list
= NULL
;
5923 return NT_STATUS_INVALID_HANDLE
;
5926 if (!lp_ea_support(SNUM(conn
))) {
5927 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5928 "EA's not supported.\n",
5929 (unsigned int)total_data
));
5930 return NT_STATUS_EAS_NOT_SUPPORTED
;
5933 if (total_data
< 10) {
5934 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5936 (unsigned int)total_data
));
5937 return NT_STATUS_INVALID_PARAMETER
;
5940 ea_list
= read_nttrans_ea_list(talloc_tos(),
5945 return NT_STATUS_INVALID_PARAMETER
;
5948 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
5950 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5951 smb_fname_str_dbg(fsp
->fsp_name
),
5952 nt_errstr(status
) ));
5958 /****************************************************************************
5959 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5960 ****************************************************************************/
5962 static NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
5966 struct smb_filename
*smb_fname
)
5968 NTSTATUS status
= NT_STATUS_OK
;
5969 bool delete_on_close
;
5972 if (total_data
< 1) {
5973 return NT_STATUS_INVALID_PARAMETER
;
5977 return NT_STATUS_INVALID_HANDLE
;
5980 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
5981 dosmode
= dos_mode(conn
, smb_fname
);
5983 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5984 "delete_on_close = %u\n",
5985 smb_fname_str_dbg(smb_fname
),
5986 (unsigned int)dosmode
,
5987 (unsigned int)delete_on_close
));
5989 if (delete_on_close
) {
5990 status
= can_set_delete_on_close(fsp
, dosmode
);
5991 if (!NT_STATUS_IS_OK(status
)) {
5996 /* The set is across all open files on this dev/inode pair. */
5997 if (!set_delete_on_close(fsp
, delete_on_close
,
5998 conn
->session_info
->security_token
,
5999 conn
->session_info
->unix_token
)) {
6000 return NT_STATUS_ACCESS_DENIED
;
6002 return NT_STATUS_OK
;
6005 /****************************************************************************
6006 Deal with SMB_FILE_POSITION_INFORMATION.
6007 ****************************************************************************/
6009 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
6014 uint64_t position_information
;
6016 if (total_data
< 8) {
6017 return NT_STATUS_INVALID_PARAMETER
;
6021 /* Ignore on pathname based set. */
6022 return NT_STATUS_OK
;
6025 position_information
= (uint64_t)IVAL(pdata
,0);
6026 position_information
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6028 DEBUG(10,("smb_file_position_information: Set file position "
6029 "information for file %s to %.0f\n", fsp_str_dbg(fsp
),
6030 (double)position_information
));
6031 fsp
->fh
->position_information
= position_information
;
6032 return NT_STATUS_OK
;
6035 /****************************************************************************
6036 Deal with SMB_FILE_MODE_INFORMATION.
6037 ****************************************************************************/
6039 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
6045 if (total_data
< 4) {
6046 return NT_STATUS_INVALID_PARAMETER
;
6048 mode
= IVAL(pdata
,0);
6049 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
6050 return NT_STATUS_INVALID_PARAMETER
;
6052 return NT_STATUS_OK
;
6055 /****************************************************************************
6056 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
6057 ****************************************************************************/
6059 static NTSTATUS
smb_set_file_unix_link(connection_struct
*conn
,
6060 struct smb_request
*req
,
6063 const struct smb_filename
*smb_fname
)
6065 char *link_target
= NULL
;
6066 const char *newname
= smb_fname
->base_name
;
6067 TALLOC_CTX
*ctx
= talloc_tos();
6069 /* Set a symbolic link. */
6070 /* Don't allow this if follow links is false. */
6072 if (total_data
== 0) {
6073 return NT_STATUS_INVALID_PARAMETER
;
6076 if (!lp_symlinks(SNUM(conn
))) {
6077 return NT_STATUS_ACCESS_DENIED
;
6080 srvstr_pull_talloc(ctx
, pdata
, req
->flags2
, &link_target
, pdata
,
6081 total_data
, STR_TERMINATE
);
6084 return NT_STATUS_INVALID_PARAMETER
;
6087 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
6088 newname
, link_target
));
6090 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0) {
6091 return map_nt_error_from_unix(errno
);
6094 return NT_STATUS_OK
;
6097 /****************************************************************************
6098 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
6099 ****************************************************************************/
6101 static NTSTATUS
smb_set_file_unix_hlink(connection_struct
*conn
,
6102 struct smb_request
*req
,
6103 const char *pdata
, int total_data
,
6104 struct smb_filename
*smb_fname_new
)
6106 char *oldname
= NULL
;
6107 struct smb_filename
*smb_fname_old
= NULL
;
6108 TALLOC_CTX
*ctx
= talloc_tos();
6109 NTSTATUS status
= NT_STATUS_OK
;
6111 /* Set a hard link. */
6112 if (total_data
== 0) {
6113 return NT_STATUS_INVALID_PARAMETER
;
6116 srvstr_get_path(ctx
, pdata
, req
->flags2
, &oldname
, pdata
,
6117 total_data
, STR_TERMINATE
, &status
);
6118 if (!NT_STATUS_IS_OK(status
)) {
6122 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6123 smb_fname_str_dbg(smb_fname_new
), oldname
));
6125 status
= filename_convert(ctx
,
6127 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6132 if (!NT_STATUS_IS_OK(status
)) {
6136 return hardlink_internals(ctx
, conn
, req
, false,
6137 smb_fname_old
, smb_fname_new
);
6140 /****************************************************************************
6141 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6142 ****************************************************************************/
6144 static NTSTATUS
smb2_file_rename_information(connection_struct
*conn
,
6145 struct smb_request
*req
,
6149 struct smb_filename
*smb_fname_src
)
6153 char *newname
= NULL
;
6154 struct smb_filename
*smb_fname_dst
= NULL
;
6155 NTSTATUS status
= NT_STATUS_OK
;
6156 TALLOC_CTX
*ctx
= talloc_tos();
6159 return NT_STATUS_INVALID_HANDLE
;
6162 if (total_data
< 20) {
6163 return NT_STATUS_INVALID_PARAMETER
;
6166 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6167 len
= IVAL(pdata
,16);
6169 if (len
> (total_data
- 20) || (len
== 0)) {
6170 return NT_STATUS_INVALID_PARAMETER
;
6173 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6174 &pdata
[20], len
, STR_TERMINATE
,
6176 if (!NT_STATUS_IS_OK(status
)) {
6180 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
6183 status
= filename_convert(ctx
,
6185 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6190 if (!NT_STATUS_IS_OK(status
)) {
6194 if (fsp
->base_fsp
) {
6195 /* newname must be a stream name. */
6196 if (newname
[0] != ':') {
6197 return NT_STATUS_NOT_SUPPORTED
;
6200 /* Create an smb_fname to call rename_internals_fsp() with. */
6201 status
= create_synthetic_smb_fname(talloc_tos(),
6202 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6204 if (!NT_STATUS_IS_OK(status
)) {
6209 * Set the original last component, since
6210 * rename_internals_fsp() requires it.
6212 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6214 if (smb_fname_dst
->original_lcomp
== NULL
) {
6215 status
= NT_STATUS_NO_MEMORY
;
6221 DEBUG(10,("smb2_file_rename_information: "
6222 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6223 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6224 smb_fname_str_dbg(smb_fname_dst
)));
6225 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6226 (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
),
6230 TALLOC_FREE(smb_fname_dst
);
6234 static NTSTATUS
smb_file_link_information(connection_struct
*conn
,
6235 struct smb_request
*req
,
6239 struct smb_filename
*smb_fname_src
)
6243 char *newname
= NULL
;
6244 struct smb_filename
*smb_fname_dst
= NULL
;
6245 NTSTATUS status
= NT_STATUS_OK
;
6246 TALLOC_CTX
*ctx
= talloc_tos();
6249 return NT_STATUS_INVALID_HANDLE
;
6252 if (total_data
< 20) {
6253 return NT_STATUS_INVALID_PARAMETER
;
6256 overwrite
= (CVAL(pdata
,0) ? true : false);
6257 len
= IVAL(pdata
,16);
6259 if (len
> (total_data
- 20) || (len
== 0)) {
6260 return NT_STATUS_INVALID_PARAMETER
;
6263 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6264 &pdata
[20], len
, STR_TERMINATE
,
6266 if (!NT_STATUS_IS_OK(status
)) {
6270 DEBUG(10,("smb_file_link_information: got name |%s|\n",
6273 status
= filename_convert(ctx
,
6275 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6280 if (!NT_STATUS_IS_OK(status
)) {
6284 if (fsp
->base_fsp
) {
6285 /* No stream names. */
6286 return NT_STATUS_NOT_SUPPORTED
;
6289 DEBUG(10,("smb_file_link_information: "
6290 "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
6291 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6292 smb_fname_str_dbg(smb_fname_dst
)));
6293 status
= hardlink_internals(ctx
,
6300 TALLOC_FREE(smb_fname_dst
);
6304 /****************************************************************************
6305 Deal with SMB_FILE_RENAME_INFORMATION.
6306 ****************************************************************************/
6308 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
6309 struct smb_request
*req
,
6313 struct smb_filename
*smb_fname_src
)
6318 char *newname
= NULL
;
6319 struct smb_filename
*smb_fname_dst
= NULL
;
6320 bool dest_has_wcard
= False
;
6321 NTSTATUS status
= NT_STATUS_OK
;
6323 TALLOC_CTX
*ctx
= talloc_tos();
6325 if (total_data
< 13) {
6326 return NT_STATUS_INVALID_PARAMETER
;
6329 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6330 root_fid
= IVAL(pdata
,4);
6331 len
= IVAL(pdata
,8);
6333 if (len
> (total_data
- 12) || (len
== 0) || (root_fid
!= 0)) {
6334 return NT_STATUS_INVALID_PARAMETER
;
6337 srvstr_get_path_wcard(ctx
, pdata
, req
->flags2
, &newname
, &pdata
[12],
6340 if (!NT_STATUS_IS_OK(status
)) {
6344 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6347 status
= resolve_dfspath_wcard(ctx
, conn
,
6348 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6351 !conn
->sconn
->using_smb2
,
6354 if (!NT_STATUS_IS_OK(status
)) {
6358 /* Check the new name has no '/' characters. */
6359 if (strchr_m(newname
, '/')) {
6360 return NT_STATUS_NOT_SUPPORTED
;
6363 if (fsp
&& fsp
->base_fsp
) {
6364 /* newname must be a stream name. */
6365 if (newname
[0] != ':') {
6366 return NT_STATUS_NOT_SUPPORTED
;
6369 /* Create an smb_fname to call rename_internals_fsp() with. */
6370 status
= create_synthetic_smb_fname(talloc_tos(),
6371 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6373 if (!NT_STATUS_IS_OK(status
)) {
6378 * Set the original last component, since
6379 * rename_internals_fsp() requires it.
6381 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6383 if (smb_fname_dst
->original_lcomp
== NULL
) {
6384 status
= NT_STATUS_NO_MEMORY
;
6390 * Build up an smb_fname_dst based on the filename passed in.
6391 * We basically just strip off the last component, and put on
6392 * the newname instead.
6394 char *base_name
= NULL
;
6396 /* newname must *not* be a stream name. */
6397 if (newname
[0] == ':') {
6398 return NT_STATUS_NOT_SUPPORTED
;
6402 * Strip off the last component (filename) of the path passed
6405 base_name
= talloc_strdup(ctx
, smb_fname_src
->base_name
);
6407 return NT_STATUS_NO_MEMORY
;
6409 p
= strrchr_m(base_name
, '/');
6413 base_name
= talloc_strdup(ctx
, "");
6415 return NT_STATUS_NO_MEMORY
;
6418 /* Append the new name. */
6419 base_name
= talloc_asprintf_append(base_name
,
6423 return NT_STATUS_NO_MEMORY
;
6426 status
= unix_convert(ctx
, conn
, base_name
, &smb_fname_dst
,
6429 UCF_ALWAYS_ALLOW_WCARD_LCOMP
:
6432 /* If an error we expect this to be
6433 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6435 if (!NT_STATUS_IS_OK(status
)) {
6436 if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND
,
6440 /* Create an smb_fname to call rename_internals_fsp() */
6441 status
= create_synthetic_smb_fname(ctx
,
6445 if (!NT_STATUS_IS_OK(status
)) {
6452 DEBUG(10,("smb_file_rename_information: "
6453 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6454 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6455 smb_fname_str_dbg(smb_fname_dst
)));
6456 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
, 0,
6459 DEBUG(10,("smb_file_rename_information: "
6460 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6461 smb_fname_str_dbg(smb_fname_src
),
6462 smb_fname_str_dbg(smb_fname_dst
)));
6463 status
= rename_internals(ctx
, conn
, req
, smb_fname_src
,
6464 smb_fname_dst
, 0, overwrite
, false,
6466 FILE_WRITE_ATTRIBUTES
);
6469 TALLOC_FREE(smb_fname_dst
);
6473 /****************************************************************************
6474 Deal with SMB_SET_POSIX_ACL.
6475 ****************************************************************************/
6477 #if defined(HAVE_POSIX_ACLS)
6478 static NTSTATUS
smb_set_posix_acl(connection_struct
*conn
,
6482 const struct smb_filename
*smb_fname
)
6484 uint16 posix_acl_version
;
6485 uint16 num_file_acls
;
6486 uint16 num_def_acls
;
6487 bool valid_file_acls
= True
;
6488 bool valid_def_acls
= True
;
6490 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
6491 return NT_STATUS_INVALID_PARAMETER
;
6493 posix_acl_version
= SVAL(pdata
,0);
6494 num_file_acls
= SVAL(pdata
,2);
6495 num_def_acls
= SVAL(pdata
,4);
6497 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6498 valid_file_acls
= False
;
6502 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6503 valid_def_acls
= False
;
6507 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
6508 return NT_STATUS_INVALID_PARAMETER
;
6511 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
6512 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
6513 return NT_STATUS_INVALID_PARAMETER
;
6516 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6517 smb_fname
? smb_fname_str_dbg(smb_fname
) : fsp_str_dbg(fsp
),
6518 (unsigned int)num_file_acls
,
6519 (unsigned int)num_def_acls
));
6521 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
,
6522 smb_fname
->base_name
, num_file_acls
,
6523 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
6524 return map_nt_error_from_unix(errno
);
6527 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
,
6528 smb_fname
->base_name
, &smb_fname
->st
, num_def_acls
,
6529 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
6530 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
6531 return map_nt_error_from_unix(errno
);
6533 return NT_STATUS_OK
;
6537 /****************************************************************************
6538 Deal with SMB_SET_POSIX_LOCK.
6539 ****************************************************************************/
6541 static NTSTATUS
smb_set_posix_lock(connection_struct
*conn
,
6542 struct smb_request
*req
,
6550 bool blocking_lock
= False
;
6551 enum brl_type lock_type
;
6553 NTSTATUS status
= NT_STATUS_OK
;
6555 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
6556 return NT_STATUS_INVALID_HANDLE
;
6559 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
6560 return NT_STATUS_INVALID_PARAMETER
;
6563 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
6564 case POSIX_LOCK_TYPE_READ
:
6565 lock_type
= READ_LOCK
;
6567 case POSIX_LOCK_TYPE_WRITE
:
6568 /* Return the right POSIX-mappable error code for files opened read-only. */
6569 if (!fsp
->can_write
) {
6570 return NT_STATUS_INVALID_HANDLE
;
6572 lock_type
= WRITE_LOCK
;
6574 case POSIX_LOCK_TYPE_UNLOCK
:
6575 lock_type
= UNLOCK_LOCK
;
6578 return NT_STATUS_INVALID_PARAMETER
;
6581 if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_NOWAIT
) {
6582 blocking_lock
= False
;
6583 } else if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_WAIT
) {
6584 blocking_lock
= True
;
6586 return NT_STATUS_INVALID_PARAMETER
;
6589 if (!lp_blocking_locks(SNUM(conn
))) {
6590 blocking_lock
= False
;
6593 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
6594 #if defined(HAVE_LONGLONG)
6595 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
6596 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
6597 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
6598 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
6599 #else /* HAVE_LONGLONG */
6600 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
6601 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
6602 #endif /* HAVE_LONGLONG */
6604 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6605 "smblctx = %llu, count = %.0f, offset = %.0f\n",
6607 (unsigned int)lock_type
,
6608 (unsigned long long)smblctx
,
6612 if (lock_type
== UNLOCK_LOCK
) {
6613 status
= do_unlock(req
->sconn
->msg_ctx
,
6620 uint64_t block_smblctx
;
6622 struct byte_range_lock
*br_lck
= do_lock(req
->sconn
->msg_ctx
,
6634 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
6636 * A blocking lock was requested. Package up
6637 * this smb into a queued request and push it
6638 * onto the blocking lock queue.
6640 if(push_blocking_lock_request(br_lck
,
6643 -1, /* infinite timeout. */
6651 TALLOC_FREE(br_lck
);
6655 TALLOC_FREE(br_lck
);
6661 /****************************************************************************
6662 Deal with SMB_SET_FILE_BASIC_INFO.
6663 ****************************************************************************/
6665 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
6669 const struct smb_filename
*smb_fname
)
6671 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6672 struct smb_file_time ft
;
6674 NTSTATUS status
= NT_STATUS_OK
;
6678 if (total_data
< 36) {
6679 return NT_STATUS_INVALID_PARAMETER
;
6682 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_ATTRIBUTES
);
6683 if (!NT_STATUS_IS_OK(status
)) {
6687 /* Set the attributes */
6688 dosmode
= IVAL(pdata
,32);
6689 status
= smb_set_file_dosmode(conn
, smb_fname
, dosmode
);
6690 if (!NT_STATUS_IS_OK(status
)) {
6695 ft
.create_time
= interpret_long_date(pdata
);
6698 ft
.atime
= interpret_long_date(pdata
+8);
6701 ft
.mtime
= interpret_long_date(pdata
+16);
6704 ft
.ctime
= interpret_long_date(pdata
+24);
6706 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6707 smb_fname_str_dbg(smb_fname
)));
6709 return smb_set_file_time(conn
, fsp
, smb_fname
, &ft
,
6713 /****************************************************************************
6714 Deal with SMB_INFO_STANDARD.
6715 ****************************************************************************/
6717 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
6721 const struct smb_filename
*smb_fname
)
6724 struct smb_file_time ft
;
6728 if (total_data
< 12) {
6729 return NT_STATUS_INVALID_PARAMETER
;
6733 ft
.create_time
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
));
6735 ft
.atime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+4));
6737 ft
.mtime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+8));
6739 DEBUG(10,("smb_set_info_standard: file %s\n",
6740 smb_fname_str_dbg(smb_fname
)));
6742 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_ATTRIBUTES
);
6743 if (!NT_STATUS_IS_OK(status
)) {
6747 return smb_set_file_time(conn
,
6754 /****************************************************************************
6755 Deal with SMB_SET_FILE_ALLOCATION_INFO.
6756 ****************************************************************************/
6758 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
6759 struct smb_request
*req
,
6763 struct smb_filename
*smb_fname
)
6765 uint64_t allocation_size
= 0;
6766 NTSTATUS status
= NT_STATUS_OK
;
6767 files_struct
*new_fsp
= NULL
;
6769 if (!VALID_STAT(smb_fname
->st
)) {
6770 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6773 if (total_data
< 8) {
6774 return NT_STATUS_INVALID_PARAMETER
;
6777 allocation_size
= (uint64_t)IVAL(pdata
,0);
6778 allocation_size
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6779 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6780 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6781 (double)allocation_size
));
6783 if (allocation_size
) {
6784 allocation_size
= smb_roundup(conn
, allocation_size
);
6787 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6788 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname
),
6789 (double)allocation_size
));
6791 if (fsp
&& fsp
->fh
->fd
!= -1) {
6792 /* Open file handle. */
6793 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6794 return NT_STATUS_ACCESS_DENIED
;
6797 /* Only change if needed. */
6798 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6799 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
6800 return map_nt_error_from_unix(errno
);
6803 /* But always update the time. */
6805 * This is equivalent to a write. Ensure it's seen immediately
6806 * if there are no pending writes.
6808 trigger_write_time_update_immediate(fsp
);
6809 return NT_STATUS_OK
;
6812 /* Pathname or stat or directory file. */
6813 status
= SMB_VFS_CREATE_FILE(
6816 0, /* root_dir_fid */
6817 smb_fname
, /* fname */
6818 FILE_WRITE_DATA
, /* access_mask */
6819 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
6821 FILE_OPEN
, /* create_disposition*/
6822 0, /* create_options */
6823 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
6824 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
6825 0, /* allocation_size */
6826 0, /* private_flags */
6829 &new_fsp
, /* result */
6832 if (!NT_STATUS_IS_OK(status
)) {
6833 /* NB. We check for open_was_deferred in the caller. */
6837 /* Only change if needed. */
6838 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6839 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
6840 status
= map_nt_error_from_unix(errno
);
6841 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6846 /* Changing the allocation size should set the last mod time. */
6848 * This is equivalent to a write. Ensure it's seen immediately
6849 * if there are no pending writes.
6851 trigger_write_time_update_immediate(new_fsp
);
6853 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6854 return NT_STATUS_OK
;
6857 /****************************************************************************
6858 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6859 ****************************************************************************/
6861 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
6862 struct smb_request
*req
,
6866 const struct smb_filename
*smb_fname
,
6867 bool fail_after_createfile
)
6871 if (total_data
< 8) {
6872 return NT_STATUS_INVALID_PARAMETER
;
6875 size
= IVAL(pdata
,0);
6876 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
6877 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6878 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6881 return smb_set_file_size(conn
, req
,
6886 fail_after_createfile
);
6889 /****************************************************************************
6890 Allow a UNIX info mknod.
6891 ****************************************************************************/
6893 static NTSTATUS
smb_unix_mknod(connection_struct
*conn
,
6896 const struct smb_filename
*smb_fname
)
6898 uint32 file_type
= IVAL(pdata
,56);
6899 #if defined(HAVE_MAKEDEV)
6900 uint32 dev_major
= IVAL(pdata
,60);
6901 uint32 dev_minor
= IVAL(pdata
,68);
6903 SMB_DEV_T dev
= (SMB_DEV_T
)0;
6904 uint32 raw_unixmode
= IVAL(pdata
,84);
6908 if (total_data
< 100) {
6909 return NT_STATUS_INVALID_PARAMETER
;
6912 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6913 PERM_NEW_FILE
, &unixmode
);
6914 if (!NT_STATUS_IS_OK(status
)) {
6918 #if defined(HAVE_MAKEDEV)
6919 dev
= makedev(dev_major
, dev_minor
);
6922 switch (file_type
) {
6923 #if defined(S_IFIFO)
6924 case UNIX_TYPE_FIFO
:
6925 unixmode
|= S_IFIFO
;
6928 #if defined(S_IFSOCK)
6929 case UNIX_TYPE_SOCKET
:
6930 unixmode
|= S_IFSOCK
;
6933 #if defined(S_IFCHR)
6934 case UNIX_TYPE_CHARDEV
:
6935 unixmode
|= S_IFCHR
;
6938 #if defined(S_IFBLK)
6939 case UNIX_TYPE_BLKDEV
:
6940 unixmode
|= S_IFBLK
;
6944 return NT_STATUS_INVALID_PARAMETER
;
6947 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6948 "%.0f mode 0%o for file %s\n", (double)dev
,
6949 (unsigned int)unixmode
, smb_fname_str_dbg(smb_fname
)));
6951 /* Ok - do the mknod. */
6952 if (SMB_VFS_MKNOD(conn
, smb_fname
->base_name
, unixmode
, dev
) != 0) {
6953 return map_nt_error_from_unix(errno
);
6956 /* If any of the other "set" calls fail we
6957 * don't want to end up with a half-constructed mknod.
6960 if (lp_inherit_perms(SNUM(conn
))) {
6962 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
,
6964 return NT_STATUS_NO_MEMORY
;
6966 inherit_access_posix_acl(conn
, parent
, smb_fname
->base_name
,
6968 TALLOC_FREE(parent
);
6971 return NT_STATUS_OK
;
6974 /****************************************************************************
6975 Deal with SMB_SET_FILE_UNIX_BASIC.
6976 ****************************************************************************/
6978 static NTSTATUS
smb_set_file_unix_basic(connection_struct
*conn
,
6979 struct smb_request
*req
,
6983 const struct smb_filename
*smb_fname
)
6985 struct smb_file_time ft
;
6986 uint32 raw_unixmode
;
6989 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
6990 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
6991 NTSTATUS status
= NT_STATUS_OK
;
6992 bool delete_on_fail
= False
;
6993 enum perm_type ptype
;
6994 files_struct
*all_fsps
= NULL
;
6995 bool modify_mtime
= true;
6997 struct smb_filename
*smb_fname_tmp
= NULL
;
6998 SMB_STRUCT_STAT sbuf
;
7002 if (total_data
< 100) {
7003 return NT_STATUS_INVALID_PARAMETER
;
7006 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
7007 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
7008 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
7009 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
7012 ft
.atime
= interpret_long_date(pdata
+24); /* access_time */
7013 ft
.mtime
= interpret_long_date(pdata
+32); /* modification_time */
7014 set_owner
= (uid_t
)IVAL(pdata
,40);
7015 set_grp
= (gid_t
)IVAL(pdata
,48);
7016 raw_unixmode
= IVAL(pdata
,84);
7018 if (VALID_STAT(smb_fname
->st
)) {
7019 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
7020 ptype
= PERM_EXISTING_DIR
;
7022 ptype
= PERM_EXISTING_FILE
;
7025 ptype
= PERM_NEW_FILE
;
7028 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7030 if (!NT_STATUS_IS_OK(status
)) {
7034 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
7035 "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
7036 smb_fname_str_dbg(smb_fname
), (double)size
,
7037 (unsigned int)set_owner
, (unsigned int)set_grp
,
7038 (int)raw_unixmode
));
7040 sbuf
= smb_fname
->st
;
7042 if (!VALID_STAT(sbuf
)) {
7044 * The only valid use of this is to create character and block
7045 * devices, and named pipes. This is deprecated (IMHO) and
7046 * a new info level should be used for mknod. JRA.
7049 status
= smb_unix_mknod(conn
,
7053 if (!NT_STATUS_IS_OK(status
)) {
7057 status
= copy_smb_filename(talloc_tos(), smb_fname
,
7059 if (!NT_STATUS_IS_OK(status
)) {
7063 if (SMB_VFS_STAT(conn
, smb_fname_tmp
) != 0) {
7064 status
= map_nt_error_from_unix(errno
);
7065 TALLOC_FREE(smb_fname_tmp
);
7066 SMB_VFS_UNLINK(conn
, smb_fname
);
7070 sbuf
= smb_fname_tmp
->st
;
7071 smb_fname
= smb_fname_tmp
;
7073 /* Ensure we don't try and change anything else. */
7074 raw_unixmode
= SMB_MODE_NO_CHANGE
;
7075 size
= get_file_size_stat(&sbuf
);
7076 ft
.atime
= sbuf
.st_ex_atime
;
7077 ft
.mtime
= sbuf
.st_ex_mtime
;
7079 * We continue here as we might want to change the
7082 delete_on_fail
= True
;
7086 /* Horrible backwards compatibility hack as an old server bug
7087 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
7091 size
= get_file_size_stat(&sbuf
);
7096 * Deal with the UNIX specific mode set.
7099 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
7100 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7101 "setting mode 0%o for file %s\n",
7102 (unsigned int)unixmode
,
7103 smb_fname_str_dbg(smb_fname
)));
7104 if (SMB_VFS_CHMOD(conn
, smb_fname
->base_name
, unixmode
) != 0) {
7105 return map_nt_error_from_unix(errno
);
7110 * Deal with the UNIX specific uid set.
7113 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) &&
7114 (sbuf
.st_ex_uid
!= set_owner
)) {
7117 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7118 "changing owner %u for path %s\n",
7119 (unsigned int)set_owner
,
7120 smb_fname_str_dbg(smb_fname
)));
7122 if (S_ISLNK(sbuf
.st_ex_mode
)) {
7123 ret
= SMB_VFS_LCHOWN(conn
, smb_fname
->base_name
,
7124 set_owner
, (gid_t
)-1);
7126 ret
= SMB_VFS_CHOWN(conn
, smb_fname
->base_name
,
7127 set_owner
, (gid_t
)-1);
7131 status
= map_nt_error_from_unix(errno
);
7132 if (delete_on_fail
) {
7133 SMB_VFS_UNLINK(conn
, smb_fname
);
7140 * Deal with the UNIX specific gid set.
7143 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) &&
7144 (sbuf
.st_ex_gid
!= set_grp
)) {
7145 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7146 "changing group %u for file %s\n",
7147 (unsigned int)set_owner
,
7148 smb_fname_str_dbg(smb_fname
)));
7149 if (SMB_VFS_CHOWN(conn
, smb_fname
->base_name
, (uid_t
)-1,
7151 status
= map_nt_error_from_unix(errno
);
7152 if (delete_on_fail
) {
7153 SMB_VFS_UNLINK(conn
, smb_fname
);
7159 /* Deal with any size changes. */
7161 status
= smb_set_file_size(conn
, req
,
7167 if (!NT_STATUS_IS_OK(status
)) {
7171 /* Deal with any time changes. */
7172 if (null_timespec(ft
.mtime
) && null_timespec(ft
.atime
)) {
7173 /* No change, don't cancel anything. */
7177 id
= vfs_file_id_from_sbuf(conn
, &sbuf
);
7178 for(all_fsps
= file_find_di_first(conn
->sconn
, id
); all_fsps
;
7179 all_fsps
= file_find_di_next(all_fsps
)) {
7181 * We're setting the time explicitly for UNIX.
7182 * Cancel any pending changes over all handles.
7184 all_fsps
->update_write_time_on_close
= false;
7185 TALLOC_FREE(all_fsps
->update_write_time_event
);
7189 * Override the "setting_write_time"
7190 * parameter here as it almost does what
7191 * we need. Just remember if we modified
7192 * mtime and send the notify ourselves.
7194 if (null_timespec(ft
.mtime
)) {
7195 modify_mtime
= false;
7198 status
= smb_set_file_time(conn
,
7204 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
7205 FILE_NOTIFY_CHANGE_LAST_WRITE
, smb_fname
->base_name
);
7210 /****************************************************************************
7211 Deal with SMB_SET_FILE_UNIX_INFO2.
7212 ****************************************************************************/
7214 static NTSTATUS
smb_set_file_unix_info2(connection_struct
*conn
,
7215 struct smb_request
*req
,
7219 const struct smb_filename
*smb_fname
)
7225 if (total_data
< 116) {
7226 return NT_STATUS_INVALID_PARAMETER
;
7229 /* Start by setting all the fields that are common between UNIX_BASIC
7232 status
= smb_set_file_unix_basic(conn
, req
, pdata
, total_data
,
7234 if (!NT_STATUS_IS_OK(status
)) {
7238 smb_fflags
= IVAL(pdata
, 108);
7239 smb_fmask
= IVAL(pdata
, 112);
7241 /* NB: We should only attempt to alter the file flags if the client
7242 * sends a non-zero mask.
7244 if (smb_fmask
!= 0) {
7245 int stat_fflags
= 0;
7247 if (!map_info2_flags_to_sbuf(&smb_fname
->st
, smb_fflags
,
7248 smb_fmask
, &stat_fflags
)) {
7249 /* Client asked to alter a flag we don't understand. */
7250 return NT_STATUS_INVALID_PARAMETER
;
7253 if (fsp
&& fsp
->fh
->fd
!= -1) {
7254 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
7255 return NT_STATUS_NOT_SUPPORTED
;
7257 if (SMB_VFS_CHFLAGS(conn
, smb_fname
->base_name
,
7258 stat_fflags
) != 0) {
7259 return map_nt_error_from_unix(errno
);
7264 /* XXX: need to add support for changing the create_time here. You
7265 * can do this for paths on Darwin with setattrlist(2). The right way
7266 * to hook this up is probably by extending the VFS utimes interface.
7269 return NT_STATUS_OK
;
7272 /****************************************************************************
7273 Create a directory with POSIX semantics.
7274 ****************************************************************************/
7276 static NTSTATUS
smb_posix_mkdir(connection_struct
*conn
,
7277 struct smb_request
*req
,
7280 struct smb_filename
*smb_fname
,
7281 int *pdata_return_size
)
7283 NTSTATUS status
= NT_STATUS_OK
;
7284 uint32 raw_unixmode
= 0;
7285 uint32 mod_unixmode
= 0;
7286 mode_t unixmode
= (mode_t
)0;
7287 files_struct
*fsp
= NULL
;
7288 uint16 info_level_return
= 0;
7290 char *pdata
= *ppdata
;
7292 if (total_data
< 18) {
7293 return NT_STATUS_INVALID_PARAMETER
;
7296 raw_unixmode
= IVAL(pdata
,8);
7297 /* Next 4 bytes are not yet defined. */
7299 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7300 PERM_NEW_DIR
, &unixmode
);
7301 if (!NT_STATUS_IS_OK(status
)) {
7305 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7307 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7308 smb_fname_str_dbg(smb_fname
), (unsigned int)unixmode
));
7310 status
= SMB_VFS_CREATE_FILE(
7313 0, /* root_dir_fid */
7314 smb_fname
, /* fname */
7315 FILE_READ_ATTRIBUTES
, /* access_mask */
7316 FILE_SHARE_NONE
, /* share_access */
7317 FILE_CREATE
, /* create_disposition*/
7318 FILE_DIRECTORY_FILE
, /* create_options */
7319 mod_unixmode
, /* file_attributes */
7320 0, /* oplock_request */
7321 0, /* allocation_size */
7322 0, /* private_flags */
7328 if (NT_STATUS_IS_OK(status
)) {
7329 close_file(req
, fsp
, NORMAL_CLOSE
);
7332 info_level_return
= SVAL(pdata
,16);
7334 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7335 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7336 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7337 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7339 *pdata_return_size
= 12;
7342 /* Realloc the data size */
7343 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7344 if (*ppdata
== NULL
) {
7345 *pdata_return_size
= 0;
7346 return NT_STATUS_NO_MEMORY
;
7350 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7351 SSVAL(pdata
,2,0); /* No fnum. */
7352 SIVAL(pdata
,4,info
); /* Was directory created. */
7354 switch (info_level_return
) {
7355 case SMB_QUERY_FILE_UNIX_BASIC
:
7356 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7357 SSVAL(pdata
,10,0); /* Padding. */
7358 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7361 case SMB_QUERY_FILE_UNIX_INFO2
:
7362 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7363 SSVAL(pdata
,10,0); /* Padding. */
7364 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7368 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7369 SSVAL(pdata
,10,0); /* Padding. */
7376 /****************************************************************************
7377 Open/Create a file with POSIX semantics.
7378 ****************************************************************************/
7380 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7381 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7383 static NTSTATUS
smb_posix_open(connection_struct
*conn
,
7384 struct smb_request
*req
,
7387 struct smb_filename
*smb_fname
,
7388 int *pdata_return_size
)
7390 bool extended_oplock_granted
= False
;
7391 char *pdata
= *ppdata
;
7393 uint32 wire_open_mode
= 0;
7394 uint32 raw_unixmode
= 0;
7395 uint32 mod_unixmode
= 0;
7396 uint32 create_disp
= 0;
7397 uint32 access_mask
= 0;
7398 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
7399 NTSTATUS status
= NT_STATUS_OK
;
7400 mode_t unixmode
= (mode_t
)0;
7401 files_struct
*fsp
= NULL
;
7402 int oplock_request
= 0;
7404 uint16 info_level_return
= 0;
7406 if (total_data
< 18) {
7407 return NT_STATUS_INVALID_PARAMETER
;
7410 flags
= IVAL(pdata
,0);
7411 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
7412 if (oplock_request
) {
7413 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
7416 wire_open_mode
= IVAL(pdata
,4);
7418 if (wire_open_mode
== (SMB_O_CREAT
|SMB_O_DIRECTORY
)) {
7419 return smb_posix_mkdir(conn
, req
,
7426 switch (wire_open_mode
& SMB_ACCMODE
) {
7428 access_mask
= SMB_O_RDONLY_MAPPING
;
7431 access_mask
= SMB_O_WRONLY_MAPPING
;
7434 access_mask
= (SMB_O_RDONLY_MAPPING
|
7435 SMB_O_WRONLY_MAPPING
);
7438 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7439 (unsigned int)wire_open_mode
));
7440 return NT_STATUS_INVALID_PARAMETER
;
7443 wire_open_mode
&= ~SMB_ACCMODE
;
7445 /* First take care of O_CREAT|O_EXCL interactions. */
7446 switch (wire_open_mode
& (SMB_O_CREAT
| SMB_O_EXCL
)) {
7447 case (SMB_O_CREAT
| SMB_O_EXCL
):
7448 /* File exists fail. File not exist create. */
7449 create_disp
= FILE_CREATE
;
7452 /* File exists open. File not exist create. */
7453 create_disp
= FILE_OPEN_IF
;
7456 /* O_EXCL on its own without O_CREAT is undefined.
7457 We deliberately ignore it as some versions of
7458 Linux CIFSFS can send a bare O_EXCL on the
7459 wire which other filesystems in the kernel
7460 ignore. See bug 9519 for details. */
7465 /* File exists open. File not exist fail. */
7466 create_disp
= FILE_OPEN
;
7469 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7470 (unsigned int)wire_open_mode
));
7471 return NT_STATUS_INVALID_PARAMETER
;
7474 /* Next factor in the effects of O_TRUNC. */
7475 wire_open_mode
&= ~(SMB_O_CREAT
| SMB_O_EXCL
);
7477 if (wire_open_mode
& SMB_O_TRUNC
) {
7478 switch (create_disp
) {
7480 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7481 /* Leave create_disp alone as
7482 (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7484 /* File exists fail. File not exist create. */
7487 /* SMB_O_CREAT | SMB_O_TRUNC */
7488 /* File exists overwrite. File not exist create. */
7489 create_disp
= FILE_OVERWRITE_IF
;
7493 /* File exists overwrite. File not exist fail. */
7494 create_disp
= FILE_OVERWRITE
;
7497 /* Cannot get here. */
7498 smb_panic("smb_posix_open: logic error");
7499 return NT_STATUS_INVALID_PARAMETER
;
7503 raw_unixmode
= IVAL(pdata
,8);
7504 /* Next 4 bytes are not yet defined. */
7506 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7507 (VALID_STAT(smb_fname
->st
) ?
7508 PERM_EXISTING_FILE
: PERM_NEW_FILE
),
7511 if (!NT_STATUS_IS_OK(status
)) {
7515 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7517 if (wire_open_mode
& SMB_O_SYNC
) {
7518 create_options
|= FILE_WRITE_THROUGH
;
7520 if (wire_open_mode
& SMB_O_APPEND
) {
7521 access_mask
|= FILE_APPEND_DATA
;
7523 if (wire_open_mode
& SMB_O_DIRECT
) {
7524 mod_unixmode
|= FILE_FLAG_NO_BUFFERING
;
7527 if ((wire_open_mode
& SMB_O_DIRECTORY
) ||
7528 VALID_STAT_OF_DIR(smb_fname
->st
)) {
7529 if (access_mask
!= SMB_O_RDONLY_MAPPING
) {
7530 return NT_STATUS_FILE_IS_A_DIRECTORY
;
7532 create_options
&= ~FILE_NON_DIRECTORY_FILE
;
7533 create_options
|= FILE_DIRECTORY_FILE
;
7536 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7537 smb_fname_str_dbg(smb_fname
),
7538 (unsigned int)wire_open_mode
,
7539 (unsigned int)unixmode
));
7541 status
= SMB_VFS_CREATE_FILE(
7544 0, /* root_dir_fid */
7545 smb_fname
, /* fname */
7546 access_mask
, /* access_mask */
7547 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7549 create_disp
, /* create_disposition*/
7550 create_options
, /* create_options */
7551 mod_unixmode
, /* file_attributes */
7552 oplock_request
, /* oplock_request */
7553 0, /* allocation_size */
7554 0, /* private_flags */
7560 if (!NT_STATUS_IS_OK(status
)) {
7564 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
7565 extended_oplock_granted
= True
;
7568 if(oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
7569 extended_oplock_granted
= True
;
7572 info_level_return
= SVAL(pdata
,16);
7574 /* Allocate the correct return size. */
7576 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7577 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7578 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7579 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7581 *pdata_return_size
= 12;
7584 /* Realloc the data size */
7585 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7586 if (*ppdata
== NULL
) {
7587 close_file(req
, fsp
, ERROR_CLOSE
);
7588 *pdata_return_size
= 0;
7589 return NT_STATUS_NO_MEMORY
;
7593 if (extended_oplock_granted
) {
7594 if (flags
& REQUEST_BATCH_OPLOCK
) {
7595 SSVAL(pdata
,0, BATCH_OPLOCK_RETURN
);
7597 SSVAL(pdata
,0, EXCLUSIVE_OPLOCK_RETURN
);
7599 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
7600 SSVAL(pdata
,0, LEVEL_II_OPLOCK_RETURN
);
7602 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7605 SSVAL(pdata
,2,fsp
->fnum
);
7606 SIVAL(pdata
,4,info
); /* Was file created etc. */
7608 switch (info_level_return
) {
7609 case SMB_QUERY_FILE_UNIX_BASIC
:
7610 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7611 SSVAL(pdata
,10,0); /* padding. */
7612 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7615 case SMB_QUERY_FILE_UNIX_INFO2
:
7616 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7617 SSVAL(pdata
,10,0); /* padding. */
7618 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7622 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7623 SSVAL(pdata
,10,0); /* padding. */
7626 return NT_STATUS_OK
;
7629 /****************************************************************************
7630 Delete a file with POSIX semantics.
7631 ****************************************************************************/
7633 static NTSTATUS
smb_posix_unlink(connection_struct
*conn
,
7634 struct smb_request
*req
,
7637 struct smb_filename
*smb_fname
)
7639 NTSTATUS status
= NT_STATUS_OK
;
7640 files_struct
*fsp
= NULL
;
7644 int create_options
= 0;
7646 struct share_mode_lock
*lck
= NULL
;
7648 if (total_data
< 2) {
7649 return NT_STATUS_INVALID_PARAMETER
;
7652 flags
= SVAL(pdata
,0);
7654 if (!VALID_STAT(smb_fname
->st
)) {
7655 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
7658 if ((flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) &&
7659 !VALID_STAT_OF_DIR(smb_fname
->st
)) {
7660 return NT_STATUS_NOT_A_DIRECTORY
;
7663 DEBUG(10,("smb_posix_unlink: %s %s\n",
7664 (flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) ? "directory" : "file",
7665 smb_fname_str_dbg(smb_fname
)));
7667 if (VALID_STAT_OF_DIR(smb_fname
->st
)) {
7668 create_options
|= FILE_DIRECTORY_FILE
;
7671 status
= SMB_VFS_CREATE_FILE(
7674 0, /* root_dir_fid */
7675 smb_fname
, /* fname */
7676 DELETE_ACCESS
, /* access_mask */
7677 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7679 FILE_OPEN
, /* create_disposition*/
7680 create_options
, /* create_options */
7681 FILE_FLAG_POSIX_SEMANTICS
|0777, /* file_attributes */
7682 0, /* oplock_request */
7683 0, /* allocation_size */
7684 0, /* private_flags */
7690 if (!NT_STATUS_IS_OK(status
)) {
7695 * Don't lie to client. If we can't really delete due to
7696 * non-POSIX opens return SHARING_VIOLATION.
7699 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
7701 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7702 "lock for file %s\n", fsp_str_dbg(fsp
)));
7703 close_file(req
, fsp
, NORMAL_CLOSE
);
7704 return NT_STATUS_INVALID_PARAMETER
;
7708 * See if others still have the file open. If this is the case, then
7709 * don't delete. If all opens are POSIX delete we can set the delete
7710 * on close disposition.
7712 for (i
=0; i
<lck
->data
->num_share_modes
; i
++) {
7713 struct share_mode_entry
*e
= &lck
->data
->share_modes
[i
];
7714 if (is_valid_share_mode_entry(e
)) {
7715 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
7718 if (share_mode_stale_pid(lck
->data
, i
)) {
7721 /* Fail with sharing violation. */
7723 close_file(req
, fsp
, NORMAL_CLOSE
);
7724 return NT_STATUS_SHARING_VIOLATION
;
7729 * Set the delete on close.
7731 status
= smb_set_file_disposition_info(conn
,
7739 if (!NT_STATUS_IS_OK(status
)) {
7740 close_file(req
, fsp
, NORMAL_CLOSE
);
7743 return close_file(req
, fsp
, NORMAL_CLOSE
);
7746 NTSTATUS
smbd_do_setfilepathinfo(connection_struct
*conn
,
7747 struct smb_request
*req
,
7748 TALLOC_CTX
*mem_ctx
,
7749 uint16_t info_level
,
7751 struct smb_filename
*smb_fname
,
7752 char **ppdata
, int total_data
,
7755 char *pdata
= *ppdata
;
7756 NTSTATUS status
= NT_STATUS_OK
;
7757 int data_return_size
= 0;
7761 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
7762 return NT_STATUS_INVALID_LEVEL
;
7765 if (!CAN_WRITE(conn
)) {
7766 /* Allow POSIX opens. The open path will deny
7767 * any non-readonly opens. */
7768 if (info_level
!= SMB_POSIX_PATH_OPEN
) {
7769 return NT_STATUS_DOS(ERRSRV
, ERRaccess
);
7773 DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
7774 "totdata=%d\n", smb_fname_str_dbg(smb_fname
),
7776 info_level
, total_data
));
7778 switch (info_level
) {
7780 case SMB_INFO_STANDARD
:
7782 status
= smb_set_info_standard(conn
,
7790 case SMB_INFO_SET_EA
:
7792 status
= smb_info_set_ea(conn
,
7800 case SMB_SET_FILE_BASIC_INFO
:
7801 case SMB_FILE_BASIC_INFORMATION
:
7803 status
= smb_set_file_basic_info(conn
,
7811 case SMB_FILE_ALLOCATION_INFORMATION
:
7812 case SMB_SET_FILE_ALLOCATION_INFO
:
7814 status
= smb_set_file_allocation_info(conn
, req
,
7822 case SMB_FILE_END_OF_FILE_INFORMATION
:
7823 case SMB_SET_FILE_END_OF_FILE_INFO
:
7826 * XP/Win7 both fail after the createfile with
7827 * SMB_SET_FILE_END_OF_FILE_INFO but not
7828 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7829 * The level is known here, so pass it down
7833 (info_level
== SMB_SET_FILE_END_OF_FILE_INFO
);
7835 status
= smb_set_file_end_of_file_info(conn
, req
,
7844 case SMB_FILE_DISPOSITION_INFORMATION
:
7845 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
7848 /* JRA - We used to just ignore this on a path ?
7849 * Shouldn't this be invalid level on a pathname
7852 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
7853 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
7856 status
= smb_set_file_disposition_info(conn
,
7864 case SMB_FILE_POSITION_INFORMATION
:
7866 status
= smb_file_position_information(conn
,
7873 case SMB_FILE_FULL_EA_INFORMATION
:
7875 status
= smb_set_file_full_ea_info(conn
,
7882 /* From tridge Samba4 :
7883 * MODE_INFORMATION in setfileinfo (I have no
7884 * idea what "mode information" on a file is - it takes a value of 0,
7885 * 2, 4 or 6. What could it be?).
7888 case SMB_FILE_MODE_INFORMATION
:
7890 status
= smb_file_mode_information(conn
,
7897 * CIFS UNIX extensions.
7900 case SMB_SET_FILE_UNIX_BASIC
:
7902 status
= smb_set_file_unix_basic(conn
, req
,
7910 case SMB_SET_FILE_UNIX_INFO2
:
7912 status
= smb_set_file_unix_info2(conn
, req
,
7920 case SMB_SET_FILE_UNIX_LINK
:
7923 /* We must have a pathname for this. */
7924 return NT_STATUS_INVALID_LEVEL
;
7926 status
= smb_set_file_unix_link(conn
, req
, pdata
,
7927 total_data
, smb_fname
);
7931 case SMB_SET_FILE_UNIX_HLINK
:
7934 /* We must have a pathname for this. */
7935 return NT_STATUS_INVALID_LEVEL
;
7937 status
= smb_set_file_unix_hlink(conn
, req
,
7943 case SMB_FILE_RENAME_INFORMATION
:
7945 status
= smb_file_rename_information(conn
, req
,
7951 case SMB2_FILE_RENAME_INFORMATION_INTERNAL
:
7953 /* SMB2 rename information. */
7954 status
= smb2_file_rename_information(conn
, req
,
7960 case SMB_FILE_LINK_INFORMATION
:
7962 status
= smb_file_link_information(conn
, req
,
7968 #if defined(HAVE_POSIX_ACLS)
7969 case SMB_SET_POSIX_ACL
:
7971 status
= smb_set_posix_acl(conn
,
7980 case SMB_SET_POSIX_LOCK
:
7983 return NT_STATUS_INVALID_LEVEL
;
7985 status
= smb_set_posix_lock(conn
, req
,
7986 pdata
, total_data
, fsp
);
7990 case SMB_POSIX_PATH_OPEN
:
7993 /* We must have a pathname for this. */
7994 return NT_STATUS_INVALID_LEVEL
;
7997 status
= smb_posix_open(conn
, req
,
8005 case SMB_POSIX_PATH_UNLINK
:
8008 /* We must have a pathname for this. */
8009 return NT_STATUS_INVALID_LEVEL
;
8012 status
= smb_posix_unlink(conn
, req
,
8020 return NT_STATUS_INVALID_LEVEL
;
8023 if (!NT_STATUS_IS_OK(status
)) {
8027 *ret_data_size
= data_return_size
;
8028 return NT_STATUS_OK
;
8031 /****************************************************************************
8032 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
8033 ****************************************************************************/
8035 static void call_trans2setfilepathinfo(connection_struct
*conn
,
8036 struct smb_request
*req
,
8037 unsigned int tran_call
,
8038 char **pparams
, int total_params
,
8039 char **ppdata
, int total_data
,
8040 unsigned int max_data_bytes
)
8042 char *params
= *pparams
;
8043 char *pdata
= *ppdata
;
8045 struct smb_filename
*smb_fname
= NULL
;
8046 files_struct
*fsp
= NULL
;
8047 NTSTATUS status
= NT_STATUS_OK
;
8048 int data_return_size
= 0;
8051 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8055 if (tran_call
== TRANSACT2_SETFILEINFO
) {
8056 if (total_params
< 4) {
8057 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8061 fsp
= file_fsp(req
, SVAL(params
,0));
8062 /* Basic check for non-null fsp. */
8063 if (!check_fsp_open(conn
, req
, fsp
)) {
8066 info_level
= SVAL(params
,2);
8068 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
8070 if (!NT_STATUS_IS_OK(status
)) {
8071 reply_nterror(req
, status
);
8075 if(fsp
->fh
->fd
== -1) {
8077 * This is actually a SETFILEINFO on a directory
8078 * handle (returned from an NT SMB). NT5.0 seems
8079 * to do this call. JRA.
8081 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8082 /* Always do lstat for UNIX calls. */
8083 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
8084 DEBUG(3,("call_trans2setfilepathinfo: "
8085 "SMB_VFS_LSTAT of %s failed "
8087 smb_fname_str_dbg(smb_fname
),
8089 reply_nterror(req
, map_nt_error_from_unix(errno
));
8093 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
8094 DEBUG(3,("call_trans2setfilepathinfo: "
8095 "fileinfo of %s failed (%s)\n",
8096 smb_fname_str_dbg(smb_fname
),
8098 reply_nterror(req
, map_nt_error_from_unix(errno
));
8102 } else if (fsp
->print_file
) {
8104 * Doing a DELETE_ON_CLOSE should cancel a print job.
8106 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
8107 fsp
->fh
->private_options
|= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE
;
8109 DEBUG(3,("call_trans2setfilepathinfo: "
8110 "Cancelling print job (%s)\n",
8114 send_trans2_replies(conn
, req
, params
, 2,
8120 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
8125 * Original code - this is an open file.
8127 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
8128 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8129 "of %s failed (%s)\n", fsp_fnum_dbg(fsp
),
8131 reply_nterror(req
, map_nt_error_from_unix(errno
));
8137 uint32_t ucf_flags
= 0;
8140 if (total_params
< 7) {
8141 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8145 info_level
= SVAL(params
,0);
8146 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
8147 total_params
- 6, STR_TERMINATE
,
8149 if (!NT_STATUS_IS_OK(status
)) {
8150 reply_nterror(req
, status
);
8154 if (info_level
== SMB_SET_FILE_UNIX_BASIC
||
8155 info_level
== SMB_SET_FILE_UNIX_INFO2
||
8156 info_level
== SMB_FILE_RENAME_INFORMATION
||
8157 info_level
== SMB_POSIX_PATH_UNLINK
) {
8158 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
8161 status
= filename_convert(req
, conn
,
8162 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8167 if (!NT_STATUS_IS_OK(status
)) {
8168 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8169 reply_botherror(req
,
8170 NT_STATUS_PATH_NOT_COVERED
,
8171 ERRSRV
, ERRbadpath
);
8174 reply_nterror(req
, status
);
8178 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8180 * For CIFS UNIX extensions the target name may not exist.
8183 /* Always do lstat for UNIX calls. */
8184 SMB_VFS_LSTAT(conn
, smb_fname
);
8186 } else if (!VALID_STAT(smb_fname
->st
) &&
8187 SMB_VFS_STAT(conn
, smb_fname
)) {
8188 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8190 smb_fname_str_dbg(smb_fname
),
8192 reply_nterror(req
, map_nt_error_from_unix(errno
));
8197 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
8198 "totdata=%d\n", tran_call
, smb_fname_str_dbg(smb_fname
),
8200 info_level
,total_data
));
8202 /* Realloc the parameter size */
8203 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8204 if (*pparams
== NULL
) {
8205 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8212 status
= smbd_do_setfilepathinfo(conn
, req
, req
,
8218 if (!NT_STATUS_IS_OK(status
)) {
8219 if (open_was_deferred(req
->sconn
, req
->mid
)) {
8220 /* We have re-scheduled this call. */
8223 if (blocking_lock_was_deferred_smb1(req
->sconn
, req
->mid
)) {
8224 /* We have re-scheduled this call. */
8227 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8228 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
8229 ERRSRV
, ERRbadpath
);
8232 if (info_level
== SMB_POSIX_PATH_OPEN
) {
8233 reply_openerror(req
, status
);
8237 reply_nterror(req
, status
);
8241 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, data_return_size
,
8247 /****************************************************************************
8248 Reply to a TRANS2_MKDIR (make directory with extended attributes).
8249 ****************************************************************************/
8251 static void call_trans2mkdir(connection_struct
*conn
, struct smb_request
*req
,
8252 char **pparams
, int total_params
,
8253 char **ppdata
, int total_data
,
8254 unsigned int max_data_bytes
)
8256 struct smb_filename
*smb_dname
= NULL
;
8257 char *params
= *pparams
;
8258 char *pdata
= *ppdata
;
8259 char *directory
= NULL
;
8260 NTSTATUS status
= NT_STATUS_OK
;
8261 struct ea_list
*ea_list
= NULL
;
8262 TALLOC_CTX
*ctx
= talloc_tos();
8264 if (!CAN_WRITE(conn
)) {
8265 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8269 if (total_params
< 5) {
8270 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8274 srvstr_get_path(ctx
, params
, req
->flags2
, &directory
, ¶ms
[4],
8275 total_params
- 4, STR_TERMINATE
,
8277 if (!NT_STATUS_IS_OK(status
)) {
8278 reply_nterror(req
, status
);
8282 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
8284 status
= filename_convert(ctx
,
8286 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8292 if (!NT_STATUS_IS_OK(status
)) {
8293 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8294 reply_botherror(req
,
8295 NT_STATUS_PATH_NOT_COVERED
,
8296 ERRSRV
, ERRbadpath
);
8299 reply_nterror(req
, status
);
8304 * OS/2 workplace shell seems to send SET_EA requests of "null"
8305 * length (4 bytes containing IVAL 4).
8306 * They seem to have no effect. Bug #3212. JRA.
8309 if (total_data
&& (total_data
!= 4)) {
8310 /* Any data in this call is an EA list. */
8311 if (total_data
< 10) {
8312 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8316 if (IVAL(pdata
,0) > total_data
) {
8317 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8318 IVAL(pdata
,0), (unsigned int)total_data
));
8319 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8323 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
8326 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8330 if (!lp_ea_support(SNUM(conn
))) {
8331 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
8335 /* If total_data == 4 Windows doesn't care what values
8336 * are placed in that field, it just ignores them.
8337 * The System i QNTC IBM SMB client puts bad values here,
8338 * so ignore them. */
8340 status
= create_directory(conn
, req
, smb_dname
);
8342 if (!NT_STATUS_IS_OK(status
)) {
8343 reply_nterror(req
, status
);
8347 /* Try and set any given EA. */
8349 status
= set_ea(conn
, NULL
, smb_dname
, ea_list
);
8350 if (!NT_STATUS_IS_OK(status
)) {
8351 reply_nterror(req
, status
);
8356 /* Realloc the parameter and data sizes */
8357 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8358 if(*pparams
== NULL
) {
8359 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8366 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, 0, max_data_bytes
);
8369 TALLOC_FREE(smb_dname
);
8373 /****************************************************************************
8374 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8375 We don't actually do this - we just send a null response.
8376 ****************************************************************************/
8378 static void call_trans2findnotifyfirst(connection_struct
*conn
,
8379 struct smb_request
*req
,
8380 char **pparams
, int total_params
,
8381 char **ppdata
, int total_data
,
8382 unsigned int max_data_bytes
)
8384 char *params
= *pparams
;
8387 if (total_params
< 6) {
8388 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8392 info_level
= SVAL(params
,4);
8393 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
8395 switch (info_level
) {
8400 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
8404 /* Realloc the parameter and data sizes */
8405 *pparams
= (char *)SMB_REALLOC(*pparams
,6);
8406 if (*pparams
== NULL
) {
8407 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8412 SSVAL(params
,0,fnf_handle
);
8413 SSVAL(params
,2,0); /* No changes */
8414 SSVAL(params
,4,0); /* No EA errors */
8421 send_trans2_replies(conn
, req
, params
, 6, *ppdata
, 0, max_data_bytes
);
8426 /****************************************************************************
8427 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
8428 changes). Currently this does nothing.
8429 ****************************************************************************/
8431 static void call_trans2findnotifynext(connection_struct
*conn
,
8432 struct smb_request
*req
,
8433 char **pparams
, int total_params
,
8434 char **ppdata
, int total_data
,
8435 unsigned int max_data_bytes
)
8437 char *params
= *pparams
;
8439 DEBUG(3,("call_trans2findnotifynext\n"));
8441 /* Realloc the parameter and data sizes */
8442 *pparams
= (char *)SMB_REALLOC(*pparams
,4);
8443 if (*pparams
== NULL
) {
8444 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8449 SSVAL(params
,0,0); /* No changes */
8450 SSVAL(params
,2,0); /* No EA errors */
8452 send_trans2_replies(conn
, req
, params
, 4, *ppdata
, 0, max_data_bytes
);
8457 /****************************************************************************
8458 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8459 ****************************************************************************/
8461 static void call_trans2getdfsreferral(connection_struct
*conn
,
8462 struct smb_request
*req
,
8463 char **pparams
, int total_params
,
8464 char **ppdata
, int total_data
,
8465 unsigned int max_data_bytes
)
8467 char *params
= *pparams
;
8468 char *pathname
= NULL
;
8470 int max_referral_level
;
8471 NTSTATUS status
= NT_STATUS_OK
;
8472 TALLOC_CTX
*ctx
= talloc_tos();
8474 DEBUG(10,("call_trans2getdfsreferral\n"));
8476 if (total_params
< 3) {
8477 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8481 max_referral_level
= SVAL(params
,0);
8483 if(!lp_host_msdfs()) {
8484 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8488 srvstr_pull_talloc(ctx
, params
, req
->flags2
, &pathname
, ¶ms
[2],
8489 total_params
- 2, STR_TERMINATE
);
8491 reply_nterror(req
, NT_STATUS_NOT_FOUND
);
8494 if((reply_size
= setup_dfs_referral(conn
, pathname
, max_referral_level
,
8495 ppdata
,&status
)) < 0) {
8496 reply_nterror(req
, status
);
8500 SSVAL((discard_const_p(uint8_t, req
->inbuf
)), smb_flg2
,
8501 SVAL(req
->inbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
8502 send_trans2_replies(conn
, req
,0,0,*ppdata
,reply_size
, max_data_bytes
);
8507 #define LMCAT_SPL 0x53
8508 #define LMFUNC_GETJOBID 0x60
8510 /****************************************************************************
8511 Reply to a TRANS2_IOCTL - used for OS/2 printing.
8512 ****************************************************************************/
8514 static void call_trans2ioctl(connection_struct
*conn
,
8515 struct smb_request
*req
,
8516 char **pparams
, int total_params
,
8517 char **ppdata
, int total_data
,
8518 unsigned int max_data_bytes
)
8520 char *pdata
= *ppdata
;
8521 files_struct
*fsp
= file_fsp(req
, SVAL(req
->vwv
+15, 0));
8523 /* check for an invalid fid before proceeding */
8526 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8530 if ((SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8531 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8532 *ppdata
= (char *)SMB_REALLOC(*ppdata
, 32);
8533 if (*ppdata
== NULL
) {
8534 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8539 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8540 CAN ACCEPT THIS IN UNICODE. JRA. */
8543 SSVAL(pdata
, 0, print_spool_rap_jobid(fsp
->print_file
));
8545 srvstr_push(pdata
, req
->flags2
, pdata
+ 2,
8546 lp_netbios_name(), 15,
8547 STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
8548 srvstr_push(pdata
, req
->flags2
, pdata
+18,
8549 lp_servicename(talloc_tos(), SNUM(conn
)), 13,
8550 STR_ASCII
|STR_TERMINATE
); /* Service name */
8551 send_trans2_replies(conn
, req
, *pparams
, 0, *ppdata
, 32,
8556 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8557 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8560 /****************************************************************************
8561 Reply to a SMBfindclose (stop trans2 directory search).
8562 ****************************************************************************/
8564 void reply_findclose(struct smb_request
*req
)
8567 struct smbd_server_connection
*sconn
= req
->sconn
;
8569 START_PROFILE(SMBfindclose
);
8572 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8573 END_PROFILE(SMBfindclose
);
8577 dptr_num
= SVALS(req
->vwv
+0, 0);
8579 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
8581 dptr_close(sconn
, &dptr_num
);
8583 reply_outbuf(req
, 0, 0);
8585 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
8587 END_PROFILE(SMBfindclose
);
8591 /****************************************************************************
8592 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8593 ****************************************************************************/
8595 void reply_findnclose(struct smb_request
*req
)
8599 START_PROFILE(SMBfindnclose
);
8602 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8603 END_PROFILE(SMBfindnclose
);
8607 dptr_num
= SVAL(req
->vwv
+0, 0);
8609 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
8611 /* We never give out valid handles for a
8612 findnotifyfirst - so any dptr_num is ok here.
8615 reply_outbuf(req
, 0, 0);
8617 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
8619 END_PROFILE(SMBfindnclose
);
8623 static void handle_trans2(connection_struct
*conn
, struct smb_request
*req
,
8624 struct trans_state
*state
)
8626 if (get_Protocol() >= PROTOCOL_NT1
) {
8627 req
->flags2
|= 0x40; /* IS_LONG_NAME */
8628 SSVAL((discard_const_p(uint8_t, req
->inbuf
)),smb_flg2
,req
->flags2
);
8631 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
8632 if (state
->call
!= TRANSACT2_QFSINFO
&&
8633 state
->call
!= TRANSACT2_SETFSINFO
) {
8634 DEBUG(0,("handle_trans2: encryption required "
8636 (unsigned int)state
->call
));
8637 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8642 SMB_PERFCOUNT_SET_SUBOP(&req
->pcd
, state
->call
);
8644 /* Now we must call the relevant TRANS2 function */
8645 switch(state
->call
) {
8646 case TRANSACT2_OPEN
:
8648 START_PROFILE(Trans2_open
);
8649 call_trans2open(conn
, req
,
8650 &state
->param
, state
->total_param
,
8651 &state
->data
, state
->total_data
,
8652 state
->max_data_return
);
8653 END_PROFILE(Trans2_open
);
8657 case TRANSACT2_FINDFIRST
:
8659 START_PROFILE(Trans2_findfirst
);
8660 call_trans2findfirst(conn
, req
,
8661 &state
->param
, state
->total_param
,
8662 &state
->data
, state
->total_data
,
8663 state
->max_data_return
);
8664 END_PROFILE(Trans2_findfirst
);
8668 case TRANSACT2_FINDNEXT
:
8670 START_PROFILE(Trans2_findnext
);
8671 call_trans2findnext(conn
, req
,
8672 &state
->param
, state
->total_param
,
8673 &state
->data
, state
->total_data
,
8674 state
->max_data_return
);
8675 END_PROFILE(Trans2_findnext
);
8679 case TRANSACT2_QFSINFO
:
8681 START_PROFILE(Trans2_qfsinfo
);
8682 call_trans2qfsinfo(conn
, req
,
8683 &state
->param
, state
->total_param
,
8684 &state
->data
, state
->total_data
,
8685 state
->max_data_return
);
8686 END_PROFILE(Trans2_qfsinfo
);
8690 case TRANSACT2_SETFSINFO
:
8692 START_PROFILE(Trans2_setfsinfo
);
8693 call_trans2setfsinfo(conn
, req
,
8694 &state
->param
, state
->total_param
,
8695 &state
->data
, state
->total_data
,
8696 state
->max_data_return
);
8697 END_PROFILE(Trans2_setfsinfo
);
8701 case TRANSACT2_QPATHINFO
:
8702 case TRANSACT2_QFILEINFO
:
8704 START_PROFILE(Trans2_qpathinfo
);
8705 call_trans2qfilepathinfo(conn
, req
, state
->call
,
8706 &state
->param
, state
->total_param
,
8707 &state
->data
, state
->total_data
,
8708 state
->max_data_return
);
8709 END_PROFILE(Trans2_qpathinfo
);
8713 case TRANSACT2_SETPATHINFO
:
8714 case TRANSACT2_SETFILEINFO
:
8716 START_PROFILE(Trans2_setpathinfo
);
8717 call_trans2setfilepathinfo(conn
, req
, state
->call
,
8718 &state
->param
, state
->total_param
,
8719 &state
->data
, state
->total_data
,
8720 state
->max_data_return
);
8721 END_PROFILE(Trans2_setpathinfo
);
8725 case TRANSACT2_FINDNOTIFYFIRST
:
8727 START_PROFILE(Trans2_findnotifyfirst
);
8728 call_trans2findnotifyfirst(conn
, req
,
8729 &state
->param
, state
->total_param
,
8730 &state
->data
, state
->total_data
,
8731 state
->max_data_return
);
8732 END_PROFILE(Trans2_findnotifyfirst
);
8736 case TRANSACT2_FINDNOTIFYNEXT
:
8738 START_PROFILE(Trans2_findnotifynext
);
8739 call_trans2findnotifynext(conn
, req
,
8740 &state
->param
, state
->total_param
,
8741 &state
->data
, state
->total_data
,
8742 state
->max_data_return
);
8743 END_PROFILE(Trans2_findnotifynext
);
8747 case TRANSACT2_MKDIR
:
8749 START_PROFILE(Trans2_mkdir
);
8750 call_trans2mkdir(conn
, req
,
8751 &state
->param
, state
->total_param
,
8752 &state
->data
, state
->total_data
,
8753 state
->max_data_return
);
8754 END_PROFILE(Trans2_mkdir
);
8758 case TRANSACT2_GET_DFS_REFERRAL
:
8760 START_PROFILE(Trans2_get_dfs_referral
);
8761 call_trans2getdfsreferral(conn
, req
,
8762 &state
->param
, state
->total_param
,
8763 &state
->data
, state
->total_data
,
8764 state
->max_data_return
);
8765 END_PROFILE(Trans2_get_dfs_referral
);
8769 case TRANSACT2_IOCTL
:
8771 START_PROFILE(Trans2_ioctl
);
8772 call_trans2ioctl(conn
, req
,
8773 &state
->param
, state
->total_param
,
8774 &state
->data
, state
->total_data
,
8775 state
->max_data_return
);
8776 END_PROFILE(Trans2_ioctl
);
8781 /* Error in request */
8782 DEBUG(2,("Unknown request %d in trans2 call\n", state
->call
));
8783 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8787 /****************************************************************************
8788 Reply to a SMBtrans2.
8789 ****************************************************************************/
8791 void reply_trans2(struct smb_request
*req
)
8793 connection_struct
*conn
= req
->conn
;
8798 unsigned int tran_call
;
8799 struct trans_state
*state
;
8802 START_PROFILE(SMBtrans2
);
8804 if (req
->wct
< 14) {
8805 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8806 END_PROFILE(SMBtrans2
);
8810 dsoff
= SVAL(req
->vwv
+12, 0);
8811 dscnt
= SVAL(req
->vwv
+11, 0);
8812 psoff
= SVAL(req
->vwv
+10, 0);
8813 pscnt
= SVAL(req
->vwv
+9, 0);
8814 tran_call
= SVAL(req
->vwv
+14, 0);
8816 result
= allow_new_trans(conn
->pending_trans
, req
->mid
);
8817 if (!NT_STATUS_IS_OK(result
)) {
8818 DEBUG(2, ("Got invalid trans2 request: %s\n",
8819 nt_errstr(result
)));
8820 reply_nterror(req
, result
);
8821 END_PROFILE(SMBtrans2
);
8826 switch (tran_call
) {
8827 /* List the allowed trans2 calls on IPC$ */
8828 case TRANSACT2_OPEN
:
8829 case TRANSACT2_GET_DFS_REFERRAL
:
8830 case TRANSACT2_QFILEINFO
:
8831 case TRANSACT2_QFSINFO
:
8832 case TRANSACT2_SETFSINFO
:
8835 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8836 END_PROFILE(SMBtrans2
);
8841 if ((state
= talloc(conn
, struct trans_state
)) == NULL
) {
8842 DEBUG(0, ("talloc failed\n"));
8843 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8844 END_PROFILE(SMBtrans2
);
8848 state
->cmd
= SMBtrans2
;
8850 state
->mid
= req
->mid
;
8851 state
->vuid
= req
->vuid
;
8852 state
->setup_count
= SVAL(req
->vwv
+13, 0);
8853 state
->setup
= NULL
;
8854 state
->total_param
= SVAL(req
->vwv
+0, 0);
8855 state
->param
= NULL
;
8856 state
->total_data
= SVAL(req
->vwv
+1, 0);
8858 state
->max_param_return
= SVAL(req
->vwv
+2, 0);
8859 state
->max_data_return
= SVAL(req
->vwv
+3, 0);
8860 state
->max_setup_return
= SVAL(req
->vwv
+4, 0);
8861 state
->close_on_completion
= BITSETW(req
->vwv
+5, 0);
8862 state
->one_way
= BITSETW(req
->vwv
+5, 1);
8864 state
->call
= tran_call
;
8866 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8867 is so as a sanity check */
8868 if (state
->setup_count
!= 1) {
8870 * Need to have rc=0 for ioctl to get job id for OS/2.
8871 * Network printing will fail if function is not successful.
8872 * Similar function in reply.c will be used if protocol
8873 * is LANMAN1.0 instead of LM1.2X002.
8874 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
8875 * outbuf doesn't have to be set(only job id is used).
8877 if ( (state
->setup_count
== 4)
8878 && (tran_call
== TRANSACT2_IOCTL
)
8879 && (SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8880 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8881 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8883 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state
->setup_count
));
8884 DEBUG(2,("Transaction is %d\n",tran_call
));
8886 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8887 END_PROFILE(SMBtrans2
);
8892 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
8895 if (state
->total_data
) {
8897 if (trans_oob(state
->total_data
, 0, dscnt
)
8898 || trans_oob(smb_len(req
->inbuf
), dsoff
, dscnt
)) {
8902 /* Can't use talloc here, the core routines do realloc on the
8903 * params and data. */
8904 state
->data
= (char *)SMB_MALLOC(state
->total_data
);
8905 if (state
->data
== NULL
) {
8906 DEBUG(0,("reply_trans2: data malloc fail for %u "
8907 "bytes !\n", (unsigned int)state
->total_data
));
8909 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8910 END_PROFILE(SMBtrans2
);
8914 memcpy(state
->data
,smb_base(req
->inbuf
)+dsoff
,dscnt
);
8917 if (state
->total_param
) {
8919 if (trans_oob(state
->total_param
, 0, pscnt
)
8920 || trans_oob(smb_len(req
->inbuf
), psoff
, pscnt
)) {
8924 /* Can't use talloc here, the core routines do realloc on the
8925 * params and data. */
8926 state
->param
= (char *)SMB_MALLOC(state
->total_param
);
8927 if (state
->param
== NULL
) {
8928 DEBUG(0,("reply_trans: param malloc fail for %u "
8929 "bytes !\n", (unsigned int)state
->total_param
));
8930 SAFE_FREE(state
->data
);
8932 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8933 END_PROFILE(SMBtrans2
);
8937 memcpy(state
->param
,smb_base(req
->inbuf
)+psoff
,pscnt
);
8940 state
->received_data
= dscnt
;
8941 state
->received_param
= pscnt
;
8943 if ((state
->received_param
== state
->total_param
) &&
8944 (state
->received_data
== state
->total_data
)) {
8946 handle_trans2(conn
, req
, state
);
8948 SAFE_FREE(state
->data
);
8949 SAFE_FREE(state
->param
);
8951 END_PROFILE(SMBtrans2
);
8955 DLIST_ADD(conn
->pending_trans
, state
);
8957 /* We need to send an interim response then receive the rest
8958 of the parameter/data bytes */
8959 reply_outbuf(req
, 0, 0);
8960 show_msg((char *)req
->outbuf
);
8961 END_PROFILE(SMBtrans2
);
8966 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8967 SAFE_FREE(state
->data
);
8968 SAFE_FREE(state
->param
);
8970 END_PROFILE(SMBtrans2
);
8971 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8975 /****************************************************************************
8976 Reply to a SMBtranss2
8977 ****************************************************************************/
8979 void reply_transs2(struct smb_request
*req
)
8981 connection_struct
*conn
= req
->conn
;
8982 unsigned int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
8983 struct trans_state
*state
;
8985 START_PROFILE(SMBtranss2
);
8987 show_msg((const char *)req
->inbuf
);
8989 /* Windows clients expect all replies to
8990 a transact secondary (SMBtranss2 0x33)
8991 to have a command code of transact
8992 (SMBtrans2 0x32). See bug #8989
8993 and also [MS-CIFS] section 2.2.4.47.2
8996 req
->cmd
= SMBtrans2
;
8999 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9000 END_PROFILE(SMBtranss2
);
9004 for (state
= conn
->pending_trans
; state
!= NULL
;
9005 state
= state
->next
) {
9006 if (state
->mid
== req
->mid
) {
9011 if ((state
== NULL
) || (state
->cmd
!= SMBtrans2
)) {
9012 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9013 END_PROFILE(SMBtranss2
);
9017 /* Revise state->total_param and state->total_data in case they have
9018 changed downwards */
9020 if (SVAL(req
->vwv
+0, 0) < state
->total_param
)
9021 state
->total_param
= SVAL(req
->vwv
+0, 0);
9022 if (SVAL(req
->vwv
+1, 0) < state
->total_data
)
9023 state
->total_data
= SVAL(req
->vwv
+1, 0);
9025 pcnt
= SVAL(req
->vwv
+2, 0);
9026 poff
= SVAL(req
->vwv
+3, 0);
9027 pdisp
= SVAL(req
->vwv
+4, 0);
9029 dcnt
= SVAL(req
->vwv
+5, 0);
9030 doff
= SVAL(req
->vwv
+6, 0);
9031 ddisp
= SVAL(req
->vwv
+7, 0);
9033 state
->received_param
+= pcnt
;
9034 state
->received_data
+= dcnt
;
9036 if ((state
->received_data
> state
->total_data
) ||
9037 (state
->received_param
> state
->total_param
))
9041 if (trans_oob(state
->total_param
, pdisp
, pcnt
)
9042 || trans_oob(smb_len(req
->inbuf
), poff
, pcnt
)) {
9045 memcpy(state
->param
+pdisp
,smb_base(req
->inbuf
)+poff
,pcnt
);
9049 if (trans_oob(state
->total_data
, ddisp
, dcnt
)
9050 || trans_oob(smb_len(req
->inbuf
), doff
, dcnt
)) {
9053 memcpy(state
->data
+ddisp
, smb_base(req
->inbuf
)+doff
,dcnt
);
9056 if ((state
->received_param
< state
->total_param
) ||
9057 (state
->received_data
< state
->total_data
)) {
9058 END_PROFILE(SMBtranss2
);
9062 handle_trans2(conn
, req
, state
);
9064 DLIST_REMOVE(conn
->pending_trans
, state
);
9065 SAFE_FREE(state
->data
);
9066 SAFE_FREE(state
->param
);
9069 END_PROFILE(SMBtranss2
);
9074 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
9075 DLIST_REMOVE(conn
->pending_trans
, state
);
9076 SAFE_FREE(state
->data
);
9077 SAFE_FREE(state
->param
);
9079 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9080 END_PROFILE(SMBtranss2
);