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
,
71 if (!NT_STATUS_IS_OK(status
)) {
78 /********************************************************************
79 Roundup a value to the nearest allocation roundup size boundary.
80 Only do this for Windows clients.
81 ********************************************************************/
83 uint64_t smb_roundup(connection_struct
*conn
, uint64_t val
)
85 uint64_t rval
= lp_allocation_roundup_size(SNUM(conn
));
87 /* Only roundup for Windows clients. */
88 enum remote_arch_types ra_type
= get_remote_arch();
89 if (rval
&& (ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
90 val
= SMB_ROUNDUP(val
,rval
);
95 /********************************************************************
96 Create a 64 bit FileIndex. If the file is on the same device as
97 the root of the share, just return the 64-bit inode. If it isn't,
98 mangle as we used to do.
99 ********************************************************************/
101 uint64_t get_FileIndex(connection_struct
*conn
, const SMB_STRUCT_STAT
*psbuf
)
104 if (conn
->base_share_dev
== psbuf
->st_ex_dev
) {
105 return (uint64_t)psbuf
->st_ex_ino
;
107 file_index
= ((psbuf
->st_ex_ino
) & UINT32_MAX
); /* FileIndexLow */
108 file_index
|= ((uint64_t)((psbuf
->st_ex_dev
) & UINT32_MAX
)) << 32; /* FileIndexHigh */
112 /****************************************************************************
113 Utility functions for dealing with extended attributes.
114 ****************************************************************************/
116 /****************************************************************************
117 Refuse to allow clients to overwrite our private xattrs.
118 ****************************************************************************/
120 static bool samba_private_attr_name(const char *unix_ea_name
)
122 static const char * const prohibited_ea_names
[] = {
123 SAMBA_POSIX_INHERITANCE_EA_NAME
,
124 SAMBA_XATTR_DOS_ATTRIB
,
132 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
133 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
136 if (strncasecmp_m(unix_ea_name
, SAMBA_XATTR_DOSSTREAM_PREFIX
,
137 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX
)) == 0) {
143 /****************************************************************************
144 Get one EA value. Fill in a struct ea_struct.
145 ****************************************************************************/
147 NTSTATUS
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
148 files_struct
*fsp
, const char *fname
,
149 const char *ea_name
, struct ea_struct
*pea
)
151 /* Get the value of this xattr. Max size is 64k. */
152 size_t attr_size
= 256;
158 val
= talloc_realloc(mem_ctx
, val
, char, attr_size
);
160 return NT_STATUS_NO_MEMORY
;
163 if (fsp
&& fsp
->fh
->fd
!= -1) {
164 sizeret
= SMB_VFS_FGETXATTR(fsp
, ea_name
, val
, attr_size
);
166 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
169 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
175 return map_nt_error_from_unix(errno
);
178 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name
, (unsigned int)sizeret
));
179 dump_data(10, (uint8
*)val
, sizeret
);
182 if (strnequal(ea_name
, "user.", 5)) {
183 pea
->name
= talloc_strdup(mem_ctx
, &ea_name
[5]);
185 pea
->name
= talloc_strdup(mem_ctx
, ea_name
);
187 if (pea
->name
== NULL
) {
189 return NT_STATUS_NO_MEMORY
;
191 pea
->value
.data
= (unsigned char *)val
;
192 pea
->value
.length
= (size_t)sizeret
;
196 NTSTATUS
get_ea_names_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
197 files_struct
*fsp
, const char *fname
,
198 char ***pnames
, size_t *pnum_names
)
200 /* Get a list of all xattrs. Max namesize is 64k. */
201 size_t ea_namelist_size
= 1024;
202 char *ea_namelist
= NULL
;
207 ssize_t sizeret
= -1;
209 if (!lp_ea_support(SNUM(conn
))) {
218 * TALLOC the result early to get the talloc hierarchy right.
221 names
= talloc_array(mem_ctx
, char *, 1);
223 DEBUG(0, ("talloc failed\n"));
224 return NT_STATUS_NO_MEMORY
;
227 while (ea_namelist_size
<= 65536) {
229 ea_namelist
= talloc_realloc(
230 names
, ea_namelist
, char, ea_namelist_size
);
231 if (ea_namelist
== NULL
) {
232 DEBUG(0, ("talloc failed\n"));
234 return NT_STATUS_NO_MEMORY
;
237 if (fsp
&& fsp
->fh
->fd
!= -1) {
238 sizeret
= SMB_VFS_FLISTXATTR(fsp
, ea_namelist
,
241 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
,
245 if ((sizeret
== -1) && (errno
== ERANGE
)) {
246 ea_namelist_size
*= 2;
255 return map_nt_error_from_unix(errno
);
258 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
259 (unsigned int)sizeret
));
271 * Ensure the result is 0-terminated
274 if (ea_namelist
[sizeret
-1] != '\0') {
276 return NT_STATUS_INTERNAL_ERROR
;
284 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
288 tmp
= talloc_realloc(mem_ctx
, names
, char *, num_names
);
290 DEBUG(0, ("talloc failed\n"));
292 return NT_STATUS_NO_MEMORY
;
298 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
299 names
[num_names
++] = p
;
307 *pnum_names
= num_names
;
311 /****************************************************************************
312 Return a linked list of the total EA's. Plus the total size
313 ****************************************************************************/
315 static struct ea_list
*get_ea_list_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
316 const char *fname
, size_t *pea_total_len
)
318 /* Get a list of all xattrs. Max namesize is 64k. */
321 struct ea_list
*ea_list_head
= NULL
;
326 if (!lp_ea_support(SNUM(conn
))) {
330 status
= get_ea_names_from_file(talloc_tos(), conn
, fsp
, fname
,
333 if (!NT_STATUS_IS_OK(status
) || (num_names
== 0)) {
337 for (i
=0; i
<num_names
; i
++) {
338 struct ea_list
*listp
;
341 if (strnequal(names
[i
], "system.", 7)
342 || samba_private_attr_name(names
[i
]))
345 listp
= talloc(mem_ctx
, struct ea_list
);
350 if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx
, conn
, fsp
,
356 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
359 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
361 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
362 "= %u\n", (unsigned int)*pea_total_len
, dos_ea_name
,
363 (unsigned int)listp
->ea
.value
.length
));
365 DLIST_ADD_END(ea_list_head
, listp
, struct ea_list
*);
369 /* Add on 4 for total length. */
370 if (*pea_total_len
) {
374 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
375 (unsigned int)*pea_total_len
));
380 /****************************************************************************
381 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
383 ****************************************************************************/
385 static unsigned int fill_ea_buffer(TALLOC_CTX
*mem_ctx
, char *pdata
, unsigned int total_data_size
,
386 connection_struct
*conn
, struct ea_list
*ea_list
)
388 unsigned int ret_data_size
= 4;
391 SMB_ASSERT(total_data_size
>= 4);
393 if (!lp_ea_support(SNUM(conn
))) {
398 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
401 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
402 dos_namelen
= strlen(dos_ea_name
);
403 if (dos_namelen
> 255 || dos_namelen
== 0) {
406 if (ea_list
->ea
.value
.length
> 65535) {
409 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
413 /* We know we have room. */
414 SCVAL(p
,0,ea_list
->ea
.flags
);
415 SCVAL(p
,1,dos_namelen
);
416 SSVAL(p
,2,ea_list
->ea
.value
.length
);
417 strlcpy(p
+4, dos_ea_name
, dos_namelen
+1);
418 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
420 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
421 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
424 ret_data_size
= PTR_DIFF(p
, pdata
);
425 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size
));
426 SIVAL(pdata
,0,ret_data_size
);
427 return ret_data_size
;
430 static NTSTATUS
fill_ea_chained_buffer(TALLOC_CTX
*mem_ctx
,
432 unsigned int total_data_size
,
433 unsigned int *ret_data_size
,
434 connection_struct
*conn
,
435 struct ea_list
*ea_list
)
437 uint8_t *p
= (uint8_t *)pdata
;
438 uint8_t *last_start
= NULL
;
442 if (!lp_ea_support(SNUM(conn
))) {
443 return NT_STATUS_NO_EAS_ON_FILE
;
446 for (; ea_list
; ea_list
= ea_list
->next
) {
452 SIVAL(last_start
, 0, PTR_DIFF(p
, last_start
));
456 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
457 dos_namelen
= strlen(dos_ea_name
);
458 if (dos_namelen
> 255 || dos_namelen
== 0) {
459 return NT_STATUS_INTERNAL_ERROR
;
461 if (ea_list
->ea
.value
.length
> 65535) {
462 return NT_STATUS_INTERNAL_ERROR
;
465 this_size
= 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
468 size_t pad
= 4 - (this_size
% 4);
472 if (this_size
> total_data_size
) {
473 return NT_STATUS_INFO_LENGTH_MISMATCH
;
476 /* We know we have room. */
477 SIVAL(p
, 0x00, 0); /* next offset */
478 SCVAL(p
, 0x04, ea_list
->ea
.flags
);
479 SCVAL(p
, 0x05, dos_namelen
);
480 SSVAL(p
, 0x06, ea_list
->ea
.value
.length
);
481 strlcpy((char *)(p
+0x08), dos_ea_name
, dos_namelen
+1);
482 memcpy(p
+ 0x08 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
484 total_data_size
-= this_size
;
488 *ret_data_size
= PTR_DIFF(p
, pdata
);
489 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size
));
493 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
495 size_t total_ea_len
= 0;
496 TALLOC_CTX
*mem_ctx
= NULL
;
498 if (!lp_ea_support(SNUM(conn
))) {
501 mem_ctx
= talloc_tos();
502 (void)get_ea_list_from_file(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
506 /****************************************************************************
507 Ensure the EA name is case insensitive by matching any existing EA name.
508 ****************************************************************************/
510 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
513 TALLOC_CTX
*mem_ctx
= talloc_tos();
514 struct ea_list
*ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
516 for (; ea_list
; ea_list
= ea_list
->next
) {
517 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
518 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
519 &unix_ea_name
[5], ea_list
->ea
.name
));
520 strlcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-5);
526 /****************************************************************************
527 Set or delete an extended attribute.
528 ****************************************************************************/
530 NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
,
531 const struct smb_filename
*smb_fname
, struct ea_list
*ea_list
)
536 if (!lp_ea_support(SNUM(conn
))) {
537 return NT_STATUS_EAS_NOT_SUPPORTED
;
540 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_EA
);
541 if (!NT_STATUS_IS_OK(status
)) {
545 /* For now setting EAs on streams isn't supported. */
546 fname
= smb_fname
->base_name
;
548 for (;ea_list
; ea_list
= ea_list
->next
) {
550 fstring unix_ea_name
;
552 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
553 fstrcat(unix_ea_name
, ea_list
->ea
.name
);
555 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
557 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, (unsigned int)ea_list
->ea
.value
.length
));
559 if (samba_private_attr_name(unix_ea_name
)) {
560 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
561 return NT_STATUS_ACCESS_DENIED
;
564 if (ea_list
->ea
.value
.length
== 0) {
565 /* Remove the attribute. */
566 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
567 DEBUG(10,("set_ea: deleting ea name %s on "
568 "file %s by file descriptor.\n",
569 unix_ea_name
, fsp_str_dbg(fsp
)));
570 ret
= SMB_VFS_FREMOVEXATTR(fsp
, unix_ea_name
);
572 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
573 unix_ea_name
, fname
));
574 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
577 /* Removing a non existent attribute always succeeds. */
578 if (ret
== -1 && errno
== ENOATTR
) {
579 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
585 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
586 DEBUG(10,("set_ea: setting ea name %s on file "
587 "%s by file descriptor.\n",
588 unix_ea_name
, fsp_str_dbg(fsp
)));
589 ret
= SMB_VFS_FSETXATTR(fsp
, unix_ea_name
,
590 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
592 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
593 unix_ea_name
, fname
));
594 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
,
595 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
601 if (errno
== ENOTSUP
) {
602 return NT_STATUS_EAS_NOT_SUPPORTED
;
605 return map_nt_error_from_unix(errno
);
611 /****************************************************************************
612 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
613 ****************************************************************************/
615 static struct ea_list
*read_ea_name_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
617 struct ea_list
*ea_list_head
= NULL
;
618 size_t converted_size
, offset
= 0;
620 while (offset
+ 2 < data_size
) {
621 struct ea_list
*eal
= talloc_zero(ctx
, struct ea_list
);
622 unsigned int namelen
= CVAL(pdata
,offset
);
624 offset
++; /* Go past the namelen byte. */
626 /* integer wrap paranioa. */
627 if ((offset
+ namelen
< offset
) || (offset
+ namelen
< namelen
) ||
628 (offset
> data_size
) || (namelen
> data_size
) ||
629 (offset
+ namelen
>= data_size
)) {
632 /* Ensure the name is null terminated. */
633 if (pdata
[offset
+ namelen
] != '\0') {
636 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, &pdata
[offset
],
638 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
639 "failed: %s", strerror(errno
)));
645 offset
+= (namelen
+ 1); /* Go past the name + terminating zero. */
646 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
647 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal
->ea
.name
));
653 /****************************************************************************
654 Read one EA list entry from the buffer.
655 ****************************************************************************/
657 struct ea_list
*read_ea_list_entry(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
, size_t *pbytes_used
)
659 struct ea_list
*eal
= talloc_zero(ctx
, struct ea_list
);
661 unsigned int namelen
;
662 size_t converted_size
;
672 eal
->ea
.flags
= CVAL(pdata
,0);
673 namelen
= CVAL(pdata
,1);
674 val_len
= SVAL(pdata
,2);
676 if (4 + namelen
+ 1 + val_len
> data_size
) {
680 /* Ensure the name is null terminated. */
681 if (pdata
[namelen
+ 4] != '\0') {
684 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, pdata
+ 4, &converted_size
)) {
685 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
692 eal
->ea
.value
= data_blob_talloc(eal
, NULL
, (size_t)val_len
+ 1);
693 if (!eal
->ea
.value
.data
) {
697 memcpy(eal
->ea
.value
.data
, pdata
+ 4 + namelen
+ 1, val_len
);
699 /* Ensure we're null terminated just in case we print the value. */
700 eal
->ea
.value
.data
[val_len
] = '\0';
701 /* But don't count the null. */
702 eal
->ea
.value
.length
--;
705 *pbytes_used
= 4 + namelen
+ 1 + val_len
;
708 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal
->ea
.name
));
709 dump_data(10, eal
->ea
.value
.data
, eal
->ea
.value
.length
);
714 /****************************************************************************
715 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
716 ****************************************************************************/
718 static struct ea_list
*read_ea_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
720 struct ea_list
*ea_list_head
= NULL
;
722 size_t bytes_used
= 0;
724 while (offset
< data_size
) {
725 struct ea_list
*eal
= read_ea_list_entry(ctx
, pdata
+ offset
, data_size
- offset
, &bytes_used
);
731 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
732 offset
+= bytes_used
;
738 /****************************************************************************
739 Count the total EA size needed.
740 ****************************************************************************/
742 static size_t ea_list_size(struct ea_list
*ealist
)
745 struct ea_list
*listp
;
748 for (listp
= ealist
; listp
; listp
= listp
->next
) {
749 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
750 ret
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
752 /* Add on 4 for total length. */
760 /****************************************************************************
761 Return a union of EA's from a file list and a list of names.
762 The TALLOC context for the two lists *MUST* be identical as we steal
763 memory from one list to add to another. JRA.
764 ****************************************************************************/
766 static struct ea_list
*ea_list_union(struct ea_list
*name_list
, struct ea_list
*file_list
, size_t *total_ea_len
)
768 struct ea_list
*nlistp
, *flistp
;
770 for (nlistp
= name_list
; nlistp
; nlistp
= nlistp
->next
) {
771 for (flistp
= file_list
; flistp
; flistp
= flistp
->next
) {
772 if (strequal(nlistp
->ea
.name
, flistp
->ea
.name
)) {
778 /* Copy the data from this entry. */
779 nlistp
->ea
.flags
= flistp
->ea
.flags
;
780 nlistp
->ea
.value
= flistp
->ea
.value
;
783 nlistp
->ea
.flags
= 0;
784 ZERO_STRUCT(nlistp
->ea
.value
);
788 *total_ea_len
= ea_list_size(name_list
);
792 /****************************************************************************
793 Send the required number of replies back.
794 We assume all fields other than the data fields are
795 set correctly for the type of call.
796 HACK ! Always assumes smb_setup field is zero.
797 ****************************************************************************/
799 void send_trans2_replies(connection_struct
*conn
,
800 struct smb_request
*req
,
807 /* As we are using a protocol > LANMAN1 then the max_send
808 variable must have been set in the sessetupX call.
809 This takes precedence over the max_xmit field in the
810 global struct. These different max_xmit variables should
811 be merged as this is now too confusing */
813 int data_to_send
= datasize
;
814 int params_to_send
= paramsize
;
816 const char *pp
= params
;
817 const char *pd
= pdata
;
818 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
819 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
820 int data_alignment_offset
= 0;
821 bool overflow
= False
;
822 struct smbd_server_connection
*sconn
= req
->sconn
;
823 int max_send
= sconn
->smb1
.sessions
.max_send
;
825 /* Modify the data_to_send and datasize and set the error if
826 we're trying to send more than max_data_bytes. We still send
827 the part of the packet(s) that fit. Strange, but needed
830 if (max_data_bytes
> 0 && datasize
> max_data_bytes
) {
831 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
832 max_data_bytes
, datasize
));
833 datasize
= data_to_send
= max_data_bytes
;
837 /* If there genuinely are no parameters or data to send just send the empty packet */
839 if(params_to_send
== 0 && data_to_send
== 0) {
840 reply_outbuf(req
, 10, 0);
841 show_msg((char *)req
->outbuf
);
842 if (!srv_send_smb(sconn
,
845 IS_CONN_ENCRYPTED(conn
),
847 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
849 TALLOC_FREE(req
->outbuf
);
853 /* When sending params and data ensure that both are nicely aligned */
854 /* Only do this alignment when there is also data to send - else
855 can cause NT redirector problems. */
857 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
858 data_alignment_offset
= 4 - (params_to_send
% 4);
860 /* Space is bufsize minus Netbios over TCP header minus SMB header */
861 /* The alignment_offset is to align the param bytes on an even byte
862 boundary. NT 4.0 Beta needs this to work correctly. */
864 useable_space
= max_send
- (smb_size
867 + data_alignment_offset
);
869 if (useable_space
< 0) {
870 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
871 "= %d!!!", useable_space
));
872 exit_server_cleanly("send_trans2_replies: Not enough space");
875 while (params_to_send
|| data_to_send
) {
876 /* Calculate whether we will totally or partially fill this packet */
878 total_sent_thistime
= params_to_send
+ data_to_send
;
880 /* We can never send more than useable_space */
882 * Note that 'useable_space' does not include the alignment offsets,
883 * but we must include the alignment offsets in the calculation of
884 * the length of the data we send over the wire, as the alignment offsets
885 * are sent here. Fix from Marc_Jacobsen@hp.com.
888 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
);
890 reply_outbuf(req
, 10, total_sent_thistime
+ alignment_offset
891 + data_alignment_offset
);
893 /* Set total params and data to be sent */
894 SSVAL(req
->outbuf
,smb_tprcnt
,paramsize
);
895 SSVAL(req
->outbuf
,smb_tdrcnt
,datasize
);
897 /* Calculate how many parameters and data we can fit into
898 * this packet. Parameters get precedence
901 params_sent_thistime
= MIN(params_to_send
,useable_space
);
902 data_sent_thistime
= useable_space
- params_sent_thistime
;
903 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
905 SSVAL(req
->outbuf
,smb_prcnt
, params_sent_thistime
);
907 /* smb_proff is the offset from the start of the SMB header to the
908 parameter bytes, however the first 4 bytes of outbuf are
909 the Netbios over TCP header. Thus use smb_base() to subtract
910 them from the calculation */
912 SSVAL(req
->outbuf
,smb_proff
,
913 ((smb_buf(req
->outbuf
)+alignment_offset
)
914 - smb_base(req
->outbuf
)));
916 if(params_sent_thistime
== 0)
917 SSVAL(req
->outbuf
,smb_prdisp
,0);
919 /* Absolute displacement of param bytes sent in this packet */
920 SSVAL(req
->outbuf
,smb_prdisp
,pp
- params
);
922 SSVAL(req
->outbuf
,smb_drcnt
, data_sent_thistime
);
923 if(data_sent_thistime
== 0) {
924 SSVAL(req
->outbuf
,smb_droff
,0);
925 SSVAL(req
->outbuf
,smb_drdisp
, 0);
927 /* The offset of the data bytes is the offset of the
928 parameter bytes plus the number of parameters being sent this time */
929 SSVAL(req
->outbuf
, smb_droff
,
930 ((smb_buf(req
->outbuf
)+alignment_offset
)
931 - smb_base(req
->outbuf
))
932 + params_sent_thistime
+ data_alignment_offset
);
933 SSVAL(req
->outbuf
,smb_drdisp
, pd
- pdata
);
936 /* Initialize the padding for alignment */
938 if (alignment_offset
!= 0) {
939 memset(smb_buf(req
->outbuf
), 0, alignment_offset
);
942 /* Copy the param bytes into the packet */
944 if(params_sent_thistime
) {
945 memcpy((smb_buf(req
->outbuf
)+alignment_offset
), pp
,
946 params_sent_thistime
);
949 /* Copy in the data bytes */
950 if(data_sent_thistime
) {
951 if (data_alignment_offset
!= 0) {
952 memset((smb_buf(req
->outbuf
)+alignment_offset
+
953 params_sent_thistime
), 0,
954 data_alignment_offset
);
956 memcpy(smb_buf(req
->outbuf
)+alignment_offset
957 +params_sent_thistime
+data_alignment_offset
,
958 pd
,data_sent_thistime
);
961 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
962 params_sent_thistime
, data_sent_thistime
, useable_space
));
963 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
964 params_to_send
, data_to_send
, paramsize
, datasize
));
967 error_packet_set((char *)req
->outbuf
,
968 ERRDOS
,ERRbufferoverflow
,
969 STATUS_BUFFER_OVERFLOW
,
973 /* Send the packet */
974 show_msg((char *)req
->outbuf
);
975 if (!srv_send_smb(sconn
,
978 IS_CONN_ENCRYPTED(conn
),
980 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
982 TALLOC_FREE(req
->outbuf
);
984 pp
+= params_sent_thistime
;
985 pd
+= data_sent_thistime
;
987 params_to_send
-= params_sent_thistime
;
988 data_to_send
-= data_sent_thistime
;
991 if(params_to_send
< 0 || data_to_send
< 0) {
992 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
993 params_to_send
, data_to_send
));
1001 /****************************************************************************
1002 Reply to a TRANSACT2_OPEN.
1003 ****************************************************************************/
1005 static void call_trans2open(connection_struct
*conn
,
1006 struct smb_request
*req
,
1007 char **pparams
, int total_params
,
1008 char **ppdata
, int total_data
,
1009 unsigned int max_data_bytes
)
1011 struct smb_filename
*smb_fname
= NULL
;
1012 char *params
= *pparams
;
1013 char *pdata
= *ppdata
;
1016 bool oplock_request
;
1018 bool return_additional_info
;
1027 int fattr
=0,mtime
=0;
1028 SMB_INO_T inode
= 0;
1031 struct ea_list
*ea_list
= NULL
;
1036 uint32 create_disposition
;
1037 uint32 create_options
= 0;
1038 uint32_t private_flags
= 0;
1039 TALLOC_CTX
*ctx
= talloc_tos();
1042 * Ensure we have enough parameters to perform the operation.
1045 if (total_params
< 29) {
1046 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1050 flags
= SVAL(params
, 0);
1051 deny_mode
= SVAL(params
, 2);
1052 open_attr
= SVAL(params
,6);
1053 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
1054 if (oplock_request
) {
1055 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
1059 return_additional_info
= BITSETW(params
,0);
1060 open_sattr
= SVAL(params
, 4);
1061 open_time
= make_unix_date3(params
+8);
1063 open_ofun
= SVAL(params
,12);
1064 open_size
= IVAL(params
,14);
1065 pname
= ¶ms
[28];
1068 reply_nterror(req
, NT_STATUS_NETWORK_ACCESS_DENIED
);
1072 srvstr_get_path(ctx
, params
, req
->flags2
, &fname
, pname
,
1073 total_params
- 28, STR_TERMINATE
,
1075 if (!NT_STATUS_IS_OK(status
)) {
1076 reply_nterror(req
, status
);
1080 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1081 fname
, (unsigned int)deny_mode
, (unsigned int)open_attr
,
1082 (unsigned int)open_ofun
, open_size
));
1084 status
= filename_convert(ctx
,
1086 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1091 if (!NT_STATUS_IS_OK(status
)) {
1092 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1093 reply_botherror(req
,
1094 NT_STATUS_PATH_NOT_COVERED
,
1095 ERRSRV
, ERRbadpath
);
1098 reply_nterror(req
, status
);
1102 if (open_ofun
== 0) {
1103 reply_nterror(req
, NT_STATUS_OBJECT_NAME_COLLISION
);
1107 if (!map_open_params_to_ntcreate(smb_fname
->base_name
, deny_mode
,
1109 &access_mask
, &share_mode
,
1110 &create_disposition
,
1113 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1117 /* Any data in this call is an EA list. */
1118 if (total_data
&& (total_data
!= 4)) {
1119 if (total_data
< 10) {
1120 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1124 if (IVAL(pdata
,0) > total_data
) {
1125 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1126 IVAL(pdata
,0), (unsigned int)total_data
));
1127 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1131 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
1134 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1138 if (!lp_ea_support(SNUM(conn
))) {
1139 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
1144 status
= SMB_VFS_CREATE_FILE(
1147 0, /* root_dir_fid */
1148 smb_fname
, /* fname */
1149 access_mask
, /* access_mask */
1150 share_mode
, /* share_access */
1151 create_disposition
, /* create_disposition*/
1152 create_options
, /* create_options */
1153 open_attr
, /* file_attributes */
1154 oplock_request
, /* oplock_request */
1155 open_size
, /* allocation_size */
1158 ea_list
, /* ea_list */
1160 &smb_action
); /* psbuf */
1162 if (!NT_STATUS_IS_OK(status
)) {
1163 if (open_was_deferred(req
->sconn
, req
->mid
)) {
1164 /* We have re-scheduled this call. */
1167 reply_openerror(req
, status
);
1171 size
= get_file_size_stat(&smb_fname
->st
);
1172 fattr
= dos_mode(conn
, smb_fname
);
1173 mtime
= convert_timespec_to_time_t(smb_fname
->st
.st_ex_mtime
);
1174 inode
= smb_fname
->st
.st_ex_ino
;
1175 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
1176 close_file(req
, fsp
, ERROR_CLOSE
);
1177 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1181 /* Realloc the size of parameters and data we will return */
1182 *pparams
= (char *)SMB_REALLOC(*pparams
, 30);
1183 if(*pparams
== NULL
) {
1184 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1189 SSVAL(params
,0,fsp
->fnum
);
1190 SSVAL(params
,2,fattr
);
1191 srv_put_dos_date2(params
,4, mtime
);
1192 SIVAL(params
,8, (uint32
)size
);
1193 SSVAL(params
,12,deny_mode
);
1194 SSVAL(params
,14,0); /* open_type - file or directory. */
1195 SSVAL(params
,16,0); /* open_state - only valid for IPC device. */
1197 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1198 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1201 SSVAL(params
,18,smb_action
);
1204 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1206 SIVAL(params
,20,inode
);
1207 SSVAL(params
,24,0); /* Padding. */
1209 uint32 ea_size
= estimate_ea_size(conn
, fsp
,
1210 fsp
->fsp_name
->base_name
);
1211 SIVAL(params
, 26, ea_size
);
1213 SIVAL(params
, 26, 0);
1216 /* Send the required number of replies */
1217 send_trans2_replies(conn
, req
, params
, 30, *ppdata
, 0, max_data_bytes
);
1219 TALLOC_FREE(smb_fname
);
1222 /*********************************************************
1223 Routine to check if a given string matches exactly.
1224 as a special case a mask of "." does NOT match. That
1225 is required for correct wildcard semantics
1226 Case can be significant or not.
1227 **********************************************************/
1229 static bool exact_match(bool has_wild
,
1230 bool case_sensitive
,
1234 if (mask
[0] == '.' && mask
[1] == 0) {
1242 if (case_sensitive
) {
1243 return strcmp(str
,mask
)==0;
1245 return strcasecmp_m(str
,mask
) == 0;
1249 /****************************************************************************
1250 Return the filetype for UNIX extensions.
1251 ****************************************************************************/
1253 static uint32
unix_filetype(mode_t mode
)
1256 return UNIX_TYPE_FILE
;
1257 else if(S_ISDIR(mode
))
1258 return UNIX_TYPE_DIR
;
1260 else if(S_ISLNK(mode
))
1261 return UNIX_TYPE_SYMLINK
;
1264 else if(S_ISCHR(mode
))
1265 return UNIX_TYPE_CHARDEV
;
1268 else if(S_ISBLK(mode
))
1269 return UNIX_TYPE_BLKDEV
;
1272 else if(S_ISFIFO(mode
))
1273 return UNIX_TYPE_FIFO
;
1276 else if(S_ISSOCK(mode
))
1277 return UNIX_TYPE_SOCKET
;
1280 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode
));
1281 return UNIX_TYPE_UNKNOWN
;
1284 /****************************************************************************
1285 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1286 ****************************************************************************/
1288 enum perm_type
{ PERM_NEW_FILE
, PERM_NEW_DIR
, PERM_EXISTING_FILE
, PERM_EXISTING_DIR
};
1290 static NTSTATUS
unix_perms_from_wire( connection_struct
*conn
,
1291 const SMB_STRUCT_STAT
*psbuf
,
1293 enum perm_type ptype
,
1298 if (perms
== SMB_MODE_NO_CHANGE
) {
1299 if (!VALID_STAT(*psbuf
)) {
1300 return NT_STATUS_INVALID_PARAMETER
;
1302 *ret_perms
= psbuf
->st_ex_mode
;
1303 return NT_STATUS_OK
;
1307 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
1308 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
1309 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
1310 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
1311 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
1312 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
1313 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
1314 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
1315 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
1317 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
1320 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
1323 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
1328 /* Apply mode mask */
1329 ret
&= lp_create_mask(SNUM(conn
));
1330 /* Add in force bits */
1331 ret
|= lp_force_create_mode(SNUM(conn
));
1334 ret
&= lp_dir_mask(SNUM(conn
));
1335 /* Add in force bits */
1336 ret
|= lp_force_dir_mode(SNUM(conn
));
1338 case PERM_EXISTING_FILE
:
1339 /* Apply mode mask */
1340 ret
&= lp_security_mask(SNUM(conn
));
1341 /* Add in force bits */
1342 ret
|= lp_force_security_mode(SNUM(conn
));
1344 case PERM_EXISTING_DIR
:
1345 /* Apply mode mask */
1346 ret
&= lp_dir_security_mask(SNUM(conn
));
1347 /* Add in force bits */
1348 ret
|= lp_force_dir_security_mode(SNUM(conn
));
1353 return NT_STATUS_OK
;
1356 /****************************************************************************
1357 Needed to show the msdfs symlinks as directories. Modifies psbuf
1358 to be a directory if it's a msdfs link.
1359 ****************************************************************************/
1361 static bool check_msdfs_link(connection_struct
*conn
,
1362 const char *pathname
,
1363 SMB_STRUCT_STAT
*psbuf
)
1365 int saved_errno
= errno
;
1366 if(lp_host_msdfs() &&
1367 lp_msdfs_root(SNUM(conn
)) &&
1368 is_msdfs_link(conn
, pathname
, psbuf
)) {
1370 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1373 psbuf
->st_ex_mode
= (psbuf
->st_ex_mode
& 0xFFF) | S_IFDIR
;
1374 errno
= saved_errno
;
1377 errno
= saved_errno
;
1382 /****************************************************************************
1383 Get a level dependent lanman2 dir entry.
1384 ****************************************************************************/
1386 struct smbd_dirptr_lanman2_state
{
1387 connection_struct
*conn
;
1388 uint32_t info_level
;
1389 bool check_mangled_names
;
1391 bool got_exact_match
;
1394 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX
*ctx
,
1400 struct smbd_dirptr_lanman2_state
*state
=
1401 (struct smbd_dirptr_lanman2_state
*)private_data
;
1403 char mangled_name
[13]; /* mangled 8.3 name. */
1407 /* Mangle fname if it's an illegal name. */
1408 if (mangle_must_mangle(dname
, state
->conn
->params
)) {
1409 ok
= name_to_8_3(dname
, mangled_name
,
1410 true, state
->conn
->params
);
1414 fname
= mangled_name
;
1419 got_match
= exact_match(state
->has_wild
,
1420 state
->conn
->case_sensitive
,
1422 state
->got_exact_match
= got_match
;
1424 got_match
= mask_match(fname
, mask
,
1425 state
->conn
->case_sensitive
);
1428 if(!got_match
&& state
->check_mangled_names
&&
1429 !mangle_is_8_3(fname
, false, state
->conn
->params
)) {
1431 * It turns out that NT matches wildcards against
1432 * both long *and* short names. This may explain some
1433 * of the wildcard wierdness from old DOS clients
1434 * that some people have been seeing.... JRA.
1436 /* Force the mangling into 8.3. */
1437 ok
= name_to_8_3(fname
, mangled_name
,
1438 false, state
->conn
->params
);
1443 got_match
= exact_match(state
->has_wild
,
1444 state
->conn
->case_sensitive
,
1445 mangled_name
, mask
);
1446 state
->got_exact_match
= got_match
;
1448 got_match
= mask_match(mangled_name
, mask
,
1449 state
->conn
->case_sensitive
);
1457 *_fname
= talloc_strdup(ctx
, fname
);
1458 if (*_fname
== NULL
) {
1465 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX
*ctx
,
1467 struct smb_filename
*smb_fname
,
1470 struct smbd_dirptr_lanman2_state
*state
=
1471 (struct smbd_dirptr_lanman2_state
*)private_data
;
1472 bool ms_dfs_link
= false;
1475 if (INFO_LEVEL_IS_UNIX(state
->info_level
)) {
1476 if (SMB_VFS_LSTAT(state
->conn
, smb_fname
) != 0) {
1477 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1478 "Couldn't lstat [%s] (%s)\n",
1479 smb_fname_str_dbg(smb_fname
),
1483 } else if (!VALID_STAT(smb_fname
->st
) &&
1484 SMB_VFS_STAT(state
->conn
, smb_fname
) != 0) {
1485 /* Needed to show the msdfs symlinks as
1488 ms_dfs_link
= check_msdfs_link(state
->conn
,
1489 smb_fname
->base_name
,
1492 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1493 "Couldn't stat [%s] (%s)\n",
1494 smb_fname_str_dbg(smb_fname
),
1501 mode
= dos_mode_msdfs(state
->conn
, smb_fname
);
1503 mode
= dos_mode(state
->conn
, smb_fname
);
1510 static bool smbd_marshall_dir_entry(TALLOC_CTX
*ctx
,
1511 connection_struct
*conn
,
1513 uint32_t info_level
,
1514 struct ea_list
*name_list
,
1515 bool check_mangled_names
,
1516 bool requires_resume_key
,
1519 const struct smb_filename
*smb_fname
,
1520 int space_remaining
,
1527 uint64_t *last_entry_off
)
1529 char *p
, *q
, *pdata
= *ppdata
;
1531 uint64_t file_size
= 0;
1532 uint64_t allocation_size
= 0;
1533 uint64_t file_index
= 0;
1535 struct timespec mdate_ts
, adate_ts
, cdate_ts
, create_date_ts
;
1536 time_t mdate
= (time_t)0, adate
= (time_t)0, create_date
= (time_t)0;
1538 char *last_entry_ptr
;
1543 *out_of_space
= false;
1545 ZERO_STRUCT(mdate_ts
);
1546 ZERO_STRUCT(adate_ts
);
1547 ZERO_STRUCT(create_date_ts
);
1548 ZERO_STRUCT(cdate_ts
);
1550 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
1551 file_size
= get_file_size_stat(&smb_fname
->st
);
1553 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, NULL
, &smb_fname
->st
);
1555 file_index
= get_FileIndex(conn
, &smb_fname
->st
);
1557 mdate_ts
= smb_fname
->st
.st_ex_mtime
;
1558 adate_ts
= smb_fname
->st
.st_ex_atime
;
1559 create_date_ts
= get_create_timespec(conn
, NULL
, smb_fname
);
1560 cdate_ts
= get_change_timespec(conn
, NULL
, smb_fname
);
1562 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1563 dos_filetime_timespec(&create_date_ts
);
1564 dos_filetime_timespec(&mdate_ts
);
1565 dos_filetime_timespec(&adate_ts
);
1566 dos_filetime_timespec(&cdate_ts
);
1569 create_date
= convert_timespec_to_time_t(create_date_ts
);
1570 mdate
= convert_timespec_to_time_t(mdate_ts
);
1571 adate
= convert_timespec_to_time_t(adate_ts
);
1573 /* align the record */
1574 SMB_ASSERT(align
>= 1);
1576 off
= (int)PTR_DIFF(pdata
, base_data
);
1577 pad
= (off
+ (align
-1)) & ~(align
-1);
1580 if (pad
&& pad
> space_remaining
) {
1581 *out_of_space
= true;
1582 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1583 "for padding (wanted %u, had %d)\n",
1586 return false; /* Not finished - just out of space */
1590 /* initialize padding to 0 */
1592 memset(pdata
, 0, pad
);
1594 space_remaining
-= pad
;
1596 DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1606 switch (info_level
) {
1607 case SMB_FIND_INFO_STANDARD
:
1608 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1609 if(requires_resume_key
) {
1613 srv_put_dos_date2(p
,0,create_date
);
1614 srv_put_dos_date2(p
,4,adate
);
1615 srv_put_dos_date2(p
,8,mdate
);
1616 SIVAL(p
,12,(uint32
)file_size
);
1617 SIVAL(p
,16,(uint32
)allocation_size
);
1621 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1622 p
+= ucs2_align(base_data
, p
, 0);
1624 len
= srvstr_push(base_data
, flags2
, p
,
1625 fname
, PTR_DIFF(end_data
, p
),
1627 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1629 SCVAL(nameptr
, -1, len
- 2);
1631 SCVAL(nameptr
, -1, 0);
1635 SCVAL(nameptr
, -1, len
- 1);
1637 SCVAL(nameptr
, -1, 0);
1643 case SMB_FIND_EA_SIZE
:
1644 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1645 if (requires_resume_key
) {
1649 srv_put_dos_date2(p
,0,create_date
);
1650 srv_put_dos_date2(p
,4,adate
);
1651 srv_put_dos_date2(p
,8,mdate
);
1652 SIVAL(p
,12,(uint32
)file_size
);
1653 SIVAL(p
,16,(uint32
)allocation_size
);
1656 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1657 smb_fname
->base_name
);
1658 SIVAL(p
,22,ea_size
); /* Extended attributes */
1662 len
= srvstr_push(base_data
, flags2
,
1663 p
, fname
, PTR_DIFF(end_data
, p
),
1664 STR_TERMINATE
| STR_NOALIGN
);
1665 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1678 SCVAL(nameptr
,0,len
);
1680 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1683 case SMB_FIND_EA_LIST
:
1685 struct ea_list
*file_list
= NULL
;
1688 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1692 if (requires_resume_key
) {
1696 srv_put_dos_date2(p
,0,create_date
);
1697 srv_put_dos_date2(p
,4,adate
);
1698 srv_put_dos_date2(p
,8,mdate
);
1699 SIVAL(p
,12,(uint32
)file_size
);
1700 SIVAL(p
,16,(uint32
)allocation_size
);
1702 p
+= 22; /* p now points to the EA area. */
1704 file_list
= get_ea_list_from_file(ctx
, conn
, NULL
,
1705 smb_fname
->base_name
,
1707 name_list
= ea_list_union(name_list
, file_list
, &ea_len
);
1709 /* We need to determine if this entry will fit in the space available. */
1710 /* Max string size is 255 bytes. */
1711 if (PTR_DIFF(p
+ 255 + ea_len
,pdata
) > space_remaining
) {
1712 *out_of_space
= true;
1713 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1714 "(wanted %u, had %d)\n",
1715 (unsigned int)PTR_DIFF(p
+ 255 + ea_len
,pdata
),
1717 return False
; /* Not finished - just out of space */
1720 /* Push the ea_data followed by the name. */
1721 p
+= fill_ea_buffer(ctx
, p
, space_remaining
, conn
, name_list
);
1723 len
= srvstr_push(base_data
, flags2
,
1724 p
+ 1, fname
, PTR_DIFF(end_data
, p
+1),
1725 STR_TERMINATE
| STR_NOALIGN
);
1726 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1739 SCVAL(nameptr
,0,len
);
1741 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1745 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1746 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1747 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1749 SIVAL(p
,0,reskey
); p
+= 4;
1750 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1751 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1752 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1753 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1754 SOFF_T(p
,0,file_size
); p
+= 8;
1755 SOFF_T(p
,0,allocation_size
); p
+= 8;
1756 SIVAL(p
,0,mode
); p
+= 4;
1757 q
= p
; p
+= 4; /* q is placeholder for name length. */
1759 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1760 smb_fname
->base_name
);
1761 SIVAL(p
,0,ea_size
); /* Extended attributes */
1764 /* Clear the short name buffer. This is
1765 * IMPORTANT as not doing so will trigger
1766 * a Win2k client bug. JRA.
1768 if (!was_8_3
&& check_mangled_names
) {
1769 char mangled_name
[13]; /* mangled 8.3 name. */
1770 if (!name_to_8_3(fname
,mangled_name
,True
,
1772 /* Error - mangle failed ! */
1773 memset(mangled_name
,'\0',12);
1775 mangled_name
[12] = 0;
1776 len
= srvstr_push(base_data
, flags2
,
1777 p
+2, mangled_name
, 24,
1778 STR_UPPER
|STR_UNICODE
);
1780 memset(p
+ 2 + len
,'\0',24 - len
);
1787 len
= srvstr_push(base_data
, flags2
, p
,
1788 fname
, PTR_DIFF(end_data
, p
),
1789 STR_TERMINATE_ASCII
);
1793 len
= PTR_DIFF(p
, pdata
);
1794 pad
= (len
+ (align
-1)) & ~(align
-1);
1796 * offset to the next entry, the caller
1797 * will overwrite it for the last entry
1798 * that's why we always include the padding
1802 * set padding to zero
1805 memset(p
, 0, pad
- len
);
1812 case SMB_FIND_FILE_DIRECTORY_INFO
:
1813 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1815 SIVAL(p
,0,reskey
); p
+= 4;
1816 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1817 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1818 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1819 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1820 SOFF_T(p
,0,file_size
); p
+= 8;
1821 SOFF_T(p
,0,allocation_size
); p
+= 8;
1822 SIVAL(p
,0,mode
); p
+= 4;
1823 len
= srvstr_push(base_data
, flags2
,
1824 p
+ 4, fname
, PTR_DIFF(end_data
, p
+4),
1825 STR_TERMINATE_ASCII
);
1829 len
= PTR_DIFF(p
, pdata
);
1830 pad
= (len
+ (align
-1)) & ~(align
-1);
1832 * offset to the next entry, the caller
1833 * will overwrite it for the last entry
1834 * that's why we always include the padding
1838 * set padding to zero
1841 memset(p
, 0, pad
- len
);
1848 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1849 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1851 SIVAL(p
,0,reskey
); p
+= 4;
1852 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1853 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1854 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1855 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1856 SOFF_T(p
,0,file_size
); p
+= 8;
1857 SOFF_T(p
,0,allocation_size
); p
+= 8;
1858 SIVAL(p
,0,mode
); p
+= 4;
1859 q
= p
; p
+= 4; /* q is placeholder for name length. */
1861 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1862 smb_fname
->base_name
);
1863 SIVAL(p
,0,ea_size
); /* Extended attributes */
1866 len
= srvstr_push(base_data
, flags2
, p
,
1867 fname
, PTR_DIFF(end_data
, p
),
1868 STR_TERMINATE_ASCII
);
1872 len
= PTR_DIFF(p
, pdata
);
1873 pad
= (len
+ (align
-1)) & ~(align
-1);
1875 * offset to the next entry, the caller
1876 * will overwrite it for the last entry
1877 * that's why we always include the padding
1881 * set padding to zero
1884 memset(p
, 0, pad
- len
);
1891 case SMB_FIND_FILE_NAMES_INFO
:
1892 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1894 SIVAL(p
,0,reskey
); p
+= 4;
1896 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1897 acl on a dir (tridge) */
1898 len
= srvstr_push(base_data
, flags2
, p
,
1899 fname
, PTR_DIFF(end_data
, p
),
1900 STR_TERMINATE_ASCII
);
1904 len
= PTR_DIFF(p
, pdata
);
1905 pad
= (len
+ (align
-1)) & ~(align
-1);
1907 * offset to the next entry, the caller
1908 * will overwrite it for the last entry
1909 * that's why we always include the padding
1913 * set padding to zero
1916 memset(p
, 0, pad
- len
);
1923 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1924 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1926 SIVAL(p
,0,reskey
); p
+= 4;
1927 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1928 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1929 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1930 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1931 SOFF_T(p
,0,file_size
); p
+= 8;
1932 SOFF_T(p
,0,allocation_size
); p
+= 8;
1933 SIVAL(p
,0,mode
); p
+= 4;
1934 q
= p
; p
+= 4; /* q is placeholder for name length. */
1936 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1937 smb_fname
->base_name
);
1938 SIVAL(p
,0,ea_size
); /* Extended attributes */
1941 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
1942 SBVAL(p
,0,file_index
); p
+= 8;
1943 len
= srvstr_push(base_data
, flags2
, p
,
1944 fname
, PTR_DIFF(end_data
, p
),
1945 STR_TERMINATE_ASCII
);
1949 len
= PTR_DIFF(p
, pdata
);
1950 pad
= (len
+ (align
-1)) & ~(align
-1);
1952 * offset to the next entry, the caller
1953 * will overwrite it for the last entry
1954 * that's why we always include the padding
1958 * set padding to zero
1961 memset(p
, 0, pad
- len
);
1968 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1969 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1970 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1972 SIVAL(p
,0,reskey
); p
+= 4;
1973 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1974 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1975 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1976 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1977 SOFF_T(p
,0,file_size
); p
+= 8;
1978 SOFF_T(p
,0,allocation_size
); p
+= 8;
1979 SIVAL(p
,0,mode
); p
+= 4;
1980 q
= p
; p
+= 4; /* q is placeholder for name length */
1982 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1983 smb_fname
->base_name
);
1984 SIVAL(p
,0,ea_size
); /* Extended attributes */
1987 /* Clear the short name buffer. This is
1988 * IMPORTANT as not doing so will trigger
1989 * a Win2k client bug. JRA.
1991 if (!was_8_3
&& check_mangled_names
) {
1992 char mangled_name
[13]; /* mangled 8.3 name. */
1993 if (!name_to_8_3(fname
,mangled_name
,True
,
1995 /* Error - mangle failed ! */
1996 memset(mangled_name
,'\0',12);
1998 mangled_name
[12] = 0;
1999 len
= srvstr_push(base_data
, flags2
,
2000 p
+2, mangled_name
, 24,
2001 STR_UPPER
|STR_UNICODE
);
2004 memset(p
+ 2 + len
,'\0',24 - len
);
2011 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
2012 SBVAL(p
,0,file_index
); p
+= 8;
2013 len
= srvstr_push(base_data
, flags2
, p
,
2014 fname
, PTR_DIFF(end_data
, p
),
2015 STR_TERMINATE_ASCII
);
2019 len
= PTR_DIFF(p
, pdata
);
2020 pad
= (len
+ (align
-1)) & ~(align
-1);
2022 * offset to the next entry, the caller
2023 * will overwrite it for the last entry
2024 * that's why we always include the padding
2028 * set padding to zero
2031 memset(p
, 0, pad
- len
);
2038 /* CIFS UNIX Extension. */
2040 case SMB_FIND_FILE_UNIX
:
2041 case SMB_FIND_FILE_UNIX_INFO2
:
2043 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
2045 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2047 if (info_level
== SMB_FIND_FILE_UNIX
) {
2048 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2049 p
= store_file_unix_basic(conn
, p
,
2050 NULL
, &smb_fname
->st
);
2051 len
= srvstr_push(base_data
, flags2
, p
,
2052 fname
, PTR_DIFF(end_data
, p
),
2055 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2056 p
= store_file_unix_basic_info2(conn
, p
,
2057 NULL
, &smb_fname
->st
);
2060 len
= srvstr_push(base_data
, flags2
, p
, fname
,
2061 PTR_DIFF(end_data
, p
), 0);
2062 SIVAL(nameptr
, 0, len
);
2067 len
= PTR_DIFF(p
, pdata
);
2068 pad
= (len
+ (align
-1)) & ~(align
-1);
2070 * offset to the next entry, the caller
2071 * will overwrite it for the last entry
2072 * that's why we always include the padding
2076 * set padding to zero
2079 memset(p
, 0, pad
- len
);
2084 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2092 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
2093 *out_of_space
= true;
2094 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2095 "(wanted %u, had %d)\n",
2096 (unsigned int)PTR_DIFF(p
,pdata
),
2098 return false; /* Not finished - just out of space */
2101 /* Setup the last entry pointer, as an offset from base_data */
2102 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
2103 /* Advance the data pointer to the next slot */
2109 bool smbd_dirptr_lanman2_entry(TALLOC_CTX
*ctx
,
2110 connection_struct
*conn
,
2111 struct dptr_struct
*dirptr
,
2113 const char *path_mask
,
2116 int requires_resume_key
,
2124 int space_remaining
,
2126 bool *got_exact_match
,
2127 int *_last_entry_off
,
2128 struct ea_list
*name_list
)
2131 const char *mask
= NULL
;
2132 long prev_dirpos
= 0;
2135 struct smb_filename
*smb_fname
= NULL
;
2136 struct smbd_dirptr_lanman2_state state
;
2138 uint64_t last_entry_off
= 0;
2142 state
.info_level
= info_level
;
2143 state
.check_mangled_names
= lp_manglednames(conn
->params
);
2144 state
.has_wild
= dptr_has_wild(dirptr
);
2145 state
.got_exact_match
= false;
2147 *out_of_space
= false;
2148 *got_exact_match
= false;
2150 p
= strrchr_m(path_mask
,'/');
2161 ok
= smbd_dirptr_get_entry(ctx
,
2167 smbd_dirptr_lanman2_match_fn
,
2168 smbd_dirptr_lanman2_mode_fn
,
2178 *got_exact_match
= state
.got_exact_match
;
2180 ok
= smbd_marshall_dir_entry(ctx
,
2185 state
.check_mangled_names
,
2186 requires_resume_key
,
2199 TALLOC_FREE(smb_fname
);
2200 if (*out_of_space
) {
2201 dptr_SeekDir(dirptr
, prev_dirpos
);
2208 *_last_entry_off
= last_entry_off
;
2212 static bool get_lanman2_dir_entry(TALLOC_CTX
*ctx
,
2213 connection_struct
*conn
,
2214 struct dptr_struct
*dirptr
,
2216 const char *path_mask
,
2219 bool requires_resume_key
,
2225 int space_remaining
,
2227 bool *got_exact_match
,
2228 int *last_entry_off
,
2229 struct ea_list
*name_list
)
2232 const bool do_pad
= true;
2234 if (info_level
>= 1 && info_level
<= 3) {
2235 /* No alignment on earlier info levels. */
2239 return smbd_dirptr_lanman2_entry(ctx
, conn
, dirptr
, flags2
,
2240 path_mask
, dirtype
, info_level
,
2241 requires_resume_key
, dont_descend
, ask_sharemode
,
2243 ppdata
, base_data
, end_data
,
2245 out_of_space
, got_exact_match
,
2246 last_entry_off
, name_list
);
2249 /****************************************************************************
2250 Reply to a TRANS2_FINDFIRST.
2251 ****************************************************************************/
2253 static void call_trans2findfirst(connection_struct
*conn
,
2254 struct smb_request
*req
,
2255 char **pparams
, int total_params
,
2256 char **ppdata
, int total_data
,
2257 unsigned int max_data_bytes
)
2259 /* We must be careful here that we don't return more than the
2260 allowed number of data bytes. If this means returning fewer than
2261 maxentries then so be it. We assume that the redirector has
2262 enough room for the fixed number of parameter bytes it has
2264 struct smb_filename
*smb_dname
= NULL
;
2265 char *params
= *pparams
;
2266 char *pdata
= *ppdata
;
2270 uint16 findfirst_flags
;
2271 bool close_after_first
;
2273 bool requires_resume_key
;
2275 char *directory
= NULL
;
2278 int last_entry_off
=0;
2282 bool finished
= False
;
2283 bool dont_descend
= False
;
2284 bool out_of_space
= False
;
2285 int space_remaining
;
2286 bool mask_contains_wcard
= False
;
2287 struct ea_list
*ea_list
= NULL
;
2288 NTSTATUS ntstatus
= NT_STATUS_OK
;
2289 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2290 TALLOC_CTX
*ctx
= talloc_tos();
2291 struct dptr_struct
*dirptr
= NULL
;
2292 struct smbd_server_connection
*sconn
= req
->sconn
;
2293 uint32_t ucf_flags
= (UCF_SAVE_LCOMP
| UCF_ALWAYS_ALLOW_WCARD_LCOMP
);
2294 bool backup_priv
= false;
2296 if (total_params
< 13) {
2297 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2301 dirtype
= SVAL(params
,0);
2302 maxentries
= SVAL(params
,2);
2303 findfirst_flags
= SVAL(params
,4);
2304 close_after_first
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE
);
2305 close_if_end
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2306 requires_resume_key
= (findfirst_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2307 backup_priv
= ((findfirst_flags
& FLAG_TRANS2_FIND_BACKUP_INTENT
) &&
2308 security_token_has_privilege(get_current_nttok(conn
),
2311 info_level
= SVAL(params
,6);
2313 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2314 close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
2315 (unsigned int)dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
2317 info_level
, max_data_bytes
));
2320 /* W2K3 seems to treat zero as 1. */
2324 switch (info_level
) {
2325 case SMB_FIND_INFO_STANDARD
:
2326 case SMB_FIND_EA_SIZE
:
2327 case SMB_FIND_EA_LIST
:
2328 case SMB_FIND_FILE_DIRECTORY_INFO
:
2329 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2330 case SMB_FIND_FILE_NAMES_INFO
:
2331 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2332 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2333 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2335 case SMB_FIND_FILE_UNIX
:
2336 case SMB_FIND_FILE_UNIX_INFO2
:
2337 /* Always use filesystem for UNIX mtime query. */
2338 ask_sharemode
= false;
2339 if (!lp_unix_extensions()) {
2340 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2343 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
2346 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2350 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &directory
,
2351 params
+12, total_params
- 12,
2352 STR_TERMINATE
, &ntstatus
, &mask_contains_wcard
);
2353 if (!NT_STATUS_IS_OK(ntstatus
)) {
2354 reply_nterror(req
, ntstatus
);
2360 ntstatus
= filename_convert_with_privilege(ctx
,
2365 &mask_contains_wcard
,
2368 ntstatus
= filename_convert(ctx
, conn
,
2369 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2372 &mask_contains_wcard
,
2376 if (!NT_STATUS_IS_OK(ntstatus
)) {
2377 if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_PATH_NOT_COVERED
)) {
2378 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
2379 ERRSRV
, ERRbadpath
);
2382 reply_nterror(req
, ntstatus
);
2386 mask
= smb_dname
->original_lcomp
;
2388 directory
= smb_dname
->base_name
;
2390 p
= strrchr_m(directory
,'/');
2392 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2393 if((directory
[0] == '.') && (directory
[1] == '\0')) {
2394 mask
= talloc_strdup(ctx
,"*");
2396 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2399 mask_contains_wcard
= True
;
2405 if (p
== NULL
|| p
== directory
) {
2406 /* Ensure we don't have a directory name of "". */
2407 directory
= talloc_strdup(talloc_tos(), ".");
2409 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2414 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
2416 if (info_level
== SMB_FIND_EA_LIST
) {
2419 if (total_data
< 4) {
2420 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2424 ea_size
= IVAL(pdata
,0);
2425 if (ea_size
!= total_data
) {
2426 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2427 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2428 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2432 if (!lp_ea_support(SNUM(conn
))) {
2433 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2437 /* Pull out the list of names. */
2438 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2440 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2445 *ppdata
= (char *)SMB_REALLOC(
2446 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2447 if(*ppdata
== NULL
) {
2448 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2452 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2454 /* Realloc the params space */
2455 *pparams
= (char *)SMB_REALLOC(*pparams
, 10);
2456 if (*pparams
== NULL
) {
2457 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2462 /* Save the wildcard match and attribs we are using on this directory -
2463 needed as lanman2 assumes these are being saved between calls */
2465 ntstatus
= dptr_create(conn
,
2473 mask_contains_wcard
,
2477 if (!NT_STATUS_IS_OK(ntstatus
)) {
2478 reply_nterror(req
, ntstatus
);
2483 /* Remember this in case we have
2484 to do a findnext. */
2485 dptr_set_priv(dirptr
);
2488 dptr_num
= dptr_dnum(dirptr
);
2489 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num
, mask
, dirtype
));
2491 /* Initialize per TRANS2_FIND_FIRST operation data */
2492 dptr_init_search_op(dirptr
);
2494 /* We don't need to check for VOL here as this is returned by
2495 a different TRANS2 call. */
2497 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2498 directory
,lp_dontdescend(SNUM(conn
))));
2499 if (in_list(directory
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
2500 dont_descend
= True
;
2503 space_remaining
= max_data_bytes
;
2504 out_of_space
= False
;
2506 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
2507 bool got_exact_match
= False
;
2509 /* this is a heuristic to avoid seeking the dirptr except when
2510 absolutely necessary. It allows for a filename of about 40 chars */
2511 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2512 out_of_space
= True
;
2515 finished
= !get_lanman2_dir_entry(ctx
,
2519 mask
,dirtype
,info_level
,
2520 requires_resume_key
,dont_descend
,
2523 space_remaining
, &out_of_space
,
2525 &last_entry_off
, ea_list
);
2528 if (finished
&& out_of_space
)
2531 if (!finished
&& !out_of_space
)
2535 * As an optimisation if we know we aren't looking
2536 * for a wildcard name (ie. the name matches the wildcard exactly)
2537 * then we can finish on any (first) match.
2538 * This speeds up large directory searches. JRA.
2544 /* Ensure space_remaining never goes -ve. */
2545 if (PTR_DIFF(p
,pdata
) > max_data_bytes
) {
2546 space_remaining
= 0;
2547 out_of_space
= true;
2549 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2553 /* Check if we can close the dirptr */
2554 if(close_after_first
|| (finished
&& close_if_end
)) {
2555 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
2556 dptr_close(sconn
, &dptr_num
);
2560 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2561 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2562 * the protocol level is less than NT1. Tested with smbclient. JRA.
2563 * This should fix the OS/2 client bug #2335.
2566 if(numentries
== 0) {
2567 dptr_close(sconn
, &dptr_num
);
2568 if (get_Protocol() < PROTOCOL_NT1
) {
2569 reply_force_doserror(req
, ERRDOS
, ERRnofiles
);
2572 reply_botherror(req
, NT_STATUS_NO_SUCH_FILE
,
2573 ERRDOS
, ERRbadfile
);
2578 /* At this point pdata points to numentries directory entries. */
2580 /* Set up the return parameter block */
2581 SSVAL(params
,0,dptr_num
);
2582 SSVAL(params
,2,numentries
);
2583 SSVAL(params
,4,finished
);
2584 SSVAL(params
,6,0); /* Never an EA error */
2585 SSVAL(params
,8,last_entry_off
);
2587 send_trans2_replies(conn
, req
, params
, 10, pdata
, PTR_DIFF(p
,pdata
),
2590 if ((! *directory
) && dptr_path(sconn
, dptr_num
)) {
2591 directory
= talloc_strdup(talloc_tos(),dptr_path(sconn
, dptr_num
));
2593 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2597 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2598 smb_fn_name(req
->cmd
),
2599 mask
, directory
, dirtype
, numentries
) );
2602 * Force a name mangle here to ensure that the
2603 * mask as an 8.3 name is top of the mangled cache.
2604 * The reasons for this are subtle. Don't remove
2605 * this code unless you know what you are doing
2606 * (see PR#13758). JRA.
2609 if(!mangle_is_8_3_wildcards( mask
, False
, conn
->params
)) {
2610 char mangled_name
[13];
2611 name_to_8_3(mask
, mangled_name
, True
, conn
->params
);
2619 TALLOC_FREE(smb_dname
);
2623 /****************************************************************************
2624 Reply to a TRANS2_FINDNEXT.
2625 ****************************************************************************/
2627 static void call_trans2findnext(connection_struct
*conn
,
2628 struct smb_request
*req
,
2629 char **pparams
, int total_params
,
2630 char **ppdata
, int total_data
,
2631 unsigned int max_data_bytes
)
2633 /* We must be careful here that we don't return more than the
2634 allowed number of data bytes. If this means returning fewer than
2635 maxentries then so be it. We assume that the redirector has
2636 enough room for the fixed number of parameter bytes it has
2638 char *params
= *pparams
;
2639 char *pdata
= *ppdata
;
2645 uint16 findnext_flags
;
2646 bool close_after_request
;
2648 bool requires_resume_key
;
2650 bool mask_contains_wcard
= False
;
2651 char *resume_name
= NULL
;
2652 const char *mask
= NULL
;
2653 const char *directory
= NULL
;
2657 int i
, last_entry_off
=0;
2658 bool finished
= False
;
2659 bool dont_descend
= False
;
2660 bool out_of_space
= False
;
2661 int space_remaining
;
2662 struct ea_list
*ea_list
= NULL
;
2663 NTSTATUS ntstatus
= NT_STATUS_OK
;
2664 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2665 TALLOC_CTX
*ctx
= talloc_tos();
2666 struct dptr_struct
*dirptr
;
2667 struct smbd_server_connection
*sconn
= req
->sconn
;
2668 bool backup_priv
= false;
2670 if (total_params
< 13) {
2671 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2675 dptr_num
= SVAL(params
,0);
2676 maxentries
= SVAL(params
,2);
2677 info_level
= SVAL(params
,4);
2678 resume_key
= IVAL(params
,6);
2679 findnext_flags
= SVAL(params
,10);
2680 close_after_request
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE
);
2681 close_if_end
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2682 requires_resume_key
= (findnext_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2683 continue_bit
= (findnext_flags
& FLAG_TRANS2_FIND_CONTINUE
);
2685 if (!continue_bit
) {
2686 /* We only need resume_name if continue_bit is zero. */
2687 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &resume_name
,
2689 total_params
- 12, STR_TERMINATE
, &ntstatus
,
2690 &mask_contains_wcard
);
2691 if (!NT_STATUS_IS_OK(ntstatus
)) {
2692 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2693 complain (it thinks we're asking for the directory above the shared
2694 path or an invalid name). Catch this as the resume name is only compared, never used in
2695 a file access. JRA. */
2696 srvstr_pull_talloc(ctx
, params
, req
->flags2
,
2697 &resume_name
, params
+12,
2701 if (!resume_name
|| !(ISDOT(resume_name
) || ISDOTDOT(resume_name
))) {
2702 reply_nterror(req
, ntstatus
);
2708 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2709 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2710 resume_key = %d resume name = %s continue=%d level = %d\n",
2711 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
2712 requires_resume_key
, resume_key
,
2713 resume_name
? resume_name
: "(NULL)", continue_bit
, info_level
));
2716 /* W2K3 seems to treat zero as 1. */
2720 switch (info_level
) {
2721 case SMB_FIND_INFO_STANDARD
:
2722 case SMB_FIND_EA_SIZE
:
2723 case SMB_FIND_EA_LIST
:
2724 case SMB_FIND_FILE_DIRECTORY_INFO
:
2725 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2726 case SMB_FIND_FILE_NAMES_INFO
:
2727 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2728 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2729 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2731 case SMB_FIND_FILE_UNIX
:
2732 case SMB_FIND_FILE_UNIX_INFO2
:
2733 /* Always use filesystem for UNIX mtime query. */
2734 ask_sharemode
= false;
2735 if (!lp_unix_extensions()) {
2736 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2741 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2745 if (info_level
== SMB_FIND_EA_LIST
) {
2748 if (total_data
< 4) {
2749 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2753 ea_size
= IVAL(pdata
,0);
2754 if (ea_size
!= total_data
) {
2755 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2756 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2757 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2761 if (!lp_ea_support(SNUM(conn
))) {
2762 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2766 /* Pull out the list of names. */
2767 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2769 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2774 *ppdata
= (char *)SMB_REALLOC(
2775 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2776 if(*ppdata
== NULL
) {
2777 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2782 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2784 /* Realloc the params space */
2785 *pparams
= (char *)SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
2786 if(*pparams
== NULL
) {
2787 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2793 /* Check that the dptr is valid */
2794 if(!(dirptr
= dptr_fetch_lanman2(sconn
, dptr_num
))) {
2795 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2799 directory
= dptr_path(sconn
, dptr_num
);
2801 /* Get the wildcard mask from the dptr */
2802 if((mask
= dptr_wcard(sconn
, dptr_num
))== NULL
) {
2803 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
2804 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2808 /* Get the attr mask from the dptr */
2809 dirtype
= dptr_attr(sconn
, dptr_num
);
2811 backup_priv
= dptr_get_priv(dirptr
);
2813 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
2814 "backup_priv = %d\n",
2815 dptr_num
, mask
, dirtype
,
2817 dptr_TellDir(dirptr
),
2820 /* Initialize per TRANS2_FIND_NEXT operation data */
2821 dptr_init_search_op(dirptr
);
2823 /* We don't need to check for VOL here as this is returned by
2824 a different TRANS2 call. */
2826 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2827 directory
,lp_dontdescend(SNUM(conn
))));
2828 if (in_list(directory
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
2829 dont_descend
= True
;
2832 space_remaining
= max_data_bytes
;
2833 out_of_space
= False
;
2840 * Seek to the correct position. We no longer use the resume key but
2841 * depend on the last file name instead.
2844 if(!continue_bit
&& resume_name
&& *resume_name
) {
2847 long current_pos
= 0;
2849 * Remember, name_to_8_3 is called by
2850 * get_lanman2_dir_entry(), so the resume name
2851 * could be mangled. Ensure we check the unmangled name.
2854 if (mangle_is_mangled(resume_name
, conn
->params
)) {
2855 char *new_resume_name
= NULL
;
2856 mangle_lookup_name_from_8_3(ctx
,
2860 if (new_resume_name
) {
2861 resume_name
= new_resume_name
;
2866 * Fix for NT redirector problem triggered by resume key indexes
2867 * changing between directory scans. We now return a resume key of 0
2868 * and instead look for the filename to continue from (also given
2869 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2870 * findfirst/findnext (as is usual) then the directory pointer
2871 * should already be at the correct place.
2874 finished
= !dptr_SearchDir(dirptr
, resume_name
, ¤t_pos
, &st
);
2875 } /* end if resume_name && !continue_bit */
2877 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
2878 bool got_exact_match
= False
;
2880 /* this is a heuristic to avoid seeking the dirptr except when
2881 absolutely necessary. It allows for a filename of about 40 chars */
2882 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2883 out_of_space
= True
;
2886 finished
= !get_lanman2_dir_entry(ctx
,
2890 mask
,dirtype
,info_level
,
2891 requires_resume_key
,dont_descend
,
2894 space_remaining
, &out_of_space
,
2896 &last_entry_off
, ea_list
);
2899 if (finished
&& out_of_space
)
2902 if (!finished
&& !out_of_space
)
2906 * As an optimisation if we know we aren't looking
2907 * for a wildcard name (ie. the name matches the wildcard exactly)
2908 * then we can finish on any (first) match.
2909 * This speeds up large directory searches. JRA.
2915 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2918 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2919 smb_fn_name(req
->cmd
),
2920 mask
, directory
, dirtype
, numentries
) );
2922 /* Check if we can close the dirptr */
2923 if(close_after_request
|| (finished
&& close_if_end
)) {
2924 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
2925 dptr_close(sconn
, &dptr_num
); /* This frees up the saved mask */
2932 /* Set up the return parameter block */
2933 SSVAL(params
,0,numentries
);
2934 SSVAL(params
,2,finished
);
2935 SSVAL(params
,4,0); /* Never an EA error */
2936 SSVAL(params
,6,last_entry_off
);
2938 send_trans2_replies(conn
, req
, params
, 8, pdata
, PTR_DIFF(p
,pdata
),
2944 unsigned char *create_volume_objectid(connection_struct
*conn
, unsigned char objid
[16])
2946 E_md4hash(lp_servicename(SNUM(conn
)),objid
);
2950 static void samba_extended_info_version(struct smb_extended_info
*extended_info
)
2952 SMB_ASSERT(extended_info
!= NULL
);
2954 extended_info
->samba_magic
= SAMBA_EXTENDED_INFO_MAGIC
;
2955 extended_info
->samba_version
= ((SAMBA_VERSION_MAJOR
& 0xff) << 24)
2956 | ((SAMBA_VERSION_MINOR
& 0xff) << 16)
2957 | ((SAMBA_VERSION_RELEASE
& 0xff) << 8);
2958 #ifdef SAMBA_VERSION_REVISION
2959 extended_info
->samba_version
|= (tolower(*SAMBA_VERSION_REVISION
) - 'a' + 1) & 0xff;
2961 extended_info
->samba_subversion
= 0;
2962 #ifdef SAMBA_VERSION_RC_RELEASE
2963 extended_info
->samba_subversion
|= (SAMBA_VERSION_RC_RELEASE
& 0xff) << 24;
2965 #ifdef SAMBA_VERSION_PRE_RELEASE
2966 extended_info
->samba_subversion
|= (SAMBA_VERSION_PRE_RELEASE
& 0xff) << 16;
2969 #ifdef SAMBA_VERSION_VENDOR_PATCH
2970 extended_info
->samba_subversion
|= (SAMBA_VERSION_VENDOR_PATCH
& 0xffff);
2972 extended_info
->samba_gitcommitdate
= 0;
2973 #ifdef SAMBA_VERSION_COMMIT_TIME
2974 unix_to_nt_time(&extended_info
->samba_gitcommitdate
, SAMBA_VERSION_COMMIT_TIME
);
2977 memset(extended_info
->samba_version_string
, 0,
2978 sizeof(extended_info
->samba_version_string
));
2980 snprintf (extended_info
->samba_version_string
,
2981 sizeof(extended_info
->samba_version_string
),
2982 "%s", samba_version_string());
2985 NTSTATUS
smbd_do_qfsinfo(connection_struct
*conn
,
2986 TALLOC_CTX
*mem_ctx
,
2987 uint16_t info_level
,
2989 unsigned int max_data_bytes
,
2993 char *pdata
, *end_data
;
2994 int data_len
= 0, len
;
2995 const char *vname
= volume_label(SNUM(conn
));
2996 int snum
= SNUM(conn
);
2997 char *fstype
= lp_fstype(SNUM(conn
));
2998 uint32 additional_flags
= 0;
2999 struct smb_filename smb_fname_dot
;
3003 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3004 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3005 "info level (0x%x) on IPC$.\n",
3006 (unsigned int)info_level
));
3007 return NT_STATUS_ACCESS_DENIED
;
3011 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level
));
3013 ZERO_STRUCT(smb_fname_dot
);
3014 smb_fname_dot
.base_name
= discard_const_p(char, ".");
3016 if(SMB_VFS_STAT(conn
, &smb_fname_dot
) != 0) {
3017 DEBUG(2,("stat of . failed (%s)\n", strerror(errno
)));
3018 return map_nt_error_from_unix(errno
);
3021 st
= smb_fname_dot
.st
;
3023 *ppdata
= (char *)SMB_REALLOC(
3024 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3025 if (*ppdata
== NULL
) {
3026 return NT_STATUS_NO_MEMORY
;
3030 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3031 end_data
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
3033 switch (info_level
) {
3034 case SMB_INFO_ALLOCATION
:
3036 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3038 if (get_dfree_info(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3039 return map_nt_error_from_unix(errno
);
3042 block_size
= lp_block_size(snum
);
3043 if (bsize
< block_size
) {
3044 uint64_t factor
= block_size
/bsize
;
3049 if (bsize
> block_size
) {
3050 uint64_t factor
= bsize
/block_size
;
3055 bytes_per_sector
= 512;
3056 sectors_per_unit
= bsize
/bytes_per_sector
;
3058 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3059 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_ex_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3060 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3062 SIVAL(pdata
,l1_idFileSystem
,st
.st_ex_dev
);
3063 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
3064 SIVAL(pdata
,l1_cUnit
,dsize
);
3065 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
3066 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
3070 case SMB_INFO_VOLUME
:
3071 /* Return volume name */
3073 * Add volume serial number - hash of a combination of
3074 * the called hostname and the service name.
3076 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
3078 * Win2k3 and previous mess this up by sending a name length
3079 * one byte short. I believe only older clients (OS/2 Win9x) use
3080 * this call so try fixing this by adding a terminating null to
3081 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3085 pdata
+l2_vol_szVolLabel
, vname
,
3086 PTR_DIFF(end_data
, pdata
+l2_vol_szVolLabel
),
3087 STR_NOALIGN
|STR_TERMINATE
);
3088 SCVAL(pdata
,l2_vol_cch
,len
);
3089 data_len
= l2_vol_szVolLabel
+ len
;
3090 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
3091 (unsigned)convert_timespec_to_time_t(st
.st_ex_ctime
),
3095 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
3096 case SMB_FS_ATTRIBUTE_INFORMATION
:
3098 additional_flags
= 0;
3099 #if defined(HAVE_SYS_QUOTAS)
3100 additional_flags
|= FILE_VOLUME_QUOTAS
;
3103 if(lp_nt_acl_support(SNUM(conn
))) {
3104 additional_flags
|= FILE_PERSISTENT_ACLS
;
3107 /* Capabilities are filled in at connection time through STATVFS call */
3108 additional_flags
|= conn
->fs_capabilities
;
3109 additional_flags
|= lp_parm_int(conn
->params
->service
,
3110 "share", "fake_fscaps",
3113 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
3114 FILE_SUPPORTS_OBJECT_IDS
|FILE_UNICODE_ON_DISK
|
3115 additional_flags
); /* FS ATTRIBUTES */
3117 SIVAL(pdata
,4,255); /* Max filename component length */
3118 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3119 and will think we can't do long filenames */
3120 len
= srvstr_push(pdata
, flags2
, pdata
+12, fstype
,
3121 PTR_DIFF(end_data
, pdata
+12),
3124 data_len
= 12 + len
;
3127 case SMB_QUERY_FS_LABEL_INFO
:
3128 case SMB_FS_LABEL_INFORMATION
:
3129 len
= srvstr_push(pdata
, flags2
, pdata
+4, vname
,
3130 PTR_DIFF(end_data
, pdata
+4), 0);
3135 case SMB_QUERY_FS_VOLUME_INFO
:
3136 case SMB_FS_VOLUME_INFORMATION
:
3139 * Add volume serial number - hash of a combination of
3140 * the called hostname and the service name.
3142 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
3143 (str_checksum(get_local_machine_name())<<16));
3145 /* Max label len is 32 characters. */
3146 len
= srvstr_push(pdata
, flags2
, pdata
+18, vname
,
3147 PTR_DIFF(end_data
, pdata
+18),
3149 SIVAL(pdata
,12,len
);
3152 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3153 (int)strlen(vname
),vname
, lp_servicename(snum
)));
3156 case SMB_QUERY_FS_SIZE_INFO
:
3157 case SMB_FS_SIZE_INFORMATION
:
3159 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3161 if (get_dfree_info(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3162 return map_nt_error_from_unix(errno
);
3164 block_size
= lp_block_size(snum
);
3165 if (bsize
< block_size
) {
3166 uint64_t factor
= block_size
/bsize
;
3171 if (bsize
> block_size
) {
3172 uint64_t factor
= bsize
/block_size
;
3177 bytes_per_sector
= 512;
3178 sectors_per_unit
= bsize
/bytes_per_sector
;
3179 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3180 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3181 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3182 SBIG_UINT(pdata
,0,dsize
);
3183 SBIG_UINT(pdata
,8,dfree
);
3184 SIVAL(pdata
,16,sectors_per_unit
);
3185 SIVAL(pdata
,20,bytes_per_sector
);
3189 case SMB_FS_FULL_SIZE_INFORMATION
:
3191 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3193 if (get_dfree_info(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3194 return map_nt_error_from_unix(errno
);
3196 block_size
= lp_block_size(snum
);
3197 if (bsize
< block_size
) {
3198 uint64_t factor
= block_size
/bsize
;
3203 if (bsize
> block_size
) {
3204 uint64_t factor
= bsize
/block_size
;
3209 bytes_per_sector
= 512;
3210 sectors_per_unit
= bsize
/bytes_per_sector
;
3211 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3212 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3213 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3214 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
3215 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
3216 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
3217 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
3218 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
3222 case SMB_QUERY_FS_DEVICE_INFO
:
3223 case SMB_FS_DEVICE_INFORMATION
:
3225 uint32_t characteristics
= FILE_DEVICE_IS_MOUNTED
;
3227 if (!CAN_WRITE(conn
)) {
3228 characteristics
|= FILE_READ_ONLY_DEVICE
;
3231 SIVAL(pdata
,0,FILE_DEVICE_DISK
); /* dev type */
3232 SIVAL(pdata
,4,characteristics
);
3236 #ifdef HAVE_SYS_QUOTAS
3237 case SMB_FS_QUOTA_INFORMATION
:
3239 * what we have to send --metze:
3241 * Unknown1: 24 NULL bytes
3242 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3243 * Hard Quota Limit: 8 bytes seems like uint64_t or so
3244 * Quota Flags: 2 byte :
3245 * Unknown3: 6 NULL bytes
3249 * details for Quota Flags:
3251 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3252 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
3253 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3254 * 0x0001 Enable Quotas: enable quota for this fs
3258 /* we need to fake up a fsp here,
3259 * because its not send in this call
3262 SMB_NTQUOTA_STRUCT quotas
;
3265 ZERO_STRUCT(quotas
);
3268 fsp
.fnum
= FNUM_FIELD_INVALID
;
3271 if (get_current_uid(conn
) != 0) {
3272 DEBUG(0,("set_user_quota: access_denied "
3273 "service [%s] user [%s]\n",
3274 lp_servicename(SNUM(conn
)),
3275 conn
->session_info
->unix_info
->unix_name
));
3276 return NT_STATUS_ACCESS_DENIED
;
3279 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3280 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3281 return map_nt_error_from_unix(errno
);
3286 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3287 lp_servicename(SNUM(conn
))));
3289 /* Unknown1 24 NULL bytes*/
3290 SBIG_UINT(pdata
,0,(uint64_t)0);
3291 SBIG_UINT(pdata
,8,(uint64_t)0);
3292 SBIG_UINT(pdata
,16,(uint64_t)0);
3294 /* Default Soft Quota 8 bytes */
3295 SBIG_UINT(pdata
,24,quotas
.softlim
);
3297 /* Default Hard Quota 8 bytes */
3298 SBIG_UINT(pdata
,32,quotas
.hardlim
);
3300 /* Quota flag 2 bytes */
3301 SSVAL(pdata
,40,quotas
.qflags
);
3303 /* Unknown3 6 NULL bytes */
3309 #endif /* HAVE_SYS_QUOTAS */
3310 case SMB_FS_OBJECTID_INFORMATION
:
3312 unsigned char objid
[16];
3313 struct smb_extended_info extended_info
;
3314 memcpy(pdata
,create_volume_objectid(conn
, objid
),16);
3315 samba_extended_info_version (&extended_info
);
3316 SIVAL(pdata
,16,extended_info
.samba_magic
);
3317 SIVAL(pdata
,20,extended_info
.samba_version
);
3318 SIVAL(pdata
,24,extended_info
.samba_subversion
);
3319 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
3320 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
3326 * Query the version and capabilities of the CIFS UNIX extensions
3330 case SMB_QUERY_CIFS_UNIX_INFO
:
3332 bool large_write
= lp_min_receive_file_size() &&
3333 !srv_is_signing_active(conn
->sconn
);
3334 bool large_read
= !srv_is_signing_active(conn
->sconn
);
3335 int encrypt_caps
= 0;
3337 if (!lp_unix_extensions()) {
3338 return NT_STATUS_INVALID_LEVEL
;
3341 switch (conn
->encrypt_level
) {
3347 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
;
3350 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
|
3351 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP
;
3352 large_write
= false;
3358 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
3359 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
3361 /* We have POSIX ACLs, pathname, encryption,
3362 * large read/write, and locking capability. */
3364 SBIG_UINT(pdata
,4,((uint64_t)(
3365 CIFS_UNIX_POSIX_ACLS_CAP
|
3366 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
3367 CIFS_UNIX_FCNTL_LOCKS_CAP
|
3368 CIFS_UNIX_EXTATTR_CAP
|
3369 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
|
3371 (large_read
? CIFS_UNIX_LARGE_READ_CAP
: 0) |
3373 CIFS_UNIX_LARGE_WRITE_CAP
: 0))));
3377 case SMB_QUERY_POSIX_FS_INFO
:
3380 vfs_statvfs_struct svfs
;
3382 if (!lp_unix_extensions()) {
3383 return NT_STATUS_INVALID_LEVEL
;
3386 rc
= SMB_VFS_STATVFS(conn
, ".", &svfs
);
3390 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
3391 SIVAL(pdata
,4,svfs
.BlockSize
);
3392 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
3393 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
3394 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
3395 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
3396 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
3397 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
3398 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3400 } else if (rc
== EOPNOTSUPP
) {
3401 return NT_STATUS_INVALID_LEVEL
;
3402 #endif /* EOPNOTSUPP */
3404 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3405 return NT_STATUS_DOS(ERRSRV
, ERRerror
);
3410 case SMB_QUERY_POSIX_WHOAMI
:
3416 if (!lp_unix_extensions()) {
3417 return NT_STATUS_INVALID_LEVEL
;
3420 if (max_data_bytes
< 40) {
3421 return NT_STATUS_BUFFER_TOO_SMALL
;
3424 if (security_session_user_level(conn
->session_info
, NULL
) < SECURITY_USER
) {
3425 flags
|= SMB_WHOAMI_GUEST
;
3428 /* NOTE: 8 bytes for UID/GID, irrespective of native
3429 * platform size. This matches
3430 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3432 data_len
= 4 /* flags */
3439 + 4 /* pad/reserved */
3440 + (conn
->session_info
->unix_token
->ngroups
* 8)
3442 + (conn
->session_info
->security_token
->num_sids
*
3446 SIVAL(pdata
, 0, flags
);
3447 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
3449 (uint64_t)conn
->session_info
->unix_token
->uid
);
3450 SBIG_UINT(pdata
, 16,
3451 (uint64_t)conn
->session_info
->unix_token
->gid
);
3454 if (data_len
>= max_data_bytes
) {
3455 /* Potential overflow, skip the GIDs and SIDs. */
3457 SIVAL(pdata
, 24, 0); /* num_groups */
3458 SIVAL(pdata
, 28, 0); /* num_sids */
3459 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
3460 SIVAL(pdata
, 36, 0); /* reserved */
3466 SIVAL(pdata
, 24, conn
->session_info
->unix_token
->ngroups
);
3467 SIVAL(pdata
, 28, conn
->session_info
->security_token
->num_sids
);
3469 /* We walk the SID list twice, but this call is fairly
3470 * infrequent, and I don't expect that it's performance
3471 * sensitive -- jpeach
3473 for (i
= 0, sid_bytes
= 0;
3474 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3475 sid_bytes
+= ndr_size_dom_sid(
3476 &conn
->session_info
->security_token
->sids
[i
],
3480 /* SID list byte count */
3481 SIVAL(pdata
, 32, sid_bytes
);
3483 /* 4 bytes pad/reserved - must be zero */
3484 SIVAL(pdata
, 36, 0);
3488 for (i
= 0; i
< conn
->session_info
->unix_token
->ngroups
; ++i
) {
3489 SBIG_UINT(pdata
, data_len
,
3490 (uint64_t)conn
->session_info
->unix_token
->groups
[i
]);
3496 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3497 int sid_len
= ndr_size_dom_sid(
3498 &conn
->session_info
->security_token
->sids
[i
],
3501 sid_linearize(pdata
+ data_len
, sid_len
,
3502 &conn
->session_info
->security_token
->sids
[i
]);
3503 data_len
+= sid_len
;
3509 case SMB_MAC_QUERY_FS_INFO
:
3511 * Thursby MAC extension... ONLY on NTFS filesystems
3512 * once we do streams then we don't need this
3514 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
3516 SIVAL(pdata
,84,0x100); /* Don't support mac... */
3521 return NT_STATUS_INVALID_LEVEL
;
3524 *ret_data_len
= data_len
;
3525 return NT_STATUS_OK
;
3528 /****************************************************************************
3529 Reply to a TRANS2_QFSINFO (query filesystem info).
3530 ****************************************************************************/
3532 static void call_trans2qfsinfo(connection_struct
*conn
,
3533 struct smb_request
*req
,
3534 char **pparams
, int total_params
,
3535 char **ppdata
, int total_data
,
3536 unsigned int max_data_bytes
)
3538 char *params
= *pparams
;
3539 uint16_t info_level
;
3543 if (total_params
< 2) {
3544 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3548 info_level
= SVAL(params
,0);
3550 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3551 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3552 DEBUG(0,("call_trans2qfsinfo: encryption required "
3553 "and info level 0x%x sent.\n",
3554 (unsigned int)info_level
));
3555 exit_server_cleanly("encryption required "
3561 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
3563 status
= smbd_do_qfsinfo(conn
, req
,
3568 if (!NT_STATUS_IS_OK(status
)) {
3569 reply_nterror(req
, status
);
3573 send_trans2_replies(conn
, req
, params
, 0, *ppdata
, data_len
,
3576 DEBUG( 4, ( "%s info_level = %d\n",
3577 smb_fn_name(req
->cmd
), info_level
) );
3582 /****************************************************************************
3583 Reply to a TRANS2_SETFSINFO (set filesystem info).
3584 ****************************************************************************/
3586 static void call_trans2setfsinfo(connection_struct
*conn
,
3587 struct smb_request
*req
,
3588 char **pparams
, int total_params
,
3589 char **ppdata
, int total_data
,
3590 unsigned int max_data_bytes
)
3592 struct smbd_server_connection
*sconn
= req
->sconn
;
3593 char *pdata
= *ppdata
;
3594 char *params
= *pparams
;
3597 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn
))));
3600 if (total_params
< 4) {
3601 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3603 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3607 info_level
= SVAL(params
,2);
3610 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
&&
3611 info_level
!= SMB_SET_CIFS_UNIX_INFO
) {
3612 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3613 "info level (0x%x) on IPC$.\n",
3614 (unsigned int)info_level
));
3615 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3620 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3621 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
) {
3622 DEBUG(0,("call_trans2setfsinfo: encryption required "
3623 "and info level 0x%x sent.\n",
3624 (unsigned int)info_level
));
3625 exit_server_cleanly("encryption required "
3631 switch(info_level
) {
3632 case SMB_SET_CIFS_UNIX_INFO
:
3633 if (!lp_unix_extensions()) {
3634 DEBUG(2,("call_trans2setfsinfo: "
3635 "SMB_SET_CIFS_UNIX_INFO is invalid with "
3636 "unix extensions off\n"));
3638 NT_STATUS_INVALID_LEVEL
);
3642 /* There should be 12 bytes of capabilities set. */
3643 if (total_data
< 12) {
3646 NT_STATUS_INVALID_PARAMETER
);
3649 sconn
->smb1
.unix_info
.client_major
= SVAL(pdata
,0);
3650 sconn
->smb1
.unix_info
.client_minor
= SVAL(pdata
,2);
3651 sconn
->smb1
.unix_info
.client_cap_low
= IVAL(pdata
,4);
3652 sconn
->smb1
.unix_info
.client_cap_high
= IVAL(pdata
,8);
3653 /* Just print these values for now. */
3654 DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
3655 "major = %u, minor = %u cap_low = 0x%x, "
3657 (unsigned int)sconn
->
3658 smb1
.unix_info
.client_major
,
3659 (unsigned int)sconn
->
3660 smb1
.unix_info
.client_minor
,
3661 (unsigned int)sconn
->
3662 smb1
.unix_info
.client_cap_low
,
3663 (unsigned int)sconn
->
3664 smb1
.unix_info
.client_cap_high
));
3666 /* Here is where we must switch to posix pathname processing... */
3667 if (sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
3668 lp_set_posix_pathnames();
3669 mangle_change_to_posix();
3672 if ((sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_FCNTL_LOCKS_CAP
) &&
3673 !(sconn
->smb1
.unix_info
.client_cap_low
& CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)) {
3674 /* Client that knows how to do posix locks,
3675 * but not posix open/mkdir operations. Set a
3676 * default type for read/write checks. */
3678 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK
);
3683 case SMB_REQUEST_TRANSPORT_ENCRYPTION
:
3686 size_t param_len
= 0;
3687 size_t data_len
= total_data
;
3689 if (!lp_unix_extensions()) {
3692 NT_STATUS_INVALID_LEVEL
);
3696 if (lp_smb_encrypt(SNUM(conn
)) == false) {
3699 NT_STATUS_NOT_SUPPORTED
);
3703 if (req
->sconn
->smb1
.echo_handler
.trusted_fde
) {
3704 DEBUG( 2,("call_trans2setfsinfo: "
3705 "request transport encryption disabled"
3706 "with 'fork echo handler = yes'\n"));
3709 NT_STATUS_NOT_SUPPORTED
);
3713 DEBUG( 4,("call_trans2setfsinfo: "
3714 "request transport encryption.\n"));
3716 status
= srv_request_encryption_setup(conn
,
3717 (unsigned char **)ppdata
,
3719 (unsigned char **)pparams
,
3722 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
3723 !NT_STATUS_IS_OK(status
)) {
3724 reply_nterror(req
, status
);
3728 send_trans2_replies(conn
, req
,
3735 if (NT_STATUS_IS_OK(status
)) {
3736 /* Server-side transport
3737 * encryption is now *on*. */
3738 status
= srv_encryption_start(conn
);
3739 if (!NT_STATUS_IS_OK(status
)) {
3740 char *reason
= talloc_asprintf(talloc_tos(),
3741 "Failure in setting "
3742 "up encrypted transport: %s",
3744 exit_server_cleanly(reason
);
3750 case SMB_FS_QUOTA_INFORMATION
:
3752 files_struct
*fsp
= NULL
;
3753 SMB_NTQUOTA_STRUCT quotas
;
3755 ZERO_STRUCT(quotas
);
3758 if ((get_current_uid(conn
) != 0) || !CAN_WRITE(conn
)) {
3759 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3760 lp_servicename(SNUM(conn
)),
3761 conn
->session_info
->unix_info
->unix_name
));
3762 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3766 /* note: normaly there're 48 bytes,
3767 * but we didn't use the last 6 bytes for now
3770 fsp
= file_fsp(req
, SVAL(params
,0));
3772 if (!check_fsp_ntquota_handle(conn
, req
,
3774 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3776 req
, NT_STATUS_INVALID_HANDLE
);
3780 if (total_data
< 42) {
3781 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3785 NT_STATUS_INVALID_PARAMETER
);
3789 /* unknown_1 24 NULL bytes in pdata*/
3791 /* the soft quotas 8 bytes (uint64_t)*/
3792 quotas
.softlim
= BVAL(pdata
,24);
3794 /* the hard quotas 8 bytes (uint64_t)*/
3795 quotas
.hardlim
= BVAL(pdata
,32);
3797 /* quota_flags 2 bytes **/
3798 quotas
.qflags
= SVAL(pdata
,40);
3800 /* unknown_2 6 NULL bytes follow*/
3802 /* now set the quotas */
3803 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3804 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3805 reply_nterror(req
, map_nt_error_from_unix(errno
));
3812 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3814 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
3820 * sending this reply works fine,
3821 * but I'm not sure it's the same
3822 * like windows do...
3825 reply_outbuf(req
, 10, 0);
3828 #if defined(HAVE_POSIX_ACLS)
3829 /****************************************************************************
3830 Utility function to count the number of entries in a POSIX acl.
3831 ****************************************************************************/
3833 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
3835 unsigned int ace_count
= 0;
3836 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3837 SMB_ACL_ENTRY_T entry
;
3839 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
3841 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3842 entry_id
= SMB_ACL_NEXT_ENTRY
;
3849 /****************************************************************************
3850 Utility function to marshall a POSIX acl into wire format.
3851 ****************************************************************************/
3853 static bool marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
3855 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3856 SMB_ACL_ENTRY_T entry
;
3858 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
3859 SMB_ACL_TAG_T tagtype
;
3860 SMB_ACL_PERMSET_T permset
;
3861 unsigned char perms
= 0;
3862 unsigned int own_grp
;
3865 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3866 entry_id
= SMB_ACL_NEXT_ENTRY
;
3869 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn
, entry
, &tagtype
) == -1) {
3870 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3874 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn
, entry
, &permset
) == -1) {
3875 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3879 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
3880 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
3881 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
3883 SCVAL(pdata
,1,perms
);
3886 case SMB_ACL_USER_OBJ
:
3887 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
3888 own_grp
= (unsigned int)pst
->st_ex_uid
;
3889 SIVAL(pdata
,2,own_grp
);
3894 uid_t
*puid
= (uid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
3896 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3899 own_grp
= (unsigned int)*puid
;
3900 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)puid
,tagtype
);
3901 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
3902 SIVAL(pdata
,2,own_grp
);
3906 case SMB_ACL_GROUP_OBJ
:
3907 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
3908 own_grp
= (unsigned int)pst
->st_ex_gid
;
3909 SIVAL(pdata
,2,own_grp
);
3914 gid_t
*pgid
= (gid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
3916 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3919 own_grp
= (unsigned int)*pgid
;
3920 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)pgid
,tagtype
);
3921 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
3922 SIVAL(pdata
,2,own_grp
);
3927 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
3928 SIVAL(pdata
,2,0xFFFFFFFF);
3929 SIVAL(pdata
,6,0xFFFFFFFF);
3932 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
3933 SIVAL(pdata
,2,0xFFFFFFFF);
3934 SIVAL(pdata
,6,0xFFFFFFFF);
3937 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
3940 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
3947 /****************************************************************************
3948 Store the FILE_UNIX_BASIC info.
3949 ****************************************************************************/
3951 static char *store_file_unix_basic(connection_struct
*conn
,
3954 const SMB_STRUCT_STAT
*psbuf
)
3956 uint64_t file_index
= get_FileIndex(conn
, psbuf
);
3959 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
3960 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_ex_mode
));
3962 SOFF_T(pdata
,0,get_file_size_stat(psbuf
)); /* File size 64 Bit */
3965 SOFF_T(pdata
,0,SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
3968 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
, psbuf
->st_ex_ctime
); /* Change Time 64 Bit */
3969 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
+8, psbuf
->st_ex_atime
); /* Last access time 64 Bit */
3970 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
+16, psbuf
->st_ex_mtime
); /* Last modification time 64 Bit */
3973 SIVAL(pdata
,0,psbuf
->st_ex_uid
); /* user id for the owner */
3977 SIVAL(pdata
,0,psbuf
->st_ex_gid
); /* group id of owner */
3981 SIVAL(pdata
,0,unix_filetype(psbuf
->st_ex_mode
));
3984 if (S_ISBLK(psbuf
->st_ex_mode
) || S_ISCHR(psbuf
->st_ex_mode
)) {
3985 devno
= psbuf
->st_ex_rdev
;
3987 devno
= psbuf
->st_ex_dev
;
3990 SIVAL(pdata
,0,unix_dev_major(devno
)); /* Major device number if type is device */
3994 SIVAL(pdata
,0,unix_dev_minor(devno
)); /* Minor device number if type is device */
3998 SINO_T_VAL(pdata
,0,(SMB_INO_T
)file_index
); /* inode number */
4001 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_ex_mode
)); /* Standard UNIX file permissions */
4005 SIVAL(pdata
,0,psbuf
->st_ex_nlink
); /* number of hard links */
4012 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4013 * the chflags(2) (or equivalent) flags.
4015 * XXX: this really should be behind the VFS interface. To do this, we would
4016 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4017 * Each VFS module could then implement its own mapping as appropriate for the
4018 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4020 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
4024 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
4028 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
4032 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
4036 { UF_HIDDEN
, EXT_HIDDEN
},
4039 /* Do not remove. We need to guarantee that this array has at least one
4040 * entry to build on HP-UX.
4046 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4047 uint32
*smb_fflags
, uint32
*smb_fmask
)
4051 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4052 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
4053 if (psbuf
->st_ex_flags
& info2_flags_map
[i
].stat_fflag
) {
4054 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
4059 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4060 const uint32 smb_fflags
,
4061 const uint32 smb_fmask
,
4064 uint32 max_fmask
= 0;
4067 *stat_fflags
= psbuf
->st_ex_flags
;
4069 /* For each flags requested in smb_fmask, check the state of the
4070 * corresponding flag in smb_fflags and set or clear the matching
4074 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4075 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
4076 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
4077 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
4078 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
4080 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
4085 /* If smb_fmask is asking to set any bits that are not supported by
4086 * our flag mappings, we should fail.
4088 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
4096 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4097 * of file flags and birth (create) time.
4099 static char *store_file_unix_basic_info2(connection_struct
*conn
,
4102 const SMB_STRUCT_STAT
*psbuf
)
4104 uint32 file_flags
= 0;
4105 uint32 flags_mask
= 0;
4107 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4109 /* Create (birth) time 64 bit */
4110 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
, psbuf
->st_ex_btime
);
4113 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
4114 SIVAL(pdata
, 0, file_flags
); /* flags */
4115 SIVAL(pdata
, 4, flags_mask
); /* mask */
4121 static NTSTATUS
marshall_stream_info(unsigned int num_streams
,
4122 const struct stream_struct
*streams
,
4124 unsigned int max_data_bytes
,
4125 unsigned int *data_size
)
4128 unsigned int ofs
= 0;
4130 for (i
= 0; i
< num_streams
&& ofs
<= max_data_bytes
; i
++) {
4131 unsigned int next_offset
;
4133 smb_ucs2_t
*namebuf
;
4135 if (!push_ucs2_talloc(talloc_tos(), &namebuf
,
4136 streams
[i
].name
, &namelen
) ||
4139 return NT_STATUS_INVALID_PARAMETER
;
4143 * name_buf is now null-terminated, we need to marshall as not
4149 SIVAL(data
, ofs
+4, namelen
);
4150 SOFF_T(data
, ofs
+8, streams
[i
].size
);
4151 SOFF_T(data
, ofs
+16, streams
[i
].alloc_size
);
4152 memcpy(data
+ofs
+24, namebuf
, namelen
);
4153 TALLOC_FREE(namebuf
);
4155 next_offset
= ofs
+ 24 + namelen
;
4157 if (i
== num_streams
-1) {
4158 SIVAL(data
, ofs
, 0);
4161 unsigned int align
= ndr_align_size(next_offset
, 8);
4163 memset(data
+next_offset
, 0, align
);
4164 next_offset
+= align
;
4166 SIVAL(data
, ofs
, next_offset
- ofs
);
4175 return NT_STATUS_OK
;
4178 /****************************************************************************
4179 Reply to a TRANSACT2_QFILEINFO on a PIPE !
4180 ****************************************************************************/
4182 static void call_trans2qpipeinfo(connection_struct
*conn
,
4183 struct smb_request
*req
,
4184 unsigned int tran_call
,
4185 char **pparams
, int total_params
,
4186 char **ppdata
, int total_data
,
4187 unsigned int max_data_bytes
)
4189 char *params
= *pparams
;
4190 char *pdata
= *ppdata
;
4191 unsigned int data_size
= 0;
4192 unsigned int param_size
= 2;
4197 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4201 if (total_params
< 4) {
4202 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4206 fsp
= file_fsp(req
, SVAL(params
,0));
4207 if (!fsp_is_np(fsp
)) {
4208 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
4212 info_level
= SVAL(params
,2);
4214 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
4215 if (*pparams
== NULL
) {
4216 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4221 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4222 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4223 if (*ppdata
== NULL
) {
4224 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4229 switch (info_level
) {
4230 case SMB_FILE_STANDARD_INFORMATION
:
4232 SOFF_T(pdata
,0,4096LL);
4239 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
4243 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
4249 NTSTATUS
smbd_do_qfilepathinfo(connection_struct
*conn
,
4250 TALLOC_CTX
*mem_ctx
,
4251 uint16_t info_level
,
4253 struct smb_filename
*smb_fname
,
4254 bool delete_pending
,
4255 struct timespec write_time_ts
,
4256 struct ea_list
*ea_list
,
4257 int lock_data_count
,
4260 unsigned int max_data_bytes
,
4262 unsigned int *pdata_size
)
4264 char *pdata
= *ppdata
;
4265 char *dstart
, *dend
;
4266 unsigned int data_size
;
4267 struct timespec create_time_ts
, mtime_ts
, atime_ts
, ctime_ts
;
4268 time_t create_time
, mtime
, atime
, c_time
;
4269 SMB_STRUCT_STAT
*psbuf
= &smb_fname
->st
;
4276 uint64_t file_size
= 0;
4278 uint64_t allocation_size
= 0;
4279 uint64_t file_index
= 0;
4280 uint32_t access_mask
= 0;
4282 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
4283 return NT_STATUS_INVALID_LEVEL
;
4286 DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
4287 smb_fname_str_dbg(smb_fname
),
4289 info_level
, max_data_bytes
));
4291 mode
= dos_mode(conn
, smb_fname
);
4292 nlink
= psbuf
->st_ex_nlink
;
4294 if (nlink
&& (mode
&FILE_ATTRIBUTE_DIRECTORY
)) {
4298 if ((nlink
> 0) && delete_pending
) {
4302 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4303 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4304 if (*ppdata
== NULL
) {
4305 return NT_STATUS_NO_MEMORY
;
4309 dend
= dstart
+ data_size
- 1;
4311 if (!null_timespec(write_time_ts
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
4312 update_stat_ex_mtime(psbuf
, write_time_ts
);
4315 create_time_ts
= get_create_timespec(conn
, fsp
, smb_fname
);
4316 mtime_ts
= psbuf
->st_ex_mtime
;
4317 atime_ts
= psbuf
->st_ex_atime
;
4318 ctime_ts
= get_change_timespec(conn
, fsp
, smb_fname
);
4320 if (lp_dos_filetime_resolution(SNUM(conn
))) {
4321 dos_filetime_timespec(&create_time_ts
);
4322 dos_filetime_timespec(&mtime_ts
);
4323 dos_filetime_timespec(&atime_ts
);
4324 dos_filetime_timespec(&ctime_ts
);
4327 create_time
= convert_timespec_to_time_t(create_time_ts
);
4328 mtime
= convert_timespec_to_time_t(mtime_ts
);
4329 atime
= convert_timespec_to_time_t(atime_ts
);
4330 c_time
= convert_timespec_to_time_t(ctime_ts
);
4332 p
= strrchr_m(smb_fname
->base_name
,'/');
4334 base_name
= smb_fname
->base_name
;
4338 /* NT expects the name to be in an exact form of the *full*
4339 filename. See the trans2 torture test */
4340 if (ISDOT(base_name
)) {
4341 dos_fname
= talloc_strdup(mem_ctx
, "\\");
4343 return NT_STATUS_NO_MEMORY
;
4346 dos_fname
= talloc_asprintf(mem_ctx
,
4348 smb_fname
->base_name
);
4350 return NT_STATUS_NO_MEMORY
;
4352 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4353 dos_fname
= talloc_asprintf(dos_fname
, "%s",
4354 smb_fname
->stream_name
);
4356 return NT_STATUS_NO_MEMORY
;
4360 string_replace(dos_fname
, '/', '\\');
4363 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, psbuf
);
4366 /* Do we have this path open ? */
4368 struct file_id fileid
= vfs_file_id_from_sbuf(conn
, psbuf
);
4369 fsp1
= file_find_di_first(conn
->sconn
, fileid
);
4370 if (fsp1
&& fsp1
->initial_allocation_size
) {
4371 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp1
, psbuf
);
4375 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
4376 file_size
= get_file_size_stat(psbuf
);
4380 pos
= fsp
->fh
->position_information
;
4384 access_mask
= fsp
->access_mask
;
4386 /* GENERIC_EXECUTE mapping from Windows */
4387 access_mask
= 0x12019F;
4390 /* This should be an index number - looks like
4393 I think this causes us to fail the IFSKIT
4394 BasicFileInformationTest. -tpot */
4395 file_index
= get_FileIndex(conn
, psbuf
);
4397 switch (info_level
) {
4398 case SMB_INFO_STANDARD
:
4399 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4401 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
4402 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
4403 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
4404 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
4405 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
4406 SSVAL(pdata
,l1_attrFile
,mode
);
4409 case SMB_INFO_QUERY_EA_SIZE
:
4411 unsigned int ea_size
=
4412 estimate_ea_size(conn
, fsp
,
4413 smb_fname
->base_name
);
4414 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4416 srv_put_dos_date2(pdata
,0,create_time
);
4417 srv_put_dos_date2(pdata
,4,atime
);
4418 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
4419 SIVAL(pdata
,12,(uint32
)file_size
);
4420 SIVAL(pdata
,16,(uint32
)allocation_size
);
4421 SSVAL(pdata
,20,mode
);
4422 SIVAL(pdata
,22,ea_size
);
4426 case SMB_INFO_IS_NAME_VALID
:
4427 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4429 /* os/2 needs this ? really ?*/
4430 return NT_STATUS_DOS(ERRDOS
, ERRbadfunc
);
4432 /* This is only reached for qpathinfo */
4436 case SMB_INFO_QUERY_EAS_FROM_LIST
:
4438 size_t total_ea_len
= 0;
4439 struct ea_list
*ea_file_list
= NULL
;
4441 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4444 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4445 smb_fname
->base_name
,
4447 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
4449 if (!ea_list
|| (total_ea_len
> data_size
)) {
4451 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4455 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4459 case SMB_INFO_QUERY_ALL_EAS
:
4461 /* We have data_size bytes to put EA's into. */
4462 size_t total_ea_len
= 0;
4464 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4466 ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4467 smb_fname
->base_name
,
4469 if (!ea_list
|| (total_ea_len
> data_size
)) {
4471 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4475 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4479 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4481 /* This is FileFullEaInformation - 0xF which maps to
4482 * 1015 (decimal) in smbd_do_setfilepathinfo. */
4484 /* We have data_size bytes to put EA's into. */
4485 size_t total_ea_len
= 0;
4486 struct ea_list
*ea_file_list
= NULL
;
4488 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4490 /*TODO: add filtering and index handling */
4493 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4494 smb_fname
->base_name
,
4496 if (!ea_file_list
) {
4497 return NT_STATUS_NO_EAS_ON_FILE
;
4500 status
= fill_ea_chained_buffer(mem_ctx
,
4504 conn
, ea_file_list
);
4505 if (!NT_STATUS_IS_OK(status
)) {
4511 case SMB_FILE_BASIC_INFORMATION
:
4512 case SMB_QUERY_FILE_BASIC_INFO
:
4514 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
4515 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4516 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
4518 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4522 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4523 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4524 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4525 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4526 SIVAL(pdata
,32,mode
);
4528 DEBUG(5,("SMB_QFBI - "));
4529 DEBUG(5,("create: %s ", ctime(&create_time
)));
4530 DEBUG(5,("access: %s ", ctime(&atime
)));
4531 DEBUG(5,("write: %s ", ctime(&mtime
)));
4532 DEBUG(5,("change: %s ", ctime(&c_time
)));
4533 DEBUG(5,("mode: %x\n", mode
));
4536 case SMB_FILE_STANDARD_INFORMATION
:
4537 case SMB_QUERY_FILE_STANDARD_INFO
:
4539 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4541 SOFF_T(pdata
,0,allocation_size
);
4542 SOFF_T(pdata
,8,file_size
);
4543 SIVAL(pdata
,16,nlink
);
4544 SCVAL(pdata
,20,delete_pending
?1:0);
4545 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4546 SSVAL(pdata
,22,0); /* Padding. */
4549 case SMB_FILE_EA_INFORMATION
:
4550 case SMB_QUERY_FILE_EA_INFO
:
4552 unsigned int ea_size
=
4553 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4554 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4556 SIVAL(pdata
,0,ea_size
);
4560 /* Get the 8.3 name - used if NT SMB was negotiated. */
4561 case SMB_QUERY_FILE_ALT_NAME_INFO
:
4562 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
4565 char mangled_name
[13];
4566 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4567 if (!name_to_8_3(base_name
,mangled_name
,
4568 True
,conn
->params
)) {
4569 return NT_STATUS_NO_MEMORY
;
4571 len
= srvstr_push(dstart
, flags2
,
4572 pdata
+4, mangled_name
,
4573 PTR_DIFF(dend
, pdata
+4),
4575 data_size
= 4 + len
;
4580 case SMB_QUERY_FILE_NAME_INFO
:
4584 this must be *exactly* right for ACLs on mapped drives to work
4586 len
= srvstr_push(dstart
, flags2
,
4588 PTR_DIFF(dend
, pdata
+4),
4590 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4591 data_size
= 4 + len
;
4596 case SMB_FILE_ALLOCATION_INFORMATION
:
4597 case SMB_QUERY_FILE_ALLOCATION_INFO
:
4598 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4600 SOFF_T(pdata
,0,allocation_size
);
4603 case SMB_FILE_END_OF_FILE_INFORMATION
:
4604 case SMB_QUERY_FILE_END_OF_FILEINFO
:
4605 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4607 SOFF_T(pdata
,0,file_size
);
4610 case SMB_QUERY_FILE_ALL_INFO
:
4611 case SMB_FILE_ALL_INFORMATION
:
4614 unsigned int ea_size
=
4615 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4616 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4617 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4618 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4619 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4620 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4621 SIVAL(pdata
,32,mode
);
4622 SIVAL(pdata
,36,0); /* padding. */
4624 SOFF_T(pdata
,0,allocation_size
);
4625 SOFF_T(pdata
,8,file_size
);
4626 SIVAL(pdata
,16,nlink
);
4627 SCVAL(pdata
,20,delete_pending
);
4628 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4631 SIVAL(pdata
,0,ea_size
);
4632 pdata
+= 4; /* EA info */
4633 len
= srvstr_push(dstart
, flags2
,
4635 PTR_DIFF(dend
, pdata
+4),
4639 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4643 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4646 unsigned int ea_size
=
4647 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4648 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4649 put_long_date_timespec(conn
->ts_res
,pdata
+0x00,create_time_ts
);
4650 put_long_date_timespec(conn
->ts_res
,pdata
+0x08,atime_ts
);
4651 put_long_date_timespec(conn
->ts_res
,pdata
+0x10,mtime_ts
); /* write time */
4652 put_long_date_timespec(conn
->ts_res
,pdata
+0x18,ctime_ts
); /* change time */
4653 SIVAL(pdata
, 0x20, mode
);
4654 SIVAL(pdata
, 0x24, 0); /* padding. */
4655 SBVAL(pdata
, 0x28, allocation_size
);
4656 SBVAL(pdata
, 0x30, file_size
);
4657 SIVAL(pdata
, 0x38, nlink
);
4658 SCVAL(pdata
, 0x3C, delete_pending
);
4659 SCVAL(pdata
, 0x3D, (mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4660 SSVAL(pdata
, 0x3E, 0); /* padding */
4661 SBVAL(pdata
, 0x40, file_index
);
4662 SIVAL(pdata
, 0x48, ea_size
);
4663 SIVAL(pdata
, 0x4C, access_mask
);
4664 SBVAL(pdata
, 0x50, pos
);
4665 SIVAL(pdata
, 0x58, mode
); /*TODO: mode != mode fix this!!! */
4666 SIVAL(pdata
, 0x5C, 0); /* No alignment needed. */
4670 len
= srvstr_push(dstart
, flags2
,
4672 PTR_DIFF(dend
, pdata
+4),
4676 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4679 case SMB_FILE_INTERNAL_INFORMATION
:
4681 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4682 SBVAL(pdata
, 0, file_index
);
4686 case SMB_FILE_ACCESS_INFORMATION
:
4687 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4688 SIVAL(pdata
, 0, access_mask
);
4692 case SMB_FILE_NAME_INFORMATION
:
4693 /* Pathname with leading '\'. */
4696 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
4697 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4698 SIVAL(pdata
,0,byte_len
);
4699 data_size
= 4 + byte_len
;
4703 case SMB_FILE_DISPOSITION_INFORMATION
:
4704 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4706 SCVAL(pdata
,0,delete_pending
);
4709 case SMB_FILE_POSITION_INFORMATION
:
4710 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4712 SOFF_T(pdata
,0,pos
);
4715 case SMB_FILE_MODE_INFORMATION
:
4716 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4717 SIVAL(pdata
,0,mode
);
4721 case SMB_FILE_ALIGNMENT_INFORMATION
:
4722 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4723 SIVAL(pdata
,0,0); /* No alignment needed. */
4728 * NT4 server just returns "invalid query" to this - if we try
4729 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4732 /* The first statement above is false - verified using Thursby
4733 * client against NT4 -- gcolley.
4735 case SMB_QUERY_FILE_STREAM_INFO
:
4736 case SMB_FILE_STREAM_INFORMATION
: {
4737 unsigned int num_streams
= 0;
4738 struct stream_struct
*streams
= NULL
;
4740 DEBUG(10,("smbd_do_qfilepathinfo: "
4741 "SMB_FILE_STREAM_INFORMATION\n"));
4743 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4744 return NT_STATUS_INVALID_PARAMETER
;
4747 status
= vfs_streaminfo(conn
, fsp
, smb_fname
->base_name
,
4748 talloc_tos(), &num_streams
, &streams
);
4750 if (!NT_STATUS_IS_OK(status
)) {
4751 DEBUG(10, ("could not get stream info: %s\n",
4752 nt_errstr(status
)));
4756 status
= marshall_stream_info(num_streams
, streams
,
4757 pdata
, max_data_bytes
,
4760 if (!NT_STATUS_IS_OK(status
)) {
4761 DEBUG(10, ("marshall_stream_info failed: %s\n",
4762 nt_errstr(status
)));
4766 TALLOC_FREE(streams
);
4770 case SMB_QUERY_COMPRESSION_INFO
:
4771 case SMB_FILE_COMPRESSION_INFORMATION
:
4772 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4773 SOFF_T(pdata
,0,file_size
);
4774 SIVAL(pdata
,8,0); /* ??? */
4775 SIVAL(pdata
,12,0); /* ??? */
4779 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
4780 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4781 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4782 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4783 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4784 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4785 SOFF_T(pdata
,32,allocation_size
);
4786 SOFF_T(pdata
,40,file_size
);
4787 SIVAL(pdata
,48,mode
);
4788 SIVAL(pdata
,52,0); /* ??? */
4792 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
4793 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4794 SIVAL(pdata
,0,mode
);
4800 * CIFS UNIX Extensions.
4803 case SMB_QUERY_FILE_UNIX_BASIC
:
4805 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4806 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4808 DEBUG(4,("smbd_do_qfilepathinfo: "
4809 "SMB_QUERY_FILE_UNIX_BASIC\n"));
4810 dump_data(4, (uint8_t *)(*ppdata
), data_size
);
4814 case SMB_QUERY_FILE_UNIX_INFO2
:
4816 pdata
= store_file_unix_basic_info2(conn
, pdata
, fsp
, psbuf
);
4817 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4821 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4823 for (i
=0; i
<100; i
++)
4824 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
4830 case SMB_QUERY_FILE_UNIX_LINK
:
4833 char *buffer
= talloc_array(mem_ctx
, char, PATH_MAX
+1);
4836 return NT_STATUS_NO_MEMORY
;
4839 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4841 if(!S_ISLNK(psbuf
->st_ex_mode
)) {
4842 return NT_STATUS_DOS(ERRSRV
, ERRbadlink
);
4845 return NT_STATUS_DOS(ERRDOS
, ERRbadlink
);
4847 len
= SMB_VFS_READLINK(conn
,
4848 smb_fname
->base_name
,
4851 return map_nt_error_from_unix(errno
);
4854 len
= srvstr_push(dstart
, flags2
,
4856 PTR_DIFF(dend
, pdata
),
4859 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4864 #if defined(HAVE_POSIX_ACLS)
4865 case SMB_QUERY_POSIX_ACL
:
4867 SMB_ACL_T file_acl
= NULL
;
4868 SMB_ACL_T def_acl
= NULL
;
4869 uint16 num_file_acls
= 0;
4870 uint16 num_def_acls
= 0;
4872 if (fsp
&& fsp
->fh
->fd
!= -1) {
4873 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
);
4876 SMB_VFS_SYS_ACL_GET_FILE(conn
,
4877 smb_fname
->base_name
,
4878 SMB_ACL_TYPE_ACCESS
);
4881 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
4882 DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4883 "not implemented on "
4884 "filesystem containing %s\n",
4885 smb_fname
->base_name
));
4886 return NT_STATUS_NOT_IMPLEMENTED
;
4889 if (S_ISDIR(psbuf
->st_ex_mode
)) {
4890 if (fsp
&& fsp
->is_directory
) {
4892 SMB_VFS_SYS_ACL_GET_FILE(
4894 fsp
->fsp_name
->base_name
,
4895 SMB_ACL_TYPE_DEFAULT
);
4898 SMB_VFS_SYS_ACL_GET_FILE(
4900 smb_fname
->base_name
,
4901 SMB_ACL_TYPE_DEFAULT
);
4903 def_acl
= free_empty_sys_acl(conn
, def_acl
);
4906 num_file_acls
= count_acl_entries(conn
, file_acl
);
4907 num_def_acls
= count_acl_entries(conn
, def_acl
);
4909 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
4910 DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
4912 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
4913 SMB_POSIX_ACL_HEADER_SIZE
) ));
4915 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4918 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4920 return NT_STATUS_BUFFER_TOO_SMALL
;
4923 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
4924 SSVAL(pdata
,2,num_file_acls
);
4925 SSVAL(pdata
,4,num_def_acls
);
4926 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, psbuf
, file_acl
)) {
4928 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4931 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4933 return NT_STATUS_INTERNAL_ERROR
;
4935 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), psbuf
, def_acl
)) {
4937 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4940 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4942 return NT_STATUS_INTERNAL_ERROR
;
4946 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4949 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4951 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
4957 case SMB_QUERY_POSIX_LOCK
:
4962 enum brl_type lock_type
;
4964 /* We need an open file with a real fd for this. */
4965 if (!fsp
|| fsp
->fh
->fd
== -1) {
4966 return NT_STATUS_INVALID_LEVEL
;
4969 if (lock_data_count
!= POSIX_LOCK_DATA_SIZE
) {
4970 return NT_STATUS_INVALID_PARAMETER
;
4973 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
4974 case POSIX_LOCK_TYPE_READ
:
4975 lock_type
= READ_LOCK
;
4977 case POSIX_LOCK_TYPE_WRITE
:
4978 lock_type
= WRITE_LOCK
;
4980 case POSIX_LOCK_TYPE_UNLOCK
:
4982 /* There's no point in asking for an unlock... */
4983 return NT_STATUS_INVALID_PARAMETER
;
4986 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
4987 #if defined(HAVE_LONGLONG)
4988 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
4989 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
4990 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
4991 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
4992 #else /* HAVE_LONGLONG */
4993 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
4994 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
4995 #endif /* HAVE_LONGLONG */
4997 status
= query_lock(fsp
,
5004 if (ERROR_WAS_LOCK_DENIED(status
)) {
5005 /* Here we need to report who has it locked... */
5006 data_size
= POSIX_LOCK_DATA_SIZE
;
5008 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, lock_type
);
5009 SSVAL(pdata
, POSIX_LOCK_FLAGS_OFFSET
, 0);
5010 SIVAL(pdata
, POSIX_LOCK_PID_OFFSET
, (uint32_t)smblctx
);
5011 #if defined(HAVE_LONGLONG)
5012 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, (uint32
)(offset
& 0xFFFFFFFF));
5013 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
+ 4, (uint32
)((offset
>> 32) & 0xFFFFFFFF));
5014 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, (uint32
)(count
& 0xFFFFFFFF));
5015 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
+ 4, (uint32
)((count
>> 32) & 0xFFFFFFFF));
5016 #else /* HAVE_LONGLONG */
5017 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, offset
);
5018 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, count
);
5019 #endif /* HAVE_LONGLONG */
5021 } else if (NT_STATUS_IS_OK(status
)) {
5022 /* For success we just return a copy of what we sent
5023 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5024 data_size
= POSIX_LOCK_DATA_SIZE
;
5025 memcpy(pdata
, lock_data
, POSIX_LOCK_DATA_SIZE
);
5026 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
5034 return NT_STATUS_INVALID_LEVEL
;
5037 *pdata_size
= data_size
;
5038 return NT_STATUS_OK
;
5041 /****************************************************************************
5042 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5043 file name or file id).
5044 ****************************************************************************/
5046 static void call_trans2qfilepathinfo(connection_struct
*conn
,
5047 struct smb_request
*req
,
5048 unsigned int tran_call
,
5049 char **pparams
, int total_params
,
5050 char **ppdata
, int total_data
,
5051 unsigned int max_data_bytes
)
5053 char *params
= *pparams
;
5054 char *pdata
= *ppdata
;
5056 unsigned int data_size
= 0;
5057 unsigned int param_size
= 2;
5058 struct smb_filename
*smb_fname
= NULL
;
5059 bool delete_pending
= False
;
5060 struct timespec write_time_ts
;
5061 files_struct
*fsp
= NULL
;
5062 struct file_id fileid
;
5063 struct ea_list
*ea_list
= NULL
;
5064 int lock_data_count
= 0;
5065 char *lock_data
= NULL
;
5066 NTSTATUS status
= NT_STATUS_OK
;
5069 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5073 ZERO_STRUCT(write_time_ts
);
5075 if (tran_call
== TRANSACT2_QFILEINFO
) {
5076 if (total_params
< 4) {
5077 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5082 call_trans2qpipeinfo(conn
, req
, tran_call
,
5083 pparams
, total_params
,
5089 fsp
= file_fsp(req
, SVAL(params
,0));
5090 info_level
= SVAL(params
,2);
5092 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
5094 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
5095 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5099 /* Initial check for valid fsp ptr. */
5100 if (!check_fsp_open(conn
, req
, fsp
)) {
5104 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
5106 if (!NT_STATUS_IS_OK(status
)) {
5107 reply_nterror(req
, status
);
5111 if(fsp
->fake_file_handle
) {
5113 * This is actually for the QUOTA_FAKE_FILE --metze
5116 /* We know this name is ok, it's already passed the checks. */
5118 } else if(fsp
->fh
->fd
== -1) {
5120 * This is actually a QFILEINFO on a directory
5121 * handle (returned from an NT SMB). NT5.0 seems
5122 * to do this call. JRA.
5125 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5126 /* Always do lstat for UNIX calls. */
5127 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5128 DEBUG(3,("call_trans2qfilepathinfo: "
5129 "SMB_VFS_LSTAT of %s failed "
5131 smb_fname_str_dbg(smb_fname
),
5134 map_nt_error_from_unix(errno
));
5137 } else if (SMB_VFS_STAT(conn
, smb_fname
)) {
5138 DEBUG(3,("call_trans2qfilepathinfo: "
5139 "SMB_VFS_STAT of %s failed (%s)\n",
5140 smb_fname_str_dbg(smb_fname
),
5143 map_nt_error_from_unix(errno
));
5147 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5148 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5151 * Original code - this is an open file.
5153 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
5154 DEBUG(3, ("fstat of %s failed (%s)\n",
5155 fsp_fnum_dbg(fsp
), strerror(errno
)));
5157 map_nt_error_from_unix(errno
));
5160 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5161 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5167 uint32_t ucf_flags
= 0;
5170 if (total_params
< 7) {
5171 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5175 info_level
= SVAL(params
,0);
5177 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
5179 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5180 if (!lp_unix_extensions()) {
5181 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5184 if (info_level
== SMB_QUERY_FILE_UNIX_BASIC
||
5185 info_level
== SMB_QUERY_FILE_UNIX_INFO2
||
5186 info_level
== SMB_QUERY_FILE_UNIX_LINK
) {
5187 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
5191 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
5193 STR_TERMINATE
, &status
);
5194 if (!NT_STATUS_IS_OK(status
)) {
5195 reply_nterror(req
, status
);
5199 status
= filename_convert(req
,
5201 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5206 if (!NT_STATUS_IS_OK(status
)) {
5207 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5208 reply_botherror(req
,
5209 NT_STATUS_PATH_NOT_COVERED
,
5210 ERRSRV
, ERRbadpath
);
5213 reply_nterror(req
, status
);
5217 /* If this is a stream, check if there is a delete_pending. */
5218 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5219 && is_ntfs_stream_smb_fname(smb_fname
)) {
5220 struct smb_filename
*smb_fname_base
= NULL
;
5222 /* Create an smb_filename with stream_name == NULL. */
5224 create_synthetic_smb_fname(talloc_tos(),
5225 smb_fname
->base_name
,
5228 if (!NT_STATUS_IS_OK(status
)) {
5229 reply_nterror(req
, status
);
5233 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5234 /* Always do lstat for UNIX calls. */
5235 if (SMB_VFS_LSTAT(conn
, smb_fname_base
) != 0) {
5236 DEBUG(3,("call_trans2qfilepathinfo: "
5237 "SMB_VFS_LSTAT of %s failed "
5239 smb_fname_str_dbg(smb_fname_base
),
5241 TALLOC_FREE(smb_fname_base
);
5243 map_nt_error_from_unix(errno
));
5247 if (SMB_VFS_STAT(conn
, smb_fname_base
) != 0) {
5248 DEBUG(3,("call_trans2qfilepathinfo: "
5249 "fileinfo of %s failed "
5251 smb_fname_str_dbg(smb_fname_base
),
5253 TALLOC_FREE(smb_fname_base
);
5255 map_nt_error_from_unix(errno
));
5260 status
= file_name_hash(conn
,
5261 smb_fname_str_dbg(smb_fname_base
),
5263 if (!NT_STATUS_IS_OK(status
)) {
5264 TALLOC_FREE(smb_fname_base
);
5265 reply_nterror(req
, status
);
5269 fileid
= vfs_file_id_from_sbuf(conn
,
5270 &smb_fname_base
->st
);
5271 TALLOC_FREE(smb_fname_base
);
5272 get_file_infos(fileid
, name_hash
, &delete_pending
, NULL
);
5273 if (delete_pending
) {
5274 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5279 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5280 /* Always do lstat for UNIX calls. */
5281 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5282 DEBUG(3,("call_trans2qfilepathinfo: "
5283 "SMB_VFS_LSTAT of %s failed (%s)\n",
5284 smb_fname_str_dbg(smb_fname
),
5287 map_nt_error_from_unix(errno
));
5292 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
5293 DEBUG(3,("call_trans2qfilepathinfo: "
5294 "SMB_VFS_STAT of %s failed (%s)\n",
5295 smb_fname_str_dbg(smb_fname
),
5298 map_nt_error_from_unix(errno
));
5303 status
= file_name_hash(conn
,
5304 smb_fname_str_dbg(smb_fname
),
5306 if (!NT_STATUS_IS_OK(status
)) {
5307 reply_nterror(req
, status
);
5311 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5312 get_file_infos(fileid
, name_hash
, &delete_pending
, &write_time_ts
);
5313 if (delete_pending
) {
5314 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5319 DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
5320 "total_data=%d\n", smb_fname_str_dbg(smb_fname
),
5322 info_level
,tran_call
,total_data
));
5324 /* Pull out any data sent here before we realloc. */
5325 switch (info_level
) {
5326 case SMB_INFO_QUERY_EAS_FROM_LIST
:
5328 /* Pull any EA list from the data portion. */
5331 if (total_data
< 4) {
5333 req
, NT_STATUS_INVALID_PARAMETER
);
5336 ea_size
= IVAL(pdata
,0);
5338 if (total_data
> 0 && ea_size
!= total_data
) {
5339 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5340 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
5342 req
, NT_STATUS_INVALID_PARAMETER
);
5346 if (!lp_ea_support(SNUM(conn
))) {
5347 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
5351 /* Pull out the list of names. */
5352 ea_list
= read_ea_name_list(req
, pdata
+ 4, ea_size
- 4);
5355 req
, NT_STATUS_INVALID_PARAMETER
);
5361 case SMB_QUERY_POSIX_LOCK
:
5363 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
5364 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
5368 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
5370 req
, NT_STATUS_INVALID_PARAMETER
);
5374 /* Copy the lock range data. */
5375 lock_data
= (char *)talloc_memdup(
5376 req
, pdata
, total_data
);
5378 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5381 lock_data_count
= total_data
;
5387 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
5388 if (*pparams
== NULL
) {
5389 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5396 * draft-leach-cifs-v1-spec-02.txt
5397 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5400 * The requested information is placed in the Data portion of the
5401 * transaction response. For the information levels greater than 0x100,
5402 * the transaction response has 1 parameter word which should be
5403 * ignored by the client.
5405 * However Windows only follows this rule for the IS_NAME_VALID call.
5407 switch (info_level
) {
5408 case SMB_INFO_IS_NAME_VALID
:
5413 if ((info_level
& 0xFF00) == 0xFF00) {
5415 * We use levels that start with 0xFF00
5416 * internally to represent SMB2 specific levels
5418 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5422 status
= smbd_do_qfilepathinfo(conn
, req
, info_level
,
5424 delete_pending
, write_time_ts
,
5426 lock_data_count
, lock_data
,
5427 req
->flags2
, max_data_bytes
,
5428 ppdata
, &data_size
);
5429 if (!NT_STATUS_IS_OK(status
)) {
5430 reply_nterror(req
, status
);
5434 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
5440 /****************************************************************************
5441 Set a hard link (called by UNIX extensions and by NT rename with HARD link
5443 ****************************************************************************/
5445 NTSTATUS
hardlink_internals(TALLOC_CTX
*ctx
,
5446 connection_struct
*conn
,
5447 struct smb_request
*req
,
5448 bool overwrite_if_exists
,
5449 const struct smb_filename
*smb_fname_old
,
5450 struct smb_filename
*smb_fname_new
)
5452 NTSTATUS status
= NT_STATUS_OK
;
5454 /* source must already exist. */
5455 if (!VALID_STAT(smb_fname_old
->st
)) {
5456 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5459 if (VALID_STAT(smb_fname_new
->st
)) {
5460 if (overwrite_if_exists
) {
5461 if (S_ISDIR(smb_fname_new
->st
.st_ex_mode
)) {
5462 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5464 status
= unlink_internals(conn
,
5466 FILE_ATTRIBUTE_NORMAL
,
5469 if (!NT_STATUS_IS_OK(status
)) {
5473 /* Disallow if newname already exists. */
5474 return NT_STATUS_OBJECT_NAME_COLLISION
;
5478 /* No links from a directory. */
5479 if (S_ISDIR(smb_fname_old
->st
.st_ex_mode
)) {
5480 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5483 /* Setting a hardlink to/from a stream isn't currently supported. */
5484 if (is_ntfs_stream_smb_fname(smb_fname_old
) ||
5485 is_ntfs_stream_smb_fname(smb_fname_new
)) {
5486 return NT_STATUS_INVALID_PARAMETER
;
5489 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5490 smb_fname_old
->base_name
, smb_fname_new
->base_name
));
5492 if (SMB_VFS_LINK(conn
, smb_fname_old
->base_name
,
5493 smb_fname_new
->base_name
) != 0) {
5494 status
= map_nt_error_from_unix(errno
);
5495 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5496 nt_errstr(status
), smb_fname_old
->base_name
,
5497 smb_fname_new
->base_name
));
5502 /****************************************************************************
5503 Deal with setting the time from any of the setfilepathinfo functions.
5504 NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
5505 calling this function.
5506 ****************************************************************************/
5508 NTSTATUS
smb_set_file_time(connection_struct
*conn
,
5510 const struct smb_filename
*smb_fname
,
5511 struct smb_file_time
*ft
,
5512 bool setting_write_time
)
5514 struct smb_filename smb_fname_base
;
5516 FILE_NOTIFY_CHANGE_LAST_ACCESS
5517 |FILE_NOTIFY_CHANGE_LAST_WRITE
5518 |FILE_NOTIFY_CHANGE_CREATION
;
5520 if (!VALID_STAT(smb_fname
->st
)) {
5521 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5524 /* get some defaults (no modifications) if any info is zero or -1. */
5525 if (null_timespec(ft
->create_time
)) {
5526 action
&= ~FILE_NOTIFY_CHANGE_CREATION
;
5529 if (null_timespec(ft
->atime
)) {
5530 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
5533 if (null_timespec(ft
->mtime
)) {
5534 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5537 if (!setting_write_time
) {
5538 /* ft->mtime comes from change time, not write time. */
5539 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5542 /* Ensure the resolution is the correct for
5543 * what we can store on this filesystem. */
5545 round_timespec(conn
->ts_res
, &ft
->create_time
);
5546 round_timespec(conn
->ts_res
, &ft
->ctime
);
5547 round_timespec(conn
->ts_res
, &ft
->atime
);
5548 round_timespec(conn
->ts_res
, &ft
->mtime
);
5550 DEBUG(5,("smb_set_filetime: actime: %s\n ",
5551 time_to_asc(convert_timespec_to_time_t(ft
->atime
))));
5552 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5553 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5554 DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5555 time_to_asc(convert_timespec_to_time_t(ft
->ctime
))));
5556 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5557 time_to_asc(convert_timespec_to_time_t(ft
->create_time
))));
5559 if (setting_write_time
) {
5561 * This was a Windows setfileinfo on an open file.
5562 * NT does this a lot. We also need to
5563 * set the time here, as it can be read by
5564 * FindFirst/FindNext and with the patch for bug #2045
5565 * in smbd/fileio.c it ensures that this timestamp is
5566 * kept sticky even after a write. We save the request
5567 * away and will set it on file close and after a write. JRA.
5570 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5571 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5574 if (fsp
->base_fsp
) {
5575 set_sticky_write_time_fsp(fsp
->base_fsp
,
5578 set_sticky_write_time_fsp(fsp
, ft
->mtime
);
5581 set_sticky_write_time_path(
5582 vfs_file_id_from_sbuf(conn
, &smb_fname
->st
),
5587 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5589 /* Always call ntimes on the base, even if a stream was passed in. */
5590 smb_fname_base
= *smb_fname
;
5591 smb_fname_base
.stream_name
= NULL
;
5593 if(file_ntimes(conn
, &smb_fname_base
, ft
)!=0) {
5594 return map_nt_error_from_unix(errno
);
5597 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
,
5598 smb_fname
->base_name
);
5599 return NT_STATUS_OK
;
5602 /****************************************************************************
5603 Deal with setting the dosmode from any of the setfilepathinfo functions.
5604 NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
5605 done before calling this function.
5606 ****************************************************************************/
5608 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
5609 const struct smb_filename
*smb_fname
,
5612 struct smb_filename
*smb_fname_base
= NULL
;
5615 if (!VALID_STAT(smb_fname
->st
)) {
5616 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5619 /* Always operate on the base_name, even if a stream was passed in. */
5620 status
= create_synthetic_smb_fname(talloc_tos(), smb_fname
->base_name
,
5621 NULL
, &smb_fname
->st
,
5623 if (!NT_STATUS_IS_OK(status
)) {
5628 if (S_ISDIR(smb_fname_base
->st
.st_ex_mode
)) {
5629 dosmode
|= FILE_ATTRIBUTE_DIRECTORY
;
5631 dosmode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
5635 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode
));
5637 /* check the mode isn't different, before changing it */
5638 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, smb_fname_base
))) {
5639 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5640 "0x%x\n", smb_fname_str_dbg(smb_fname_base
),
5641 (unsigned int)dosmode
));
5643 if(file_set_dosmode(conn
, smb_fname_base
, dosmode
, NULL
,
5645 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5647 smb_fname_str_dbg(smb_fname_base
),
5649 status
= map_nt_error_from_unix(errno
);
5653 status
= NT_STATUS_OK
;
5655 TALLOC_FREE(smb_fname_base
);
5659 /****************************************************************************
5660 Deal with setting the size from any of the setfilepathinfo functions.
5661 ****************************************************************************/
5663 static NTSTATUS
smb_set_file_size(connection_struct
*conn
,
5664 struct smb_request
*req
,
5666 const struct smb_filename
*smb_fname
,
5667 const SMB_STRUCT_STAT
*psbuf
,
5669 bool fail_after_createfile
)
5671 NTSTATUS status
= NT_STATUS_OK
;
5672 struct smb_filename
*smb_fname_tmp
= NULL
;
5673 files_struct
*new_fsp
= NULL
;
5675 if (!VALID_STAT(*psbuf
)) {
5676 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5679 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size
));
5681 if (size
== get_file_size_stat(psbuf
)) {
5682 return NT_STATUS_OK
;
5685 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5686 smb_fname_str_dbg(smb_fname
), (double)size
));
5688 if (fsp
&& fsp
->fh
->fd
!= -1) {
5689 /* Handle based call. */
5690 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
5691 return NT_STATUS_ACCESS_DENIED
;
5694 if (vfs_set_filelen(fsp
, size
) == -1) {
5695 return map_nt_error_from_unix(errno
);
5697 trigger_write_time_update_immediate(fsp
);
5698 return NT_STATUS_OK
;
5701 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
5702 if (!NT_STATUS_IS_OK(status
)) {
5706 smb_fname_tmp
->st
= *psbuf
;
5708 status
= SMB_VFS_CREATE_FILE(
5711 0, /* root_dir_fid */
5712 smb_fname_tmp
, /* fname */
5713 FILE_WRITE_DATA
, /* access_mask */
5714 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5716 FILE_OPEN
, /* create_disposition*/
5717 0, /* create_options */
5718 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5719 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
5720 0, /* allocation_size */
5721 0, /* private_flags */
5724 &new_fsp
, /* result */
5727 TALLOC_FREE(smb_fname_tmp
);
5729 if (!NT_STATUS_IS_OK(status
)) {
5730 /* NB. We check for open_was_deferred in the caller. */
5734 /* See RAW-SFILEINFO-END-OF-FILE */
5735 if (fail_after_createfile
) {
5736 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5737 return NT_STATUS_INVALID_LEVEL
;
5740 if (vfs_set_filelen(new_fsp
, size
) == -1) {
5741 status
= map_nt_error_from_unix(errno
);
5742 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5746 trigger_write_time_update_immediate(new_fsp
);
5747 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5748 return NT_STATUS_OK
;
5751 /****************************************************************************
5752 Deal with SMB_INFO_SET_EA.
5753 ****************************************************************************/
5755 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
5759 const struct smb_filename
*smb_fname
)
5761 struct ea_list
*ea_list
= NULL
;
5762 TALLOC_CTX
*ctx
= NULL
;
5763 NTSTATUS status
= NT_STATUS_OK
;
5765 if (total_data
< 10) {
5767 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5768 length. They seem to have no effect. Bug #3212. JRA */
5770 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
5771 /* We're done. We only get EA info in this call. */
5772 return NT_STATUS_OK
;
5775 return NT_STATUS_INVALID_PARAMETER
;
5778 if (IVAL(pdata
,0) > total_data
) {
5779 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5780 IVAL(pdata
,0), (unsigned int)total_data
));
5781 return NT_STATUS_INVALID_PARAMETER
;
5785 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
5787 return NT_STATUS_INVALID_PARAMETER
;
5790 status
= set_ea(conn
, fsp
, smb_fname
, ea_list
);
5795 /****************************************************************************
5796 Deal with SMB_FILE_FULL_EA_INFORMATION set.
5797 ****************************************************************************/
5799 static NTSTATUS
smb_set_file_full_ea_info(connection_struct
*conn
,
5804 struct ea_list
*ea_list
= NULL
;
5808 return NT_STATUS_INVALID_HANDLE
;
5811 if (!lp_ea_support(SNUM(conn
))) {
5812 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5813 "EA's not supported.\n",
5814 (unsigned int)total_data
));
5815 return NT_STATUS_EAS_NOT_SUPPORTED
;
5818 if (total_data
< 10) {
5819 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5821 (unsigned int)total_data
));
5822 return NT_STATUS_INVALID_PARAMETER
;
5825 ea_list
= read_nttrans_ea_list(talloc_tos(),
5830 return NT_STATUS_INVALID_PARAMETER
;
5833 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
5835 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5836 smb_fname_str_dbg(fsp
->fsp_name
),
5837 nt_errstr(status
) ));
5843 /****************************************************************************
5844 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5845 ****************************************************************************/
5847 static NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
5851 struct smb_filename
*smb_fname
)
5853 NTSTATUS status
= NT_STATUS_OK
;
5854 bool delete_on_close
;
5857 if (total_data
< 1) {
5858 return NT_STATUS_INVALID_PARAMETER
;
5862 return NT_STATUS_INVALID_HANDLE
;
5865 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
5866 dosmode
= dos_mode(conn
, smb_fname
);
5868 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5869 "delete_on_close = %u\n",
5870 smb_fname_str_dbg(smb_fname
),
5871 (unsigned int)dosmode
,
5872 (unsigned int)delete_on_close
));
5874 if (delete_on_close
) {
5875 status
= can_set_delete_on_close(fsp
, dosmode
);
5876 if (!NT_STATUS_IS_OK(status
)) {
5881 /* The set is across all open files on this dev/inode pair. */
5882 if (!set_delete_on_close(fsp
, delete_on_close
,
5883 conn
->session_info
->security_token
,
5884 conn
->session_info
->unix_token
)) {
5885 return NT_STATUS_ACCESS_DENIED
;
5887 return NT_STATUS_OK
;
5890 /****************************************************************************
5891 Deal with SMB_FILE_POSITION_INFORMATION.
5892 ****************************************************************************/
5894 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
5899 uint64_t position_information
;
5901 if (total_data
< 8) {
5902 return NT_STATUS_INVALID_PARAMETER
;
5906 /* Ignore on pathname based set. */
5907 return NT_STATUS_OK
;
5910 position_information
= (uint64_t)IVAL(pdata
,0);
5911 position_information
|= (((uint64_t)IVAL(pdata
,4)) << 32);
5913 DEBUG(10,("smb_file_position_information: Set file position "
5914 "information for file %s to %.0f\n", fsp_str_dbg(fsp
),
5915 (double)position_information
));
5916 fsp
->fh
->position_information
= position_information
;
5917 return NT_STATUS_OK
;
5920 /****************************************************************************
5921 Deal with SMB_FILE_MODE_INFORMATION.
5922 ****************************************************************************/
5924 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
5930 if (total_data
< 4) {
5931 return NT_STATUS_INVALID_PARAMETER
;
5933 mode
= IVAL(pdata
,0);
5934 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
5935 return NT_STATUS_INVALID_PARAMETER
;
5937 return NT_STATUS_OK
;
5940 /****************************************************************************
5941 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
5942 ****************************************************************************/
5944 static NTSTATUS
smb_set_file_unix_link(connection_struct
*conn
,
5945 struct smb_request
*req
,
5948 const struct smb_filename
*smb_fname
)
5950 char *link_target
= NULL
;
5951 const char *newname
= smb_fname
->base_name
;
5952 TALLOC_CTX
*ctx
= talloc_tos();
5954 /* Set a symbolic link. */
5955 /* Don't allow this if follow links is false. */
5957 if (total_data
== 0) {
5958 return NT_STATUS_INVALID_PARAMETER
;
5961 if (!lp_symlinks(SNUM(conn
))) {
5962 return NT_STATUS_ACCESS_DENIED
;
5965 srvstr_pull_talloc(ctx
, pdata
, req
->flags2
, &link_target
, pdata
,
5966 total_data
, STR_TERMINATE
);
5969 return NT_STATUS_INVALID_PARAMETER
;
5972 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
5973 newname
, link_target
));
5975 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0) {
5976 return map_nt_error_from_unix(errno
);
5979 return NT_STATUS_OK
;
5982 /****************************************************************************
5983 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
5984 ****************************************************************************/
5986 static NTSTATUS
smb_set_file_unix_hlink(connection_struct
*conn
,
5987 struct smb_request
*req
,
5988 const char *pdata
, int total_data
,
5989 struct smb_filename
*smb_fname_new
)
5991 char *oldname
= NULL
;
5992 struct smb_filename
*smb_fname_old
= NULL
;
5993 TALLOC_CTX
*ctx
= talloc_tos();
5994 NTSTATUS status
= NT_STATUS_OK
;
5996 /* Set a hard link. */
5997 if (total_data
== 0) {
5998 return NT_STATUS_INVALID_PARAMETER
;
6001 srvstr_get_path(ctx
, pdata
, req
->flags2
, &oldname
, pdata
,
6002 total_data
, STR_TERMINATE
, &status
);
6003 if (!NT_STATUS_IS_OK(status
)) {
6007 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6008 smb_fname_str_dbg(smb_fname_new
), oldname
));
6010 status
= filename_convert(ctx
,
6012 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6017 if (!NT_STATUS_IS_OK(status
)) {
6021 return hardlink_internals(ctx
, conn
, req
, false,
6022 smb_fname_old
, smb_fname_new
);
6025 /****************************************************************************
6026 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6027 ****************************************************************************/
6029 static NTSTATUS
smb2_file_rename_information(connection_struct
*conn
,
6030 struct smb_request
*req
,
6034 struct smb_filename
*smb_fname_src
)
6038 char *newname
= NULL
;
6039 struct smb_filename
*smb_fname_dst
= NULL
;
6040 NTSTATUS status
= NT_STATUS_OK
;
6041 TALLOC_CTX
*ctx
= talloc_tos();
6044 return NT_STATUS_INVALID_HANDLE
;
6047 if (total_data
< 20) {
6048 return NT_STATUS_INVALID_PARAMETER
;
6051 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6052 len
= IVAL(pdata
,16);
6054 if (len
> (total_data
- 20) || (len
== 0)) {
6055 return NT_STATUS_INVALID_PARAMETER
;
6058 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6059 &pdata
[20], len
, STR_TERMINATE
,
6061 if (!NT_STATUS_IS_OK(status
)) {
6065 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
6068 status
= filename_convert(ctx
,
6070 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6075 if (!NT_STATUS_IS_OK(status
)) {
6079 if (fsp
->base_fsp
) {
6080 /* newname must be a stream name. */
6081 if (newname
[0] != ':') {
6082 return NT_STATUS_NOT_SUPPORTED
;
6085 /* Create an smb_fname to call rename_internals_fsp() with. */
6086 status
= create_synthetic_smb_fname(talloc_tos(),
6087 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6089 if (!NT_STATUS_IS_OK(status
)) {
6094 * Set the original last component, since
6095 * rename_internals_fsp() requires it.
6097 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6099 if (smb_fname_dst
->original_lcomp
== NULL
) {
6100 status
= NT_STATUS_NO_MEMORY
;
6106 DEBUG(10,("smb2_file_rename_information: "
6107 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6108 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6109 smb_fname_str_dbg(smb_fname_dst
)));
6110 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6111 (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
),
6115 TALLOC_FREE(smb_fname_dst
);
6119 static NTSTATUS
smb_file_link_information(connection_struct
*conn
,
6120 struct smb_request
*req
,
6124 struct smb_filename
*smb_fname_src
)
6128 char *newname
= NULL
;
6129 struct smb_filename
*smb_fname_dst
= NULL
;
6130 NTSTATUS status
= NT_STATUS_OK
;
6131 TALLOC_CTX
*ctx
= talloc_tos();
6134 return NT_STATUS_INVALID_HANDLE
;
6137 if (total_data
< 20) {
6138 return NT_STATUS_INVALID_PARAMETER
;
6141 overwrite
= (CVAL(pdata
,0) ? true : false);
6142 len
= IVAL(pdata
,16);
6144 if (len
> (total_data
- 20) || (len
== 0)) {
6145 return NT_STATUS_INVALID_PARAMETER
;
6148 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6149 &pdata
[20], len
, STR_TERMINATE
,
6151 if (!NT_STATUS_IS_OK(status
)) {
6155 DEBUG(10,("smb_file_link_information: got name |%s|\n",
6158 status
= filename_convert(ctx
,
6160 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6165 if (!NT_STATUS_IS_OK(status
)) {
6169 if (fsp
->base_fsp
) {
6170 /* No stream names. */
6171 return NT_STATUS_NOT_SUPPORTED
;
6174 DEBUG(10,("smb_file_link_information: "
6175 "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
6176 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6177 smb_fname_str_dbg(smb_fname_dst
)));
6178 status
= hardlink_internals(ctx
,
6185 TALLOC_FREE(smb_fname_dst
);
6189 /****************************************************************************
6190 Deal with SMB_FILE_RENAME_INFORMATION.
6191 ****************************************************************************/
6193 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
6194 struct smb_request
*req
,
6198 struct smb_filename
*smb_fname_src
)
6203 char *newname
= NULL
;
6204 struct smb_filename
*smb_fname_dst
= NULL
;
6205 bool dest_has_wcard
= False
;
6206 NTSTATUS status
= NT_STATUS_OK
;
6208 TALLOC_CTX
*ctx
= talloc_tos();
6210 if (total_data
< 13) {
6211 return NT_STATUS_INVALID_PARAMETER
;
6214 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6215 root_fid
= IVAL(pdata
,4);
6216 len
= IVAL(pdata
,8);
6218 if (len
> (total_data
- 12) || (len
== 0) || (root_fid
!= 0)) {
6219 return NT_STATUS_INVALID_PARAMETER
;
6222 srvstr_get_path_wcard(ctx
, pdata
, req
->flags2
, &newname
, &pdata
[12],
6225 if (!NT_STATUS_IS_OK(status
)) {
6229 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6232 status
= resolve_dfspath_wcard(ctx
, conn
,
6233 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6236 !conn
->sconn
->using_smb2
,
6239 if (!NT_STATUS_IS_OK(status
)) {
6243 /* Check the new name has no '/' characters. */
6244 if (strchr_m(newname
, '/')) {
6245 return NT_STATUS_NOT_SUPPORTED
;
6248 if (fsp
&& fsp
->base_fsp
) {
6249 /* newname must be a stream name. */
6250 if (newname
[0] != ':') {
6251 return NT_STATUS_NOT_SUPPORTED
;
6254 /* Create an smb_fname to call rename_internals_fsp() with. */
6255 status
= create_synthetic_smb_fname(talloc_tos(),
6256 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6258 if (!NT_STATUS_IS_OK(status
)) {
6263 * Set the original last component, since
6264 * rename_internals_fsp() requires it.
6266 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6268 if (smb_fname_dst
->original_lcomp
== NULL
) {
6269 status
= NT_STATUS_NO_MEMORY
;
6275 * Build up an smb_fname_dst based on the filename passed in.
6276 * We basically just strip off the last component, and put on
6277 * the newname instead.
6279 char *base_name
= NULL
;
6281 /* newname must *not* be a stream name. */
6282 if (newname
[0] == ':') {
6283 return NT_STATUS_NOT_SUPPORTED
;
6287 * Strip off the last component (filename) of the path passed
6290 base_name
= talloc_strdup(ctx
, smb_fname_src
->base_name
);
6292 return NT_STATUS_NO_MEMORY
;
6294 p
= strrchr_m(base_name
, '/');
6298 base_name
= talloc_strdup(ctx
, "");
6300 return NT_STATUS_NO_MEMORY
;
6303 /* Append the new name. */
6304 base_name
= talloc_asprintf_append(base_name
,
6308 return NT_STATUS_NO_MEMORY
;
6311 status
= unix_convert(ctx
, conn
, base_name
, &smb_fname_dst
,
6314 UCF_ALWAYS_ALLOW_WCARD_LCOMP
:
6317 /* If an error we expect this to be
6318 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6320 if (!NT_STATUS_IS_OK(status
)) {
6321 if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND
,
6325 /* Create an smb_fname to call rename_internals_fsp() */
6326 status
= create_synthetic_smb_fname(ctx
,
6330 if (!NT_STATUS_IS_OK(status
)) {
6337 DEBUG(10,("smb_file_rename_information: "
6338 "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6339 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
6340 smb_fname_str_dbg(smb_fname_dst
)));
6341 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
, 0,
6344 DEBUG(10,("smb_file_rename_information: "
6345 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6346 smb_fname_str_dbg(smb_fname_src
),
6347 smb_fname_str_dbg(smb_fname_dst
)));
6348 status
= rename_internals(ctx
, conn
, req
, smb_fname_src
,
6349 smb_fname_dst
, 0, overwrite
, false,
6351 FILE_WRITE_ATTRIBUTES
);
6354 TALLOC_FREE(smb_fname_dst
);
6358 /****************************************************************************
6359 Deal with SMB_SET_POSIX_ACL.
6360 ****************************************************************************/
6362 #if defined(HAVE_POSIX_ACLS)
6363 static NTSTATUS
smb_set_posix_acl(connection_struct
*conn
,
6367 const struct smb_filename
*smb_fname
)
6369 uint16 posix_acl_version
;
6370 uint16 num_file_acls
;
6371 uint16 num_def_acls
;
6372 bool valid_file_acls
= True
;
6373 bool valid_def_acls
= True
;
6375 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
6376 return NT_STATUS_INVALID_PARAMETER
;
6378 posix_acl_version
= SVAL(pdata
,0);
6379 num_file_acls
= SVAL(pdata
,2);
6380 num_def_acls
= SVAL(pdata
,4);
6382 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6383 valid_file_acls
= False
;
6387 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6388 valid_def_acls
= False
;
6392 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
6393 return NT_STATUS_INVALID_PARAMETER
;
6396 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
6397 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
6398 return NT_STATUS_INVALID_PARAMETER
;
6401 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6402 smb_fname
? smb_fname_str_dbg(smb_fname
) : fsp_str_dbg(fsp
),
6403 (unsigned int)num_file_acls
,
6404 (unsigned int)num_def_acls
));
6406 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
,
6407 smb_fname
->base_name
, num_file_acls
,
6408 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
6409 return map_nt_error_from_unix(errno
);
6412 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
,
6413 smb_fname
->base_name
, &smb_fname
->st
, num_def_acls
,
6414 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
6415 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
6416 return map_nt_error_from_unix(errno
);
6418 return NT_STATUS_OK
;
6422 /****************************************************************************
6423 Deal with SMB_SET_POSIX_LOCK.
6424 ****************************************************************************/
6426 static NTSTATUS
smb_set_posix_lock(connection_struct
*conn
,
6427 struct smb_request
*req
,
6435 bool blocking_lock
= False
;
6436 enum brl_type lock_type
;
6438 NTSTATUS status
= NT_STATUS_OK
;
6440 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
6441 return NT_STATUS_INVALID_HANDLE
;
6444 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
6445 return NT_STATUS_INVALID_PARAMETER
;
6448 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
6449 case POSIX_LOCK_TYPE_READ
:
6450 lock_type
= READ_LOCK
;
6452 case POSIX_LOCK_TYPE_WRITE
:
6453 /* Return the right POSIX-mappable error code for files opened read-only. */
6454 if (!fsp
->can_write
) {
6455 return NT_STATUS_INVALID_HANDLE
;
6457 lock_type
= WRITE_LOCK
;
6459 case POSIX_LOCK_TYPE_UNLOCK
:
6460 lock_type
= UNLOCK_LOCK
;
6463 return NT_STATUS_INVALID_PARAMETER
;
6466 if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_NOWAIT
) {
6467 blocking_lock
= False
;
6468 } else if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_WAIT
) {
6469 blocking_lock
= True
;
6471 return NT_STATUS_INVALID_PARAMETER
;
6474 if (!lp_blocking_locks(SNUM(conn
))) {
6475 blocking_lock
= False
;
6478 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
6479 #if defined(HAVE_LONGLONG)
6480 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
6481 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
6482 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
6483 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
6484 #else /* HAVE_LONGLONG */
6485 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
6486 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
6487 #endif /* HAVE_LONGLONG */
6489 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6490 "smblctx = %llu, count = %.0f, offset = %.0f\n",
6492 (unsigned int)lock_type
,
6493 (unsigned long long)smblctx
,
6497 if (lock_type
== UNLOCK_LOCK
) {
6498 status
= do_unlock(req
->sconn
->msg_ctx
,
6505 uint64_t block_smblctx
;
6507 struct byte_range_lock
*br_lck
= do_lock(req
->sconn
->msg_ctx
,
6519 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
6521 * A blocking lock was requested. Package up
6522 * this smb into a queued request and push it
6523 * onto the blocking lock queue.
6525 if(push_blocking_lock_request(br_lck
,
6528 -1, /* infinite timeout. */
6536 TALLOC_FREE(br_lck
);
6540 TALLOC_FREE(br_lck
);
6546 /****************************************************************************
6547 Deal with SMB_SET_FILE_BASIC_INFO.
6548 ****************************************************************************/
6550 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
6554 const struct smb_filename
*smb_fname
)
6556 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6557 struct smb_file_time ft
;
6559 NTSTATUS status
= NT_STATUS_OK
;
6563 if (total_data
< 36) {
6564 return NT_STATUS_INVALID_PARAMETER
;
6567 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_ATTRIBUTES
);
6568 if (!NT_STATUS_IS_OK(status
)) {
6572 /* Set the attributes */
6573 dosmode
= IVAL(pdata
,32);
6574 status
= smb_set_file_dosmode(conn
, smb_fname
, dosmode
);
6575 if (!NT_STATUS_IS_OK(status
)) {
6580 ft
.create_time
= interpret_long_date(pdata
);
6583 ft
.atime
= interpret_long_date(pdata
+8);
6586 ft
.mtime
= interpret_long_date(pdata
+16);
6589 ft
.ctime
= interpret_long_date(pdata
+24);
6591 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6592 smb_fname_str_dbg(smb_fname
)));
6594 return smb_set_file_time(conn
, fsp
, smb_fname
, &ft
,
6598 /****************************************************************************
6599 Deal with SMB_INFO_STANDARD.
6600 ****************************************************************************/
6602 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
6606 const struct smb_filename
*smb_fname
)
6609 struct smb_file_time ft
;
6613 if (total_data
< 12) {
6614 return NT_STATUS_INVALID_PARAMETER
;
6618 ft
.create_time
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
));
6620 ft
.atime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+4));
6622 ft
.mtime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+8));
6624 DEBUG(10,("smb_set_info_standard: file %s\n",
6625 smb_fname_str_dbg(smb_fname
)));
6627 status
= check_access(conn
, fsp
, smb_fname
, FILE_WRITE_ATTRIBUTES
);
6628 if (!NT_STATUS_IS_OK(status
)) {
6632 return smb_set_file_time(conn
,
6639 /****************************************************************************
6640 Deal with SMB_SET_FILE_ALLOCATION_INFO.
6641 ****************************************************************************/
6643 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
6644 struct smb_request
*req
,
6648 struct smb_filename
*smb_fname
)
6650 uint64_t allocation_size
= 0;
6651 NTSTATUS status
= NT_STATUS_OK
;
6652 files_struct
*new_fsp
= NULL
;
6654 if (!VALID_STAT(smb_fname
->st
)) {
6655 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6658 if (total_data
< 8) {
6659 return NT_STATUS_INVALID_PARAMETER
;
6662 allocation_size
= (uint64_t)IVAL(pdata
,0);
6663 allocation_size
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6664 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6665 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6666 (double)allocation_size
));
6668 if (allocation_size
) {
6669 allocation_size
= smb_roundup(conn
, allocation_size
);
6672 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6673 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname
),
6674 (double)allocation_size
));
6676 if (fsp
&& fsp
->fh
->fd
!= -1) {
6677 /* Open file handle. */
6678 if (!(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6679 return NT_STATUS_ACCESS_DENIED
;
6682 /* Only change if needed. */
6683 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6684 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
6685 return map_nt_error_from_unix(errno
);
6688 /* But always update the time. */
6690 * This is equivalent to a write. Ensure it's seen immediately
6691 * if there are no pending writes.
6693 trigger_write_time_update_immediate(fsp
);
6694 return NT_STATUS_OK
;
6697 /* Pathname or stat or directory file. */
6698 status
= SMB_VFS_CREATE_FILE(
6701 0, /* root_dir_fid */
6702 smb_fname
, /* fname */
6703 FILE_WRITE_DATA
, /* access_mask */
6704 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
6706 FILE_OPEN
, /* create_disposition*/
6707 0, /* create_options */
6708 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
6709 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
6710 0, /* allocation_size */
6711 0, /* private_flags */
6714 &new_fsp
, /* result */
6717 if (!NT_STATUS_IS_OK(status
)) {
6718 /* NB. We check for open_was_deferred in the caller. */
6722 /* Only change if needed. */
6723 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6724 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
6725 status
= map_nt_error_from_unix(errno
);
6726 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6731 /* Changing the allocation size should set the last mod time. */
6733 * This is equivalent to a write. Ensure it's seen immediately
6734 * if there are no pending writes.
6736 trigger_write_time_update_immediate(new_fsp
);
6738 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6739 return NT_STATUS_OK
;
6742 /****************************************************************************
6743 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6744 ****************************************************************************/
6746 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
6747 struct smb_request
*req
,
6751 const struct smb_filename
*smb_fname
,
6752 bool fail_after_createfile
)
6756 if (total_data
< 8) {
6757 return NT_STATUS_INVALID_PARAMETER
;
6760 size
= IVAL(pdata
,0);
6761 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
6762 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6763 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6766 return smb_set_file_size(conn
, req
,
6771 fail_after_createfile
);
6774 /****************************************************************************
6775 Allow a UNIX info mknod.
6776 ****************************************************************************/
6778 static NTSTATUS
smb_unix_mknod(connection_struct
*conn
,
6781 const struct smb_filename
*smb_fname
)
6783 uint32 file_type
= IVAL(pdata
,56);
6784 #if defined(HAVE_MAKEDEV)
6785 uint32 dev_major
= IVAL(pdata
,60);
6786 uint32 dev_minor
= IVAL(pdata
,68);
6788 SMB_DEV_T dev
= (SMB_DEV_T
)0;
6789 uint32 raw_unixmode
= IVAL(pdata
,84);
6793 if (total_data
< 100) {
6794 return NT_STATUS_INVALID_PARAMETER
;
6797 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6798 PERM_NEW_FILE
, &unixmode
);
6799 if (!NT_STATUS_IS_OK(status
)) {
6803 #if defined(HAVE_MAKEDEV)
6804 dev
= makedev(dev_major
, dev_minor
);
6807 switch (file_type
) {
6808 #if defined(S_IFIFO)
6809 case UNIX_TYPE_FIFO
:
6810 unixmode
|= S_IFIFO
;
6813 #if defined(S_IFSOCK)
6814 case UNIX_TYPE_SOCKET
:
6815 unixmode
|= S_IFSOCK
;
6818 #if defined(S_IFCHR)
6819 case UNIX_TYPE_CHARDEV
:
6820 unixmode
|= S_IFCHR
;
6823 #if defined(S_IFBLK)
6824 case UNIX_TYPE_BLKDEV
:
6825 unixmode
|= S_IFBLK
;
6829 return NT_STATUS_INVALID_PARAMETER
;
6832 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6833 "%.0f mode 0%o for file %s\n", (double)dev
,
6834 (unsigned int)unixmode
, smb_fname_str_dbg(smb_fname
)));
6836 /* Ok - do the mknod. */
6837 if (SMB_VFS_MKNOD(conn
, smb_fname
->base_name
, unixmode
, dev
) != 0) {
6838 return map_nt_error_from_unix(errno
);
6841 /* If any of the other "set" calls fail we
6842 * don't want to end up with a half-constructed mknod.
6845 if (lp_inherit_perms(SNUM(conn
))) {
6847 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
,
6849 return NT_STATUS_NO_MEMORY
;
6851 inherit_access_posix_acl(conn
, parent
, smb_fname
->base_name
,
6853 TALLOC_FREE(parent
);
6856 return NT_STATUS_OK
;
6859 /****************************************************************************
6860 Deal with SMB_SET_FILE_UNIX_BASIC.
6861 ****************************************************************************/
6863 static NTSTATUS
smb_set_file_unix_basic(connection_struct
*conn
,
6864 struct smb_request
*req
,
6868 const struct smb_filename
*smb_fname
)
6870 struct smb_file_time ft
;
6871 uint32 raw_unixmode
;
6874 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
6875 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
6876 NTSTATUS status
= NT_STATUS_OK
;
6877 bool delete_on_fail
= False
;
6878 enum perm_type ptype
;
6879 files_struct
*all_fsps
= NULL
;
6880 bool modify_mtime
= true;
6882 struct smb_filename
*smb_fname_tmp
= NULL
;
6883 SMB_STRUCT_STAT sbuf
;
6887 if (total_data
< 100) {
6888 return NT_STATUS_INVALID_PARAMETER
;
6891 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
6892 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
6893 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
6894 size
|= (((off_t
)IVAL(pdata
,4)) << 32);
6897 ft
.atime
= interpret_long_date(pdata
+24); /* access_time */
6898 ft
.mtime
= interpret_long_date(pdata
+32); /* modification_time */
6899 set_owner
= (uid_t
)IVAL(pdata
,40);
6900 set_grp
= (gid_t
)IVAL(pdata
,48);
6901 raw_unixmode
= IVAL(pdata
,84);
6903 if (VALID_STAT(smb_fname
->st
)) {
6904 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
6905 ptype
= PERM_EXISTING_DIR
;
6907 ptype
= PERM_EXISTING_FILE
;
6910 ptype
= PERM_NEW_FILE
;
6913 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6915 if (!NT_STATUS_IS_OK(status
)) {
6919 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
6920 "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
6921 smb_fname_str_dbg(smb_fname
), (double)size
,
6922 (unsigned int)set_owner
, (unsigned int)set_grp
,
6923 (int)raw_unixmode
));
6925 sbuf
= smb_fname
->st
;
6927 if (!VALID_STAT(sbuf
)) {
6929 * The only valid use of this is to create character and block
6930 * devices, and named pipes. This is deprecated (IMHO) and
6931 * a new info level should be used for mknod. JRA.
6934 status
= smb_unix_mknod(conn
,
6938 if (!NT_STATUS_IS_OK(status
)) {
6942 status
= copy_smb_filename(talloc_tos(), smb_fname
,
6944 if (!NT_STATUS_IS_OK(status
)) {
6948 if (SMB_VFS_STAT(conn
, smb_fname_tmp
) != 0) {
6949 status
= map_nt_error_from_unix(errno
);
6950 TALLOC_FREE(smb_fname_tmp
);
6951 SMB_VFS_UNLINK(conn
, smb_fname
);
6955 sbuf
= smb_fname_tmp
->st
;
6956 smb_fname
= smb_fname_tmp
;
6958 /* Ensure we don't try and change anything else. */
6959 raw_unixmode
= SMB_MODE_NO_CHANGE
;
6960 size
= get_file_size_stat(&sbuf
);
6961 ft
.atime
= sbuf
.st_ex_atime
;
6962 ft
.mtime
= sbuf
.st_ex_mtime
;
6964 * We continue here as we might want to change the
6967 delete_on_fail
= True
;
6971 /* Horrible backwards compatibility hack as an old server bug
6972 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
6976 size
= get_file_size_stat(&sbuf
);
6981 * Deal with the UNIX specific mode set.
6984 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
6985 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
6986 "setting mode 0%o for file %s\n",
6987 (unsigned int)unixmode
,
6988 smb_fname_str_dbg(smb_fname
)));
6989 if (SMB_VFS_CHMOD(conn
, smb_fname
->base_name
, unixmode
) != 0) {
6990 return map_nt_error_from_unix(errno
);
6995 * Deal with the UNIX specific uid set.
6998 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) &&
6999 (sbuf
.st_ex_uid
!= set_owner
)) {
7002 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7003 "changing owner %u for path %s\n",
7004 (unsigned int)set_owner
,
7005 smb_fname_str_dbg(smb_fname
)));
7007 if (S_ISLNK(sbuf
.st_ex_mode
)) {
7008 ret
= SMB_VFS_LCHOWN(conn
, smb_fname
->base_name
,
7009 set_owner
, (gid_t
)-1);
7011 ret
= SMB_VFS_CHOWN(conn
, smb_fname
->base_name
,
7012 set_owner
, (gid_t
)-1);
7016 status
= map_nt_error_from_unix(errno
);
7017 if (delete_on_fail
) {
7018 SMB_VFS_UNLINK(conn
, smb_fname
);
7025 * Deal with the UNIX specific gid set.
7028 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) &&
7029 (sbuf
.st_ex_gid
!= set_grp
)) {
7030 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7031 "changing group %u for file %s\n",
7032 (unsigned int)set_owner
,
7033 smb_fname_str_dbg(smb_fname
)));
7034 if (SMB_VFS_CHOWN(conn
, smb_fname
->base_name
, (uid_t
)-1,
7036 status
= map_nt_error_from_unix(errno
);
7037 if (delete_on_fail
) {
7038 SMB_VFS_UNLINK(conn
, smb_fname
);
7044 /* Deal with any size changes. */
7046 status
= smb_set_file_size(conn
, req
,
7052 if (!NT_STATUS_IS_OK(status
)) {
7056 /* Deal with any time changes. */
7057 if (null_timespec(ft
.mtime
) && null_timespec(ft
.atime
)) {
7058 /* No change, don't cancel anything. */
7062 id
= vfs_file_id_from_sbuf(conn
, &sbuf
);
7063 for(all_fsps
= file_find_di_first(conn
->sconn
, id
); all_fsps
;
7064 all_fsps
= file_find_di_next(all_fsps
)) {
7066 * We're setting the time explicitly for UNIX.
7067 * Cancel any pending changes over all handles.
7069 all_fsps
->update_write_time_on_close
= false;
7070 TALLOC_FREE(all_fsps
->update_write_time_event
);
7074 * Override the "setting_write_time"
7075 * parameter here as it almost does what
7076 * we need. Just remember if we modified
7077 * mtime and send the notify ourselves.
7079 if (null_timespec(ft
.mtime
)) {
7080 modify_mtime
= false;
7083 status
= smb_set_file_time(conn
,
7089 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
7090 FILE_NOTIFY_CHANGE_LAST_WRITE
, smb_fname
->base_name
);
7095 /****************************************************************************
7096 Deal with SMB_SET_FILE_UNIX_INFO2.
7097 ****************************************************************************/
7099 static NTSTATUS
smb_set_file_unix_info2(connection_struct
*conn
,
7100 struct smb_request
*req
,
7104 const struct smb_filename
*smb_fname
)
7110 if (total_data
< 116) {
7111 return NT_STATUS_INVALID_PARAMETER
;
7114 /* Start by setting all the fields that are common between UNIX_BASIC
7117 status
= smb_set_file_unix_basic(conn
, req
, pdata
, total_data
,
7119 if (!NT_STATUS_IS_OK(status
)) {
7123 smb_fflags
= IVAL(pdata
, 108);
7124 smb_fmask
= IVAL(pdata
, 112);
7126 /* NB: We should only attempt to alter the file flags if the client
7127 * sends a non-zero mask.
7129 if (smb_fmask
!= 0) {
7130 int stat_fflags
= 0;
7132 if (!map_info2_flags_to_sbuf(&smb_fname
->st
, smb_fflags
,
7133 smb_fmask
, &stat_fflags
)) {
7134 /* Client asked to alter a flag we don't understand. */
7135 return NT_STATUS_INVALID_PARAMETER
;
7138 if (fsp
&& fsp
->fh
->fd
!= -1) {
7139 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
7140 return NT_STATUS_NOT_SUPPORTED
;
7142 if (SMB_VFS_CHFLAGS(conn
, smb_fname
->base_name
,
7143 stat_fflags
) != 0) {
7144 return map_nt_error_from_unix(errno
);
7149 /* XXX: need to add support for changing the create_time here. You
7150 * can do this for paths on Darwin with setattrlist(2). The right way
7151 * to hook this up is probably by extending the VFS utimes interface.
7154 return NT_STATUS_OK
;
7157 /****************************************************************************
7158 Create a directory with POSIX semantics.
7159 ****************************************************************************/
7161 static NTSTATUS
smb_posix_mkdir(connection_struct
*conn
,
7162 struct smb_request
*req
,
7165 struct smb_filename
*smb_fname
,
7166 int *pdata_return_size
)
7168 NTSTATUS status
= NT_STATUS_OK
;
7169 uint32 raw_unixmode
= 0;
7170 uint32 mod_unixmode
= 0;
7171 mode_t unixmode
= (mode_t
)0;
7172 files_struct
*fsp
= NULL
;
7173 uint16 info_level_return
= 0;
7175 char *pdata
= *ppdata
;
7177 if (total_data
< 18) {
7178 return NT_STATUS_INVALID_PARAMETER
;
7181 raw_unixmode
= IVAL(pdata
,8);
7182 /* Next 4 bytes are not yet defined. */
7184 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7185 PERM_NEW_DIR
, &unixmode
);
7186 if (!NT_STATUS_IS_OK(status
)) {
7190 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7192 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7193 smb_fname_str_dbg(smb_fname
), (unsigned int)unixmode
));
7195 status
= SMB_VFS_CREATE_FILE(
7198 0, /* root_dir_fid */
7199 smb_fname
, /* fname */
7200 FILE_READ_ATTRIBUTES
, /* access_mask */
7201 FILE_SHARE_NONE
, /* share_access */
7202 FILE_CREATE
, /* create_disposition*/
7203 FILE_DIRECTORY_FILE
, /* create_options */
7204 mod_unixmode
, /* file_attributes */
7205 0, /* oplock_request */
7206 0, /* allocation_size */
7207 0, /* private_flags */
7213 if (NT_STATUS_IS_OK(status
)) {
7214 close_file(req
, fsp
, NORMAL_CLOSE
);
7217 info_level_return
= SVAL(pdata
,16);
7219 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7220 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7221 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7222 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7224 *pdata_return_size
= 12;
7227 /* Realloc the data size */
7228 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7229 if (*ppdata
== NULL
) {
7230 *pdata_return_size
= 0;
7231 return NT_STATUS_NO_MEMORY
;
7235 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7236 SSVAL(pdata
,2,0); /* No fnum. */
7237 SIVAL(pdata
,4,info
); /* Was directory created. */
7239 switch (info_level_return
) {
7240 case SMB_QUERY_FILE_UNIX_BASIC
:
7241 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7242 SSVAL(pdata
,10,0); /* Padding. */
7243 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7246 case SMB_QUERY_FILE_UNIX_INFO2
:
7247 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7248 SSVAL(pdata
,10,0); /* Padding. */
7249 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7253 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7254 SSVAL(pdata
,10,0); /* Padding. */
7261 /****************************************************************************
7262 Open/Create a file with POSIX semantics.
7263 ****************************************************************************/
7265 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7266 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7268 static NTSTATUS
smb_posix_open(connection_struct
*conn
,
7269 struct smb_request
*req
,
7272 struct smb_filename
*smb_fname
,
7273 int *pdata_return_size
)
7275 bool extended_oplock_granted
= False
;
7276 char *pdata
= *ppdata
;
7278 uint32 wire_open_mode
= 0;
7279 uint32 raw_unixmode
= 0;
7280 uint32 mod_unixmode
= 0;
7281 uint32 create_disp
= 0;
7282 uint32 access_mask
= 0;
7283 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
7284 NTSTATUS status
= NT_STATUS_OK
;
7285 mode_t unixmode
= (mode_t
)0;
7286 files_struct
*fsp
= NULL
;
7287 int oplock_request
= 0;
7289 uint16 info_level_return
= 0;
7291 if (total_data
< 18) {
7292 return NT_STATUS_INVALID_PARAMETER
;
7295 flags
= IVAL(pdata
,0);
7296 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
7297 if (oplock_request
) {
7298 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
7301 wire_open_mode
= IVAL(pdata
,4);
7303 if (wire_open_mode
== (SMB_O_CREAT
|SMB_O_DIRECTORY
)) {
7304 return smb_posix_mkdir(conn
, req
,
7311 switch (wire_open_mode
& SMB_ACCMODE
) {
7313 access_mask
= SMB_O_RDONLY_MAPPING
;
7316 access_mask
= SMB_O_WRONLY_MAPPING
;
7319 access_mask
= (SMB_O_RDONLY_MAPPING
|
7320 SMB_O_WRONLY_MAPPING
);
7323 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7324 (unsigned int)wire_open_mode
));
7325 return NT_STATUS_INVALID_PARAMETER
;
7328 wire_open_mode
&= ~SMB_ACCMODE
;
7330 /* First take care of O_CREAT|O_EXCL interactions. */
7331 switch (wire_open_mode
& (SMB_O_CREAT
| SMB_O_EXCL
)) {
7332 case (SMB_O_CREAT
| SMB_O_EXCL
):
7333 /* File exists fail. File not exist create. */
7334 create_disp
= FILE_CREATE
;
7337 /* File exists open. File not exist create. */
7338 create_disp
= FILE_OPEN_IF
;
7341 /* File exists open. File not exist fail. */
7342 create_disp
= FILE_OPEN
;
7345 /* O_EXCL on its own without O_CREAT is undefined. */
7347 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7348 (unsigned int)wire_open_mode
));
7349 return NT_STATUS_INVALID_PARAMETER
;
7352 /* Next factor in the effects of O_TRUNC. */
7353 wire_open_mode
&= ~(SMB_O_CREAT
| SMB_O_EXCL
);
7355 if (wire_open_mode
& SMB_O_TRUNC
) {
7356 switch (create_disp
) {
7358 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7359 /* Leave create_disp alone as
7360 (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7362 /* File exists fail. File not exist create. */
7365 /* SMB_O_CREAT | SMB_O_TRUNC */
7366 /* File exists overwrite. File not exist create. */
7367 create_disp
= FILE_OVERWRITE_IF
;
7371 /* File exists overwrite. File not exist fail. */
7372 create_disp
= FILE_OVERWRITE
;
7375 /* Cannot get here. */
7376 smb_panic("smb_posix_open: logic error");
7377 return NT_STATUS_INVALID_PARAMETER
;
7381 raw_unixmode
= IVAL(pdata
,8);
7382 /* Next 4 bytes are not yet defined. */
7384 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7385 (VALID_STAT(smb_fname
->st
) ?
7386 PERM_EXISTING_FILE
: PERM_NEW_FILE
),
7389 if (!NT_STATUS_IS_OK(status
)) {
7393 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7395 if (wire_open_mode
& SMB_O_SYNC
) {
7396 create_options
|= FILE_WRITE_THROUGH
;
7398 if (wire_open_mode
& SMB_O_APPEND
) {
7399 access_mask
|= FILE_APPEND_DATA
;
7401 if (wire_open_mode
& SMB_O_DIRECT
) {
7402 mod_unixmode
|= FILE_FLAG_NO_BUFFERING
;
7405 if ((wire_open_mode
& SMB_O_DIRECTORY
) ||
7406 VALID_STAT_OF_DIR(smb_fname
->st
)) {
7407 if (access_mask
!= SMB_O_RDONLY_MAPPING
) {
7408 return NT_STATUS_FILE_IS_A_DIRECTORY
;
7410 create_options
&= ~FILE_NON_DIRECTORY_FILE
;
7411 create_options
|= FILE_DIRECTORY_FILE
;
7414 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7415 smb_fname_str_dbg(smb_fname
),
7416 (unsigned int)wire_open_mode
,
7417 (unsigned int)unixmode
));
7419 status
= SMB_VFS_CREATE_FILE(
7422 0, /* root_dir_fid */
7423 smb_fname
, /* fname */
7424 access_mask
, /* access_mask */
7425 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7427 create_disp
, /* create_disposition*/
7428 create_options
, /* create_options */
7429 mod_unixmode
, /* file_attributes */
7430 oplock_request
, /* oplock_request */
7431 0, /* allocation_size */
7432 0, /* private_flags */
7438 if (!NT_STATUS_IS_OK(status
)) {
7442 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
7443 extended_oplock_granted
= True
;
7446 if(oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
7447 extended_oplock_granted
= True
;
7450 info_level_return
= SVAL(pdata
,16);
7452 /* Allocate the correct return size. */
7454 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7455 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7456 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7457 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7459 *pdata_return_size
= 12;
7462 /* Realloc the data size */
7463 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7464 if (*ppdata
== NULL
) {
7465 close_file(req
, fsp
, ERROR_CLOSE
);
7466 *pdata_return_size
= 0;
7467 return NT_STATUS_NO_MEMORY
;
7471 if (extended_oplock_granted
) {
7472 if (flags
& REQUEST_BATCH_OPLOCK
) {
7473 SSVAL(pdata
,0, BATCH_OPLOCK_RETURN
);
7475 SSVAL(pdata
,0, EXCLUSIVE_OPLOCK_RETURN
);
7477 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
7478 SSVAL(pdata
,0, LEVEL_II_OPLOCK_RETURN
);
7480 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7483 SSVAL(pdata
,2,fsp
->fnum
);
7484 SIVAL(pdata
,4,info
); /* Was file created etc. */
7486 switch (info_level_return
) {
7487 case SMB_QUERY_FILE_UNIX_BASIC
:
7488 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7489 SSVAL(pdata
,10,0); /* padding. */
7490 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7493 case SMB_QUERY_FILE_UNIX_INFO2
:
7494 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7495 SSVAL(pdata
,10,0); /* padding. */
7496 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7500 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7501 SSVAL(pdata
,10,0); /* padding. */
7504 return NT_STATUS_OK
;
7507 /****************************************************************************
7508 Delete a file with POSIX semantics.
7509 ****************************************************************************/
7511 static NTSTATUS
smb_posix_unlink(connection_struct
*conn
,
7512 struct smb_request
*req
,
7515 struct smb_filename
*smb_fname
)
7517 NTSTATUS status
= NT_STATUS_OK
;
7518 files_struct
*fsp
= NULL
;
7522 int create_options
= 0;
7524 struct share_mode_lock
*lck
= NULL
;
7526 if (total_data
< 2) {
7527 return NT_STATUS_INVALID_PARAMETER
;
7530 flags
= SVAL(pdata
,0);
7532 if (!VALID_STAT(smb_fname
->st
)) {
7533 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
7536 if ((flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) &&
7537 !VALID_STAT_OF_DIR(smb_fname
->st
)) {
7538 return NT_STATUS_NOT_A_DIRECTORY
;
7541 DEBUG(10,("smb_posix_unlink: %s %s\n",
7542 (flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) ? "directory" : "file",
7543 smb_fname_str_dbg(smb_fname
)));
7545 if (VALID_STAT_OF_DIR(smb_fname
->st
)) {
7546 create_options
|= FILE_DIRECTORY_FILE
;
7549 status
= SMB_VFS_CREATE_FILE(
7552 0, /* root_dir_fid */
7553 smb_fname
, /* fname */
7554 DELETE_ACCESS
, /* access_mask */
7555 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7557 FILE_OPEN
, /* create_disposition*/
7558 create_options
, /* create_options */
7559 FILE_FLAG_POSIX_SEMANTICS
|0777, /* file_attributes */
7560 0, /* oplock_request */
7561 0, /* allocation_size */
7562 0, /* private_flags */
7568 if (!NT_STATUS_IS_OK(status
)) {
7573 * Don't lie to client. If we can't really delete due to
7574 * non-POSIX opens return SHARING_VIOLATION.
7577 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
7579 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7580 "lock for file %s\n", fsp_str_dbg(fsp
)));
7581 close_file(req
, fsp
, NORMAL_CLOSE
);
7582 return NT_STATUS_INVALID_PARAMETER
;
7586 * See if others still have the file open. If this is the case, then
7587 * don't delete. If all opens are POSIX delete we can set the delete
7588 * on close disposition.
7590 for (i
=0; i
<lck
->data
->num_share_modes
; i
++) {
7591 struct share_mode_entry
*e
= &lck
->data
->share_modes
[i
];
7592 if (is_valid_share_mode_entry(e
)) {
7593 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
7596 if (share_mode_stale_pid(lck
->data
, i
)) {
7599 /* Fail with sharing violation. */
7600 close_file(req
, fsp
, NORMAL_CLOSE
);
7602 return NT_STATUS_SHARING_VIOLATION
;
7607 * Set the delete on close.
7609 status
= smb_set_file_disposition_info(conn
,
7615 if (!NT_STATUS_IS_OK(status
)) {
7616 close_file(req
, fsp
, NORMAL_CLOSE
);
7621 return close_file(req
, fsp
, NORMAL_CLOSE
);
7624 NTSTATUS
smbd_do_setfilepathinfo(connection_struct
*conn
,
7625 struct smb_request
*req
,
7626 TALLOC_CTX
*mem_ctx
,
7627 uint16_t info_level
,
7629 struct smb_filename
*smb_fname
,
7630 char **ppdata
, int total_data
,
7633 char *pdata
= *ppdata
;
7634 NTSTATUS status
= NT_STATUS_OK
;
7635 int data_return_size
= 0;
7639 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
7640 return NT_STATUS_INVALID_LEVEL
;
7643 if (!CAN_WRITE(conn
)) {
7644 /* Allow POSIX opens. The open path will deny
7645 * any non-readonly opens. */
7646 if (info_level
!= SMB_POSIX_PATH_OPEN
) {
7647 return NT_STATUS_DOS(ERRSRV
, ERRaccess
);
7651 DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
7652 "totdata=%d\n", smb_fname_str_dbg(smb_fname
),
7654 info_level
, total_data
));
7656 switch (info_level
) {
7658 case SMB_INFO_STANDARD
:
7660 status
= smb_set_info_standard(conn
,
7668 case SMB_INFO_SET_EA
:
7670 status
= smb_info_set_ea(conn
,
7678 case SMB_SET_FILE_BASIC_INFO
:
7679 case SMB_FILE_BASIC_INFORMATION
:
7681 status
= smb_set_file_basic_info(conn
,
7689 case SMB_FILE_ALLOCATION_INFORMATION
:
7690 case SMB_SET_FILE_ALLOCATION_INFO
:
7692 status
= smb_set_file_allocation_info(conn
, req
,
7700 case SMB_FILE_END_OF_FILE_INFORMATION
:
7701 case SMB_SET_FILE_END_OF_FILE_INFO
:
7704 * XP/Win7 both fail after the createfile with
7705 * SMB_SET_FILE_END_OF_FILE_INFO but not
7706 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7707 * The level is known here, so pass it down
7711 (info_level
== SMB_SET_FILE_END_OF_FILE_INFO
);
7713 status
= smb_set_file_end_of_file_info(conn
, req
,
7722 case SMB_FILE_DISPOSITION_INFORMATION
:
7723 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
7726 /* JRA - We used to just ignore this on a path ?
7727 * Shouldn't this be invalid level on a pathname
7730 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
7731 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
7734 status
= smb_set_file_disposition_info(conn
,
7742 case SMB_FILE_POSITION_INFORMATION
:
7744 status
= smb_file_position_information(conn
,
7751 case SMB_FILE_FULL_EA_INFORMATION
:
7753 status
= smb_set_file_full_ea_info(conn
,
7760 /* From tridge Samba4 :
7761 * MODE_INFORMATION in setfileinfo (I have no
7762 * idea what "mode information" on a file is - it takes a value of 0,
7763 * 2, 4 or 6. What could it be?).
7766 case SMB_FILE_MODE_INFORMATION
:
7768 status
= smb_file_mode_information(conn
,
7775 * CIFS UNIX extensions.
7778 case SMB_SET_FILE_UNIX_BASIC
:
7780 status
= smb_set_file_unix_basic(conn
, req
,
7788 case SMB_SET_FILE_UNIX_INFO2
:
7790 status
= smb_set_file_unix_info2(conn
, req
,
7798 case SMB_SET_FILE_UNIX_LINK
:
7801 /* We must have a pathname for this. */
7802 return NT_STATUS_INVALID_LEVEL
;
7804 status
= smb_set_file_unix_link(conn
, req
, pdata
,
7805 total_data
, smb_fname
);
7809 case SMB_SET_FILE_UNIX_HLINK
:
7812 /* We must have a pathname for this. */
7813 return NT_STATUS_INVALID_LEVEL
;
7815 status
= smb_set_file_unix_hlink(conn
, req
,
7821 case SMB_FILE_RENAME_INFORMATION
:
7823 status
= smb_file_rename_information(conn
, req
,
7829 case SMB2_FILE_RENAME_INFORMATION_INTERNAL
:
7831 /* SMB2 rename information. */
7832 status
= smb2_file_rename_information(conn
, req
,
7838 case SMB_FILE_LINK_INFORMATION
:
7840 status
= smb_file_link_information(conn
, req
,
7846 #if defined(HAVE_POSIX_ACLS)
7847 case SMB_SET_POSIX_ACL
:
7849 status
= smb_set_posix_acl(conn
,
7858 case SMB_SET_POSIX_LOCK
:
7861 return NT_STATUS_INVALID_LEVEL
;
7863 status
= smb_set_posix_lock(conn
, req
,
7864 pdata
, total_data
, fsp
);
7868 case SMB_POSIX_PATH_OPEN
:
7871 /* We must have a pathname for this. */
7872 return NT_STATUS_INVALID_LEVEL
;
7875 status
= smb_posix_open(conn
, req
,
7883 case SMB_POSIX_PATH_UNLINK
:
7886 /* We must have a pathname for this. */
7887 return NT_STATUS_INVALID_LEVEL
;
7890 status
= smb_posix_unlink(conn
, req
,
7898 return NT_STATUS_INVALID_LEVEL
;
7901 if (!NT_STATUS_IS_OK(status
)) {
7905 *ret_data_size
= data_return_size
;
7906 return NT_STATUS_OK
;
7909 /****************************************************************************
7910 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
7911 ****************************************************************************/
7913 static void call_trans2setfilepathinfo(connection_struct
*conn
,
7914 struct smb_request
*req
,
7915 unsigned int tran_call
,
7916 char **pparams
, int total_params
,
7917 char **ppdata
, int total_data
,
7918 unsigned int max_data_bytes
)
7920 char *params
= *pparams
;
7921 char *pdata
= *ppdata
;
7923 struct smb_filename
*smb_fname
= NULL
;
7924 files_struct
*fsp
= NULL
;
7925 NTSTATUS status
= NT_STATUS_OK
;
7926 int data_return_size
= 0;
7929 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7933 if (tran_call
== TRANSACT2_SETFILEINFO
) {
7934 if (total_params
< 4) {
7935 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7939 fsp
= file_fsp(req
, SVAL(params
,0));
7940 /* Basic check for non-null fsp. */
7941 if (!check_fsp_open(conn
, req
, fsp
)) {
7944 info_level
= SVAL(params
,2);
7946 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
7948 if (!NT_STATUS_IS_OK(status
)) {
7949 reply_nterror(req
, status
);
7953 if(fsp
->fh
->fd
== -1) {
7955 * This is actually a SETFILEINFO on a directory
7956 * handle (returned from an NT SMB). NT5.0 seems
7957 * to do this call. JRA.
7959 if (INFO_LEVEL_IS_UNIX(info_level
)) {
7960 /* Always do lstat for UNIX calls. */
7961 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
7962 DEBUG(3,("call_trans2setfilepathinfo: "
7963 "SMB_VFS_LSTAT of %s failed "
7965 smb_fname_str_dbg(smb_fname
),
7967 reply_nterror(req
, map_nt_error_from_unix(errno
));
7971 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
7972 DEBUG(3,("call_trans2setfilepathinfo: "
7973 "fileinfo of %s failed (%s)\n",
7974 smb_fname_str_dbg(smb_fname
),
7976 reply_nterror(req
, map_nt_error_from_unix(errno
));
7980 } else if (fsp
->print_file
) {
7982 * Doing a DELETE_ON_CLOSE should cancel a print job.
7984 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
7985 fsp
->fh
->private_options
|= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE
;
7987 DEBUG(3,("call_trans2setfilepathinfo: "
7988 "Cancelling print job (%s)\n",
7992 send_trans2_replies(conn
, req
, params
, 2,
7998 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
8003 * Original code - this is an open file.
8005 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
8006 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8007 "of %s failed (%s)\n", fsp_fnum_dbg(fsp
),
8009 reply_nterror(req
, map_nt_error_from_unix(errno
));
8015 uint32_t ucf_flags
= 0;
8018 if (total_params
< 7) {
8019 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8023 info_level
= SVAL(params
,0);
8024 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
8025 total_params
- 6, STR_TERMINATE
,
8027 if (!NT_STATUS_IS_OK(status
)) {
8028 reply_nterror(req
, status
);
8032 if (info_level
== SMB_SET_FILE_UNIX_BASIC
||
8033 info_level
== SMB_SET_FILE_UNIX_INFO2
||
8034 info_level
== SMB_FILE_RENAME_INFORMATION
||
8035 info_level
== SMB_POSIX_PATH_UNLINK
) {
8036 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
8039 status
= filename_convert(req
, conn
,
8040 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8045 if (!NT_STATUS_IS_OK(status
)) {
8046 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8047 reply_botherror(req
,
8048 NT_STATUS_PATH_NOT_COVERED
,
8049 ERRSRV
, ERRbadpath
);
8052 reply_nterror(req
, status
);
8056 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8058 * For CIFS UNIX extensions the target name may not exist.
8061 /* Always do lstat for UNIX calls. */
8062 SMB_VFS_LSTAT(conn
, smb_fname
);
8064 } else if (!VALID_STAT(smb_fname
->st
) &&
8065 SMB_VFS_STAT(conn
, smb_fname
)) {
8066 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8068 smb_fname_str_dbg(smb_fname
),
8070 reply_nterror(req
, map_nt_error_from_unix(errno
));
8075 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
8076 "totdata=%d\n", tran_call
, smb_fname_str_dbg(smb_fname
),
8078 info_level
,total_data
));
8080 /* Realloc the parameter size */
8081 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8082 if (*pparams
== NULL
) {
8083 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8090 status
= smbd_do_setfilepathinfo(conn
, req
, req
,
8096 if (!NT_STATUS_IS_OK(status
)) {
8097 if (open_was_deferred(req
->sconn
, req
->mid
)) {
8098 /* We have re-scheduled this call. */
8101 if (blocking_lock_was_deferred_smb1(req
->sconn
, req
->mid
)) {
8102 /* We have re-scheduled this call. */
8105 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8106 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
8107 ERRSRV
, ERRbadpath
);
8110 if (info_level
== SMB_POSIX_PATH_OPEN
) {
8111 reply_openerror(req
, status
);
8115 reply_nterror(req
, status
);
8119 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, data_return_size
,
8125 /****************************************************************************
8126 Reply to a TRANS2_MKDIR (make directory with extended attributes).
8127 ****************************************************************************/
8129 static void call_trans2mkdir(connection_struct
*conn
, struct smb_request
*req
,
8130 char **pparams
, int total_params
,
8131 char **ppdata
, int total_data
,
8132 unsigned int max_data_bytes
)
8134 struct smb_filename
*smb_dname
= NULL
;
8135 char *params
= *pparams
;
8136 char *pdata
= *ppdata
;
8137 char *directory
= NULL
;
8138 NTSTATUS status
= NT_STATUS_OK
;
8139 struct ea_list
*ea_list
= NULL
;
8140 TALLOC_CTX
*ctx
= talloc_tos();
8142 if (!CAN_WRITE(conn
)) {
8143 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8147 if (total_params
< 5) {
8148 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8152 srvstr_get_path(ctx
, params
, req
->flags2
, &directory
, ¶ms
[4],
8153 total_params
- 4, STR_TERMINATE
,
8155 if (!NT_STATUS_IS_OK(status
)) {
8156 reply_nterror(req
, status
);
8160 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
8162 status
= filename_convert(ctx
,
8164 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8170 if (!NT_STATUS_IS_OK(status
)) {
8171 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8172 reply_botherror(req
,
8173 NT_STATUS_PATH_NOT_COVERED
,
8174 ERRSRV
, ERRbadpath
);
8177 reply_nterror(req
, status
);
8182 * OS/2 workplace shell seems to send SET_EA requests of "null"
8183 * length (4 bytes containing IVAL 4).
8184 * They seem to have no effect. Bug #3212. JRA.
8187 if (total_data
&& (total_data
!= 4)) {
8188 /* Any data in this call is an EA list. */
8189 if (total_data
< 10) {
8190 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8194 if (IVAL(pdata
,0) > total_data
) {
8195 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8196 IVAL(pdata
,0), (unsigned int)total_data
));
8197 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8201 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
8204 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8208 if (!lp_ea_support(SNUM(conn
))) {
8209 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
8213 /* If total_data == 4 Windows doesn't care what values
8214 * are placed in that field, it just ignores them.
8215 * The System i QNTC IBM SMB client puts bad values here,
8216 * so ignore them. */
8218 status
= create_directory(conn
, req
, smb_dname
);
8220 if (!NT_STATUS_IS_OK(status
)) {
8221 reply_nterror(req
, status
);
8225 /* Try and set any given EA. */
8227 status
= set_ea(conn
, NULL
, smb_dname
, ea_list
);
8228 if (!NT_STATUS_IS_OK(status
)) {
8229 reply_nterror(req
, status
);
8234 /* Realloc the parameter and data sizes */
8235 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8236 if(*pparams
== NULL
) {
8237 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8244 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, 0, max_data_bytes
);
8247 TALLOC_FREE(smb_dname
);
8251 /****************************************************************************
8252 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8253 We don't actually do this - we just send a null response.
8254 ****************************************************************************/
8256 static void call_trans2findnotifyfirst(connection_struct
*conn
,
8257 struct smb_request
*req
,
8258 char **pparams
, int total_params
,
8259 char **ppdata
, int total_data
,
8260 unsigned int max_data_bytes
)
8262 char *params
= *pparams
;
8265 if (total_params
< 6) {
8266 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8270 info_level
= SVAL(params
,4);
8271 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
8273 switch (info_level
) {
8278 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
8282 /* Realloc the parameter and data sizes */
8283 *pparams
= (char *)SMB_REALLOC(*pparams
,6);
8284 if (*pparams
== NULL
) {
8285 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8290 SSVAL(params
,0,fnf_handle
);
8291 SSVAL(params
,2,0); /* No changes */
8292 SSVAL(params
,4,0); /* No EA errors */
8299 send_trans2_replies(conn
, req
, params
, 6, *ppdata
, 0, max_data_bytes
);
8304 /****************************************************************************
8305 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
8306 changes). Currently this does nothing.
8307 ****************************************************************************/
8309 static void call_trans2findnotifynext(connection_struct
*conn
,
8310 struct smb_request
*req
,
8311 char **pparams
, int total_params
,
8312 char **ppdata
, int total_data
,
8313 unsigned int max_data_bytes
)
8315 char *params
= *pparams
;
8317 DEBUG(3,("call_trans2findnotifynext\n"));
8319 /* Realloc the parameter and data sizes */
8320 *pparams
= (char *)SMB_REALLOC(*pparams
,4);
8321 if (*pparams
== NULL
) {
8322 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8327 SSVAL(params
,0,0); /* No changes */
8328 SSVAL(params
,2,0); /* No EA errors */
8330 send_trans2_replies(conn
, req
, params
, 4, *ppdata
, 0, max_data_bytes
);
8335 /****************************************************************************
8336 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8337 ****************************************************************************/
8339 static void call_trans2getdfsreferral(connection_struct
*conn
,
8340 struct smb_request
*req
,
8341 char **pparams
, int total_params
,
8342 char **ppdata
, int total_data
,
8343 unsigned int max_data_bytes
)
8345 char *params
= *pparams
;
8346 char *pathname
= NULL
;
8348 int max_referral_level
;
8349 NTSTATUS status
= NT_STATUS_OK
;
8350 TALLOC_CTX
*ctx
= talloc_tos();
8352 DEBUG(10,("call_trans2getdfsreferral\n"));
8354 if (total_params
< 3) {
8355 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8359 max_referral_level
= SVAL(params
,0);
8361 if(!lp_host_msdfs()) {
8362 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8366 srvstr_pull_talloc(ctx
, params
, req
->flags2
, &pathname
, ¶ms
[2],
8367 total_params
- 2, STR_TERMINATE
);
8369 reply_nterror(req
, NT_STATUS_NOT_FOUND
);
8372 if((reply_size
= setup_dfs_referral(conn
, pathname
, max_referral_level
,
8373 ppdata
,&status
)) < 0) {
8374 reply_nterror(req
, status
);
8378 SSVAL((discard_const_p(uint8_t, req
->inbuf
)), smb_flg2
,
8379 SVAL(req
->inbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
8380 send_trans2_replies(conn
, req
,0,0,*ppdata
,reply_size
, max_data_bytes
);
8385 #define LMCAT_SPL 0x53
8386 #define LMFUNC_GETJOBID 0x60
8388 /****************************************************************************
8389 Reply to a TRANS2_IOCTL - used for OS/2 printing.
8390 ****************************************************************************/
8392 static void call_trans2ioctl(connection_struct
*conn
,
8393 struct smb_request
*req
,
8394 char **pparams
, int total_params
,
8395 char **ppdata
, int total_data
,
8396 unsigned int max_data_bytes
)
8398 char *pdata
= *ppdata
;
8399 files_struct
*fsp
= file_fsp(req
, SVAL(req
->vwv
+15, 0));
8401 /* check for an invalid fid before proceeding */
8404 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8408 if ((SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8409 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8410 *ppdata
= (char *)SMB_REALLOC(*ppdata
, 32);
8411 if (*ppdata
== NULL
) {
8412 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8417 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8418 CAN ACCEPT THIS IN UNICODE. JRA. */
8421 SSVAL(pdata
, 0, print_spool_rap_jobid(fsp
->print_file
));
8423 srvstr_push(pdata
, req
->flags2
, pdata
+ 2,
8424 lp_netbios_name(), 15,
8425 STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
8426 srvstr_push(pdata
, req
->flags2
, pdata
+18,
8427 lp_servicename(SNUM(conn
)), 13,
8428 STR_ASCII
|STR_TERMINATE
); /* Service name */
8429 send_trans2_replies(conn
, req
, *pparams
, 0, *ppdata
, 32,
8434 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8435 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8438 /****************************************************************************
8439 Reply to a SMBfindclose (stop trans2 directory search).
8440 ****************************************************************************/
8442 void reply_findclose(struct smb_request
*req
)
8445 struct smbd_server_connection
*sconn
= req
->sconn
;
8447 START_PROFILE(SMBfindclose
);
8450 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8451 END_PROFILE(SMBfindclose
);
8455 dptr_num
= SVALS(req
->vwv
+0, 0);
8457 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
8459 dptr_close(sconn
, &dptr_num
);
8461 reply_outbuf(req
, 0, 0);
8463 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
8465 END_PROFILE(SMBfindclose
);
8469 /****************************************************************************
8470 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8471 ****************************************************************************/
8473 void reply_findnclose(struct smb_request
*req
)
8477 START_PROFILE(SMBfindnclose
);
8480 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8481 END_PROFILE(SMBfindnclose
);
8485 dptr_num
= SVAL(req
->vwv
+0, 0);
8487 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
8489 /* We never give out valid handles for a
8490 findnotifyfirst - so any dptr_num is ok here.
8493 reply_outbuf(req
, 0, 0);
8495 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
8497 END_PROFILE(SMBfindnclose
);
8501 static void handle_trans2(connection_struct
*conn
, struct smb_request
*req
,
8502 struct trans_state
*state
)
8504 if (get_Protocol() >= PROTOCOL_NT1
) {
8505 req
->flags2
|= 0x40; /* IS_LONG_NAME */
8506 SSVAL((discard_const_p(uint8_t, req
->inbuf
)),smb_flg2
,req
->flags2
);
8509 if (conn
->encrypt_level
== Required
&& !req
->encrypted
) {
8510 if (state
->call
!= TRANSACT2_QFSINFO
&&
8511 state
->call
!= TRANSACT2_SETFSINFO
) {
8512 DEBUG(0,("handle_trans2: encryption required "
8514 (unsigned int)state
->call
));
8515 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8520 SMB_PERFCOUNT_SET_SUBOP(&req
->pcd
, state
->call
);
8522 /* Now we must call the relevant TRANS2 function */
8523 switch(state
->call
) {
8524 case TRANSACT2_OPEN
:
8526 START_PROFILE(Trans2_open
);
8527 call_trans2open(conn
, req
,
8528 &state
->param
, state
->total_param
,
8529 &state
->data
, state
->total_data
,
8530 state
->max_data_return
);
8531 END_PROFILE(Trans2_open
);
8535 case TRANSACT2_FINDFIRST
:
8537 START_PROFILE(Trans2_findfirst
);
8538 call_trans2findfirst(conn
, req
,
8539 &state
->param
, state
->total_param
,
8540 &state
->data
, state
->total_data
,
8541 state
->max_data_return
);
8542 END_PROFILE(Trans2_findfirst
);
8546 case TRANSACT2_FINDNEXT
:
8548 START_PROFILE(Trans2_findnext
);
8549 call_trans2findnext(conn
, req
,
8550 &state
->param
, state
->total_param
,
8551 &state
->data
, state
->total_data
,
8552 state
->max_data_return
);
8553 END_PROFILE(Trans2_findnext
);
8557 case TRANSACT2_QFSINFO
:
8559 START_PROFILE(Trans2_qfsinfo
);
8560 call_trans2qfsinfo(conn
, req
,
8561 &state
->param
, state
->total_param
,
8562 &state
->data
, state
->total_data
,
8563 state
->max_data_return
);
8564 END_PROFILE(Trans2_qfsinfo
);
8568 case TRANSACT2_SETFSINFO
:
8570 START_PROFILE(Trans2_setfsinfo
);
8571 call_trans2setfsinfo(conn
, req
,
8572 &state
->param
, state
->total_param
,
8573 &state
->data
, state
->total_data
,
8574 state
->max_data_return
);
8575 END_PROFILE(Trans2_setfsinfo
);
8579 case TRANSACT2_QPATHINFO
:
8580 case TRANSACT2_QFILEINFO
:
8582 START_PROFILE(Trans2_qpathinfo
);
8583 call_trans2qfilepathinfo(conn
, req
, state
->call
,
8584 &state
->param
, state
->total_param
,
8585 &state
->data
, state
->total_data
,
8586 state
->max_data_return
);
8587 END_PROFILE(Trans2_qpathinfo
);
8591 case TRANSACT2_SETPATHINFO
:
8592 case TRANSACT2_SETFILEINFO
:
8594 START_PROFILE(Trans2_setpathinfo
);
8595 call_trans2setfilepathinfo(conn
, req
, state
->call
,
8596 &state
->param
, state
->total_param
,
8597 &state
->data
, state
->total_data
,
8598 state
->max_data_return
);
8599 END_PROFILE(Trans2_setpathinfo
);
8603 case TRANSACT2_FINDNOTIFYFIRST
:
8605 START_PROFILE(Trans2_findnotifyfirst
);
8606 call_trans2findnotifyfirst(conn
, req
,
8607 &state
->param
, state
->total_param
,
8608 &state
->data
, state
->total_data
,
8609 state
->max_data_return
);
8610 END_PROFILE(Trans2_findnotifyfirst
);
8614 case TRANSACT2_FINDNOTIFYNEXT
:
8616 START_PROFILE(Trans2_findnotifynext
);
8617 call_trans2findnotifynext(conn
, req
,
8618 &state
->param
, state
->total_param
,
8619 &state
->data
, state
->total_data
,
8620 state
->max_data_return
);
8621 END_PROFILE(Trans2_findnotifynext
);
8625 case TRANSACT2_MKDIR
:
8627 START_PROFILE(Trans2_mkdir
);
8628 call_trans2mkdir(conn
, req
,
8629 &state
->param
, state
->total_param
,
8630 &state
->data
, state
->total_data
,
8631 state
->max_data_return
);
8632 END_PROFILE(Trans2_mkdir
);
8636 case TRANSACT2_GET_DFS_REFERRAL
:
8638 START_PROFILE(Trans2_get_dfs_referral
);
8639 call_trans2getdfsreferral(conn
, req
,
8640 &state
->param
, state
->total_param
,
8641 &state
->data
, state
->total_data
,
8642 state
->max_data_return
);
8643 END_PROFILE(Trans2_get_dfs_referral
);
8647 case TRANSACT2_IOCTL
:
8649 START_PROFILE(Trans2_ioctl
);
8650 call_trans2ioctl(conn
, req
,
8651 &state
->param
, state
->total_param
,
8652 &state
->data
, state
->total_data
,
8653 state
->max_data_return
);
8654 END_PROFILE(Trans2_ioctl
);
8659 /* Error in request */
8660 DEBUG(2,("Unknown request %d in trans2 call\n", state
->call
));
8661 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8665 /****************************************************************************
8666 Reply to a SMBtrans2.
8667 ****************************************************************************/
8669 void reply_trans2(struct smb_request
*req
)
8671 connection_struct
*conn
= req
->conn
;
8676 unsigned int tran_call
;
8677 struct trans_state
*state
;
8680 START_PROFILE(SMBtrans2
);
8682 if (req
->wct
< 14) {
8683 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8684 END_PROFILE(SMBtrans2
);
8688 dsoff
= SVAL(req
->vwv
+12, 0);
8689 dscnt
= SVAL(req
->vwv
+11, 0);
8690 psoff
= SVAL(req
->vwv
+10, 0);
8691 pscnt
= SVAL(req
->vwv
+9, 0);
8692 tran_call
= SVAL(req
->vwv
+14, 0);
8694 result
= allow_new_trans(conn
->pending_trans
, req
->mid
);
8695 if (!NT_STATUS_IS_OK(result
)) {
8696 DEBUG(2, ("Got invalid trans2 request: %s\n",
8697 nt_errstr(result
)));
8698 reply_nterror(req
, result
);
8699 END_PROFILE(SMBtrans2
);
8704 switch (tran_call
) {
8705 /* List the allowed trans2 calls on IPC$ */
8706 case TRANSACT2_OPEN
:
8707 case TRANSACT2_GET_DFS_REFERRAL
:
8708 case TRANSACT2_QFILEINFO
:
8709 case TRANSACT2_QFSINFO
:
8710 case TRANSACT2_SETFSINFO
:
8713 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8714 END_PROFILE(SMBtrans2
);
8719 if ((state
= talloc(conn
, struct trans_state
)) == NULL
) {
8720 DEBUG(0, ("talloc failed\n"));
8721 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8722 END_PROFILE(SMBtrans2
);
8726 state
->cmd
= SMBtrans2
;
8728 state
->mid
= req
->mid
;
8729 state
->vuid
= req
->vuid
;
8730 state
->setup_count
= SVAL(req
->vwv
+13, 0);
8731 state
->setup
= NULL
;
8732 state
->total_param
= SVAL(req
->vwv
+0, 0);
8733 state
->param
= NULL
;
8734 state
->total_data
= SVAL(req
->vwv
+1, 0);
8736 state
->max_param_return
= SVAL(req
->vwv
+2, 0);
8737 state
->max_data_return
= SVAL(req
->vwv
+3, 0);
8738 state
->max_setup_return
= SVAL(req
->vwv
+4, 0);
8739 state
->close_on_completion
= BITSETW(req
->vwv
+5, 0);
8740 state
->one_way
= BITSETW(req
->vwv
+5, 1);
8742 state
->call
= tran_call
;
8744 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8745 is so as a sanity check */
8746 if (state
->setup_count
!= 1) {
8748 * Need to have rc=0 for ioctl to get job id for OS/2.
8749 * Network printing will fail if function is not successful.
8750 * Similar function in reply.c will be used if protocol
8751 * is LANMAN1.0 instead of LM1.2X002.
8752 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
8753 * outbuf doesn't have to be set(only job id is used).
8755 if ( (state
->setup_count
== 4)
8756 && (tran_call
== TRANSACT2_IOCTL
)
8757 && (SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8758 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8759 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8761 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state
->setup_count
));
8762 DEBUG(2,("Transaction is %d\n",tran_call
));
8764 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8765 END_PROFILE(SMBtrans2
);
8770 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
8773 if (state
->total_data
) {
8775 if (trans_oob(state
->total_data
, 0, dscnt
)
8776 || trans_oob(smb_len(req
->inbuf
), dsoff
, dscnt
)) {
8780 /* Can't use talloc here, the core routines do realloc on the
8781 * params and data. */
8782 state
->data
= (char *)SMB_MALLOC(state
->total_data
);
8783 if (state
->data
== NULL
) {
8784 DEBUG(0,("reply_trans2: data malloc fail for %u "
8785 "bytes !\n", (unsigned int)state
->total_data
));
8787 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8788 END_PROFILE(SMBtrans2
);
8792 memcpy(state
->data
,smb_base(req
->inbuf
)+dsoff
,dscnt
);
8795 if (state
->total_param
) {
8797 if (trans_oob(state
->total_param
, 0, pscnt
)
8798 || trans_oob(smb_len(req
->inbuf
), psoff
, pscnt
)) {
8802 /* Can't use talloc here, the core routines do realloc on the
8803 * params and data. */
8804 state
->param
= (char *)SMB_MALLOC(state
->total_param
);
8805 if (state
->param
== NULL
) {
8806 DEBUG(0,("reply_trans: param malloc fail for %u "
8807 "bytes !\n", (unsigned int)state
->total_param
));
8808 SAFE_FREE(state
->data
);
8810 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8811 END_PROFILE(SMBtrans2
);
8815 memcpy(state
->param
,smb_base(req
->inbuf
)+psoff
,pscnt
);
8818 state
->received_data
= dscnt
;
8819 state
->received_param
= pscnt
;
8821 if ((state
->received_param
== state
->total_param
) &&
8822 (state
->received_data
== state
->total_data
)) {
8824 handle_trans2(conn
, req
, state
);
8826 SAFE_FREE(state
->data
);
8827 SAFE_FREE(state
->param
);
8829 END_PROFILE(SMBtrans2
);
8833 DLIST_ADD(conn
->pending_trans
, state
);
8835 /* We need to send an interim response then receive the rest
8836 of the parameter/data bytes */
8837 reply_outbuf(req
, 0, 0);
8838 show_msg((char *)req
->outbuf
);
8839 END_PROFILE(SMBtrans2
);
8844 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8845 SAFE_FREE(state
->data
);
8846 SAFE_FREE(state
->param
);
8848 END_PROFILE(SMBtrans2
);
8849 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8853 /****************************************************************************
8854 Reply to a SMBtranss2
8855 ****************************************************************************/
8857 void reply_transs2(struct smb_request
*req
)
8859 connection_struct
*conn
= req
->conn
;
8860 unsigned int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
8861 struct trans_state
*state
;
8863 START_PROFILE(SMBtranss2
);
8865 show_msg((const char *)req
->inbuf
);
8867 /* Windows clients expect all replies to
8868 a transact secondary (SMBtranss2 0x33)
8869 to have a command code of transact
8870 (SMBtrans2 0x32). See bug #8989
8871 and also [MS-CIFS] section 2.2.4.47.2
8874 req
->cmd
= SMBtrans2
;
8877 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8878 END_PROFILE(SMBtranss2
);
8882 for (state
= conn
->pending_trans
; state
!= NULL
;
8883 state
= state
->next
) {
8884 if (state
->mid
== req
->mid
) {
8889 if ((state
== NULL
) || (state
->cmd
!= SMBtrans2
)) {
8890 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8891 END_PROFILE(SMBtranss2
);
8895 /* Revise state->total_param and state->total_data in case they have
8896 changed downwards */
8898 if (SVAL(req
->vwv
+0, 0) < state
->total_param
)
8899 state
->total_param
= SVAL(req
->vwv
+0, 0);
8900 if (SVAL(req
->vwv
+1, 0) < state
->total_data
)
8901 state
->total_data
= SVAL(req
->vwv
+1, 0);
8903 pcnt
= SVAL(req
->vwv
+2, 0);
8904 poff
= SVAL(req
->vwv
+3, 0);
8905 pdisp
= SVAL(req
->vwv
+4, 0);
8907 dcnt
= SVAL(req
->vwv
+5, 0);
8908 doff
= SVAL(req
->vwv
+6, 0);
8909 ddisp
= SVAL(req
->vwv
+7, 0);
8911 state
->received_param
+= pcnt
;
8912 state
->received_data
+= dcnt
;
8914 if ((state
->received_data
> state
->total_data
) ||
8915 (state
->received_param
> state
->total_param
))
8919 if (trans_oob(state
->total_param
, pdisp
, pcnt
)
8920 || trans_oob(smb_len(req
->inbuf
), poff
, pcnt
)) {
8923 memcpy(state
->param
+pdisp
,smb_base(req
->inbuf
)+poff
,pcnt
);
8927 if (trans_oob(state
->total_data
, ddisp
, dcnt
)
8928 || trans_oob(smb_len(req
->inbuf
), doff
, dcnt
)) {
8931 memcpy(state
->data
+ddisp
, smb_base(req
->inbuf
)+doff
,dcnt
);
8934 if ((state
->received_param
< state
->total_param
) ||
8935 (state
->received_data
< state
->total_data
)) {
8936 END_PROFILE(SMBtranss2
);
8940 handle_trans2(conn
, req
, state
);
8942 DLIST_REMOVE(conn
->pending_trans
, state
);
8943 SAFE_FREE(state
->data
);
8944 SAFE_FREE(state
->param
);
8947 END_PROFILE(SMBtranss2
);
8952 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
8953 DLIST_REMOVE(conn
->pending_trans
, state
);
8954 SAFE_FREE(state
->data
);
8955 SAFE_FREE(state
->param
);
8957 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8958 END_PROFILE(SMBtranss2
);