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 "libcli/security/security.h"
37 #include "smbprofile.h"
38 #include "rpc_server/srv_pipe_hnd.h"
39 #include "libsmb/libsmb.h"
41 #define DIR_ENTRY_SAFETY_MARGIN 4096
43 static char *store_file_unix_basic(connection_struct
*conn
,
46 const SMB_STRUCT_STAT
*psbuf
);
48 static char *store_file_unix_basic_info2(connection_struct
*conn
,
51 const SMB_STRUCT_STAT
*psbuf
);
53 /********************************************************************
54 Roundup a value to the nearest allocation roundup size boundary.
55 Only do this for Windows clients.
56 ********************************************************************/
58 uint64_t smb_roundup(connection_struct
*conn
, uint64_t val
)
60 uint64_t rval
= lp_allocation_roundup_size(SNUM(conn
));
62 /* Only roundup for Windows clients. */
63 enum remote_arch_types ra_type
= get_remote_arch();
64 if (rval
&& (ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
65 val
= SMB_ROUNDUP(val
,rval
);
70 /********************************************************************
71 Create a 64 bit FileIndex. If the file is on the same device as
72 the root of the share, just return the 64-bit inode. If it isn't,
73 mangle as we used to do.
74 ********************************************************************/
76 uint64_t get_FileIndex(connection_struct
*conn
, const SMB_STRUCT_STAT
*psbuf
)
79 if (conn
->base_share_dev
== psbuf
->st_ex_dev
) {
80 return (uint64_t)psbuf
->st_ex_ino
;
82 file_index
= ((psbuf
->st_ex_ino
) & UINT32_MAX
); /* FileIndexLow */
83 file_index
|= ((uint64_t)((psbuf
->st_ex_dev
) & UINT32_MAX
)) << 32; /* FileIndexHigh */
87 /****************************************************************************
88 Utility functions for dealing with extended attributes.
89 ****************************************************************************/
91 /****************************************************************************
92 Refuse to allow clients to overwrite our private xattrs.
93 ****************************************************************************/
95 static bool samba_private_attr_name(const char *unix_ea_name
)
97 static const char * const prohibited_ea_names
[] = {
98 SAMBA_POSIX_INHERITANCE_EA_NAME
,
99 SAMBA_XATTR_DOS_ATTRIB
,
107 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
108 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
111 if (StrnCaseCmp(unix_ea_name
, SAMBA_XATTR_DOSSTREAM_PREFIX
,
112 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX
)) == 0) {
118 /****************************************************************************
119 Get one EA value. Fill in a struct ea_struct.
120 ****************************************************************************/
122 NTSTATUS
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
123 files_struct
*fsp
, const char *fname
,
124 const char *ea_name
, struct ea_struct
*pea
)
126 /* Get the value of this xattr. Max size is 64k. */
127 size_t attr_size
= 256;
133 val
= TALLOC_REALLOC_ARRAY(mem_ctx
, val
, char, attr_size
);
135 return NT_STATUS_NO_MEMORY
;
138 if (fsp
&& fsp
->fh
->fd
!= -1) {
139 sizeret
= SMB_VFS_FGETXATTR(fsp
, ea_name
, val
, attr_size
);
141 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
144 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
150 return map_nt_error_from_unix(errno
);
153 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name
, (unsigned int)sizeret
));
154 dump_data(10, (uint8
*)val
, sizeret
);
157 if (strnequal(ea_name
, "user.", 5)) {
158 pea
->name
= talloc_strdup(mem_ctx
, &ea_name
[5]);
160 pea
->name
= talloc_strdup(mem_ctx
, ea_name
);
162 if (pea
->name
== NULL
) {
164 return NT_STATUS_NO_MEMORY
;
166 pea
->value
.data
= (unsigned char *)val
;
167 pea
->value
.length
= (size_t)sizeret
;
171 NTSTATUS
get_ea_names_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
172 files_struct
*fsp
, const char *fname
,
173 char ***pnames
, size_t *pnum_names
)
175 /* Get a list of all xattrs. Max namesize is 64k. */
176 size_t ea_namelist_size
= 1024;
177 char *ea_namelist
= NULL
;
182 ssize_t sizeret
= -1;
184 if (!lp_ea_support(SNUM(conn
))) {
193 * TALLOC the result early to get the talloc hierarchy right.
196 names
= TALLOC_ARRAY(mem_ctx
, char *, 1);
198 DEBUG(0, ("talloc failed\n"));
199 return NT_STATUS_NO_MEMORY
;
202 while (ea_namelist_size
<= 65536) {
204 ea_namelist
= TALLOC_REALLOC_ARRAY(
205 names
, ea_namelist
, char, ea_namelist_size
);
206 if (ea_namelist
== NULL
) {
207 DEBUG(0, ("talloc failed\n"));
209 return NT_STATUS_NO_MEMORY
;
212 if (fsp
&& fsp
->fh
->fd
!= -1) {
213 sizeret
= SMB_VFS_FLISTXATTR(fsp
, ea_namelist
,
216 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
,
220 if ((sizeret
== -1) && (errno
== ERANGE
)) {
221 ea_namelist_size
*= 2;
230 return map_nt_error_from_unix(errno
);
233 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
234 (unsigned int)sizeret
));
246 * Ensure the result is 0-terminated
249 if (ea_namelist
[sizeret
-1] != '\0') {
251 return NT_STATUS_INTERNAL_ERROR
;
259 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
263 tmp
= TALLOC_REALLOC_ARRAY(mem_ctx
, names
, char *, num_names
);
265 DEBUG(0, ("talloc failed\n"));
267 return NT_STATUS_NO_MEMORY
;
273 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
274 names
[num_names
++] = p
;
282 *pnum_names
= num_names
;
286 /****************************************************************************
287 Return a linked list of the total EA's. Plus the total size
288 ****************************************************************************/
290 static struct ea_list
*get_ea_list_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
291 const char *fname
, size_t *pea_total_len
)
293 /* Get a list of all xattrs. Max namesize is 64k. */
296 struct ea_list
*ea_list_head
= NULL
;
301 if (!lp_ea_support(SNUM(conn
))) {
305 status
= get_ea_names_from_file(talloc_tos(), conn
, fsp
, fname
,
308 if (!NT_STATUS_IS_OK(status
) || (num_names
== 0)) {
312 for (i
=0; i
<num_names
; i
++) {
313 struct ea_list
*listp
;
316 if (strnequal(names
[i
], "system.", 7)
317 || samba_private_attr_name(names
[i
]))
320 listp
= TALLOC_P(mem_ctx
, struct ea_list
);
325 if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx
, conn
, fsp
,
331 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
334 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
336 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
337 "= %u\n", (unsigned int)*pea_total_len
, dos_ea_name
,
338 (unsigned int)listp
->ea
.value
.length
));
340 DLIST_ADD_END(ea_list_head
, listp
, struct ea_list
*);
344 /* Add on 4 for total length. */
345 if (*pea_total_len
) {
349 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
350 (unsigned int)*pea_total_len
));
355 /****************************************************************************
356 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
358 ****************************************************************************/
360 static unsigned int fill_ea_buffer(TALLOC_CTX
*mem_ctx
, char *pdata
, unsigned int total_data_size
,
361 connection_struct
*conn
, struct ea_list
*ea_list
)
363 unsigned int ret_data_size
= 4;
366 SMB_ASSERT(total_data_size
>= 4);
368 if (!lp_ea_support(SNUM(conn
))) {
373 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
376 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
377 dos_namelen
= strlen(dos_ea_name
);
378 if (dos_namelen
> 255 || dos_namelen
== 0) {
381 if (ea_list
->ea
.value
.length
> 65535) {
384 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
388 /* We know we have room. */
389 SCVAL(p
,0,ea_list
->ea
.flags
);
390 SCVAL(p
,1,dos_namelen
);
391 SSVAL(p
,2,ea_list
->ea
.value
.length
);
392 fstrcpy(p
+4, dos_ea_name
);
393 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
395 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
396 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
399 ret_data_size
= PTR_DIFF(p
, pdata
);
400 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size
));
401 SIVAL(pdata
,0,ret_data_size
);
402 return ret_data_size
;
405 static NTSTATUS
fill_ea_chained_buffer(TALLOC_CTX
*mem_ctx
,
407 unsigned int total_data_size
,
408 unsigned int *ret_data_size
,
409 connection_struct
*conn
,
410 struct ea_list
*ea_list
)
412 uint8_t *p
= (uint8_t *)pdata
;
413 uint8_t *last_start
= NULL
;
414 bool store_data
= (pdata
!= NULL
);
418 if (!lp_ea_support(SNUM(conn
))) {
419 return NT_STATUS_NO_EAS_ON_FILE
;
422 for (; ea_list
; ea_list
= ea_list
->next
) {
427 if (last_start
&& store_data
) {
428 SIVAL(last_start
, 0, PTR_DIFF(p
, last_start
));
432 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
433 dos_namelen
= strlen(dos_ea_name
);
434 if (dos_namelen
> 255 || dos_namelen
== 0) {
435 return NT_STATUS_INTERNAL_ERROR
;
437 if (ea_list
->ea
.value
.length
> 65535) {
438 return NT_STATUS_INTERNAL_ERROR
;
441 this_size
= 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
444 size_t pad
= 4 - (this_size
% 4);
448 if (this_size
> total_data_size
) {
449 return NT_STATUS_INFO_LENGTH_MISMATCH
;
452 /* We know we have room. */
454 SIVAL(p
, 0x00, 0); /* next offset */
455 SCVAL(p
, 0x04, ea_list
->ea
.flags
);
456 SCVAL(p
, 0x05, dos_namelen
);
457 SSVAL(p
, 0x06, ea_list
->ea
.value
.length
);
458 fstrcpy((char *)(p
+0x08), dos_ea_name
);
459 memcpy(p
+ 0x08 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
462 total_data_size
-= this_size
;
466 *ret_data_size
= PTR_DIFF(p
, pdata
);
467 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size
));
471 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
473 size_t total_ea_len
= 0;
474 struct ea_list
*ea_list
= NULL
;
475 TALLOC_CTX
*mem_ctx
= NULL
;
477 if (!lp_ea_support(SNUM(conn
))) {
480 mem_ctx
= talloc_tos();
481 ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
482 if (ea_list
== NULL
) {
485 if(conn
->sconn
->using_smb2
) {
487 unsigned int ret_data_size
;
489 * We're going to be using fill_ea_chained_buffer() to
490 * marshall EA's - this size is significantly larger
491 * than the SMB1 buffer. Re-calculate the size without
494 status
= fill_ea_chained_buffer(mem_ctx
,
500 if (!NT_STATUS_IS_OK(status
)) {
503 total_ea_len
= ret_data_size
;
509 /****************************************************************************
510 Ensure the EA name is case insensitive by matching any existing EA name.
511 ****************************************************************************/
513 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
516 TALLOC_CTX
*mem_ctx
= talloc_tos();
517 struct ea_list
*ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
519 for (; ea_list
; ea_list
= ea_list
->next
) {
520 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
521 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
522 &unix_ea_name
[5], ea_list
->ea
.name
));
523 safe_strcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-6);
529 /****************************************************************************
530 Set or delete an extended attribute.
531 ****************************************************************************/
533 NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
,
534 const struct smb_filename
*smb_fname
, struct ea_list
*ea_list
)
538 if (!lp_ea_support(SNUM(conn
))) {
539 return NT_STATUS_EAS_NOT_SUPPORTED
;
542 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_EA
)) {
543 return NT_STATUS_ACCESS_DENIED
;
546 /* For now setting EAs on streams isn't supported. */
547 fname
= smb_fname
->base_name
;
549 for (;ea_list
; ea_list
= ea_list
->next
) {
551 fstring unix_ea_name
;
553 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
554 fstrcat(unix_ea_name
, ea_list
->ea
.name
);
556 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
558 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, (unsigned int)ea_list
->ea
.value
.length
));
560 if (samba_private_attr_name(unix_ea_name
)) {
561 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
562 return NT_STATUS_ACCESS_DENIED
;
565 if (ea_list
->ea
.value
.length
== 0) {
566 /* Remove the attribute. */
567 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
568 DEBUG(10,("set_ea: deleting ea name %s on "
569 "file %s by file descriptor.\n",
570 unix_ea_name
, fsp_str_dbg(fsp
)));
571 ret
= SMB_VFS_FREMOVEXATTR(fsp
, unix_ea_name
);
573 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
574 unix_ea_name
, fname
));
575 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
578 /* Removing a non existent attribute always succeeds. */
579 if (ret
== -1 && errno
== ENOATTR
) {
580 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
586 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
587 DEBUG(10,("set_ea: setting ea name %s on file "
588 "%s by file descriptor.\n",
589 unix_ea_name
, fsp_str_dbg(fsp
)));
590 ret
= SMB_VFS_FSETXATTR(fsp
, unix_ea_name
,
591 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
593 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
594 unix_ea_name
, fname
));
595 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
,
596 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
602 if (errno
== ENOTSUP
) {
603 return NT_STATUS_EAS_NOT_SUPPORTED
;
606 return map_nt_error_from_unix(errno
);
612 /****************************************************************************
613 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
614 ****************************************************************************/
616 static struct ea_list
*read_ea_name_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
618 struct ea_list
*ea_list_head
= NULL
;
619 size_t converted_size
, offset
= 0;
621 while (offset
+ 2 < data_size
) {
622 struct ea_list
*eal
= TALLOC_ZERO_P(ctx
, struct ea_list
);
623 unsigned int namelen
= CVAL(pdata
,offset
);
625 offset
++; /* Go past the namelen byte. */
627 /* integer wrap paranioa. */
628 if ((offset
+ namelen
< offset
) || (offset
+ namelen
< namelen
) ||
629 (offset
> data_size
) || (namelen
> data_size
) ||
630 (offset
+ namelen
>= data_size
)) {
633 /* Ensure the name is null terminated. */
634 if (pdata
[offset
+ namelen
] != '\0') {
637 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, &pdata
[offset
],
639 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
640 "failed: %s", strerror(errno
)));
646 offset
+= (namelen
+ 1); /* Go past the name + terminating zero. */
647 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
648 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal
->ea
.name
));
654 /****************************************************************************
655 Read one EA list entry from the buffer.
656 ****************************************************************************/
658 struct ea_list
*read_ea_list_entry(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
, size_t *pbytes_used
)
660 struct ea_list
*eal
= TALLOC_ZERO_P(ctx
, struct ea_list
);
662 unsigned int namelen
;
663 size_t converted_size
;
673 eal
->ea
.flags
= CVAL(pdata
,0);
674 namelen
= CVAL(pdata
,1);
675 val_len
= SVAL(pdata
,2);
677 if (4 + namelen
+ 1 + val_len
> data_size
) {
681 /* Ensure the name is null terminated. */
682 if (pdata
[namelen
+ 4] != '\0') {
685 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, pdata
+ 4, &converted_size
)) {
686 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
693 eal
->ea
.value
= data_blob_talloc(eal
, NULL
, (size_t)val_len
+ 1);
694 if (!eal
->ea
.value
.data
) {
698 memcpy(eal
->ea
.value
.data
, pdata
+ 4 + namelen
+ 1, val_len
);
700 /* Ensure we're null terminated just in case we print the value. */
701 eal
->ea
.value
.data
[val_len
] = '\0';
702 /* But don't count the null. */
703 eal
->ea
.value
.length
--;
706 *pbytes_used
= 4 + namelen
+ 1 + val_len
;
709 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal
->ea
.name
));
710 dump_data(10, eal
->ea
.value
.data
, eal
->ea
.value
.length
);
715 /****************************************************************************
716 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
717 ****************************************************************************/
719 static struct ea_list
*read_ea_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
721 struct ea_list
*ea_list_head
= NULL
;
723 size_t bytes_used
= 0;
725 while (offset
< data_size
) {
726 struct ea_list
*eal
= read_ea_list_entry(ctx
, pdata
+ offset
, data_size
- offset
, &bytes_used
);
732 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
733 offset
+= bytes_used
;
739 /****************************************************************************
740 Count the total EA size needed.
741 ****************************************************************************/
743 static size_t ea_list_size(struct ea_list
*ealist
)
746 struct ea_list
*listp
;
749 for (listp
= ealist
; listp
; listp
= listp
->next
) {
750 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
751 ret
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
753 /* Add on 4 for total length. */
761 /****************************************************************************
762 Return a union of EA's from a file list and a list of names.
763 The TALLOC context for the two lists *MUST* be identical as we steal
764 memory from one list to add to another. JRA.
765 ****************************************************************************/
767 static struct ea_list
*ea_list_union(struct ea_list
*name_list
, struct ea_list
*file_list
, size_t *total_ea_len
)
769 struct ea_list
*nlistp
, *flistp
;
771 for (nlistp
= name_list
; nlistp
; nlistp
= nlistp
->next
) {
772 for (flistp
= file_list
; flistp
; flistp
= flistp
->next
) {
773 if (strequal(nlistp
->ea
.name
, flistp
->ea
.name
)) {
779 /* Copy the data from this entry. */
780 nlistp
->ea
.flags
= flistp
->ea
.flags
;
781 nlistp
->ea
.value
= flistp
->ea
.value
;
784 nlistp
->ea
.flags
= 0;
785 ZERO_STRUCT(nlistp
->ea
.value
);
789 *total_ea_len
= ea_list_size(name_list
);
793 /****************************************************************************
794 Send the required number of replies back.
795 We assume all fields other than the data fields are
796 set correctly for the type of call.
797 HACK ! Always assumes smb_setup field is zero.
798 ****************************************************************************/
800 void send_trans2_replies(connection_struct
*conn
,
801 struct smb_request
*req
,
808 /* As we are using a protocol > LANMAN1 then the max_send
809 variable must have been set in the sessetupX call.
810 This takes precedence over the max_xmit field in the
811 global struct. These different max_xmit variables should
812 be merged as this is now too confusing */
814 int data_to_send
= datasize
;
815 int params_to_send
= paramsize
;
817 const char *pp
= params
;
818 const char *pd
= pdata
;
819 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
820 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
821 int data_alignment_offset
= 0;
822 bool overflow
= False
;
823 struct smbd_server_connection
*sconn
= req
->sconn
;
824 int max_send
= sconn
->smb1
.sessions
.max_send
;
826 /* Modify the data_to_send and datasize and set the error if
827 we're trying to send more than max_data_bytes. We still send
828 the part of the packet(s) that fit. Strange, but needed
831 if (max_data_bytes
> 0 && datasize
> max_data_bytes
) {
832 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
833 max_data_bytes
, datasize
));
834 datasize
= data_to_send
= max_data_bytes
;
838 /* If there genuinely are no parameters or data to send just send the empty packet */
840 if(params_to_send
== 0 && data_to_send
== 0) {
841 reply_outbuf(req
, 10, 0);
842 show_msg((char *)req
->outbuf
);
843 if (!srv_send_smb(sconn
,
846 IS_CONN_ENCRYPTED(conn
),
848 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
850 TALLOC_FREE(req
->outbuf
);
854 /* When sending params and data ensure that both are nicely aligned */
855 /* Only do this alignment when there is also data to send - else
856 can cause NT redirector problems. */
858 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
859 data_alignment_offset
= 4 - (params_to_send
% 4);
861 /* Space is bufsize minus Netbios over TCP header minus SMB header */
862 /* The alignment_offset is to align the param bytes on an even byte
863 boundary. NT 4.0 Beta needs this to work correctly. */
865 useable_space
= max_send
- (smb_size
868 + data_alignment_offset
);
870 if (useable_space
< 0) {
871 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
872 "= %d!!!", useable_space
));
873 exit_server_cleanly("send_trans2_replies: Not enough space");
876 while (params_to_send
|| data_to_send
) {
877 /* Calculate whether we will totally or partially fill this packet */
879 total_sent_thistime
= params_to_send
+ data_to_send
;
881 /* We can never send more than useable_space */
883 * Note that 'useable_space' does not include the alignment offsets,
884 * but we must include the alignment offsets in the calculation of
885 * the length of the data we send over the wire, as the alignment offsets
886 * are sent here. Fix from Marc_Jacobsen@hp.com.
889 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
);
891 reply_outbuf(req
, 10, total_sent_thistime
+ alignment_offset
892 + data_alignment_offset
);
894 /* Set total params and data to be sent */
895 SSVAL(req
->outbuf
,smb_tprcnt
,paramsize
);
896 SSVAL(req
->outbuf
,smb_tdrcnt
,datasize
);
898 /* Calculate how many parameters and data we can fit into
899 * this packet. Parameters get precedence
902 params_sent_thistime
= MIN(params_to_send
,useable_space
);
903 data_sent_thistime
= useable_space
- params_sent_thistime
;
904 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
906 SSVAL(req
->outbuf
,smb_prcnt
, params_sent_thistime
);
908 /* smb_proff is the offset from the start of the SMB header to the
909 parameter bytes, however the first 4 bytes of outbuf are
910 the Netbios over TCP header. Thus use smb_base() to subtract
911 them from the calculation */
913 SSVAL(req
->outbuf
,smb_proff
,
914 ((smb_buf(req
->outbuf
)+alignment_offset
)
915 - smb_base(req
->outbuf
)));
917 if(params_sent_thistime
== 0)
918 SSVAL(req
->outbuf
,smb_prdisp
,0);
920 /* Absolute displacement of param bytes sent in this packet */
921 SSVAL(req
->outbuf
,smb_prdisp
,pp
- params
);
923 SSVAL(req
->outbuf
,smb_drcnt
, data_sent_thistime
);
924 if(data_sent_thistime
== 0) {
925 SSVAL(req
->outbuf
,smb_droff
,0);
926 SSVAL(req
->outbuf
,smb_drdisp
, 0);
928 /* The offset of the data bytes is the offset of the
929 parameter bytes plus the number of parameters being sent this time */
930 SSVAL(req
->outbuf
, smb_droff
,
931 ((smb_buf(req
->outbuf
)+alignment_offset
)
932 - smb_base(req
->outbuf
))
933 + params_sent_thistime
+ data_alignment_offset
);
934 SSVAL(req
->outbuf
,smb_drdisp
, pd
- pdata
);
937 /* Initialize the padding for alignment */
939 if (alignment_offset
!= 0) {
940 memset(smb_buf(req
->outbuf
), 0, alignment_offset
);
943 /* Copy the param bytes into the packet */
945 if(params_sent_thistime
) {
946 memcpy((smb_buf(req
->outbuf
)+alignment_offset
), pp
,
947 params_sent_thistime
);
950 /* Copy in the data bytes */
951 if(data_sent_thistime
) {
952 if (data_alignment_offset
!= 0) {
953 memset((smb_buf(req
->outbuf
)+alignment_offset
+
954 params_sent_thistime
), 0,
955 data_alignment_offset
);
957 memcpy(smb_buf(req
->outbuf
)+alignment_offset
958 +params_sent_thistime
+data_alignment_offset
,
959 pd
,data_sent_thistime
);
962 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
963 params_sent_thistime
, data_sent_thistime
, useable_space
));
964 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
965 params_to_send
, data_to_send
, paramsize
, datasize
));
968 error_packet_set((char *)req
->outbuf
,
969 ERRDOS
,ERRbufferoverflow
,
970 STATUS_BUFFER_OVERFLOW
,
974 /* Send the packet */
975 show_msg((char *)req
->outbuf
);
976 if (!srv_send_smb(sconn
,
979 IS_CONN_ENCRYPTED(conn
),
981 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
983 TALLOC_FREE(req
->outbuf
);
985 pp
+= params_sent_thistime
;
986 pd
+= data_sent_thistime
;
988 params_to_send
-= params_sent_thistime
;
989 data_to_send
-= data_sent_thistime
;
992 if(params_to_send
< 0 || data_to_send
< 0) {
993 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
994 params_to_send
, data_to_send
));
1002 /****************************************************************************
1003 Reply to a TRANSACT2_OPEN.
1004 ****************************************************************************/
1006 static void call_trans2open(connection_struct
*conn
,
1007 struct smb_request
*req
,
1008 char **pparams
, int total_params
,
1009 char **ppdata
, int total_data
,
1010 unsigned int max_data_bytes
)
1012 struct smb_filename
*smb_fname
= NULL
;
1013 char *params
= *pparams
;
1014 char *pdata
= *ppdata
;
1017 bool oplock_request
;
1019 bool return_additional_info
;
1028 int fattr
=0,mtime
=0;
1029 SMB_INO_T inode
= 0;
1032 struct ea_list
*ea_list
= NULL
;
1037 uint32 create_disposition
;
1038 uint32 create_options
= 0;
1039 uint32_t private_flags
= 0;
1040 TALLOC_CTX
*ctx
= talloc_tos();
1043 * Ensure we have enough parameters to perform the operation.
1046 if (total_params
< 29) {
1047 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1051 flags
= SVAL(params
, 0);
1052 deny_mode
= SVAL(params
, 2);
1053 open_attr
= SVAL(params
,6);
1054 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
1055 if (oplock_request
) {
1056 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
1060 return_additional_info
= BITSETW(params
,0);
1061 open_sattr
= SVAL(params
, 4);
1062 open_time
= make_unix_date3(params
+8);
1064 open_ofun
= SVAL(params
,12);
1065 open_size
= IVAL(params
,14);
1066 pname
= ¶ms
[28];
1069 reply_nterror(req
, NT_STATUS_NETWORK_ACCESS_DENIED
);
1073 srvstr_get_path(ctx
, params
, req
->flags2
, &fname
, pname
,
1074 total_params
- 28, STR_TERMINATE
,
1076 if (!NT_STATUS_IS_OK(status
)) {
1077 reply_nterror(req
, status
);
1081 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1082 fname
, (unsigned int)deny_mode
, (unsigned int)open_attr
,
1083 (unsigned int)open_ofun
, open_size
));
1085 status
= filename_convert(ctx
,
1087 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1092 if (!NT_STATUS_IS_OK(status
)) {
1093 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1094 reply_botherror(req
,
1095 NT_STATUS_PATH_NOT_COVERED
,
1096 ERRSRV
, ERRbadpath
);
1099 reply_nterror(req
, status
);
1103 if (open_ofun
== 0) {
1104 reply_nterror(req
, NT_STATUS_OBJECT_NAME_COLLISION
);
1108 if (!map_open_params_to_ntcreate(smb_fname
->base_name
, deny_mode
,
1110 &access_mask
, &share_mode
,
1111 &create_disposition
,
1114 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1118 /* Any data in this call is an EA list. */
1119 if (total_data
&& (total_data
!= 4)) {
1120 if (total_data
< 10) {
1121 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1125 if (IVAL(pdata
,0) > total_data
) {
1126 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1127 IVAL(pdata
,0), (unsigned int)total_data
));
1128 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1132 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
1135 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1139 if (!lp_ea_support(SNUM(conn
))) {
1140 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
1145 status
= SMB_VFS_CREATE_FILE(
1148 0, /* root_dir_fid */
1149 smb_fname
, /* fname */
1150 access_mask
, /* access_mask */
1151 share_mode
, /* share_access */
1152 create_disposition
, /* create_disposition*/
1153 create_options
, /* create_options */
1154 open_attr
, /* file_attributes */
1155 oplock_request
, /* oplock_request */
1156 open_size
, /* allocation_size */
1159 ea_list
, /* ea_list */
1161 &smb_action
); /* psbuf */
1163 if (!NT_STATUS_IS_OK(status
)) {
1164 if (open_was_deferred(req
->mid
)) {
1165 /* We have re-scheduled this call. */
1168 reply_openerror(req
, status
);
1172 size
= get_file_size_stat(&smb_fname
->st
);
1173 fattr
= dos_mode(conn
, smb_fname
);
1174 mtime
= convert_timespec_to_time_t(smb_fname
->st
.st_ex_mtime
);
1175 inode
= smb_fname
->st
.st_ex_ino
;
1176 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
1177 close_file(req
, fsp
, ERROR_CLOSE
);
1178 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1182 /* Realloc the size of parameters and data we will return */
1183 *pparams
= (char *)SMB_REALLOC(*pparams
, 30);
1184 if(*pparams
== NULL
) {
1185 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1190 SSVAL(params
,0,fsp
->fnum
);
1191 SSVAL(params
,2,fattr
);
1192 srv_put_dos_date2(params
,4, mtime
);
1193 SIVAL(params
,8, (uint32
)size
);
1194 SSVAL(params
,12,deny_mode
);
1195 SSVAL(params
,14,0); /* open_type - file or directory. */
1196 SSVAL(params
,16,0); /* open_state - only valid for IPC device. */
1198 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1199 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1202 SSVAL(params
,18,smb_action
);
1205 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1207 SIVAL(params
,20,inode
);
1208 SSVAL(params
,24,0); /* Padding. */
1210 uint32 ea_size
= estimate_ea_size(conn
, fsp
,
1211 fsp
->fsp_name
->base_name
);
1212 SIVAL(params
, 26, ea_size
);
1214 SIVAL(params
, 26, 0);
1217 /* Send the required number of replies */
1218 send_trans2_replies(conn
, req
, params
, 30, *ppdata
, 0, max_data_bytes
);
1220 TALLOC_FREE(smb_fname
);
1223 /*********************************************************
1224 Routine to check if a given string matches exactly.
1225 as a special case a mask of "." does NOT match. That
1226 is required for correct wildcard semantics
1227 Case can be significant or not.
1228 **********************************************************/
1230 static bool exact_match(bool has_wild
,
1231 bool case_sensitive
,
1235 if (mask
[0] == '.' && mask
[1] == 0) {
1243 if (case_sensitive
) {
1244 return strcmp(str
,mask
)==0;
1246 return StrCaseCmp(str
,mask
) == 0;
1250 /****************************************************************************
1251 Return the filetype for UNIX extensions.
1252 ****************************************************************************/
1254 static uint32
unix_filetype(mode_t mode
)
1257 return UNIX_TYPE_FILE
;
1258 else if(S_ISDIR(mode
))
1259 return UNIX_TYPE_DIR
;
1261 else if(S_ISLNK(mode
))
1262 return UNIX_TYPE_SYMLINK
;
1265 else if(S_ISCHR(mode
))
1266 return UNIX_TYPE_CHARDEV
;
1269 else if(S_ISBLK(mode
))
1270 return UNIX_TYPE_BLKDEV
;
1273 else if(S_ISFIFO(mode
))
1274 return UNIX_TYPE_FIFO
;
1277 else if(S_ISSOCK(mode
))
1278 return UNIX_TYPE_SOCKET
;
1281 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode
));
1282 return UNIX_TYPE_UNKNOWN
;
1285 /****************************************************************************
1286 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1287 ****************************************************************************/
1289 enum perm_type
{ PERM_NEW_FILE
, PERM_NEW_DIR
, PERM_EXISTING_FILE
, PERM_EXISTING_DIR
};
1291 static NTSTATUS
unix_perms_from_wire( connection_struct
*conn
,
1292 const SMB_STRUCT_STAT
*psbuf
,
1294 enum perm_type ptype
,
1299 if (perms
== SMB_MODE_NO_CHANGE
) {
1300 if (!VALID_STAT(*psbuf
)) {
1301 return NT_STATUS_INVALID_PARAMETER
;
1303 *ret_perms
= psbuf
->st_ex_mode
;
1304 return NT_STATUS_OK
;
1308 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
1309 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
1310 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
1311 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
1312 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
1313 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
1314 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
1315 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
1316 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
1318 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
1321 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
1324 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
1329 /* Apply mode mask */
1330 ret
&= lp_create_mask(SNUM(conn
));
1331 /* Add in force bits */
1332 ret
|= lp_force_create_mode(SNUM(conn
));
1335 ret
&= lp_dir_mask(SNUM(conn
));
1336 /* Add in force bits */
1337 ret
|= lp_force_dir_mode(SNUM(conn
));
1339 case PERM_EXISTING_FILE
:
1340 /* Apply mode mask */
1341 ret
&= lp_security_mask(SNUM(conn
));
1342 /* Add in force bits */
1343 ret
|= lp_force_security_mode(SNUM(conn
));
1345 case PERM_EXISTING_DIR
:
1346 /* Apply mode mask */
1347 ret
&= lp_dir_security_mask(SNUM(conn
));
1348 /* Add in force bits */
1349 ret
|= lp_force_dir_security_mode(SNUM(conn
));
1354 return NT_STATUS_OK
;
1357 /****************************************************************************
1358 Needed to show the msdfs symlinks as directories. Modifies psbuf
1359 to be a directory if it's a msdfs link.
1360 ****************************************************************************/
1362 static bool check_msdfs_link(connection_struct
*conn
,
1363 const char *pathname
,
1364 SMB_STRUCT_STAT
*psbuf
)
1366 int saved_errno
= errno
;
1367 if(lp_host_msdfs() &&
1368 lp_msdfs_root(SNUM(conn
)) &&
1369 is_msdfs_link(conn
, pathname
, psbuf
)) {
1371 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1374 psbuf
->st_ex_mode
= (psbuf
->st_ex_mode
& 0xFFF) | S_IFDIR
;
1375 errno
= saved_errno
;
1378 errno
= saved_errno
;
1383 /****************************************************************************
1384 Get a level dependent lanman2 dir entry.
1385 ****************************************************************************/
1387 struct smbd_dirptr_lanman2_state
{
1388 connection_struct
*conn
;
1389 uint32_t info_level
;
1390 bool check_mangled_names
;
1392 bool got_exact_match
;
1395 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX
*ctx
,
1401 struct smbd_dirptr_lanman2_state
*state
=
1402 (struct smbd_dirptr_lanman2_state
*)private_data
;
1404 char mangled_name
[13]; /* mangled 8.3 name. */
1408 /* Mangle fname if it's an illegal name. */
1409 if (mangle_must_mangle(dname
, state
->conn
->params
)) {
1410 ok
= name_to_8_3(dname
, mangled_name
,
1411 true, state
->conn
->params
);
1415 fname
= mangled_name
;
1420 got_match
= exact_match(state
->has_wild
,
1421 state
->conn
->case_sensitive
,
1423 state
->got_exact_match
= got_match
;
1425 got_match
= mask_match(fname
, mask
,
1426 state
->conn
->case_sensitive
);
1429 if(!got_match
&& state
->check_mangled_names
&&
1430 !mangle_is_8_3(fname
, false, state
->conn
->params
)) {
1432 * It turns out that NT matches wildcards against
1433 * both long *and* short names. This may explain some
1434 * of the wildcard wierdness from old DOS clients
1435 * that some people have been seeing.... JRA.
1437 /* Force the mangling into 8.3. */
1438 ok
= name_to_8_3(fname
, mangled_name
,
1439 false, state
->conn
->params
);
1444 got_match
= exact_match(state
->has_wild
,
1445 state
->conn
->case_sensitive
,
1446 mangled_name
, mask
);
1447 state
->got_exact_match
= got_match
;
1449 got_match
= mask_match(mangled_name
, mask
,
1450 state
->conn
->case_sensitive
);
1458 *_fname
= talloc_strdup(ctx
, fname
);
1459 if (*_fname
== NULL
) {
1466 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX
*ctx
,
1468 struct smb_filename
*smb_fname
,
1471 struct smbd_dirptr_lanman2_state
*state
=
1472 (struct smbd_dirptr_lanman2_state
*)private_data
;
1473 bool ms_dfs_link
= false;
1476 if (INFO_LEVEL_IS_UNIX(state
->info_level
)) {
1477 if (SMB_VFS_LSTAT(state
->conn
, smb_fname
) != 0) {
1478 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1479 "Couldn't lstat [%s] (%s)\n",
1480 smb_fname_str_dbg(smb_fname
),
1484 } else if (!VALID_STAT(smb_fname
->st
) &&
1485 SMB_VFS_STAT(state
->conn
, smb_fname
) != 0) {
1486 /* Needed to show the msdfs symlinks as
1489 ms_dfs_link
= check_msdfs_link(state
->conn
,
1490 smb_fname
->base_name
,
1493 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1494 "Couldn't stat [%s] (%s)\n",
1495 smb_fname_str_dbg(smb_fname
),
1502 mode
= dos_mode_msdfs(state
->conn
, smb_fname
);
1504 mode
= dos_mode(state
->conn
, smb_fname
);
1511 static bool smbd_marshall_dir_entry(TALLOC_CTX
*ctx
,
1512 connection_struct
*conn
,
1514 uint32_t info_level
,
1515 struct ea_list
*name_list
,
1516 bool check_mangled_names
,
1517 bool requires_resume_key
,
1520 const struct smb_filename
*smb_fname
,
1521 int space_remaining
,
1528 uint64_t *last_entry_off
)
1530 char *p
, *q
, *pdata
= *ppdata
;
1532 uint64_t file_size
= 0;
1533 uint64_t allocation_size
= 0;
1534 uint64_t file_index
= 0;
1536 struct timespec mdate_ts
, adate_ts
, cdate_ts
, create_date_ts
;
1537 time_t mdate
= (time_t)0, adate
= (time_t)0, create_date
= (time_t)0;
1538 time_t c_date
= (time_t)0;
1540 char *last_entry_ptr
;
1545 *out_of_space
= false;
1547 ZERO_STRUCT(mdate_ts
);
1548 ZERO_STRUCT(adate_ts
);
1549 ZERO_STRUCT(create_date_ts
);
1550 ZERO_STRUCT(cdate_ts
);
1552 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
1553 file_size
= get_file_size_stat(&smb_fname
->st
);
1555 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, NULL
, &smb_fname
->st
);
1557 file_index
= get_FileIndex(conn
, &smb_fname
->st
);
1559 mdate_ts
= smb_fname
->st
.st_ex_mtime
;
1560 adate_ts
= smb_fname
->st
.st_ex_atime
;
1561 create_date_ts
= get_create_timespec(conn
, NULL
, smb_fname
);
1562 cdate_ts
= get_change_timespec(conn
, NULL
, smb_fname
);
1564 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1565 dos_filetime_timespec(&create_date_ts
);
1566 dos_filetime_timespec(&mdate_ts
);
1567 dos_filetime_timespec(&adate_ts
);
1568 dos_filetime_timespec(&cdate_ts
);
1571 create_date
= convert_timespec_to_time_t(create_date_ts
);
1572 mdate
= convert_timespec_to_time_t(mdate_ts
);
1573 adate
= convert_timespec_to_time_t(adate_ts
);
1574 c_date
= convert_timespec_to_time_t(cdate_ts
);
1576 /* align the record */
1577 SMB_ASSERT(align
>= 1);
1579 off
= (int)PTR_DIFF(pdata
, base_data
);
1580 pad
= (off
+ (align
-1)) & ~(align
-1);
1583 if (pad
&& pad
> space_remaining
) {
1584 *out_of_space
= true;
1585 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1586 "for padding (wanted %u, had %d)\n",
1589 return false; /* Not finished - just out of space */
1593 /* initialize padding to 0 */
1595 memset(pdata
, 0, pad
);
1597 space_remaining
-= pad
;
1599 DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1609 switch (info_level
) {
1610 case SMB_FIND_INFO_STANDARD
:
1611 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1612 if(requires_resume_key
) {
1616 srv_put_dos_date2(p
,0,create_date
);
1617 srv_put_dos_date2(p
,4,adate
);
1618 srv_put_dos_date2(p
,8,mdate
);
1619 SIVAL(p
,12,(uint32
)file_size
);
1620 SIVAL(p
,16,(uint32
)allocation_size
);
1624 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1625 p
+= ucs2_align(base_data
, p
, 0);
1627 len
= srvstr_push(base_data
, flags2
, p
,
1628 fname
, PTR_DIFF(end_data
, p
),
1630 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1632 SCVAL(nameptr
, -1, len
- 2);
1634 SCVAL(nameptr
, -1, 0);
1638 SCVAL(nameptr
, -1, len
- 1);
1640 SCVAL(nameptr
, -1, 0);
1646 case SMB_FIND_EA_SIZE
:
1647 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1648 if (requires_resume_key
) {
1652 srv_put_dos_date2(p
,0,create_date
);
1653 srv_put_dos_date2(p
,4,adate
);
1654 srv_put_dos_date2(p
,8,mdate
);
1655 SIVAL(p
,12,(uint32
)file_size
);
1656 SIVAL(p
,16,(uint32
)allocation_size
);
1659 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1660 smb_fname
->base_name
);
1661 SIVAL(p
,22,ea_size
); /* Extended attributes */
1665 len
= srvstr_push(base_data
, flags2
,
1666 p
, fname
, PTR_DIFF(end_data
, p
),
1667 STR_TERMINATE
| STR_NOALIGN
);
1668 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1681 SCVAL(nameptr
,0,len
);
1683 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1686 case SMB_FIND_EA_LIST
:
1688 struct ea_list
*file_list
= NULL
;
1691 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1695 if (requires_resume_key
) {
1699 srv_put_dos_date2(p
,0,create_date
);
1700 srv_put_dos_date2(p
,4,adate
);
1701 srv_put_dos_date2(p
,8,mdate
);
1702 SIVAL(p
,12,(uint32
)file_size
);
1703 SIVAL(p
,16,(uint32
)allocation_size
);
1705 p
+= 22; /* p now points to the EA area. */
1707 file_list
= get_ea_list_from_file(ctx
, conn
, NULL
,
1708 smb_fname
->base_name
,
1710 name_list
= ea_list_union(name_list
, file_list
, &ea_len
);
1712 /* We need to determine if this entry will fit in the space available. */
1713 /* Max string size is 255 bytes. */
1714 if (PTR_DIFF(p
+ 255 + ea_len
,pdata
) > space_remaining
) {
1715 *out_of_space
= true;
1716 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1717 "(wanted %u, had %d)\n",
1718 (unsigned int)PTR_DIFF(p
+ 255 + ea_len
,pdata
),
1720 return False
; /* Not finished - just out of space */
1723 /* Push the ea_data followed by the name. */
1724 p
+= fill_ea_buffer(ctx
, p
, space_remaining
, conn
, name_list
);
1726 len
= srvstr_push(base_data
, flags2
,
1727 p
+ 1, fname
, PTR_DIFF(end_data
, p
+1),
1728 STR_TERMINATE
| STR_NOALIGN
);
1729 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1742 SCVAL(nameptr
,0,len
);
1744 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1748 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1749 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1750 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1752 SIVAL(p
,0,reskey
); p
+= 4;
1753 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1754 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1755 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1756 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1757 SOFF_T(p
,0,file_size
); p
+= 8;
1758 SOFF_T(p
,0,allocation_size
); p
+= 8;
1759 SIVAL(p
,0,mode
); p
+= 4;
1760 q
= p
; p
+= 4; /* q is placeholder for name length. */
1762 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1763 smb_fname
->base_name
);
1764 SIVAL(p
,0,ea_size
); /* Extended attributes */
1767 /* Clear the short name buffer. This is
1768 * IMPORTANT as not doing so will trigger
1769 * a Win2k client bug. JRA.
1771 if (!was_8_3
&& check_mangled_names
) {
1772 char mangled_name
[13]; /* mangled 8.3 name. */
1773 if (!name_to_8_3(fname
,mangled_name
,True
,
1775 /* Error - mangle failed ! */
1776 memset(mangled_name
,'\0',12);
1778 mangled_name
[12] = 0;
1779 len
= srvstr_push(base_data
, flags2
,
1780 p
+2, mangled_name
, 24,
1781 STR_UPPER
|STR_UNICODE
);
1783 memset(p
+ 2 + len
,'\0',24 - len
);
1790 len
= srvstr_push(base_data
, flags2
, p
,
1791 fname
, PTR_DIFF(end_data
, p
),
1792 STR_TERMINATE_ASCII
);
1796 len
= PTR_DIFF(p
, pdata
);
1797 pad
= (len
+ (align
-1)) & ~(align
-1);
1799 * offset to the next entry, the caller
1800 * will overwrite it for the last entry
1801 * that's why we always include the padding
1805 * set padding to zero
1808 memset(p
, 0, pad
- len
);
1815 case SMB_FIND_FILE_DIRECTORY_INFO
:
1816 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1818 SIVAL(p
,0,reskey
); p
+= 4;
1819 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1820 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1821 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1822 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1823 SOFF_T(p
,0,file_size
); p
+= 8;
1824 SOFF_T(p
,0,allocation_size
); p
+= 8;
1825 SIVAL(p
,0,mode
); p
+= 4;
1826 len
= srvstr_push(base_data
, flags2
,
1827 p
+ 4, fname
, PTR_DIFF(end_data
, p
+4),
1828 STR_TERMINATE_ASCII
);
1832 len
= PTR_DIFF(p
, pdata
);
1833 pad
= (len
+ (align
-1)) & ~(align
-1);
1835 * offset to the next entry, the caller
1836 * will overwrite it for the last entry
1837 * that's why we always include the padding
1841 * set padding to zero
1844 memset(p
, 0, pad
- len
);
1851 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1852 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1854 SIVAL(p
,0,reskey
); p
+= 4;
1855 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1856 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1857 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1858 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1859 SOFF_T(p
,0,file_size
); p
+= 8;
1860 SOFF_T(p
,0,allocation_size
); p
+= 8;
1861 SIVAL(p
,0,mode
); p
+= 4;
1862 q
= p
; p
+= 4; /* q is placeholder for name length. */
1864 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1865 smb_fname
->base_name
);
1866 SIVAL(p
,0,ea_size
); /* Extended attributes */
1869 len
= srvstr_push(base_data
, flags2
, p
,
1870 fname
, PTR_DIFF(end_data
, p
),
1871 STR_TERMINATE_ASCII
);
1875 len
= PTR_DIFF(p
, pdata
);
1876 pad
= (len
+ (align
-1)) & ~(align
-1);
1878 * offset to the next entry, the caller
1879 * will overwrite it for the last entry
1880 * that's why we always include the padding
1884 * set padding to zero
1887 memset(p
, 0, pad
- len
);
1894 case SMB_FIND_FILE_NAMES_INFO
:
1895 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1897 SIVAL(p
,0,reskey
); p
+= 4;
1899 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1900 acl on a dir (tridge) */
1901 len
= srvstr_push(base_data
, flags2
, p
,
1902 fname
, PTR_DIFF(end_data
, p
),
1903 STR_TERMINATE_ASCII
);
1907 len
= PTR_DIFF(p
, pdata
);
1908 pad
= (len
+ (align
-1)) & ~(align
-1);
1910 * offset to the next entry, the caller
1911 * will overwrite it for the last entry
1912 * that's why we always include the padding
1916 * set padding to zero
1919 memset(p
, 0, pad
- len
);
1926 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1927 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1929 SIVAL(p
,0,reskey
); p
+= 4;
1930 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1931 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1932 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1933 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1934 SOFF_T(p
,0,file_size
); p
+= 8;
1935 SOFF_T(p
,0,allocation_size
); p
+= 8;
1936 SIVAL(p
,0,mode
); p
+= 4;
1937 q
= p
; p
+= 4; /* q is placeholder for name length. */
1939 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1940 smb_fname
->base_name
);
1941 SIVAL(p
,0,ea_size
); /* Extended attributes */
1944 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
1945 SBVAL(p
,0,file_index
); p
+= 8;
1946 len
= srvstr_push(base_data
, flags2
, p
,
1947 fname
, PTR_DIFF(end_data
, p
),
1948 STR_TERMINATE_ASCII
);
1952 len
= PTR_DIFF(p
, pdata
);
1953 pad
= (len
+ (align
-1)) & ~(align
-1);
1955 * offset to the next entry, the caller
1956 * will overwrite it for the last entry
1957 * that's why we always include the padding
1961 * set padding to zero
1964 memset(p
, 0, pad
- len
);
1971 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1972 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1973 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1975 SIVAL(p
,0,reskey
); p
+= 4;
1976 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1977 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1978 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1979 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1980 SOFF_T(p
,0,file_size
); p
+= 8;
1981 SOFF_T(p
,0,allocation_size
); p
+= 8;
1982 SIVAL(p
,0,mode
); p
+= 4;
1983 q
= p
; p
+= 4; /* q is placeholder for name length */
1985 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1986 smb_fname
->base_name
);
1987 SIVAL(p
,0,ea_size
); /* Extended attributes */
1990 /* Clear the short name buffer. This is
1991 * IMPORTANT as not doing so will trigger
1992 * a Win2k client bug. JRA.
1994 if (!was_8_3
&& check_mangled_names
) {
1995 char mangled_name
[13]; /* mangled 8.3 name. */
1996 if (!name_to_8_3(fname
,mangled_name
,True
,
1998 /* Error - mangle failed ! */
1999 memset(mangled_name
,'\0',12);
2001 mangled_name
[12] = 0;
2002 len
= srvstr_push(base_data
, flags2
,
2003 p
+2, mangled_name
, 24,
2004 STR_UPPER
|STR_UNICODE
);
2007 memset(p
+ 2 + len
,'\0',24 - len
);
2014 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
2015 SBVAL(p
,0,file_index
); p
+= 8;
2016 len
= srvstr_push(base_data
, flags2
, p
,
2017 fname
, PTR_DIFF(end_data
, p
),
2018 STR_TERMINATE_ASCII
);
2022 len
= PTR_DIFF(p
, pdata
);
2023 pad
= (len
+ (align
-1)) & ~(align
-1);
2025 * offset to the next entry, the caller
2026 * will overwrite it for the last entry
2027 * that's why we always include the padding
2031 * set padding to zero
2034 memset(p
, 0, pad
- len
);
2041 /* CIFS UNIX Extension. */
2043 case SMB_FIND_FILE_UNIX
:
2044 case SMB_FIND_FILE_UNIX_INFO2
:
2046 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
2048 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2050 if (info_level
== SMB_FIND_FILE_UNIX
) {
2051 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2052 p
= store_file_unix_basic(conn
, p
,
2053 NULL
, &smb_fname
->st
);
2054 len
= srvstr_push(base_data
, flags2
, p
,
2055 fname
, PTR_DIFF(end_data
, p
),
2058 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2059 p
= store_file_unix_basic_info2(conn
, p
,
2060 NULL
, &smb_fname
->st
);
2063 len
= srvstr_push(base_data
, flags2
, p
, fname
,
2064 PTR_DIFF(end_data
, p
), 0);
2065 SIVAL(nameptr
, 0, len
);
2070 len
= PTR_DIFF(p
, pdata
);
2071 pad
= (len
+ (align
-1)) & ~(align
-1);
2073 * offset to the next entry, the caller
2074 * will overwrite it for the last entry
2075 * that's why we always include the padding
2079 * set padding to zero
2082 memset(p
, 0, pad
- len
);
2087 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2095 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
2096 *out_of_space
= true;
2097 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2098 "(wanted %u, had %d)\n",
2099 (unsigned int)PTR_DIFF(p
,pdata
),
2101 return false; /* Not finished - just out of space */
2104 /* Setup the last entry pointer, as an offset from base_data */
2105 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
2106 /* Advance the data pointer to the next slot */
2112 bool smbd_dirptr_lanman2_entry(TALLOC_CTX
*ctx
,
2113 connection_struct
*conn
,
2114 struct dptr_struct
*dirptr
,
2116 const char *path_mask
,
2119 int requires_resume_key
,
2127 int space_remaining
,
2129 bool *got_exact_match
,
2130 int *_last_entry_off
,
2131 struct ea_list
*name_list
)
2134 const char *mask
= NULL
;
2135 long prev_dirpos
= 0;
2138 struct smb_filename
*smb_fname
= NULL
;
2139 struct smbd_dirptr_lanman2_state state
;
2141 uint64_t last_entry_off
= 0;
2145 state
.info_level
= info_level
;
2146 state
.check_mangled_names
= lp_manglednames(conn
->params
);
2147 state
.has_wild
= dptr_has_wild(dirptr
);
2148 state
.got_exact_match
= false;
2150 *out_of_space
= false;
2151 *got_exact_match
= false;
2153 p
= strrchr_m(path_mask
,'/');
2164 ok
= smbd_dirptr_get_entry(ctx
,
2170 smbd_dirptr_lanman2_match_fn
,
2171 smbd_dirptr_lanman2_mode_fn
,
2181 *got_exact_match
= state
.got_exact_match
;
2183 ok
= smbd_marshall_dir_entry(ctx
,
2188 state
.check_mangled_names
,
2189 requires_resume_key
,
2202 TALLOC_FREE(smb_fname
);
2203 if (*out_of_space
) {
2204 dptr_SeekDir(dirptr
, prev_dirpos
);
2211 *_last_entry_off
= last_entry_off
;
2215 static bool get_lanman2_dir_entry(TALLOC_CTX
*ctx
,
2216 connection_struct
*conn
,
2217 struct dptr_struct
*dirptr
,
2219 const char *path_mask
,
2222 bool requires_resume_key
,
2228 int space_remaining
,
2230 bool *got_exact_match
,
2231 int *last_entry_off
,
2232 struct ea_list
*name_list
)
2235 const bool do_pad
= true;
2237 if (info_level
>= 1 && info_level
<= 3) {
2238 /* No alignment on earlier info levels. */
2242 return smbd_dirptr_lanman2_entry(ctx
, conn
, dirptr
, flags2
,
2243 path_mask
, dirtype
, info_level
,
2244 requires_resume_key
, dont_descend
, ask_sharemode
,
2246 ppdata
, base_data
, end_data
,
2248 out_of_space
, got_exact_match
,
2249 last_entry_off
, name_list
);
2252 /****************************************************************************
2253 Reply to a TRANS2_FINDFIRST.
2254 ****************************************************************************/
2256 static void call_trans2findfirst(connection_struct
*conn
,
2257 struct smb_request
*req
,
2258 char **pparams
, int total_params
,
2259 char **ppdata
, int total_data
,
2260 unsigned int max_data_bytes
)
2262 /* We must be careful here that we don't return more than the
2263 allowed number of data bytes. If this means returning fewer than
2264 maxentries then so be it. We assume that the redirector has
2265 enough room for the fixed number of parameter bytes it has
2267 struct smb_filename
*smb_dname
= NULL
;
2268 char *params
= *pparams
;
2269 char *pdata
= *ppdata
;
2273 uint16 findfirst_flags
;
2274 bool close_after_first
;
2276 bool requires_resume_key
;
2278 char *directory
= NULL
;
2281 int last_entry_off
=0;
2285 bool finished
= False
;
2286 bool dont_descend
= False
;
2287 bool out_of_space
= False
;
2288 int space_remaining
;
2289 bool mask_contains_wcard
= False
;
2290 struct ea_list
*ea_list
= NULL
;
2291 NTSTATUS ntstatus
= NT_STATUS_OK
;
2292 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2293 TALLOC_CTX
*ctx
= talloc_tos();
2294 struct dptr_struct
*dirptr
= NULL
;
2295 struct smbd_server_connection
*sconn
= req
->sconn
;
2296 uint32_t ucf_flags
= (UCF_SAVE_LCOMP
| UCF_ALWAYS_ALLOW_WCARD_LCOMP
);
2298 if (total_params
< 13) {
2299 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2303 dirtype
= SVAL(params
,0);
2304 maxentries
= SVAL(params
,2);
2305 findfirst_flags
= SVAL(params
,4);
2306 close_after_first
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE
);
2307 close_if_end
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2308 requires_resume_key
= (findfirst_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2309 info_level
= SVAL(params
,6);
2311 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2312 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
2313 (unsigned int)dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
2314 info_level
, max_data_bytes
));
2317 /* W2K3 seems to treat zero as 1. */
2321 switch (info_level
) {
2322 case SMB_FIND_INFO_STANDARD
:
2323 case SMB_FIND_EA_SIZE
:
2324 case SMB_FIND_EA_LIST
:
2325 case SMB_FIND_FILE_DIRECTORY_INFO
:
2326 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2327 case SMB_FIND_FILE_NAMES_INFO
:
2328 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2329 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2330 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2332 case SMB_FIND_FILE_UNIX
:
2333 case SMB_FIND_FILE_UNIX_INFO2
:
2334 /* Always use filesystem for UNIX mtime query. */
2335 ask_sharemode
= false;
2336 if (!lp_unix_extensions()) {
2337 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2340 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
2343 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2347 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &directory
,
2348 params
+12, total_params
- 12,
2349 STR_TERMINATE
, &ntstatus
, &mask_contains_wcard
);
2350 if (!NT_STATUS_IS_OK(ntstatus
)) {
2351 reply_nterror(req
, ntstatus
);
2355 ntstatus
= filename_convert(ctx
, conn
,
2356 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2359 &mask_contains_wcard
,
2361 if (!NT_STATUS_IS_OK(ntstatus
)) {
2362 if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_PATH_NOT_COVERED
)) {
2363 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
2364 ERRSRV
, ERRbadpath
);
2367 reply_nterror(req
, ntstatus
);
2371 mask
= smb_dname
->original_lcomp
;
2373 directory
= smb_dname
->base_name
;
2375 p
= strrchr_m(directory
,'/');
2377 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2378 if((directory
[0] == '.') && (directory
[1] == '\0')) {
2379 mask
= talloc_strdup(ctx
,"*");
2381 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2384 mask_contains_wcard
= True
;
2390 if (p
== NULL
|| p
== directory
) {
2391 /* Ensure we don't have a directory name of "". */
2392 directory
= talloc_strdup(talloc_tos(), ".");
2394 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2399 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
2401 if (info_level
== SMB_FIND_EA_LIST
) {
2404 if (total_data
< 4) {
2405 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2409 ea_size
= IVAL(pdata
,0);
2410 if (ea_size
!= total_data
) {
2411 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2412 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2413 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2417 if (!lp_ea_support(SNUM(conn
))) {
2418 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2422 /* Pull out the list of names. */
2423 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2425 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2430 *ppdata
= (char *)SMB_REALLOC(
2431 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2432 if(*ppdata
== NULL
) {
2433 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2437 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2439 /* Realloc the params space */
2440 *pparams
= (char *)SMB_REALLOC(*pparams
, 10);
2441 if (*pparams
== NULL
) {
2442 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2447 /* Save the wildcard match and attribs we are using on this directory -
2448 needed as lanman2 assumes these are being saved between calls */
2450 ntstatus
= dptr_create(conn
,
2457 mask_contains_wcard
,
2461 if (!NT_STATUS_IS_OK(ntstatus
)) {
2462 reply_nterror(req
, ntstatus
);
2466 dptr_num
= dptr_dnum(dirptr
);
2467 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num
, mask
, dirtype
));
2469 /* Initialize per TRANS2_FIND_FIRST operation data */
2470 dptr_init_search_op(dirptr
);
2472 /* We don't need to check for VOL here as this is returned by
2473 a different TRANS2 call. */
2475 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2476 directory
,lp_dontdescend(SNUM(conn
))));
2477 if (in_list(directory
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
2478 dont_descend
= True
;
2481 space_remaining
= max_data_bytes
;
2482 out_of_space
= False
;
2484 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
2485 bool got_exact_match
= False
;
2487 /* this is a heuristic to avoid seeking the dirptr except when
2488 absolutely necessary. It allows for a filename of about 40 chars */
2489 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2490 out_of_space
= True
;
2493 finished
= !get_lanman2_dir_entry(ctx
,
2497 mask
,dirtype
,info_level
,
2498 requires_resume_key
,dont_descend
,
2501 space_remaining
, &out_of_space
,
2503 &last_entry_off
, ea_list
);
2506 if (finished
&& out_of_space
)
2509 if (!finished
&& !out_of_space
)
2513 * As an optimisation if we know we aren't looking
2514 * for a wildcard name (ie. the name matches the wildcard exactly)
2515 * then we can finish on any (first) match.
2516 * This speeds up large directory searches. JRA.
2522 /* Ensure space_remaining never goes -ve. */
2523 if (PTR_DIFF(p
,pdata
) > max_data_bytes
) {
2524 space_remaining
= 0;
2525 out_of_space
= true;
2527 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2531 /* Check if we can close the dirptr */
2532 if(close_after_first
|| (finished
&& close_if_end
)) {
2533 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
2534 dptr_close(sconn
, &dptr_num
);
2538 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2539 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2540 * the protocol level is less than NT1. Tested with smbclient. JRA.
2541 * This should fix the OS/2 client bug #2335.
2544 if(numentries
== 0) {
2545 dptr_close(sconn
, &dptr_num
);
2546 if (get_Protocol() < PROTOCOL_NT1
) {
2547 reply_force_doserror(req
, ERRDOS
, ERRnofiles
);
2550 reply_botherror(req
, NT_STATUS_NO_SUCH_FILE
,
2551 ERRDOS
, ERRbadfile
);
2556 /* At this point pdata points to numentries directory entries. */
2558 /* Set up the return parameter block */
2559 SSVAL(params
,0,dptr_num
);
2560 SSVAL(params
,2,numentries
);
2561 SSVAL(params
,4,finished
);
2562 SSVAL(params
,6,0); /* Never an EA error */
2563 SSVAL(params
,8,last_entry_off
);
2565 send_trans2_replies(conn
, req
, params
, 10, pdata
, PTR_DIFF(p
,pdata
),
2568 if ((! *directory
) && dptr_path(sconn
, dptr_num
)) {
2569 directory
= talloc_strdup(talloc_tos(),dptr_path(sconn
, dptr_num
));
2571 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2575 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2576 smb_fn_name(req
->cmd
),
2577 mask
, directory
, dirtype
, numentries
) );
2580 * Force a name mangle here to ensure that the
2581 * mask as an 8.3 name is top of the mangled cache.
2582 * The reasons for this are subtle. Don't remove
2583 * this code unless you know what you are doing
2584 * (see PR#13758). JRA.
2587 if(!mangle_is_8_3_wildcards( mask
, False
, conn
->params
)) {
2588 char mangled_name
[13];
2589 name_to_8_3(mask
, mangled_name
, True
, conn
->params
);
2592 TALLOC_FREE(smb_dname
);
2596 /****************************************************************************
2597 Reply to a TRANS2_FINDNEXT.
2598 ****************************************************************************/
2600 static void call_trans2findnext(connection_struct
*conn
,
2601 struct smb_request
*req
,
2602 char **pparams
, int total_params
,
2603 char **ppdata
, int total_data
,
2604 unsigned int max_data_bytes
)
2606 /* We must be careful here that we don't return more than the
2607 allowed number of data bytes. If this means returning fewer than
2608 maxentries then so be it. We assume that the redirector has
2609 enough room for the fixed number of parameter bytes it has
2611 char *params
= *pparams
;
2612 char *pdata
= *ppdata
;
2618 uint16 findnext_flags
;
2619 bool close_after_request
;
2621 bool requires_resume_key
;
2623 bool mask_contains_wcard
= False
;
2624 char *resume_name
= NULL
;
2625 const char *mask
= NULL
;
2626 const char *directory
= NULL
;
2630 int i
, last_entry_off
=0;
2631 bool finished
= False
;
2632 bool dont_descend
= False
;
2633 bool out_of_space
= False
;
2634 int space_remaining
;
2635 struct ea_list
*ea_list
= NULL
;
2636 NTSTATUS ntstatus
= NT_STATUS_OK
;
2637 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2638 TALLOC_CTX
*ctx
= talloc_tos();
2639 struct dptr_struct
*dirptr
;
2640 struct smbd_server_connection
*sconn
= req
->sconn
;
2642 if (total_params
< 13) {
2643 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2647 dptr_num
= SVAL(params
,0);
2648 maxentries
= SVAL(params
,2);
2649 info_level
= SVAL(params
,4);
2650 resume_key
= IVAL(params
,6);
2651 findnext_flags
= SVAL(params
,10);
2652 close_after_request
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE
);
2653 close_if_end
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2654 requires_resume_key
= (findnext_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2655 continue_bit
= (findnext_flags
& FLAG_TRANS2_FIND_CONTINUE
);
2657 if (!continue_bit
) {
2658 /* We only need resume_name if continue_bit is zero. */
2659 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &resume_name
,
2661 total_params
- 12, STR_TERMINATE
, &ntstatus
,
2662 &mask_contains_wcard
);
2663 if (!NT_STATUS_IS_OK(ntstatus
)) {
2664 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2665 complain (it thinks we're asking for the directory above the shared
2666 path or an invalid name). Catch this as the resume name is only compared, never used in
2667 a file access. JRA. */
2668 srvstr_pull_talloc(ctx
, params
, req
->flags2
,
2669 &resume_name
, params
+12,
2673 if (!resume_name
|| !(ISDOT(resume_name
) || ISDOTDOT(resume_name
))) {
2674 reply_nterror(req
, ntstatus
);
2680 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2681 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2682 resume_key = %d resume name = %s continue=%d level = %d\n",
2683 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
2684 requires_resume_key
, resume_key
,
2685 resume_name
? resume_name
: "(NULL)", continue_bit
, info_level
));
2688 /* W2K3 seems to treat zero as 1. */
2692 switch (info_level
) {
2693 case SMB_FIND_INFO_STANDARD
:
2694 case SMB_FIND_EA_SIZE
:
2695 case SMB_FIND_EA_LIST
:
2696 case SMB_FIND_FILE_DIRECTORY_INFO
:
2697 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2698 case SMB_FIND_FILE_NAMES_INFO
:
2699 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2700 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2701 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2703 case SMB_FIND_FILE_UNIX
:
2704 case SMB_FIND_FILE_UNIX_INFO2
:
2705 /* Always use filesystem for UNIX mtime query. */
2706 ask_sharemode
= false;
2707 if (!lp_unix_extensions()) {
2708 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2713 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2717 if (info_level
== SMB_FIND_EA_LIST
) {
2720 if (total_data
< 4) {
2721 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2725 ea_size
= IVAL(pdata
,0);
2726 if (ea_size
!= total_data
) {
2727 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2728 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2729 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2733 if (!lp_ea_support(SNUM(conn
))) {
2734 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2738 /* Pull out the list of names. */
2739 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2741 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2746 *ppdata
= (char *)SMB_REALLOC(
2747 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2748 if(*ppdata
== NULL
) {
2749 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2754 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2756 /* Realloc the params space */
2757 *pparams
= (char *)SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
2758 if(*pparams
== NULL
) {
2759 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2765 /* Check that the dptr is valid */
2766 if(!(dirptr
= dptr_fetch_lanman2(sconn
, dptr_num
))) {
2767 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2771 directory
= dptr_path(sconn
, dptr_num
);
2773 /* Get the wildcard mask from the dptr */
2774 if((p
= dptr_wcard(sconn
, dptr_num
))== NULL
) {
2775 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
2776 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2782 /* Get the attr mask from the dptr */
2783 dirtype
= dptr_attr(sconn
, dptr_num
);
2785 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2786 dptr_num
, mask
, dirtype
,
2788 dptr_TellDir(dirptr
)));
2790 /* Initialize per TRANS2_FIND_NEXT operation data */
2791 dptr_init_search_op(dirptr
);
2793 /* We don't need to check for VOL here as this is returned by
2794 a different TRANS2 call. */
2796 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2797 directory
,lp_dontdescend(SNUM(conn
))));
2798 if (in_list(directory
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
2799 dont_descend
= True
;
2802 space_remaining
= max_data_bytes
;
2803 out_of_space
= False
;
2806 * Seek to the correct position. We no longer use the resume key but
2807 * depend on the last file name instead.
2810 if(!continue_bit
&& resume_name
&& *resume_name
) {
2813 long current_pos
= 0;
2815 * Remember, name_to_8_3 is called by
2816 * get_lanman2_dir_entry(), so the resume name
2817 * could be mangled. Ensure we check the unmangled name.
2820 if (mangle_is_mangled(resume_name
, conn
->params
)) {
2821 char *new_resume_name
= NULL
;
2822 mangle_lookup_name_from_8_3(ctx
,
2826 if (new_resume_name
) {
2827 resume_name
= new_resume_name
;
2832 * Fix for NT redirector problem triggered by resume key indexes
2833 * changing between directory scans. We now return a resume key of 0
2834 * and instead look for the filename to continue from (also given
2835 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2836 * findfirst/findnext (as is usual) then the directory pointer
2837 * should already be at the correct place.
2840 finished
= !dptr_SearchDir(dirptr
, resume_name
, ¤t_pos
, &st
);
2841 } /* end if resume_name && !continue_bit */
2843 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
2844 bool got_exact_match
= False
;
2846 /* this is a heuristic to avoid seeking the dirptr except when
2847 absolutely necessary. It allows for a filename of about 40 chars */
2848 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2849 out_of_space
= True
;
2852 finished
= !get_lanman2_dir_entry(ctx
,
2856 mask
,dirtype
,info_level
,
2857 requires_resume_key
,dont_descend
,
2860 space_remaining
, &out_of_space
,
2862 &last_entry_off
, ea_list
);
2865 if (finished
&& out_of_space
)
2868 if (!finished
&& !out_of_space
)
2872 * As an optimisation if we know we aren't looking
2873 * for a wildcard name (ie. the name matches the wildcard exactly)
2874 * then we can finish on any (first) match.
2875 * This speeds up large directory searches. JRA.
2881 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2884 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2885 smb_fn_name(req
->cmd
),
2886 mask
, directory
, dirtype
, numentries
) );
2888 /* Check if we can close the dirptr */
2889 if(close_after_request
|| (finished
&& close_if_end
)) {
2890 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
2891 dptr_close(sconn
, &dptr_num
); /* This frees up the saved mask */
2894 /* Set up the return parameter block */
2895 SSVAL(params
,0,numentries
);
2896 SSVAL(params
,2,finished
);
2897 SSVAL(params
,4,0); /* Never an EA error */
2898 SSVAL(params
,6,last_entry_off
);
2900 send_trans2_replies(conn
, req
, params
, 8, pdata
, PTR_DIFF(p
,pdata
),
2906 unsigned char *create_volume_objectid(connection_struct
*conn
, unsigned char objid
[16])
2908 E_md4hash(lp_servicename(SNUM(conn
)),objid
);
2912 static void samba_extended_info_version(struct smb_extended_info
*extended_info
)
2914 SMB_ASSERT(extended_info
!= NULL
);
2916 extended_info
->samba_magic
= SAMBA_EXTENDED_INFO_MAGIC
;
2917 extended_info
->samba_version
= ((SAMBA_VERSION_MAJOR
& 0xff) << 24)
2918 | ((SAMBA_VERSION_MINOR
& 0xff) << 16)
2919 | ((SAMBA_VERSION_RELEASE
& 0xff) << 8);
2920 #ifdef SAMBA_VERSION_REVISION
2921 extended_info
->samba_version
|= (tolower(*SAMBA_VERSION_REVISION
) - 'a' + 1) & 0xff;
2923 extended_info
->samba_subversion
= 0;
2924 #ifdef SAMBA_VERSION_RC_RELEASE
2925 extended_info
->samba_subversion
|= (SAMBA_VERSION_RC_RELEASE
& 0xff) << 24;
2927 #ifdef SAMBA_VERSION_PRE_RELEASE
2928 extended_info
->samba_subversion
|= (SAMBA_VERSION_PRE_RELEASE
& 0xff) << 16;
2931 #ifdef SAMBA_VERSION_VENDOR_PATCH
2932 extended_info
->samba_subversion
|= (SAMBA_VERSION_VENDOR_PATCH
& 0xffff);
2934 extended_info
->samba_gitcommitdate
= 0;
2935 #ifdef SAMBA_VERSION_COMMIT_TIME
2936 unix_to_nt_time(&extended_info
->samba_gitcommitdate
, SAMBA_VERSION_COMMIT_TIME
);
2939 memset(extended_info
->samba_version_string
, 0,
2940 sizeof(extended_info
->samba_version_string
));
2942 snprintf (extended_info
->samba_version_string
,
2943 sizeof(extended_info
->samba_version_string
),
2944 "%s", samba_version_string());
2947 NTSTATUS
smbd_do_qfsinfo(connection_struct
*conn
,
2948 TALLOC_CTX
*mem_ctx
,
2949 uint16_t info_level
,
2951 unsigned int max_data_bytes
,
2952 struct smb_filename
*fname
,
2956 char *pdata
, *end_data
;
2957 int data_len
= 0, len
;
2958 const char *vname
= volume_label(SNUM(conn
));
2959 int snum
= SNUM(conn
);
2960 char *fstype
= lp_fstype(SNUM(conn
));
2961 const char *filename
= NULL
;
2962 uint32 additional_flags
= 0;
2963 struct smb_filename smb_fname
;
2966 if (fname
== NULL
|| fname
->base_name
== NULL
) {
2969 filename
= fname
->base_name
;
2973 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
2974 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
2975 "info level (0x%x) on IPC$.\n",
2976 (unsigned int)info_level
));
2977 return NT_STATUS_ACCESS_DENIED
;
2981 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level
));
2983 ZERO_STRUCT(smb_fname
);
2984 smb_fname
.base_name
= discard_const_p(char, filename
);
2986 if(SMB_VFS_STAT(conn
, &smb_fname
) != 0) {
2987 DEBUG(2,("stat of . failed (%s)\n", strerror(errno
)));
2988 return map_nt_error_from_unix(errno
);
2993 *ppdata
= (char *)SMB_REALLOC(
2994 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2995 if (*ppdata
== NULL
) {
2996 return NT_STATUS_NO_MEMORY
;
3000 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3001 end_data
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
3003 switch (info_level
) {
3004 case SMB_INFO_ALLOCATION
:
3006 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3008 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3009 return map_nt_error_from_unix(errno
);
3012 block_size
= lp_block_size(snum
);
3013 if (bsize
< block_size
) {
3014 uint64_t factor
= block_size
/bsize
;
3019 if (bsize
> block_size
) {
3020 uint64_t factor
= bsize
/block_size
;
3025 bytes_per_sector
= 512;
3026 sectors_per_unit
= bsize
/bytes_per_sector
;
3028 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3029 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_ex_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3030 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3032 SIVAL(pdata
,l1_idFileSystem
,st
.st_ex_dev
);
3033 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
3034 SIVAL(pdata
,l1_cUnit
,dsize
);
3035 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
3036 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
3040 case SMB_INFO_VOLUME
:
3041 /* Return volume name */
3043 * Add volume serial number - hash of a combination of
3044 * the called hostname and the service name.
3046 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
3048 * Win2k3 and previous mess this up by sending a name length
3049 * one byte short. I believe only older clients (OS/2 Win9x) use
3050 * this call so try fixing this by adding a terminating null to
3051 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3055 pdata
+l2_vol_szVolLabel
, vname
,
3056 PTR_DIFF(end_data
, pdata
+l2_vol_szVolLabel
),
3057 STR_NOALIGN
|STR_TERMINATE
);
3058 SCVAL(pdata
,l2_vol_cch
,len
);
3059 data_len
= l2_vol_szVolLabel
+ len
;
3060 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
3061 (unsigned)convert_timespec_to_time_t(st
.st_ex_ctime
),
3065 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
3066 case SMB_FS_ATTRIBUTE_INFORMATION
:
3068 additional_flags
= 0;
3069 #if defined(HAVE_SYS_QUOTAS)
3070 additional_flags
|= FILE_VOLUME_QUOTAS
;
3073 if(lp_nt_acl_support(SNUM(conn
))) {
3074 additional_flags
|= FILE_PERSISTENT_ACLS
;
3077 /* Capabilities are filled in at connection time through STATVFS call */
3078 additional_flags
|= conn
->fs_capabilities
;
3079 additional_flags
|= lp_parm_int(conn
->params
->service
,
3080 "share", "fake_fscaps",
3083 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
3084 FILE_SUPPORTS_OBJECT_IDS
|FILE_UNICODE_ON_DISK
|
3085 additional_flags
); /* FS ATTRIBUTES */
3087 SIVAL(pdata
,4,255); /* Max filename component length */
3088 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3089 and will think we can't do long filenames */
3090 len
= srvstr_push(pdata
, flags2
, pdata
+12, fstype
,
3091 PTR_DIFF(end_data
, pdata
+12),
3094 data_len
= 12 + len
;
3097 case SMB_QUERY_FS_LABEL_INFO
:
3098 case SMB_FS_LABEL_INFORMATION
:
3099 len
= srvstr_push(pdata
, flags2
, pdata
+4, vname
,
3100 PTR_DIFF(end_data
, pdata
+4), 0);
3105 case SMB_QUERY_FS_VOLUME_INFO
:
3106 case SMB_FS_VOLUME_INFORMATION
:
3109 * Add volume serial number - hash of a combination of
3110 * the called hostname and the service name.
3112 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
3113 (str_checksum(get_local_machine_name())<<16));
3115 /* Max label len is 32 characters. */
3116 len
= srvstr_push(pdata
, flags2
, pdata
+18, vname
,
3117 PTR_DIFF(end_data
, pdata
+18),
3119 SIVAL(pdata
,12,len
);
3122 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3123 (int)strlen(vname
),vname
, lp_servicename(snum
)));
3126 case SMB_QUERY_FS_SIZE_INFO
:
3127 case SMB_FS_SIZE_INFORMATION
:
3129 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3131 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3132 return map_nt_error_from_unix(errno
);
3134 block_size
= lp_block_size(snum
);
3135 if (bsize
< block_size
) {
3136 uint64_t factor
= block_size
/bsize
;
3141 if (bsize
> block_size
) {
3142 uint64_t factor
= bsize
/block_size
;
3147 bytes_per_sector
= 512;
3148 sectors_per_unit
= bsize
/bytes_per_sector
;
3149 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3150 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3151 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3152 SBIG_UINT(pdata
,0,dsize
);
3153 SBIG_UINT(pdata
,8,dfree
);
3154 SIVAL(pdata
,16,sectors_per_unit
);
3155 SIVAL(pdata
,20,bytes_per_sector
);
3159 case SMB_FS_FULL_SIZE_INFORMATION
:
3161 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3163 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3164 return map_nt_error_from_unix(errno
);
3166 block_size
= lp_block_size(snum
);
3167 if (bsize
< block_size
) {
3168 uint64_t factor
= block_size
/bsize
;
3173 if (bsize
> block_size
) {
3174 uint64_t factor
= bsize
/block_size
;
3179 bytes_per_sector
= 512;
3180 sectors_per_unit
= bsize
/bytes_per_sector
;
3181 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3182 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3183 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3184 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
3185 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
3186 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
3187 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
3188 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
3192 case SMB_QUERY_FS_DEVICE_INFO
:
3193 case SMB_FS_DEVICE_INFORMATION
:
3195 uint32_t characteristics
= FILE_DEVICE_IS_MOUNTED
;
3197 if (!CAN_WRITE(conn
)) {
3198 characteristics
|= FILE_READ_ONLY_DEVICE
;
3201 SIVAL(pdata
,0,FILE_DEVICE_DISK
); /* dev type */
3202 SIVAL(pdata
,4,characteristics
);
3206 #ifdef HAVE_SYS_QUOTAS
3207 case SMB_FS_QUOTA_INFORMATION
:
3209 * what we have to send --metze:
3211 * Unknown1: 24 NULL bytes
3212 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3213 * Hard Quota Limit: 8 bytes seems like uint64_t or so
3214 * Quota Flags: 2 byte :
3215 * Unknown3: 6 NULL bytes
3219 * details for Quota Flags:
3221 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3222 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
3223 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3224 * 0x0001 Enable Quotas: enable quota for this fs
3228 /* we need to fake up a fsp here,
3229 * because its not send in this call
3232 SMB_NTQUOTA_STRUCT quotas
;
3235 ZERO_STRUCT(quotas
);
3241 if (get_current_uid(conn
) != 0) {
3242 DEBUG(0,("set_user_quota: access_denied "
3243 "service [%s] user [%s]\n",
3244 lp_servicename(SNUM(conn
)),
3245 conn
->session_info
->unix_name
));
3246 return NT_STATUS_ACCESS_DENIED
;
3249 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3250 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3251 return map_nt_error_from_unix(errno
);
3256 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3257 lp_servicename(SNUM(conn
))));
3259 /* Unknown1 24 NULL bytes*/
3260 SBIG_UINT(pdata
,0,(uint64_t)0);
3261 SBIG_UINT(pdata
,8,(uint64_t)0);
3262 SBIG_UINT(pdata
,16,(uint64_t)0);
3264 /* Default Soft Quota 8 bytes */
3265 SBIG_UINT(pdata
,24,quotas
.softlim
);
3267 /* Default Hard Quota 8 bytes */
3268 SBIG_UINT(pdata
,32,quotas
.hardlim
);
3270 /* Quota flag 2 bytes */
3271 SSVAL(pdata
,40,quotas
.qflags
);
3273 /* Unknown3 6 NULL bytes */
3279 #endif /* HAVE_SYS_QUOTAS */
3280 case SMB_FS_OBJECTID_INFORMATION
:
3282 unsigned char objid
[16];
3283 struct smb_extended_info extended_info
;
3284 memcpy(pdata
,create_volume_objectid(conn
, objid
),16);
3285 samba_extended_info_version (&extended_info
);
3286 SIVAL(pdata
,16,extended_info
.samba_magic
);
3287 SIVAL(pdata
,20,extended_info
.samba_version
);
3288 SIVAL(pdata
,24,extended_info
.samba_subversion
);
3289 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
3290 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
3296 * Query the version and capabilities of the CIFS UNIX extensions
3300 case SMB_QUERY_CIFS_UNIX_INFO
:
3302 bool large_write
= lp_min_receive_file_size() &&
3303 !srv_is_signing_active(conn
->sconn
);
3304 bool large_read
= !srv_is_signing_active(conn
->sconn
);
3305 int encrypt_caps
= 0;
3307 if (!lp_unix_extensions()) {
3308 return NT_STATUS_INVALID_LEVEL
;
3311 switch (conn
->encrypt_level
) {
3317 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
;
3320 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
|
3321 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP
;
3322 large_write
= false;
3328 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
3329 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
3331 /* We have POSIX ACLs, pathname, encryption,
3332 * large read/write, and locking capability. */
3334 SBIG_UINT(pdata
,4,((uint64_t)(
3335 CIFS_UNIX_POSIX_ACLS_CAP
|
3336 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
3337 CIFS_UNIX_FCNTL_LOCKS_CAP
|
3338 CIFS_UNIX_EXTATTR_CAP
|
3339 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
|
3341 (large_read
? CIFS_UNIX_LARGE_READ_CAP
: 0) |
3343 CIFS_UNIX_LARGE_WRITE_CAP
: 0))));
3347 case SMB_QUERY_POSIX_FS_INFO
:
3350 vfs_statvfs_struct svfs
;
3352 if (!lp_unix_extensions()) {
3353 return NT_STATUS_INVALID_LEVEL
;
3356 rc
= SMB_VFS_STATVFS(conn
, filename
, &svfs
);
3360 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
3361 SIVAL(pdata
,4,svfs
.BlockSize
);
3362 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
3363 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
3364 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
3365 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
3366 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
3367 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
3368 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3370 } else if (rc
== EOPNOTSUPP
) {
3371 return NT_STATUS_INVALID_LEVEL
;
3372 #endif /* EOPNOTSUPP */
3374 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3375 return NT_STATUS_DOS(ERRSRV
, ERRerror
);
3380 case SMB_QUERY_POSIX_WHOAMI
:
3386 if (!lp_unix_extensions()) {
3387 return NT_STATUS_INVALID_LEVEL
;
3390 if (max_data_bytes
< 40) {
3391 return NT_STATUS_BUFFER_TOO_SMALL
;
3394 /* We ARE guest if global_sid_Builtin_Guests is
3395 * in our list of SIDs.
3397 if (nt_token_check_sid(&global_sid_Builtin_Guests
,
3398 conn
->session_info
->security_token
)) {
3399 flags
|= SMB_WHOAMI_GUEST
;
3402 /* We are NOT guest if global_sid_Authenticated_Users
3403 * is in our list of SIDs.
3405 if (nt_token_check_sid(&global_sid_Authenticated_Users
,
3406 conn
->session_info
->security_token
)) {
3407 flags
&= ~SMB_WHOAMI_GUEST
;
3410 /* NOTE: 8 bytes for UID/GID, irrespective of native
3411 * platform size. This matches
3412 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3414 data_len
= 4 /* flags */
3421 + 4 /* pad/reserved */
3422 + (conn
->session_info
->utok
.ngroups
* 8)
3424 + (conn
->session_info
->security_token
->num_sids
*
3428 SIVAL(pdata
, 0, flags
);
3429 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
3431 (uint64_t)conn
->session_info
->utok
.uid
);
3432 SBIG_UINT(pdata
, 16,
3433 (uint64_t)conn
->session_info
->utok
.gid
);
3436 if (data_len
>= max_data_bytes
) {
3437 /* Potential overflow, skip the GIDs and SIDs. */
3439 SIVAL(pdata
, 24, 0); /* num_groups */
3440 SIVAL(pdata
, 28, 0); /* num_sids */
3441 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
3442 SIVAL(pdata
, 36, 0); /* reserved */
3448 SIVAL(pdata
, 24, conn
->session_info
->utok
.ngroups
);
3449 SIVAL(pdata
, 28, conn
->session_info
->security_token
->num_sids
);
3451 /* We walk the SID list twice, but this call is fairly
3452 * infrequent, and I don't expect that it's performance
3453 * sensitive -- jpeach
3455 for (i
= 0, sid_bytes
= 0;
3456 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3457 sid_bytes
+= ndr_size_dom_sid(
3458 &conn
->session_info
->security_token
->sids
[i
],
3462 /* SID list byte count */
3463 SIVAL(pdata
, 32, sid_bytes
);
3465 /* 4 bytes pad/reserved - must be zero */
3466 SIVAL(pdata
, 36, 0);
3470 for (i
= 0; i
< conn
->session_info
->utok
.ngroups
; ++i
) {
3471 SBIG_UINT(pdata
, data_len
,
3472 (uint64_t)conn
->session_info
->utok
.groups
[i
]);
3478 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3479 int sid_len
= ndr_size_dom_sid(
3480 &conn
->session_info
->security_token
->sids
[i
],
3483 sid_linearize(pdata
+ data_len
, sid_len
,
3484 &conn
->session_info
->security_token
->sids
[i
]);
3485 data_len
+= sid_len
;
3491 case SMB_MAC_QUERY_FS_INFO
:
3493 * Thursby MAC extension... ONLY on NTFS filesystems
3494 * once we do streams then we don't need this
3496 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
3498 SIVAL(pdata
,84,0x100); /* Don't support mac... */
3503 return NT_STATUS_INVALID_LEVEL
;
3506 *ret_data_len
= data_len
;
3507 return NT_STATUS_OK
;
3510 /****************************************************************************
3511 Reply to a TRANS2_QFSINFO (query filesystem info).
3512 ****************************************************************************/
3514 static void call_trans2qfsinfo(connection_struct
*conn
,
3515 struct smb_request
*req
,
3516 char **pparams
, int total_params
,
3517 char **ppdata
, int total_data
,
3518 unsigned int max_data_bytes
)
3520 char *params
= *pparams
;
3521 uint16_t info_level
;
3525 if (total_params
< 2) {
3526 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3530 info_level
= SVAL(params
,0);
3532 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3533 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3534 DEBUG(0,("call_trans2qfsinfo: encryption required "
3535 "and info level 0x%x sent.\n",
3536 (unsigned int)info_level
));
3537 exit_server_cleanly("encryption required "
3543 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
3545 status
= smbd_do_qfsinfo(conn
, req
,
3551 if (!NT_STATUS_IS_OK(status
)) {
3552 reply_nterror(req
, status
);
3556 send_trans2_replies(conn
, req
, params
, 0, *ppdata
, data_len
,
3559 DEBUG( 4, ( "%s info_level = %d\n",
3560 smb_fn_name(req
->cmd
), info_level
) );
3565 /****************************************************************************
3566 Reply to a TRANS2_SETFSINFO (set filesystem info).
3567 ****************************************************************************/
3569 static void call_trans2setfsinfo(connection_struct
*conn
,
3570 struct smb_request
*req
,
3571 char **pparams
, int total_params
,
3572 char **ppdata
, int total_data
,
3573 unsigned int max_data_bytes
)
3575 char *pdata
= *ppdata
;
3576 char *params
= *pparams
;
3579 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn
))));
3582 if (total_params
< 4) {
3583 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3585 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3589 info_level
= SVAL(params
,2);
3592 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
&&
3593 info_level
!= SMB_SET_CIFS_UNIX_INFO
) {
3594 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3595 "info level (0x%x) on IPC$.\n",
3596 (unsigned int)info_level
));
3597 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3602 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3603 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
) {
3604 DEBUG(0,("call_trans2setfsinfo: encryption required "
3605 "and info level 0x%x sent.\n",
3606 (unsigned int)info_level
));
3607 exit_server_cleanly("encryption required "
3613 switch(info_level
) {
3614 case SMB_SET_CIFS_UNIX_INFO
:
3616 uint16 client_unix_major
;
3617 uint16 client_unix_minor
;
3618 uint32 client_unix_cap_low
;
3619 uint32 client_unix_cap_high
;
3621 if (!lp_unix_extensions()) {
3623 NT_STATUS_INVALID_LEVEL
);
3627 /* There should be 12 bytes of capabilities set. */
3628 if (total_data
< 8) {
3631 NT_STATUS_INVALID_PARAMETER
);
3634 client_unix_major
= SVAL(pdata
,0);
3635 client_unix_minor
= SVAL(pdata
,2);
3636 client_unix_cap_low
= IVAL(pdata
,4);
3637 client_unix_cap_high
= IVAL(pdata
,8);
3638 /* Just print these values for now. */
3639 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
3640 cap_low = 0x%x, cap_high = 0x%x\n",
3641 (unsigned int)client_unix_major
,
3642 (unsigned int)client_unix_minor
,
3643 (unsigned int)client_unix_cap_low
,
3644 (unsigned int)client_unix_cap_high
));
3646 /* Here is where we must switch to posix pathname processing... */
3647 if (client_unix_cap_low
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
3648 lp_set_posix_pathnames();
3649 mangle_change_to_posix();
3652 if ((client_unix_cap_low
& CIFS_UNIX_FCNTL_LOCKS_CAP
) &&
3653 !(client_unix_cap_low
& CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)) {
3654 /* Client that knows how to do posix locks,
3655 * but not posix open/mkdir operations. Set a
3656 * default type for read/write checks. */
3658 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK
);
3664 case SMB_REQUEST_TRANSPORT_ENCRYPTION
:
3667 size_t param_len
= 0;
3668 size_t data_len
= total_data
;
3670 if (!lp_unix_extensions()) {
3673 NT_STATUS_INVALID_LEVEL
);
3677 if (lp_smb_encrypt(SNUM(conn
)) == false) {
3680 NT_STATUS_NOT_SUPPORTED
);
3684 if (req
->sconn
->smb1
.echo_handler
.trusted_fde
) {
3685 DEBUG( 2,("call_trans2setfsinfo: "
3686 "request transport encryption disabled"
3687 "with 'fork echo handler = yes'\n"));
3690 NT_STATUS_NOT_SUPPORTED
);
3694 DEBUG( 4,("call_trans2setfsinfo: "
3695 "request transport encryption.\n"));
3697 status
= srv_request_encryption_setup(conn
,
3698 (unsigned char **)ppdata
,
3700 (unsigned char **)pparams
,
3703 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
3704 !NT_STATUS_IS_OK(status
)) {
3705 reply_nterror(req
, status
);
3709 send_trans2_replies(conn
, req
,
3716 if (NT_STATUS_IS_OK(status
)) {
3717 /* Server-side transport
3718 * encryption is now *on*. */
3719 status
= srv_encryption_start(conn
);
3720 if (!NT_STATUS_IS_OK(status
)) {
3721 exit_server_cleanly(
3722 "Failure in setting "
3723 "up encrypted transport");
3729 case SMB_FS_QUOTA_INFORMATION
:
3731 files_struct
*fsp
= NULL
;
3732 SMB_NTQUOTA_STRUCT quotas
;
3734 ZERO_STRUCT(quotas
);
3737 if ((get_current_uid(conn
) != 0) || !CAN_WRITE(conn
)) {
3738 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3739 lp_servicename(SNUM(conn
)),
3740 conn
->session_info
->unix_name
));
3741 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3745 /* note: normaly there're 48 bytes,
3746 * but we didn't use the last 6 bytes for now
3749 fsp
= file_fsp(req
, SVAL(params
,0));
3751 if (!check_fsp_ntquota_handle(conn
, req
,
3753 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3755 req
, NT_STATUS_INVALID_HANDLE
);
3759 if (total_data
< 42) {
3760 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3764 NT_STATUS_INVALID_PARAMETER
);
3768 /* unknown_1 24 NULL bytes in pdata*/
3770 /* the soft quotas 8 bytes (uint64_t)*/
3771 quotas
.softlim
= BVAL(pdata
,24);
3773 /* the hard quotas 8 bytes (uint64_t)*/
3774 quotas
.hardlim
= BVAL(pdata
,32);
3776 /* quota_flags 2 bytes **/
3777 quotas
.qflags
= SVAL(pdata
,40);
3779 /* unknown_2 6 NULL bytes follow*/
3781 /* now set the quotas */
3782 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3783 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3784 reply_nterror(req
, map_nt_error_from_unix(errno
));
3791 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3793 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
3799 * sending this reply works fine,
3800 * but I'm not sure it's the same
3801 * like windows do...
3804 reply_outbuf(req
, 10, 0);
3807 #if defined(HAVE_POSIX_ACLS)
3808 /****************************************************************************
3809 Utility function to count the number of entries in a POSIX acl.
3810 ****************************************************************************/
3812 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
3814 unsigned int ace_count
= 0;
3815 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3816 SMB_ACL_ENTRY_T entry
;
3818 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
3820 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3821 entry_id
= SMB_ACL_NEXT_ENTRY
;
3828 /****************************************************************************
3829 Utility function to marshall a POSIX acl into wire format.
3830 ****************************************************************************/
3832 static bool marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
3834 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3835 SMB_ACL_ENTRY_T entry
;
3837 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
3838 SMB_ACL_TAG_T tagtype
;
3839 SMB_ACL_PERMSET_T permset
;
3840 unsigned char perms
= 0;
3841 unsigned int own_grp
;
3844 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3845 entry_id
= SMB_ACL_NEXT_ENTRY
;
3848 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn
, entry
, &tagtype
) == -1) {
3849 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3853 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn
, entry
, &permset
) == -1) {
3854 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3858 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
3859 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
3860 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
3862 SCVAL(pdata
,1,perms
);
3865 case SMB_ACL_USER_OBJ
:
3866 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
3867 own_grp
= (unsigned int)pst
->st_ex_uid
;
3868 SIVAL(pdata
,2,own_grp
);
3873 uid_t
*puid
= (uid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
3875 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3878 own_grp
= (unsigned int)*puid
;
3879 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)puid
,tagtype
);
3880 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
3881 SIVAL(pdata
,2,own_grp
);
3885 case SMB_ACL_GROUP_OBJ
:
3886 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
3887 own_grp
= (unsigned int)pst
->st_ex_gid
;
3888 SIVAL(pdata
,2,own_grp
);
3893 gid_t
*pgid
= (gid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
3895 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3898 own_grp
= (unsigned int)*pgid
;
3899 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)pgid
,tagtype
);
3900 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
3901 SIVAL(pdata
,2,own_grp
);
3906 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
3907 SIVAL(pdata
,2,0xFFFFFFFF);
3908 SIVAL(pdata
,6,0xFFFFFFFF);
3911 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
3912 SIVAL(pdata
,2,0xFFFFFFFF);
3913 SIVAL(pdata
,6,0xFFFFFFFF);
3916 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
3919 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
3926 /****************************************************************************
3927 Store the FILE_UNIX_BASIC info.
3928 ****************************************************************************/
3930 static char *store_file_unix_basic(connection_struct
*conn
,
3933 const SMB_STRUCT_STAT
*psbuf
)
3935 uint64_t file_index
= get_FileIndex(conn
, psbuf
);
3937 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
3938 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_ex_mode
));
3940 SOFF_T(pdata
,0,get_file_size_stat(psbuf
)); /* File size 64 Bit */
3943 SOFF_T(pdata
,0,SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
3946 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
, psbuf
->st_ex_ctime
); /* Change Time 64 Bit */
3947 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
+8, psbuf
->st_ex_atime
); /* Last access time 64 Bit */
3948 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
+16, psbuf
->st_ex_mtime
); /* Last modification time 64 Bit */
3951 SIVAL(pdata
,0,psbuf
->st_ex_uid
); /* user id for the owner */
3955 SIVAL(pdata
,0,psbuf
->st_ex_gid
); /* group id of owner */
3959 SIVAL(pdata
,0,unix_filetype(psbuf
->st_ex_mode
));
3962 SIVAL(pdata
,0,unix_dev_major(psbuf
->st_ex_rdev
)); /* Major device number if type is device */
3966 SIVAL(pdata
,0,unix_dev_minor(psbuf
->st_ex_rdev
)); /* Minor device number if type is device */
3970 SINO_T_VAL(pdata
,0,(SMB_INO_T
)file_index
); /* inode number */
3973 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_ex_mode
)); /* Standard UNIX file permissions */
3977 SIVAL(pdata
,0,psbuf
->st_ex_nlink
); /* number of hard links */
3984 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
3985 * the chflags(2) (or equivalent) flags.
3987 * XXX: this really should be behind the VFS interface. To do this, we would
3988 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
3989 * Each VFS module could then implement its own mapping as appropriate for the
3990 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
3992 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
3996 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
4000 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
4004 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
4008 { UF_HIDDEN
, EXT_HIDDEN
},
4011 /* Do not remove. We need to guarantee that this array has at least one
4012 * entry to build on HP-UX.
4018 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4019 uint32
*smb_fflags
, uint32
*smb_fmask
)
4023 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4024 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
4025 if (psbuf
->st_ex_flags
& info2_flags_map
[i
].stat_fflag
) {
4026 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
4031 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4032 const uint32 smb_fflags
,
4033 const uint32 smb_fmask
,
4036 uint32 max_fmask
= 0;
4039 *stat_fflags
= psbuf
->st_ex_flags
;
4041 /* For each flags requested in smb_fmask, check the state of the
4042 * corresponding flag in smb_fflags and set or clear the matching
4046 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4047 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
4048 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
4049 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
4050 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
4052 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
4057 /* If smb_fmask is asking to set any bits that are not supported by
4058 * our flag mappings, we should fail.
4060 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
4068 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4069 * of file flags and birth (create) time.
4071 static char *store_file_unix_basic_info2(connection_struct
*conn
,
4074 const SMB_STRUCT_STAT
*psbuf
)
4076 uint32 file_flags
= 0;
4077 uint32 flags_mask
= 0;
4079 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4081 /* Create (birth) time 64 bit */
4082 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
, psbuf
->st_ex_btime
);
4085 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
4086 SIVAL(pdata
, 0, file_flags
); /* flags */
4087 SIVAL(pdata
, 4, flags_mask
); /* mask */
4093 static NTSTATUS
marshall_stream_info(unsigned int num_streams
,
4094 const struct stream_struct
*streams
,
4096 unsigned int max_data_bytes
,
4097 unsigned int *data_size
)
4100 unsigned int ofs
= 0;
4102 for (i
= 0; i
< num_streams
; i
++) {
4103 unsigned int next_offset
;
4105 smb_ucs2_t
*namebuf
;
4107 if (!push_ucs2_talloc(talloc_tos(), &namebuf
,
4108 streams
[i
].name
, &namelen
) ||
4111 return NT_STATUS_INVALID_PARAMETER
;
4115 * name_buf is now null-terminated, we need to marshall as not
4122 * We cannot overflow ...
4124 if ((ofs
+ 24 + namelen
) > max_data_bytes
) {
4125 DEBUG(10, ("refusing to overflow reply at stream %u\n",
4127 TALLOC_FREE(namebuf
);
4128 return STATUS_BUFFER_OVERFLOW
;
4131 SIVAL(data
, ofs
+4, namelen
);
4132 SOFF_T(data
, ofs
+8, streams
[i
].size
);
4133 SOFF_T(data
, ofs
+16, streams
[i
].alloc_size
);
4134 memcpy(data
+ofs
+24, namebuf
, namelen
);
4135 TALLOC_FREE(namebuf
);
4137 next_offset
= ofs
+ 24 + namelen
;
4139 if (i
== num_streams
-1) {
4140 SIVAL(data
, ofs
, 0);
4143 unsigned int align
= ndr_align_size(next_offset
, 8);
4145 if ((next_offset
+ align
) > max_data_bytes
) {
4146 DEBUG(10, ("refusing to overflow align "
4147 "reply at stream %u\n",
4149 TALLOC_FREE(namebuf
);
4150 return STATUS_BUFFER_OVERFLOW
;
4153 memset(data
+next_offset
, 0, align
);
4154 next_offset
+= align
;
4156 SIVAL(data
, ofs
, next_offset
- ofs
);
4163 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes
, ofs
));
4167 return NT_STATUS_OK
;
4170 /****************************************************************************
4171 Reply to a TRANSACT2_QFILEINFO on a PIPE !
4172 ****************************************************************************/
4174 static void call_trans2qpipeinfo(connection_struct
*conn
,
4175 struct smb_request
*req
,
4176 unsigned int tran_call
,
4177 char **pparams
, int total_params
,
4178 char **ppdata
, int total_data
,
4179 unsigned int max_data_bytes
)
4181 char *params
= *pparams
;
4182 char *pdata
= *ppdata
;
4183 unsigned int data_size
= 0;
4184 unsigned int param_size
= 2;
4189 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4193 if (total_params
< 4) {
4194 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4198 fsp
= file_fsp(req
, SVAL(params
,0));
4199 if (!fsp_is_np(fsp
)) {
4200 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
4204 info_level
= SVAL(params
,2);
4206 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
4207 if (*pparams
== NULL
) {
4208 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4213 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4214 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4215 if (*ppdata
== NULL
) {
4216 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4221 switch (info_level
) {
4222 case SMB_FILE_STANDARD_INFORMATION
:
4224 SOFF_T(pdata
,0,4096LL);
4231 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
4235 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
4241 NTSTATUS
smbd_do_qfilepathinfo(connection_struct
*conn
,
4242 TALLOC_CTX
*mem_ctx
,
4243 uint16_t info_level
,
4245 struct smb_filename
*smb_fname
,
4246 bool delete_pending
,
4247 struct timespec write_time_ts
,
4248 struct ea_list
*ea_list
,
4249 int lock_data_count
,
4252 unsigned int max_data_bytes
,
4254 unsigned int *pdata_size
)
4256 char *pdata
= *ppdata
;
4257 char *dstart
, *dend
;
4258 unsigned int data_size
;
4259 struct timespec create_time_ts
, mtime_ts
, atime_ts
, ctime_ts
;
4260 time_t create_time
, mtime
, atime
, c_time
;
4261 SMB_STRUCT_STAT
*psbuf
= &smb_fname
->st
;
4268 uint64_t file_size
= 0;
4270 uint64_t allocation_size
= 0;
4271 uint64_t file_index
= 0;
4272 uint32_t access_mask
= 0;
4274 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
4275 return NT_STATUS_INVALID_LEVEL
;
4278 DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
4279 smb_fname_str_dbg(smb_fname
), fsp
? fsp
->fnum
: -1,
4280 info_level
, max_data_bytes
));
4282 mode
= dos_mode(conn
, smb_fname
);
4283 nlink
= psbuf
->st_ex_nlink
;
4285 if (nlink
&& (mode
&FILE_ATTRIBUTE_DIRECTORY
)) {
4289 if ((nlink
> 0) && delete_pending
) {
4293 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4294 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4295 if (*ppdata
== NULL
) {
4296 return NT_STATUS_NO_MEMORY
;
4300 dend
= dstart
+ data_size
- 1;
4302 if (!null_timespec(write_time_ts
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
4303 update_stat_ex_mtime(psbuf
, write_time_ts
);
4306 create_time_ts
= get_create_timespec(conn
, fsp
, smb_fname
);
4307 mtime_ts
= psbuf
->st_ex_mtime
;
4308 atime_ts
= psbuf
->st_ex_atime
;
4309 ctime_ts
= get_change_timespec(conn
, fsp
, smb_fname
);
4311 if (lp_dos_filetime_resolution(SNUM(conn
))) {
4312 dos_filetime_timespec(&create_time_ts
);
4313 dos_filetime_timespec(&mtime_ts
);
4314 dos_filetime_timespec(&atime_ts
);
4315 dos_filetime_timespec(&ctime_ts
);
4318 create_time
= convert_timespec_to_time_t(create_time_ts
);
4319 mtime
= convert_timespec_to_time_t(mtime_ts
);
4320 atime
= convert_timespec_to_time_t(atime_ts
);
4321 c_time
= convert_timespec_to_time_t(ctime_ts
);
4323 p
= strrchr_m(smb_fname
->base_name
,'/');
4325 base_name
= smb_fname
->base_name
;
4329 /* NT expects the name to be in an exact form of the *full*
4330 filename. See the trans2 torture test */
4331 if (ISDOT(base_name
)) {
4332 dos_fname
= talloc_strdup(mem_ctx
, "\\");
4334 return NT_STATUS_NO_MEMORY
;
4337 dos_fname
= talloc_asprintf(mem_ctx
,
4339 smb_fname
->base_name
);
4341 return NT_STATUS_NO_MEMORY
;
4343 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4344 dos_fname
= talloc_asprintf(dos_fname
, "%s",
4345 smb_fname
->stream_name
);
4347 return NT_STATUS_NO_MEMORY
;
4351 string_replace(dos_fname
, '/', '\\');
4354 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, psbuf
);
4357 /* Do we have this path open ? */
4359 struct file_id fileid
= vfs_file_id_from_sbuf(conn
, psbuf
);
4360 fsp1
= file_find_di_first(conn
->sconn
, fileid
);
4361 if (fsp1
&& fsp1
->initial_allocation_size
) {
4362 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp1
, psbuf
);
4366 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
4367 file_size
= get_file_size_stat(psbuf
);
4371 pos
= fsp
->fh
->position_information
;
4375 access_mask
= fsp
->access_mask
;
4377 /* GENERIC_EXECUTE mapping from Windows */
4378 access_mask
= 0x12019F;
4381 /* This should be an index number - looks like
4384 I think this causes us to fail the IFSKIT
4385 BasicFileInformationTest. -tpot */
4386 file_index
= get_FileIndex(conn
, psbuf
);
4388 switch (info_level
) {
4389 case SMB_INFO_STANDARD
:
4390 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4392 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
4393 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
4394 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
4395 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
4396 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
4397 SSVAL(pdata
,l1_attrFile
,mode
);
4400 case SMB_INFO_QUERY_EA_SIZE
:
4402 unsigned int ea_size
=
4403 estimate_ea_size(conn
, fsp
,
4404 smb_fname
->base_name
);
4405 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4407 srv_put_dos_date2(pdata
,0,create_time
);
4408 srv_put_dos_date2(pdata
,4,atime
);
4409 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
4410 SIVAL(pdata
,12,(uint32
)file_size
);
4411 SIVAL(pdata
,16,(uint32
)allocation_size
);
4412 SSVAL(pdata
,20,mode
);
4413 SIVAL(pdata
,22,ea_size
);
4417 case SMB_INFO_IS_NAME_VALID
:
4418 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4420 /* os/2 needs this ? really ?*/
4421 return NT_STATUS_DOS(ERRDOS
, ERRbadfunc
);
4423 /* This is only reached for qpathinfo */
4427 case SMB_INFO_QUERY_EAS_FROM_LIST
:
4429 size_t total_ea_len
= 0;
4430 struct ea_list
*ea_file_list
= NULL
;
4432 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4435 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4436 smb_fname
->base_name
,
4438 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
4440 if (!ea_list
|| (total_ea_len
> data_size
)) {
4442 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4446 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4450 case SMB_INFO_QUERY_ALL_EAS
:
4452 /* We have data_size bytes to put EA's into. */
4453 size_t total_ea_len
= 0;
4455 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4457 ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4458 smb_fname
->base_name
,
4460 if (!ea_list
|| (total_ea_len
> data_size
)) {
4462 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4466 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4470 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4472 /* This is FileFullEaInformation - 0xF which maps to
4473 * 1015 (decimal) in smbd_do_setfilepathinfo. */
4475 /* We have data_size bytes to put EA's into. */
4476 size_t total_ea_len
= 0;
4477 struct ea_list
*ea_file_list
= NULL
;
4479 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4481 /*TODO: add filtering and index handling */
4484 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4485 smb_fname
->base_name
,
4487 if (!ea_file_list
) {
4488 return NT_STATUS_NO_EAS_ON_FILE
;
4491 status
= fill_ea_chained_buffer(mem_ctx
,
4495 conn
, ea_file_list
);
4496 if (!NT_STATUS_IS_OK(status
)) {
4502 case SMB_FILE_BASIC_INFORMATION
:
4503 case SMB_QUERY_FILE_BASIC_INFO
:
4505 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
4506 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4507 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
4509 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4513 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4514 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4515 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4516 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4517 SIVAL(pdata
,32,mode
);
4519 DEBUG(5,("SMB_QFBI - "));
4520 DEBUG(5,("create: %s ", ctime(&create_time
)));
4521 DEBUG(5,("access: %s ", ctime(&atime
)));
4522 DEBUG(5,("write: %s ", ctime(&mtime
)));
4523 DEBUG(5,("change: %s ", ctime(&c_time
)));
4524 DEBUG(5,("mode: %x\n", mode
));
4527 case SMB_FILE_STANDARD_INFORMATION
:
4528 case SMB_QUERY_FILE_STANDARD_INFO
:
4530 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4532 SOFF_T(pdata
,0,allocation_size
);
4533 SOFF_T(pdata
,8,file_size
);
4534 SIVAL(pdata
,16,nlink
);
4535 SCVAL(pdata
,20,delete_pending
?1:0);
4536 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4537 SSVAL(pdata
,22,0); /* Padding. */
4540 case SMB_FILE_EA_INFORMATION
:
4541 case SMB_QUERY_FILE_EA_INFO
:
4543 unsigned int ea_size
=
4544 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4545 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4547 SIVAL(pdata
,0,ea_size
);
4551 /* Get the 8.3 name - used if NT SMB was negotiated. */
4552 case SMB_QUERY_FILE_ALT_NAME_INFO
:
4553 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
4556 char mangled_name
[13];
4557 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4558 if (!name_to_8_3(base_name
,mangled_name
,
4559 True
,conn
->params
)) {
4560 return NT_STATUS_NO_MEMORY
;
4562 len
= srvstr_push(dstart
, flags2
,
4563 pdata
+4, mangled_name
,
4564 PTR_DIFF(dend
, pdata
+4),
4566 data_size
= 4 + len
;
4571 case SMB_QUERY_FILE_NAME_INFO
:
4575 this must be *exactly* right for ACLs on mapped drives to work
4577 len
= srvstr_push(dstart
, flags2
,
4579 PTR_DIFF(dend
, pdata
+4),
4581 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4582 data_size
= 4 + len
;
4587 case SMB_FILE_ALLOCATION_INFORMATION
:
4588 case SMB_QUERY_FILE_ALLOCATION_INFO
:
4589 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4591 SOFF_T(pdata
,0,allocation_size
);
4594 case SMB_FILE_END_OF_FILE_INFORMATION
:
4595 case SMB_QUERY_FILE_END_OF_FILEINFO
:
4596 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4598 SOFF_T(pdata
,0,file_size
);
4601 case SMB_QUERY_FILE_ALL_INFO
:
4602 case SMB_FILE_ALL_INFORMATION
:
4605 unsigned int ea_size
=
4606 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4607 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4608 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4609 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4610 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4611 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4612 SIVAL(pdata
,32,mode
);
4613 SIVAL(pdata
,36,0); /* padding. */
4615 SOFF_T(pdata
,0,allocation_size
);
4616 SOFF_T(pdata
,8,file_size
);
4617 SIVAL(pdata
,16,nlink
);
4618 SCVAL(pdata
,20,delete_pending
);
4619 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4622 SIVAL(pdata
,0,ea_size
);
4623 pdata
+= 4; /* EA info */
4624 len
= srvstr_push(dstart
, flags2
,
4626 PTR_DIFF(dend
, pdata
+4),
4630 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4634 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4637 unsigned int ea_size
=
4638 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4639 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4640 put_long_date_timespec(conn
->ts_res
,pdata
+0x00,create_time_ts
);
4641 put_long_date_timespec(conn
->ts_res
,pdata
+0x08,atime_ts
);
4642 put_long_date_timespec(conn
->ts_res
,pdata
+0x10,mtime_ts
); /* write time */
4643 put_long_date_timespec(conn
->ts_res
,pdata
+0x18,ctime_ts
); /* change time */
4644 SIVAL(pdata
, 0x20, mode
);
4645 SIVAL(pdata
, 0x24, 0); /* padding. */
4646 SBVAL(pdata
, 0x28, allocation_size
);
4647 SBVAL(pdata
, 0x30, file_size
);
4648 SIVAL(pdata
, 0x38, nlink
);
4649 SCVAL(pdata
, 0x3C, delete_pending
);
4650 SCVAL(pdata
, 0x3D, (mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4651 SSVAL(pdata
, 0x3E, 0); /* padding */
4652 SBVAL(pdata
, 0x40, file_index
);
4653 SIVAL(pdata
, 0x48, ea_size
);
4654 SIVAL(pdata
, 0x4C, access_mask
);
4655 SBVAL(pdata
, 0x50, pos
);
4656 SIVAL(pdata
, 0x58, mode
); /*TODO: mode != mode fix this!!! */
4657 SIVAL(pdata
, 0x5C, 0); /* No alignment needed. */
4661 len
= srvstr_push(dstart
, flags2
,
4663 PTR_DIFF(dend
, pdata
+4),
4667 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4670 case SMB_FILE_INTERNAL_INFORMATION
:
4672 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4673 SBVAL(pdata
, 0, file_index
);
4677 case SMB_FILE_ACCESS_INFORMATION
:
4678 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4679 SIVAL(pdata
, 0, access_mask
);
4683 case SMB_FILE_NAME_INFORMATION
:
4684 /* Pathname with leading '\'. */
4687 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
4688 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4689 SIVAL(pdata
,0,byte_len
);
4690 data_size
= 4 + byte_len
;
4694 case SMB_FILE_DISPOSITION_INFORMATION
:
4695 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4697 SCVAL(pdata
,0,delete_pending
);
4700 case SMB_FILE_POSITION_INFORMATION
:
4701 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4703 SOFF_T(pdata
,0,pos
);
4706 case SMB_FILE_MODE_INFORMATION
:
4707 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4708 SIVAL(pdata
,0,mode
);
4712 case SMB_FILE_ALIGNMENT_INFORMATION
:
4713 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4714 SIVAL(pdata
,0,0); /* No alignment needed. */
4719 * NT4 server just returns "invalid query" to this - if we try
4720 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4723 /* The first statement above is false - verified using Thursby
4724 * client against NT4 -- gcolley.
4726 case SMB_QUERY_FILE_STREAM_INFO
:
4727 case SMB_FILE_STREAM_INFORMATION
: {
4728 unsigned int num_streams
= 0;
4729 struct stream_struct
*streams
= NULL
;
4731 DEBUG(10,("smbd_do_qfilepathinfo: "
4732 "SMB_FILE_STREAM_INFORMATION\n"));
4734 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4735 return NT_STATUS_INVALID_PARAMETER
;
4738 status
= vfs_streaminfo(conn
, fsp
, smb_fname
->base_name
,
4739 talloc_tos(), &num_streams
, &streams
);
4741 if (!NT_STATUS_IS_OK(status
)) {
4742 DEBUG(10, ("could not get stream info: %s\n",
4743 nt_errstr(status
)));
4747 status
= marshall_stream_info(num_streams
, streams
,
4748 pdata
, max_data_bytes
,
4751 if (!NT_STATUS_IS_OK(status
)) {
4752 DEBUG(10, ("marshall_stream_info failed: %s\n",
4753 nt_errstr(status
)));
4754 TALLOC_FREE(streams
);
4758 TALLOC_FREE(streams
);
4762 case SMB_QUERY_COMPRESSION_INFO
:
4763 case SMB_FILE_COMPRESSION_INFORMATION
:
4764 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4765 SOFF_T(pdata
,0,file_size
);
4766 SIVAL(pdata
,8,0); /* ??? */
4767 SIVAL(pdata
,12,0); /* ??? */
4771 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
4772 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4773 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4774 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4775 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4776 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4777 SOFF_T(pdata
,32,allocation_size
);
4778 SOFF_T(pdata
,40,file_size
);
4779 SIVAL(pdata
,48,mode
);
4780 SIVAL(pdata
,52,0); /* ??? */
4784 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
4785 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4786 SIVAL(pdata
,0,mode
);
4792 * CIFS UNIX Extensions.
4795 case SMB_QUERY_FILE_UNIX_BASIC
:
4797 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4798 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4800 DEBUG(4,("smbd_do_qfilepathinfo: "
4801 "SMB_QUERY_FILE_UNIX_BASIC\n"));
4802 dump_data(4, (uint8_t *)(*ppdata
), data_size
);
4806 case SMB_QUERY_FILE_UNIX_INFO2
:
4808 pdata
= store_file_unix_basic_info2(conn
, pdata
, fsp
, psbuf
);
4809 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4813 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4815 for (i
=0; i
<100; i
++)
4816 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
4822 case SMB_QUERY_FILE_UNIX_LINK
:
4825 char *buffer
= TALLOC_ARRAY(mem_ctx
, char, PATH_MAX
+1);
4828 return NT_STATUS_NO_MEMORY
;
4831 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4833 if(!S_ISLNK(psbuf
->st_ex_mode
)) {
4834 return NT_STATUS_DOS(ERRSRV
, ERRbadlink
);
4837 return NT_STATUS_DOS(ERRDOS
, ERRbadlink
);
4839 len
= SMB_VFS_READLINK(conn
,
4840 smb_fname
->base_name
,
4843 return map_nt_error_from_unix(errno
);
4846 len
= srvstr_push(dstart
, flags2
,
4848 PTR_DIFF(dend
, pdata
),
4851 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4856 #if defined(HAVE_POSIX_ACLS)
4857 case SMB_QUERY_POSIX_ACL
:
4859 SMB_ACL_T file_acl
= NULL
;
4860 SMB_ACL_T def_acl
= NULL
;
4861 uint16 num_file_acls
= 0;
4862 uint16 num_def_acls
= 0;
4864 if (fsp
&& fsp
->fh
->fd
!= -1) {
4865 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
);
4868 SMB_VFS_SYS_ACL_GET_FILE(conn
,
4869 smb_fname
->base_name
,
4870 SMB_ACL_TYPE_ACCESS
);
4873 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
4874 DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4875 "not implemented on "
4876 "filesystem containing %s\n",
4877 smb_fname
->base_name
));
4878 return NT_STATUS_NOT_IMPLEMENTED
;
4881 if (S_ISDIR(psbuf
->st_ex_mode
)) {
4882 if (fsp
&& fsp
->is_directory
) {
4884 SMB_VFS_SYS_ACL_GET_FILE(
4886 fsp
->fsp_name
->base_name
,
4887 SMB_ACL_TYPE_DEFAULT
);
4890 SMB_VFS_SYS_ACL_GET_FILE(
4892 smb_fname
->base_name
,
4893 SMB_ACL_TYPE_DEFAULT
);
4895 def_acl
= free_empty_sys_acl(conn
, def_acl
);
4898 num_file_acls
= count_acl_entries(conn
, file_acl
);
4899 num_def_acls
= count_acl_entries(conn
, def_acl
);
4901 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
4902 DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
4904 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
4905 SMB_POSIX_ACL_HEADER_SIZE
) ));
4907 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4910 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4912 return NT_STATUS_BUFFER_TOO_SMALL
;
4915 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
4916 SSVAL(pdata
,2,num_file_acls
);
4917 SSVAL(pdata
,4,num_def_acls
);
4918 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, psbuf
, file_acl
)) {
4920 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4923 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4925 return NT_STATUS_INTERNAL_ERROR
;
4927 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), psbuf
, def_acl
)) {
4929 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4932 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4934 return NT_STATUS_INTERNAL_ERROR
;
4938 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4941 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4943 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
4949 case SMB_QUERY_POSIX_LOCK
:
4954 enum brl_type lock_type
;
4956 /* We need an open file with a real fd for this. */
4957 if (!fsp
|| fsp
->fh
->fd
== -1) {
4958 return NT_STATUS_INVALID_LEVEL
;
4961 if (lock_data_count
!= POSIX_LOCK_DATA_SIZE
) {
4962 return NT_STATUS_INVALID_PARAMETER
;
4965 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
4966 case POSIX_LOCK_TYPE_READ
:
4967 lock_type
= READ_LOCK
;
4969 case POSIX_LOCK_TYPE_WRITE
:
4970 lock_type
= WRITE_LOCK
;
4972 case POSIX_LOCK_TYPE_UNLOCK
:
4974 /* There's no point in asking for an unlock... */
4975 return NT_STATUS_INVALID_PARAMETER
;
4978 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
4979 #if defined(HAVE_LONGLONG)
4980 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
4981 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
4982 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
4983 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
4984 #else /* HAVE_LONGLONG */
4985 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
4986 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
4987 #endif /* HAVE_LONGLONG */
4989 status
= query_lock(fsp
,
4996 if (ERROR_WAS_LOCK_DENIED(status
)) {
4997 /* Here we need to report who has it locked... */
4998 data_size
= POSIX_LOCK_DATA_SIZE
;
5000 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, lock_type
);
5001 SSVAL(pdata
, POSIX_LOCK_FLAGS_OFFSET
, 0);
5002 SIVAL(pdata
, POSIX_LOCK_PID_OFFSET
, (uint32_t)smblctx
);
5003 #if defined(HAVE_LONGLONG)
5004 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, (uint32
)(offset
& 0xFFFFFFFF));
5005 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
+ 4, (uint32
)((offset
>> 32) & 0xFFFFFFFF));
5006 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, (uint32
)(count
& 0xFFFFFFFF));
5007 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
+ 4, (uint32
)((count
>> 32) & 0xFFFFFFFF));
5008 #else /* HAVE_LONGLONG */
5009 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, offset
);
5010 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, count
);
5011 #endif /* HAVE_LONGLONG */
5013 } else if (NT_STATUS_IS_OK(status
)) {
5014 /* For success we just return a copy of what we sent
5015 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5016 data_size
= POSIX_LOCK_DATA_SIZE
;
5017 memcpy(pdata
, lock_data
, POSIX_LOCK_DATA_SIZE
);
5018 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
5026 return NT_STATUS_INVALID_LEVEL
;
5029 *pdata_size
= data_size
;
5030 return NT_STATUS_OK
;
5033 /****************************************************************************
5034 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5035 file name or file id).
5036 ****************************************************************************/
5038 static void call_trans2qfilepathinfo(connection_struct
*conn
,
5039 struct smb_request
*req
,
5040 unsigned int tran_call
,
5041 char **pparams
, int total_params
,
5042 char **ppdata
, int total_data
,
5043 unsigned int max_data_bytes
)
5045 char *params
= *pparams
;
5046 char *pdata
= *ppdata
;
5048 unsigned int data_size
= 0;
5049 unsigned int param_size
= 2;
5050 struct smb_filename
*smb_fname
= NULL
;
5051 bool delete_pending
= False
;
5052 struct timespec write_time_ts
;
5053 files_struct
*fsp
= NULL
;
5054 struct file_id fileid
;
5055 struct ea_list
*ea_list
= NULL
;
5056 int lock_data_count
= 0;
5057 char *lock_data
= NULL
;
5058 NTSTATUS status
= NT_STATUS_OK
;
5061 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5065 ZERO_STRUCT(write_time_ts
);
5067 if (tran_call
== TRANSACT2_QFILEINFO
) {
5068 if (total_params
< 4) {
5069 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5074 call_trans2qpipeinfo(conn
, req
, tran_call
,
5075 pparams
, total_params
,
5081 fsp
= file_fsp(req
, SVAL(params
,0));
5082 info_level
= SVAL(params
,2);
5084 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
5086 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
5087 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5091 /* Initial check for valid fsp ptr. */
5092 if (!check_fsp_open(conn
, req
, fsp
)) {
5096 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
5098 if (!NT_STATUS_IS_OK(status
)) {
5099 reply_nterror(req
, status
);
5103 if(fsp
->fake_file_handle
) {
5105 * This is actually for the QUOTA_FAKE_FILE --metze
5108 /* We know this name is ok, it's already passed the checks. */
5110 } else if(fsp
->fh
->fd
== -1) {
5112 * This is actually a QFILEINFO on a directory
5113 * handle (returned from an NT SMB). NT5.0 seems
5114 * to do this call. JRA.
5117 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5118 /* Always do lstat for UNIX calls. */
5119 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5120 DEBUG(3,("call_trans2qfilepathinfo: "
5121 "SMB_VFS_LSTAT of %s failed "
5123 smb_fname_str_dbg(smb_fname
),
5126 map_nt_error_from_unix(errno
));
5129 } else if (SMB_VFS_STAT(conn
, smb_fname
)) {
5130 DEBUG(3,("call_trans2qfilepathinfo: "
5131 "SMB_VFS_STAT of %s failed (%s)\n",
5132 smb_fname_str_dbg(smb_fname
),
5135 map_nt_error_from_unix(errno
));
5139 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5140 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5143 * Original code - this is an open file.
5145 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
5146 DEBUG(3, ("fstat of fnum %d failed (%s)\n",
5147 fsp
->fnum
, strerror(errno
)));
5149 map_nt_error_from_unix(errno
));
5152 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5153 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5159 uint32_t ucf_flags
= 0;
5162 if (total_params
< 7) {
5163 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5167 info_level
= SVAL(params
,0);
5169 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
5171 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5172 if (!lp_unix_extensions()) {
5173 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5176 if (info_level
== SMB_QUERY_FILE_UNIX_BASIC
||
5177 info_level
== SMB_QUERY_FILE_UNIX_INFO2
||
5178 info_level
== SMB_QUERY_FILE_UNIX_LINK
) {
5179 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
5183 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
5185 STR_TERMINATE
, &status
);
5186 if (!NT_STATUS_IS_OK(status
)) {
5187 reply_nterror(req
, status
);
5191 status
= filename_convert(req
,
5193 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5198 if (!NT_STATUS_IS_OK(status
)) {
5199 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5200 reply_botherror(req
,
5201 NT_STATUS_PATH_NOT_COVERED
,
5202 ERRSRV
, ERRbadpath
);
5205 reply_nterror(req
, status
);
5209 /* If this is a stream, check if there is a delete_pending. */
5210 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5211 && is_ntfs_stream_smb_fname(smb_fname
)) {
5212 struct smb_filename
*smb_fname_base
= NULL
;
5214 /* Create an smb_filename with stream_name == NULL. */
5216 create_synthetic_smb_fname(talloc_tos(),
5217 smb_fname
->base_name
,
5220 if (!NT_STATUS_IS_OK(status
)) {
5221 reply_nterror(req
, status
);
5225 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5226 /* Always do lstat for UNIX calls. */
5227 if (SMB_VFS_LSTAT(conn
, smb_fname_base
) != 0) {
5228 DEBUG(3,("call_trans2qfilepathinfo: "
5229 "SMB_VFS_LSTAT of %s failed "
5231 smb_fname_str_dbg(smb_fname_base
),
5233 TALLOC_FREE(smb_fname_base
);
5235 map_nt_error_from_unix(errno
));
5239 if (SMB_VFS_STAT(conn
, smb_fname_base
) != 0) {
5240 DEBUG(3,("call_trans2qfilepathinfo: "
5241 "fileinfo of %s failed "
5243 smb_fname_str_dbg(smb_fname_base
),
5245 TALLOC_FREE(smb_fname_base
);
5247 map_nt_error_from_unix(errno
));
5252 status
= file_name_hash(conn
,
5253 smb_fname_str_dbg(smb_fname_base
),
5255 if (!NT_STATUS_IS_OK(status
)) {
5256 TALLOC_FREE(smb_fname_base
);
5257 reply_nterror(req
, status
);
5261 fileid
= vfs_file_id_from_sbuf(conn
,
5262 &smb_fname_base
->st
);
5263 TALLOC_FREE(smb_fname_base
);
5264 get_file_infos(fileid
, name_hash
, &delete_pending
, NULL
);
5265 if (delete_pending
) {
5266 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5271 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5272 /* Always do lstat for UNIX calls. */
5273 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5274 DEBUG(3,("call_trans2qfilepathinfo: "
5275 "SMB_VFS_LSTAT of %s failed (%s)\n",
5276 smb_fname_str_dbg(smb_fname
),
5279 map_nt_error_from_unix(errno
));
5284 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
5285 DEBUG(3,("call_trans2qfilepathinfo: "
5286 "SMB_VFS_STAT of %s failed (%s)\n",
5287 smb_fname_str_dbg(smb_fname
),
5290 map_nt_error_from_unix(errno
));
5295 status
= file_name_hash(conn
,
5296 smb_fname_str_dbg(smb_fname
),
5298 if (!NT_STATUS_IS_OK(status
)) {
5299 reply_nterror(req
, status
);
5303 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5304 get_file_infos(fileid
, name_hash
, &delete_pending
, &write_time_ts
);
5305 if (delete_pending
) {
5306 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5311 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
5312 "total_data=%d\n", smb_fname_str_dbg(smb_fname
),
5313 fsp
? fsp
->fnum
: -1, info_level
,tran_call
,total_data
));
5315 /* Pull out any data sent here before we realloc. */
5316 switch (info_level
) {
5317 case SMB_INFO_QUERY_EAS_FROM_LIST
:
5319 /* Pull any EA list from the data portion. */
5322 if (total_data
< 4) {
5324 req
, NT_STATUS_INVALID_PARAMETER
);
5327 ea_size
= IVAL(pdata
,0);
5329 if (total_data
> 0 && ea_size
!= total_data
) {
5330 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5331 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
5333 req
, NT_STATUS_INVALID_PARAMETER
);
5337 if (!lp_ea_support(SNUM(conn
))) {
5338 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
5342 /* Pull out the list of names. */
5343 ea_list
= read_ea_name_list(req
, pdata
+ 4, ea_size
- 4);
5346 req
, NT_STATUS_INVALID_PARAMETER
);
5352 case SMB_QUERY_POSIX_LOCK
:
5354 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
5355 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
5359 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
5361 req
, NT_STATUS_INVALID_PARAMETER
);
5365 /* Copy the lock range data. */
5366 lock_data
= (char *)TALLOC_MEMDUP(
5367 req
, pdata
, total_data
);
5369 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5372 lock_data_count
= total_data
;
5378 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
5379 if (*pparams
== NULL
) {
5380 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5387 * draft-leach-cifs-v1-spec-02.txt
5388 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5391 * The requested information is placed in the Data portion of the
5392 * transaction response. For the information levels greater than 0x100,
5393 * the transaction response has 1 parameter word which should be
5394 * ignored by the client.
5396 * However Windows only follows this rule for the IS_NAME_VALID call.
5398 switch (info_level
) {
5399 case SMB_INFO_IS_NAME_VALID
:
5404 if ((info_level
& 0xFF00) == 0xFF00) {
5406 * We use levels that start with 0xFF00
5407 * internally to represent SMB2 specific levels
5409 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5413 status
= smbd_do_qfilepathinfo(conn
, req
, info_level
,
5415 delete_pending
, write_time_ts
,
5417 lock_data_count
, lock_data
,
5418 req
->flags2
, max_data_bytes
,
5419 ppdata
, &data_size
);
5420 if (!NT_STATUS_IS_OK(status
)) {
5421 reply_nterror(req
, status
);
5425 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
5431 /****************************************************************************
5432 Set a hard link (called by UNIX extensions and by NT rename with HARD link
5434 ****************************************************************************/
5436 NTSTATUS
hardlink_internals(TALLOC_CTX
*ctx
,
5437 connection_struct
*conn
,
5438 struct smb_request
*req
,
5439 bool overwrite_if_exists
,
5440 const struct smb_filename
*smb_fname_old
,
5441 struct smb_filename
*smb_fname_new
)
5443 NTSTATUS status
= NT_STATUS_OK
;
5445 /* source must already exist. */
5446 if (!VALID_STAT(smb_fname_old
->st
)) {
5447 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5450 if (VALID_STAT(smb_fname_new
->st
)) {
5451 if (overwrite_if_exists
) {
5452 if (S_ISDIR(smb_fname_new
->st
.st_ex_mode
)) {
5453 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5455 status
= unlink_internals(conn
,
5457 FILE_ATTRIBUTE_NORMAL
,
5460 if (!NT_STATUS_IS_OK(status
)) {
5464 /* Disallow if newname already exists. */
5465 return NT_STATUS_OBJECT_NAME_COLLISION
;
5469 /* No links from a directory. */
5470 if (S_ISDIR(smb_fname_old
->st
.st_ex_mode
)) {
5471 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5474 /* Setting a hardlink to/from a stream isn't currently supported. */
5475 if (is_ntfs_stream_smb_fname(smb_fname_old
) ||
5476 is_ntfs_stream_smb_fname(smb_fname_new
)) {
5477 return NT_STATUS_INVALID_PARAMETER
;
5480 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5481 smb_fname_old
->base_name
, smb_fname_new
->base_name
));
5483 if (SMB_VFS_LINK(conn
, smb_fname_old
->base_name
,
5484 smb_fname_new
->base_name
) != 0) {
5485 status
= map_nt_error_from_unix(errno
);
5486 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5487 nt_errstr(status
), smb_fname_old
->base_name
,
5488 smb_fname_new
->base_name
));
5493 /****************************************************************************
5494 Deal with setting the time from any of the setfilepathinfo functions.
5495 ****************************************************************************/
5497 NTSTATUS
smb_set_file_time(connection_struct
*conn
,
5499 const struct smb_filename
*smb_fname
,
5500 struct smb_file_time
*ft
,
5501 bool setting_write_time
)
5503 struct smb_filename smb_fname_base
;
5505 FILE_NOTIFY_CHANGE_LAST_ACCESS
5506 |FILE_NOTIFY_CHANGE_LAST_WRITE
5507 |FILE_NOTIFY_CHANGE_CREATION
;
5509 if (!VALID_STAT(smb_fname
->st
)) {
5510 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5513 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
5514 return NT_STATUS_ACCESS_DENIED
;
5517 /* get some defaults (no modifications) if any info is zero or -1. */
5518 if (null_timespec(ft
->create_time
)) {
5519 action
&= ~FILE_NOTIFY_CHANGE_CREATION
;
5522 if (null_timespec(ft
->atime
)) {
5523 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
5526 if (null_timespec(ft
->mtime
)) {
5527 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5530 if (!setting_write_time
) {
5531 /* ft->mtime comes from change time, not write time. */
5532 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5535 /* Ensure the resolution is the correct for
5536 * what we can store on this filesystem. */
5538 round_timespec(conn
->ts_res
, &ft
->create_time
);
5539 round_timespec(conn
->ts_res
, &ft
->ctime
);
5540 round_timespec(conn
->ts_res
, &ft
->atime
);
5541 round_timespec(conn
->ts_res
, &ft
->mtime
);
5543 DEBUG(5,("smb_set_filetime: actime: %s\n ",
5544 time_to_asc(convert_timespec_to_time_t(ft
->atime
))));
5545 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5546 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5547 DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5548 time_to_asc(convert_timespec_to_time_t(ft
->ctime
))));
5549 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5550 time_to_asc(convert_timespec_to_time_t(ft
->create_time
))));
5552 if (setting_write_time
) {
5554 * This was a Windows setfileinfo on an open file.
5555 * NT does this a lot. We also need to
5556 * set the time here, as it can be read by
5557 * FindFirst/FindNext and with the patch for bug #2045
5558 * in smbd/fileio.c it ensures that this timestamp is
5559 * kept sticky even after a write. We save the request
5560 * away and will set it on file close and after a write. JRA.
5563 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5564 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5567 if (fsp
->base_fsp
) {
5568 set_sticky_write_time_fsp(fsp
->base_fsp
,
5571 set_sticky_write_time_fsp(fsp
, ft
->mtime
);
5574 set_sticky_write_time_path(
5575 vfs_file_id_from_sbuf(conn
, &smb_fname
->st
),
5580 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5582 /* Always call ntimes on the base, even if a stream was passed in. */
5583 smb_fname_base
= *smb_fname
;
5584 smb_fname_base
.stream_name
= NULL
;
5586 if(file_ntimes(conn
, &smb_fname_base
, ft
)!=0) {
5587 return map_nt_error_from_unix(errno
);
5590 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
,
5591 smb_fname
->base_name
);
5592 return NT_STATUS_OK
;
5595 /****************************************************************************
5596 Deal with setting the dosmode from any of the setfilepathinfo functions.
5597 ****************************************************************************/
5599 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
5600 const struct smb_filename
*smb_fname
,
5603 struct smb_filename
*smb_fname_base
= NULL
;
5606 if (!VALID_STAT(smb_fname
->st
)) {
5607 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5610 /* Always operate on the base_name, even if a stream was passed in. */
5611 status
= create_synthetic_smb_fname(talloc_tos(), smb_fname
->base_name
,
5612 NULL
, &smb_fname
->st
,
5614 if (!NT_STATUS_IS_OK(status
)) {
5619 if (S_ISDIR(smb_fname_base
->st
.st_ex_mode
)) {
5620 dosmode
|= FILE_ATTRIBUTE_DIRECTORY
;
5622 dosmode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
5626 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode
));
5628 /* check the mode isn't different, before changing it */
5629 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, smb_fname_base
))) {
5630 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5631 "0x%x\n", smb_fname_str_dbg(smb_fname_base
),
5632 (unsigned int)dosmode
));
5634 if(file_set_dosmode(conn
, smb_fname_base
, dosmode
, NULL
,
5636 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5638 smb_fname_str_dbg(smb_fname_base
),
5640 status
= map_nt_error_from_unix(errno
);
5644 status
= NT_STATUS_OK
;
5646 TALLOC_FREE(smb_fname_base
);
5650 /****************************************************************************
5651 Deal with setting the size from any of the setfilepathinfo functions.
5652 ****************************************************************************/
5654 static NTSTATUS
smb_set_file_size(connection_struct
*conn
,
5655 struct smb_request
*req
,
5657 const struct smb_filename
*smb_fname
,
5658 const SMB_STRUCT_STAT
*psbuf
,
5660 bool fail_after_createfile
)
5662 NTSTATUS status
= NT_STATUS_OK
;
5663 struct smb_filename
*smb_fname_tmp
= NULL
;
5664 files_struct
*new_fsp
= NULL
;
5666 if (!VALID_STAT(*psbuf
)) {
5667 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5670 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
5671 return NT_STATUS_ACCESS_DENIED
;
5674 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size
));
5676 if (size
== get_file_size_stat(psbuf
)) {
5677 return NT_STATUS_OK
;
5680 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5681 smb_fname_str_dbg(smb_fname
), (double)size
));
5683 if (fsp
&& fsp
->fh
->fd
!= -1) {
5684 /* Handle based call. */
5685 if (vfs_set_filelen(fsp
, size
) == -1) {
5686 return map_nt_error_from_unix(errno
);
5688 trigger_write_time_update_immediate(fsp
);
5689 return NT_STATUS_OK
;
5692 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
5693 if (!NT_STATUS_IS_OK(status
)) {
5697 smb_fname_tmp
->st
= *psbuf
;
5699 status
= SMB_VFS_CREATE_FILE(
5702 0, /* root_dir_fid */
5703 smb_fname_tmp
, /* fname */
5704 FILE_WRITE_DATA
, /* access_mask */
5705 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5707 FILE_OPEN
, /* create_disposition*/
5708 0, /* create_options */
5709 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5710 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
5711 0, /* allocation_size */
5712 0, /* private_flags */
5715 &new_fsp
, /* result */
5718 TALLOC_FREE(smb_fname_tmp
);
5720 if (!NT_STATUS_IS_OK(status
)) {
5721 /* NB. We check for open_was_deferred in the caller. */
5725 /* See RAW-SFILEINFO-END-OF-FILE */
5726 if (fail_after_createfile
) {
5727 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5728 return NT_STATUS_INVALID_LEVEL
;
5731 if (vfs_set_filelen(new_fsp
, size
) == -1) {
5732 status
= map_nt_error_from_unix(errno
);
5733 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5737 trigger_write_time_update_immediate(new_fsp
);
5738 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5739 return NT_STATUS_OK
;
5742 /****************************************************************************
5743 Deal with SMB_INFO_SET_EA.
5744 ****************************************************************************/
5746 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
5750 const struct smb_filename
*smb_fname
)
5752 struct ea_list
*ea_list
= NULL
;
5753 TALLOC_CTX
*ctx
= NULL
;
5754 NTSTATUS status
= NT_STATUS_OK
;
5756 if (total_data
< 10) {
5758 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5759 length. They seem to have no effect. Bug #3212. JRA */
5761 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
5762 /* We're done. We only get EA info in this call. */
5763 return NT_STATUS_OK
;
5766 return NT_STATUS_INVALID_PARAMETER
;
5769 if (IVAL(pdata
,0) > total_data
) {
5770 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5771 IVAL(pdata
,0), (unsigned int)total_data
));
5772 return NT_STATUS_INVALID_PARAMETER
;
5776 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
5778 return NT_STATUS_INVALID_PARAMETER
;
5781 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_EA
)) {
5782 return NT_STATUS_ACCESS_DENIED
;
5785 status
= set_ea(conn
, fsp
, smb_fname
, ea_list
);
5790 /****************************************************************************
5791 Deal with SMB_FILE_FULL_EA_INFORMATION set.
5792 ****************************************************************************/
5794 static NTSTATUS
smb_set_file_full_ea_info(connection_struct
*conn
,
5799 struct ea_list
*ea_list
= NULL
;
5803 return NT_STATUS_INVALID_HANDLE
;
5806 if (!lp_ea_support(SNUM(conn
))) {
5807 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5808 "EA's not supported.\n",
5809 (unsigned int)total_data
));
5810 return NT_STATUS_EAS_NOT_SUPPORTED
;
5813 if (total_data
< 10) {
5814 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5816 (unsigned int)total_data
));
5817 return NT_STATUS_INVALID_PARAMETER
;
5820 ea_list
= read_nttrans_ea_list(talloc_tos(),
5825 return NT_STATUS_INVALID_PARAMETER
;
5828 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_EA
)) {
5829 return NT_STATUS_ACCESS_DENIED
;
5832 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
5834 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5835 smb_fname_str_dbg(fsp
->fsp_name
),
5836 nt_errstr(status
) ));
5842 /****************************************************************************
5843 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5844 ****************************************************************************/
5846 static NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
5850 struct smb_filename
*smb_fname
)
5852 NTSTATUS status
= NT_STATUS_OK
;
5853 bool delete_on_close
;
5856 if (total_data
< 1) {
5857 return NT_STATUS_INVALID_PARAMETER
;
5861 return NT_STATUS_INVALID_HANDLE
;
5864 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
5865 dosmode
= dos_mode(conn
, smb_fname
);
5867 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5868 "delete_on_close = %u\n",
5869 smb_fname_str_dbg(smb_fname
),
5870 (unsigned int)dosmode
,
5871 (unsigned int)delete_on_close
));
5873 if (delete_on_close
) {
5874 status
= can_set_delete_on_close(fsp
, dosmode
);
5875 if (!NT_STATUS_IS_OK(status
)) {
5880 /* The set is across all open files on this dev/inode pair. */
5881 if (!set_delete_on_close(fsp
, delete_on_close
,
5882 conn
->session_info
->security_token
,
5883 &conn
->session_info
->utok
)) {
5884 return NT_STATUS_ACCESS_DENIED
;
5886 return NT_STATUS_OK
;
5889 /****************************************************************************
5890 Deal with SMB_FILE_POSITION_INFORMATION.
5891 ****************************************************************************/
5893 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
5898 uint64_t position_information
;
5900 if (total_data
< 8) {
5901 return NT_STATUS_INVALID_PARAMETER
;
5905 /* Ignore on pathname based set. */
5906 return NT_STATUS_OK
;
5909 position_information
= (uint64_t)IVAL(pdata
,0);
5910 #ifdef LARGE_SMB_OFF_T
5911 position_information
|= (((uint64_t)IVAL(pdata
,4)) << 32);
5912 #else /* LARGE_SMB_OFF_T */
5913 if (IVAL(pdata
,4) != 0) {
5914 /* more than 32 bits? */
5915 return NT_STATUS_INVALID_PARAMETER
;
5917 #endif /* LARGE_SMB_OFF_T */
5919 DEBUG(10,("smb_file_position_information: Set file position "
5920 "information for file %s to %.0f\n", fsp_str_dbg(fsp
),
5921 (double)position_information
));
5922 fsp
->fh
->position_information
= position_information
;
5923 return NT_STATUS_OK
;
5926 /****************************************************************************
5927 Deal with SMB_FILE_MODE_INFORMATION.
5928 ****************************************************************************/
5930 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
5936 if (total_data
< 4) {
5937 return NT_STATUS_INVALID_PARAMETER
;
5939 mode
= IVAL(pdata
,0);
5940 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
5941 return NT_STATUS_INVALID_PARAMETER
;
5943 return NT_STATUS_OK
;
5946 /****************************************************************************
5947 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
5948 ****************************************************************************/
5950 static NTSTATUS
smb_set_file_unix_link(connection_struct
*conn
,
5951 struct smb_request
*req
,
5954 const struct smb_filename
*smb_fname
)
5956 char *link_target
= NULL
;
5957 const char *newname
= smb_fname
->base_name
;
5958 TALLOC_CTX
*ctx
= talloc_tos();
5960 /* Set a symbolic link. */
5961 /* Don't allow this if follow links is false. */
5963 if (total_data
== 0) {
5964 return NT_STATUS_INVALID_PARAMETER
;
5967 if (!lp_symlinks(SNUM(conn
))) {
5968 return NT_STATUS_ACCESS_DENIED
;
5971 srvstr_pull_talloc(ctx
, pdata
, req
->flags2
, &link_target
, pdata
,
5972 total_data
, STR_TERMINATE
);
5975 return NT_STATUS_INVALID_PARAMETER
;
5978 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
5979 newname
, link_target
));
5981 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0) {
5982 return map_nt_error_from_unix(errno
);
5985 return NT_STATUS_OK
;
5988 /****************************************************************************
5989 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
5990 ****************************************************************************/
5992 static NTSTATUS
smb_set_file_unix_hlink(connection_struct
*conn
,
5993 struct smb_request
*req
,
5994 const char *pdata
, int total_data
,
5995 struct smb_filename
*smb_fname_new
)
5997 char *oldname
= NULL
;
5998 struct smb_filename
*smb_fname_old
= NULL
;
5999 TALLOC_CTX
*ctx
= talloc_tos();
6000 NTSTATUS status
= NT_STATUS_OK
;
6002 /* Set a hard link. */
6003 if (total_data
== 0) {
6004 return NT_STATUS_INVALID_PARAMETER
;
6007 srvstr_get_path(ctx
, pdata
, req
->flags2
, &oldname
, pdata
,
6008 total_data
, STR_TERMINATE
, &status
);
6009 if (!NT_STATUS_IS_OK(status
)) {
6013 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6014 smb_fname_str_dbg(smb_fname_new
), oldname
));
6016 status
= filename_convert(ctx
,
6018 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6023 if (!NT_STATUS_IS_OK(status
)) {
6027 return hardlink_internals(ctx
, conn
, req
, false,
6028 smb_fname_old
, smb_fname_new
);
6031 /****************************************************************************
6032 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6033 ****************************************************************************/
6035 static NTSTATUS
smb2_file_rename_information(connection_struct
*conn
,
6036 struct smb_request
*req
,
6040 struct smb_filename
*smb_fname_src
)
6044 char *newname
= NULL
;
6045 struct smb_filename
*smb_fname_dst
= NULL
;
6046 NTSTATUS status
= NT_STATUS_OK
;
6047 TALLOC_CTX
*ctx
= talloc_tos();
6050 return NT_STATUS_INVALID_HANDLE
;
6053 if (total_data
< 20) {
6054 return NT_STATUS_INVALID_PARAMETER
;
6057 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6058 len
= IVAL(pdata
,16);
6060 if (len
> (total_data
- 20) || (len
== 0)) {
6061 return NT_STATUS_INVALID_PARAMETER
;
6064 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6065 &pdata
[20], len
, STR_TERMINATE
,
6067 if (!NT_STATUS_IS_OK(status
)) {
6071 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
6074 status
= filename_convert(ctx
,
6076 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6081 if (!NT_STATUS_IS_OK(status
)) {
6085 if (fsp
->base_fsp
) {
6086 /* newname must be a stream name. */
6087 if (newname
[0] != ':') {
6088 return NT_STATUS_NOT_SUPPORTED
;
6091 /* Create an smb_fname to call rename_internals_fsp() with. */
6092 status
= create_synthetic_smb_fname(talloc_tos(),
6093 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6095 if (!NT_STATUS_IS_OK(status
)) {
6100 * Set the original last component, since
6101 * rename_internals_fsp() requires it.
6103 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6105 if (smb_fname_dst
->original_lcomp
== NULL
) {
6106 status
= NT_STATUS_NO_MEMORY
;
6112 DEBUG(10,("smb2_file_rename_information: "
6113 "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6114 fsp
->fnum
, fsp_str_dbg(fsp
),
6115 smb_fname_str_dbg(smb_fname_dst
)));
6116 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6117 (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
),
6121 TALLOC_FREE(smb_fname_dst
);
6125 static NTSTATUS
smb_file_link_information(connection_struct
*conn
,
6126 struct smb_request
*req
,
6130 struct smb_filename
*smb_fname_src
)
6134 char *newname
= NULL
;
6135 struct smb_filename
*smb_fname_dst
= NULL
;
6136 NTSTATUS status
= NT_STATUS_OK
;
6137 TALLOC_CTX
*ctx
= talloc_tos();
6140 return NT_STATUS_INVALID_HANDLE
;
6143 if (total_data
< 20) {
6144 return NT_STATUS_INVALID_PARAMETER
;
6147 overwrite
= (CVAL(pdata
,0) ? true : false);
6148 len
= IVAL(pdata
,16);
6150 if (len
> (total_data
- 20) || (len
== 0)) {
6151 return NT_STATUS_INVALID_PARAMETER
;
6154 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6155 &pdata
[20], len
, STR_TERMINATE
,
6157 if (!NT_STATUS_IS_OK(status
)) {
6161 DEBUG(10,("smb_file_link_information: got name |%s|\n",
6164 status
= filename_convert(ctx
,
6166 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6171 if (!NT_STATUS_IS_OK(status
)) {
6175 if (fsp
->base_fsp
) {
6176 /* No stream names. */
6177 return NT_STATUS_NOT_SUPPORTED
;
6180 DEBUG(10,("smb_file_link_information: "
6181 "SMB_FILE_LINK_INFORMATION (fnum %d) %s -> %s\n",
6182 fsp
->fnum
, fsp_str_dbg(fsp
),
6183 smb_fname_str_dbg(smb_fname_dst
)));
6184 status
= hardlink_internals(ctx
,
6191 TALLOC_FREE(smb_fname_dst
);
6195 /****************************************************************************
6196 Deal with SMB_FILE_RENAME_INFORMATION.
6197 ****************************************************************************/
6199 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
6200 struct smb_request
*req
,
6204 struct smb_filename
*smb_fname_src
)
6209 char *newname
= NULL
;
6210 struct smb_filename
*smb_fname_dst
= NULL
;
6211 bool dest_has_wcard
= False
;
6212 NTSTATUS status
= NT_STATUS_OK
;
6214 TALLOC_CTX
*ctx
= talloc_tos();
6216 if (total_data
< 13) {
6217 return NT_STATUS_INVALID_PARAMETER
;
6220 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6221 root_fid
= IVAL(pdata
,4);
6222 len
= IVAL(pdata
,8);
6224 if (len
> (total_data
- 12) || (len
== 0) || (root_fid
!= 0)) {
6225 return NT_STATUS_INVALID_PARAMETER
;
6228 srvstr_get_path_wcard(ctx
, pdata
, req
->flags2
, &newname
, &pdata
[12],
6231 if (!NT_STATUS_IS_OK(status
)) {
6235 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6238 status
= resolve_dfspath_wcard(ctx
, conn
,
6239 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6244 if (!NT_STATUS_IS_OK(status
)) {
6248 /* Check the new name has no '/' characters. */
6249 if (strchr_m(newname
, '/')) {
6250 return NT_STATUS_NOT_SUPPORTED
;
6253 if (fsp
&& fsp
->base_fsp
) {
6254 /* newname must be a stream name. */
6255 if (newname
[0] != ':') {
6256 return NT_STATUS_NOT_SUPPORTED
;
6259 /* Create an smb_fname to call rename_internals_fsp() with. */
6260 status
= create_synthetic_smb_fname(talloc_tos(),
6261 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6263 if (!NT_STATUS_IS_OK(status
)) {
6268 * Set the original last component, since
6269 * rename_internals_fsp() requires it.
6271 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6273 if (smb_fname_dst
->original_lcomp
== NULL
) {
6274 status
= NT_STATUS_NO_MEMORY
;
6280 * Build up an smb_fname_dst based on the filename passed in.
6281 * We basically just strip off the last component, and put on
6282 * the newname instead.
6284 char *base_name
= NULL
;
6286 /* newname must *not* be a stream name. */
6287 if (newname
[0] == ':') {
6288 return NT_STATUS_NOT_SUPPORTED
;
6292 * Strip off the last component (filename) of the path passed
6295 base_name
= talloc_strdup(ctx
, smb_fname_src
->base_name
);
6297 return NT_STATUS_NO_MEMORY
;
6299 p
= strrchr_m(base_name
, '/');
6303 base_name
= talloc_strdup(ctx
, "");
6305 return NT_STATUS_NO_MEMORY
;
6308 /* Append the new name. */
6309 base_name
= talloc_asprintf_append(base_name
,
6313 return NT_STATUS_NO_MEMORY
;
6316 status
= unix_convert(ctx
, conn
, base_name
, &smb_fname_dst
,
6319 UCF_ALWAYS_ALLOW_WCARD_LCOMP
:
6322 /* If an error we expect this to be
6323 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6325 if (!NT_STATUS_IS_OK(status
)) {
6326 if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND
,
6330 /* Create an smb_fname to call rename_internals_fsp() */
6331 status
= create_synthetic_smb_fname(ctx
,
6335 if (!NT_STATUS_IS_OK(status
)) {
6342 DEBUG(10,("smb_file_rename_information: "
6343 "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6344 fsp
->fnum
, fsp_str_dbg(fsp
),
6345 smb_fname_str_dbg(smb_fname_dst
)));
6346 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
, 0,
6349 DEBUG(10,("smb_file_rename_information: "
6350 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6351 smb_fname_str_dbg(smb_fname_src
),
6352 smb_fname_str_dbg(smb_fname_dst
)));
6353 status
= rename_internals(ctx
, conn
, req
, smb_fname_src
,
6354 smb_fname_dst
, 0, overwrite
, false,
6356 FILE_WRITE_ATTRIBUTES
);
6359 TALLOC_FREE(smb_fname_dst
);
6363 /****************************************************************************
6364 Deal with SMB_SET_POSIX_ACL.
6365 ****************************************************************************/
6367 #if defined(HAVE_POSIX_ACLS)
6368 static NTSTATUS
smb_set_posix_acl(connection_struct
*conn
,
6372 const struct smb_filename
*smb_fname
)
6374 uint16 posix_acl_version
;
6375 uint16 num_file_acls
;
6376 uint16 num_def_acls
;
6377 bool valid_file_acls
= True
;
6378 bool valid_def_acls
= True
;
6380 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
6381 return NT_STATUS_INVALID_PARAMETER
;
6383 posix_acl_version
= SVAL(pdata
,0);
6384 num_file_acls
= SVAL(pdata
,2);
6385 num_def_acls
= SVAL(pdata
,4);
6387 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6388 valid_file_acls
= False
;
6392 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6393 valid_def_acls
= False
;
6397 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
6398 return NT_STATUS_INVALID_PARAMETER
;
6401 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
6402 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
6403 return NT_STATUS_INVALID_PARAMETER
;
6406 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6407 smb_fname
? smb_fname_str_dbg(smb_fname
) : fsp_str_dbg(fsp
),
6408 (unsigned int)num_file_acls
,
6409 (unsigned int)num_def_acls
));
6411 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
,
6412 smb_fname
->base_name
, num_file_acls
,
6413 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
6414 return map_nt_error_from_unix(errno
);
6417 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
,
6418 smb_fname
->base_name
, &smb_fname
->st
, num_def_acls
,
6419 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
6420 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
6421 return map_nt_error_from_unix(errno
);
6423 return NT_STATUS_OK
;
6427 /****************************************************************************
6428 Deal with SMB_SET_POSIX_LOCK.
6429 ****************************************************************************/
6431 static NTSTATUS
smb_set_posix_lock(connection_struct
*conn
,
6432 struct smb_request
*req
,
6440 bool blocking_lock
= False
;
6441 enum brl_type lock_type
;
6443 NTSTATUS status
= NT_STATUS_OK
;
6445 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
6446 return NT_STATUS_INVALID_HANDLE
;
6449 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
6450 return NT_STATUS_INVALID_PARAMETER
;
6453 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
6454 case POSIX_LOCK_TYPE_READ
:
6455 lock_type
= READ_LOCK
;
6457 case POSIX_LOCK_TYPE_WRITE
:
6458 /* Return the right POSIX-mappable error code for files opened read-only. */
6459 if (!fsp
->can_write
) {
6460 return NT_STATUS_INVALID_HANDLE
;
6462 lock_type
= WRITE_LOCK
;
6464 case POSIX_LOCK_TYPE_UNLOCK
:
6465 lock_type
= UNLOCK_LOCK
;
6468 return NT_STATUS_INVALID_PARAMETER
;
6471 if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_NOWAIT
) {
6472 blocking_lock
= False
;
6473 } else if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_WAIT
) {
6474 blocking_lock
= True
;
6476 return NT_STATUS_INVALID_PARAMETER
;
6479 if (!lp_blocking_locks(SNUM(conn
))) {
6480 blocking_lock
= False
;
6483 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
6484 #if defined(HAVE_LONGLONG)
6485 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
6486 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
6487 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
6488 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
6489 #else /* HAVE_LONGLONG */
6490 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
6491 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
6492 #endif /* HAVE_LONGLONG */
6494 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6495 "smblctx = %llu, count = %.0f, offset = %.0f\n",
6497 (unsigned int)lock_type
,
6498 (unsigned long long)smblctx
,
6502 if (lock_type
== UNLOCK_LOCK
) {
6503 status
= do_unlock(req
->sconn
->msg_ctx
,
6510 uint64_t block_smblctx
;
6512 struct byte_range_lock
*br_lck
= do_lock(req
->sconn
->msg_ctx
,
6524 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
6526 * A blocking lock was requested. Package up
6527 * this smb into a queued request and push it
6528 * onto the blocking lock queue.
6530 if(push_blocking_lock_request(br_lck
,
6533 -1, /* infinite timeout. */
6541 TALLOC_FREE(br_lck
);
6545 TALLOC_FREE(br_lck
);
6551 /****************************************************************************
6552 Deal with SMB_SET_FILE_BASIC_INFO.
6553 ****************************************************************************/
6555 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
6559 const struct smb_filename
*smb_fname
)
6561 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6562 struct smb_file_time ft
;
6564 NTSTATUS status
= NT_STATUS_OK
;
6568 if (total_data
< 36) {
6569 return NT_STATUS_INVALID_PARAMETER
;
6572 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
6573 return NT_STATUS_ACCESS_DENIED
;
6576 /* Set the attributes */
6577 dosmode
= IVAL(pdata
,32);
6578 status
= smb_set_file_dosmode(conn
, smb_fname
, dosmode
);
6579 if (!NT_STATUS_IS_OK(status
)) {
6584 ft
.create_time
= interpret_long_date(pdata
);
6587 ft
.atime
= interpret_long_date(pdata
+8);
6590 ft
.mtime
= interpret_long_date(pdata
+16);
6593 ft
.ctime
= interpret_long_date(pdata
+24);
6595 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6596 smb_fname_str_dbg(smb_fname
)));
6598 return smb_set_file_time(conn
, fsp
, smb_fname
, &ft
,
6602 /****************************************************************************
6603 Deal with SMB_INFO_STANDARD.
6604 ****************************************************************************/
6606 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
6610 const struct smb_filename
*smb_fname
)
6612 struct smb_file_time ft
;
6616 if (total_data
< 12) {
6617 return NT_STATUS_INVALID_PARAMETER
;
6620 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
6621 return NT_STATUS_ACCESS_DENIED
;
6625 ft
.create_time
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
));
6627 ft
.atime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+4));
6629 ft
.mtime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+8));
6631 DEBUG(10,("smb_set_info_standard: file %s\n",
6632 smb_fname_str_dbg(smb_fname
)));
6634 return smb_set_file_time(conn
,
6641 /****************************************************************************
6642 Deal with SMB_SET_FILE_ALLOCATION_INFO.
6643 ****************************************************************************/
6645 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
6646 struct smb_request
*req
,
6650 struct smb_filename
*smb_fname
)
6652 uint64_t allocation_size
= 0;
6653 NTSTATUS status
= NT_STATUS_OK
;
6654 files_struct
*new_fsp
= NULL
;
6656 if (!VALID_STAT(smb_fname
->st
)) {
6657 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6660 if (total_data
< 8) {
6661 return NT_STATUS_INVALID_PARAMETER
;
6664 allocation_size
= (uint64_t)IVAL(pdata
,0);
6665 #ifdef LARGE_SMB_OFF_T
6666 allocation_size
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6667 #else /* LARGE_SMB_OFF_T */
6668 if (IVAL(pdata
,4) != 0) {
6669 /* more than 32 bits? */
6670 return NT_STATUS_INVALID_PARAMETER
;
6672 #endif /* LARGE_SMB_OFF_T */
6674 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6675 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6676 (double)allocation_size
));
6678 if (allocation_size
) {
6679 allocation_size
= smb_roundup(conn
, allocation_size
);
6682 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6683 return NT_STATUS_ACCESS_DENIED
;
6686 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6687 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname
),
6688 (double)allocation_size
));
6690 if (fsp
&& fsp
->fh
->fd
!= -1) {
6691 /* Open file handle. */
6692 /* Only change if needed. */
6693 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6694 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
6695 return map_nt_error_from_unix(errno
);
6698 /* But always update the time. */
6700 * This is equivalent to a write. Ensure it's seen immediately
6701 * if there are no pending writes.
6703 trigger_write_time_update_immediate(fsp
);
6704 return NT_STATUS_OK
;
6707 /* Pathname or stat or directory file. */
6708 status
= SMB_VFS_CREATE_FILE(
6711 0, /* root_dir_fid */
6712 smb_fname
, /* fname */
6713 FILE_WRITE_DATA
, /* access_mask */
6714 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
6716 FILE_OPEN
, /* create_disposition*/
6717 0, /* create_options */
6718 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
6719 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
6720 0, /* allocation_size */
6721 0, /* private_flags */
6724 &new_fsp
, /* result */
6727 if (!NT_STATUS_IS_OK(status
)) {
6728 /* NB. We check for open_was_deferred in the caller. */
6732 /* Only change if needed. */
6733 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6734 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
6735 status
= map_nt_error_from_unix(errno
);
6736 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6741 /* Changing the allocation size should set the last mod time. */
6743 * This is equivalent to a write. Ensure it's seen immediately
6744 * if there are no pending writes.
6746 trigger_write_time_update_immediate(new_fsp
);
6748 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6749 return NT_STATUS_OK
;
6752 /****************************************************************************
6753 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6754 ****************************************************************************/
6756 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
6757 struct smb_request
*req
,
6761 const struct smb_filename
*smb_fname
,
6762 bool fail_after_createfile
)
6766 if (total_data
< 8) {
6767 return NT_STATUS_INVALID_PARAMETER
;
6770 size
= IVAL(pdata
,0);
6771 #ifdef LARGE_SMB_OFF_T
6772 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
6773 #else /* LARGE_SMB_OFF_T */
6774 if (IVAL(pdata
,4) != 0) {
6775 /* more than 32 bits? */
6776 return NT_STATUS_INVALID_PARAMETER
;
6778 #endif /* LARGE_SMB_OFF_T */
6779 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6780 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6783 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6784 return NT_STATUS_ACCESS_DENIED
;
6787 return smb_set_file_size(conn
, req
,
6792 fail_after_createfile
);
6795 /****************************************************************************
6796 Allow a UNIX info mknod.
6797 ****************************************************************************/
6799 static NTSTATUS
smb_unix_mknod(connection_struct
*conn
,
6802 const struct smb_filename
*smb_fname
)
6804 uint32 file_type
= IVAL(pdata
,56);
6805 #if defined(HAVE_MAKEDEV)
6806 uint32 dev_major
= IVAL(pdata
,60);
6807 uint32 dev_minor
= IVAL(pdata
,68);
6809 SMB_DEV_T dev
= (SMB_DEV_T
)0;
6810 uint32 raw_unixmode
= IVAL(pdata
,84);
6814 if (total_data
< 100) {
6815 return NT_STATUS_INVALID_PARAMETER
;
6818 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6819 PERM_NEW_FILE
, &unixmode
);
6820 if (!NT_STATUS_IS_OK(status
)) {
6824 #if defined(HAVE_MAKEDEV)
6825 dev
= makedev(dev_major
, dev_minor
);
6828 switch (file_type
) {
6829 #if defined(S_IFIFO)
6830 case UNIX_TYPE_FIFO
:
6831 unixmode
|= S_IFIFO
;
6834 #if defined(S_IFSOCK)
6835 case UNIX_TYPE_SOCKET
:
6836 unixmode
|= S_IFSOCK
;
6839 #if defined(S_IFCHR)
6840 case UNIX_TYPE_CHARDEV
:
6841 unixmode
|= S_IFCHR
;
6844 #if defined(S_IFBLK)
6845 case UNIX_TYPE_BLKDEV
:
6846 unixmode
|= S_IFBLK
;
6850 return NT_STATUS_INVALID_PARAMETER
;
6853 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6854 "%.0f mode 0%o for file %s\n", (double)dev
,
6855 (unsigned int)unixmode
, smb_fname_str_dbg(smb_fname
)));
6857 /* Ok - do the mknod. */
6858 if (SMB_VFS_MKNOD(conn
, smb_fname
->base_name
, unixmode
, dev
) != 0) {
6859 return map_nt_error_from_unix(errno
);
6862 /* If any of the other "set" calls fail we
6863 * don't want to end up with a half-constructed mknod.
6866 if (lp_inherit_perms(SNUM(conn
))) {
6868 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
,
6870 return NT_STATUS_NO_MEMORY
;
6872 inherit_access_posix_acl(conn
, parent
, smb_fname
->base_name
,
6874 TALLOC_FREE(parent
);
6877 return NT_STATUS_OK
;
6880 /****************************************************************************
6881 Deal with SMB_SET_FILE_UNIX_BASIC.
6882 ****************************************************************************/
6884 static NTSTATUS
smb_set_file_unix_basic(connection_struct
*conn
,
6885 struct smb_request
*req
,
6889 const struct smb_filename
*smb_fname
)
6891 struct smb_file_time ft
;
6892 uint32 raw_unixmode
;
6895 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
6896 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
6897 NTSTATUS status
= NT_STATUS_OK
;
6898 bool delete_on_fail
= False
;
6899 enum perm_type ptype
;
6900 files_struct
*all_fsps
= NULL
;
6901 bool modify_mtime
= true;
6903 struct smb_filename
*smb_fname_tmp
= NULL
;
6904 SMB_STRUCT_STAT sbuf
;
6908 if (total_data
< 100) {
6909 return NT_STATUS_INVALID_PARAMETER
;
6912 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
6913 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
6914 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
6915 #ifdef LARGE_SMB_OFF_T
6916 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
6917 #else /* LARGE_SMB_OFF_T */
6918 if (IVAL(pdata
,4) != 0) {
6919 /* more than 32 bits? */
6920 return NT_STATUS_INVALID_PARAMETER
;
6922 #endif /* LARGE_SMB_OFF_T */
6925 ft
.atime
= interpret_long_date(pdata
+24); /* access_time */
6926 ft
.mtime
= interpret_long_date(pdata
+32); /* modification_time */
6927 set_owner
= (uid_t
)IVAL(pdata
,40);
6928 set_grp
= (gid_t
)IVAL(pdata
,48);
6929 raw_unixmode
= IVAL(pdata
,84);
6931 if (VALID_STAT(smb_fname
->st
)) {
6932 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
6933 ptype
= PERM_EXISTING_DIR
;
6935 ptype
= PERM_EXISTING_FILE
;
6938 ptype
= PERM_NEW_FILE
;
6941 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6943 if (!NT_STATUS_IS_OK(status
)) {
6947 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
6948 "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
6949 smb_fname_str_dbg(smb_fname
), (double)size
,
6950 (unsigned int)set_owner
, (unsigned int)set_grp
,
6951 (int)raw_unixmode
));
6953 sbuf
= smb_fname
->st
;
6955 if (!VALID_STAT(sbuf
)) {
6957 * The only valid use of this is to create character and block
6958 * devices, and named pipes. This is deprecated (IMHO) and
6959 * a new info level should be used for mknod. JRA.
6962 status
= smb_unix_mknod(conn
,
6966 if (!NT_STATUS_IS_OK(status
)) {
6970 status
= copy_smb_filename(talloc_tos(), smb_fname
,
6972 if (!NT_STATUS_IS_OK(status
)) {
6976 if (SMB_VFS_STAT(conn
, smb_fname_tmp
) != 0) {
6977 status
= map_nt_error_from_unix(errno
);
6978 TALLOC_FREE(smb_fname_tmp
);
6979 SMB_VFS_UNLINK(conn
, smb_fname
);
6983 sbuf
= smb_fname_tmp
->st
;
6984 smb_fname
= smb_fname_tmp
;
6986 /* Ensure we don't try and change anything else. */
6987 raw_unixmode
= SMB_MODE_NO_CHANGE
;
6988 size
= get_file_size_stat(&sbuf
);
6989 ft
.atime
= sbuf
.st_ex_atime
;
6990 ft
.mtime
= sbuf
.st_ex_mtime
;
6992 * We continue here as we might want to change the
6995 delete_on_fail
= True
;
6999 /* Horrible backwards compatibility hack as an old server bug
7000 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
7004 size
= get_file_size_stat(&sbuf
);
7009 * Deal with the UNIX specific mode set.
7012 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
7013 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7014 "setting mode 0%o for file %s\n",
7015 (unsigned int)unixmode
,
7016 smb_fname_str_dbg(smb_fname
)));
7017 if (SMB_VFS_CHMOD(conn
, smb_fname
->base_name
, unixmode
) != 0) {
7018 return map_nt_error_from_unix(errno
);
7023 * Deal with the UNIX specific uid set.
7026 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) &&
7027 (sbuf
.st_ex_uid
!= set_owner
)) {
7030 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7031 "changing owner %u for path %s\n",
7032 (unsigned int)set_owner
,
7033 smb_fname_str_dbg(smb_fname
)));
7035 if (S_ISLNK(sbuf
.st_ex_mode
)) {
7036 ret
= SMB_VFS_LCHOWN(conn
, smb_fname
->base_name
,
7037 set_owner
, (gid_t
)-1);
7039 ret
= SMB_VFS_CHOWN(conn
, smb_fname
->base_name
,
7040 set_owner
, (gid_t
)-1);
7044 status
= map_nt_error_from_unix(errno
);
7045 if (delete_on_fail
) {
7046 SMB_VFS_UNLINK(conn
, smb_fname
);
7053 * Deal with the UNIX specific gid set.
7056 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) &&
7057 (sbuf
.st_ex_gid
!= set_grp
)) {
7058 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7059 "changing group %u for file %s\n",
7060 (unsigned int)set_owner
,
7061 smb_fname_str_dbg(smb_fname
)));
7062 if (SMB_VFS_CHOWN(conn
, smb_fname
->base_name
, (uid_t
)-1,
7064 status
= map_nt_error_from_unix(errno
);
7065 if (delete_on_fail
) {
7066 SMB_VFS_UNLINK(conn
, smb_fname
);
7072 /* Deal with any size changes. */
7074 status
= smb_set_file_size(conn
, req
,
7080 if (!NT_STATUS_IS_OK(status
)) {
7084 /* Deal with any time changes. */
7085 if (null_timespec(ft
.mtime
) && null_timespec(ft
.atime
)) {
7086 /* No change, don't cancel anything. */
7090 id
= vfs_file_id_from_sbuf(conn
, &sbuf
);
7091 for(all_fsps
= file_find_di_first(conn
->sconn
, id
); all_fsps
;
7092 all_fsps
= file_find_di_next(all_fsps
)) {
7094 * We're setting the time explicitly for UNIX.
7095 * Cancel any pending changes over all handles.
7097 all_fsps
->update_write_time_on_close
= false;
7098 TALLOC_FREE(all_fsps
->update_write_time_event
);
7102 * Override the "setting_write_time"
7103 * parameter here as it almost does what
7104 * we need. Just remember if we modified
7105 * mtime and send the notify ourselves.
7107 if (null_timespec(ft
.mtime
)) {
7108 modify_mtime
= false;
7111 status
= smb_set_file_time(conn
,
7117 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
7118 FILE_NOTIFY_CHANGE_LAST_WRITE
, smb_fname
->base_name
);
7123 /****************************************************************************
7124 Deal with SMB_SET_FILE_UNIX_INFO2.
7125 ****************************************************************************/
7127 static NTSTATUS
smb_set_file_unix_info2(connection_struct
*conn
,
7128 struct smb_request
*req
,
7132 const struct smb_filename
*smb_fname
)
7138 if (total_data
< 116) {
7139 return NT_STATUS_INVALID_PARAMETER
;
7142 /* Start by setting all the fields that are common between UNIX_BASIC
7145 status
= smb_set_file_unix_basic(conn
, req
, pdata
, total_data
,
7147 if (!NT_STATUS_IS_OK(status
)) {
7151 smb_fflags
= IVAL(pdata
, 108);
7152 smb_fmask
= IVAL(pdata
, 112);
7154 /* NB: We should only attempt to alter the file flags if the client
7155 * sends a non-zero mask.
7157 if (smb_fmask
!= 0) {
7158 int stat_fflags
= 0;
7160 if (!map_info2_flags_to_sbuf(&smb_fname
->st
, smb_fflags
,
7161 smb_fmask
, &stat_fflags
)) {
7162 /* Client asked to alter a flag we don't understand. */
7163 return NT_STATUS_INVALID_PARAMETER
;
7166 if (fsp
&& fsp
->fh
->fd
!= -1) {
7167 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
7168 return NT_STATUS_NOT_SUPPORTED
;
7170 if (SMB_VFS_CHFLAGS(conn
, smb_fname
->base_name
,
7171 stat_fflags
) != 0) {
7172 return map_nt_error_from_unix(errno
);
7177 /* XXX: need to add support for changing the create_time here. You
7178 * can do this for paths on Darwin with setattrlist(2). The right way
7179 * to hook this up is probably by extending the VFS utimes interface.
7182 return NT_STATUS_OK
;
7185 /****************************************************************************
7186 Create a directory with POSIX semantics.
7187 ****************************************************************************/
7189 static NTSTATUS
smb_posix_mkdir(connection_struct
*conn
,
7190 struct smb_request
*req
,
7193 struct smb_filename
*smb_fname
,
7194 int *pdata_return_size
)
7196 NTSTATUS status
= NT_STATUS_OK
;
7197 uint32 raw_unixmode
= 0;
7198 uint32 mod_unixmode
= 0;
7199 mode_t unixmode
= (mode_t
)0;
7200 files_struct
*fsp
= NULL
;
7201 uint16 info_level_return
= 0;
7203 char *pdata
= *ppdata
;
7205 if (total_data
< 18) {
7206 return NT_STATUS_INVALID_PARAMETER
;
7209 raw_unixmode
= IVAL(pdata
,8);
7210 /* Next 4 bytes are not yet defined. */
7212 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7213 PERM_NEW_DIR
, &unixmode
);
7214 if (!NT_STATUS_IS_OK(status
)) {
7218 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7220 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7221 smb_fname_str_dbg(smb_fname
), (unsigned int)unixmode
));
7223 status
= SMB_VFS_CREATE_FILE(
7226 0, /* root_dir_fid */
7227 smb_fname
, /* fname */
7228 FILE_READ_ATTRIBUTES
, /* access_mask */
7229 FILE_SHARE_NONE
, /* share_access */
7230 FILE_CREATE
, /* create_disposition*/
7231 FILE_DIRECTORY_FILE
, /* create_options */
7232 mod_unixmode
, /* file_attributes */
7233 0, /* oplock_request */
7234 0, /* allocation_size */
7235 0, /* private_flags */
7241 if (NT_STATUS_IS_OK(status
)) {
7242 close_file(req
, fsp
, NORMAL_CLOSE
);
7245 info_level_return
= SVAL(pdata
,16);
7247 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7248 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7249 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7250 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7252 *pdata_return_size
= 12;
7255 /* Realloc the data size */
7256 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7257 if (*ppdata
== NULL
) {
7258 *pdata_return_size
= 0;
7259 return NT_STATUS_NO_MEMORY
;
7263 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7264 SSVAL(pdata
,2,0); /* No fnum. */
7265 SIVAL(pdata
,4,info
); /* Was directory created. */
7267 switch (info_level_return
) {
7268 case SMB_QUERY_FILE_UNIX_BASIC
:
7269 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7270 SSVAL(pdata
,10,0); /* Padding. */
7271 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7274 case SMB_QUERY_FILE_UNIX_INFO2
:
7275 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7276 SSVAL(pdata
,10,0); /* Padding. */
7277 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7281 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7282 SSVAL(pdata
,10,0); /* Padding. */
7289 /****************************************************************************
7290 Open/Create a file with POSIX semantics.
7291 ****************************************************************************/
7293 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7294 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7296 static NTSTATUS
smb_posix_open(connection_struct
*conn
,
7297 struct smb_request
*req
,
7300 struct smb_filename
*smb_fname
,
7301 int *pdata_return_size
)
7303 bool extended_oplock_granted
= False
;
7304 char *pdata
= *ppdata
;
7306 uint32 wire_open_mode
= 0;
7307 uint32 raw_unixmode
= 0;
7308 uint32 mod_unixmode
= 0;
7309 uint32 create_disp
= 0;
7310 uint32 access_mask
= 0;
7311 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
7312 NTSTATUS status
= NT_STATUS_OK
;
7313 mode_t unixmode
= (mode_t
)0;
7314 files_struct
*fsp
= NULL
;
7315 int oplock_request
= 0;
7317 uint16 info_level_return
= 0;
7319 if (total_data
< 18) {
7320 return NT_STATUS_INVALID_PARAMETER
;
7323 flags
= IVAL(pdata
,0);
7324 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
7325 if (oplock_request
) {
7326 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
7329 wire_open_mode
= IVAL(pdata
,4);
7331 if (wire_open_mode
== (SMB_O_CREAT
|SMB_O_DIRECTORY
)) {
7332 return smb_posix_mkdir(conn
, req
,
7339 switch (wire_open_mode
& SMB_ACCMODE
) {
7341 access_mask
= SMB_O_RDONLY_MAPPING
;
7344 access_mask
= SMB_O_WRONLY_MAPPING
;
7347 access_mask
= (SMB_O_RDONLY_MAPPING
|
7348 SMB_O_WRONLY_MAPPING
);
7351 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7352 (unsigned int)wire_open_mode
));
7353 return NT_STATUS_INVALID_PARAMETER
;
7356 wire_open_mode
&= ~SMB_ACCMODE
;
7358 /* First take care of O_CREAT|O_EXCL interactions. */
7359 switch (wire_open_mode
& (SMB_O_CREAT
| SMB_O_EXCL
)) {
7360 case (SMB_O_CREAT
| SMB_O_EXCL
):
7361 /* File exists fail. File not exist create. */
7362 create_disp
= FILE_CREATE
;
7365 /* File exists open. File not exist create. */
7366 create_disp
= FILE_OPEN_IF
;
7369 /* O_EXCL on its own without O_CREAT is undefined.
7370 We deliberately ignore it as some versions of
7371 Linux CIFSFS can send a bare O_EXCL on the
7372 wire which other filesystems in the kernel
7373 ignore. See bug 9519 for details. */
7378 /* File exists open. File not exist fail. */
7379 create_disp
= FILE_OPEN
;
7382 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7383 (unsigned int)wire_open_mode
));
7384 return NT_STATUS_INVALID_PARAMETER
;
7387 /* Next factor in the effects of O_TRUNC. */
7388 wire_open_mode
&= ~(SMB_O_CREAT
| SMB_O_EXCL
);
7390 if (wire_open_mode
& SMB_O_TRUNC
) {
7391 switch (create_disp
) {
7393 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7394 /* Leave create_disp alone as
7395 (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7397 /* File exists fail. File not exist create. */
7400 /* SMB_O_CREAT | SMB_O_TRUNC */
7401 /* File exists overwrite. File not exist create. */
7402 create_disp
= FILE_OVERWRITE_IF
;
7406 /* File exists overwrite. File not exist fail. */
7407 create_disp
= FILE_OVERWRITE
;
7410 /* Cannot get here. */
7411 smb_panic("smb_posix_open: logic error");
7412 return NT_STATUS_INVALID_PARAMETER
;
7416 raw_unixmode
= IVAL(pdata
,8);
7417 /* Next 4 bytes are not yet defined. */
7419 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7420 (VALID_STAT(smb_fname
->st
) ?
7421 PERM_EXISTING_FILE
: PERM_NEW_FILE
),
7424 if (!NT_STATUS_IS_OK(status
)) {
7428 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7430 if (wire_open_mode
& SMB_O_SYNC
) {
7431 create_options
|= FILE_WRITE_THROUGH
;
7433 if (wire_open_mode
& SMB_O_APPEND
) {
7434 access_mask
|= FILE_APPEND_DATA
;
7436 if (wire_open_mode
& SMB_O_DIRECT
) {
7437 mod_unixmode
|= FILE_FLAG_NO_BUFFERING
;
7440 if ((wire_open_mode
& SMB_O_DIRECTORY
) ||
7441 VALID_STAT_OF_DIR(smb_fname
->st
)) {
7442 if (access_mask
!= SMB_O_RDONLY_MAPPING
) {
7443 return NT_STATUS_FILE_IS_A_DIRECTORY
;
7445 create_options
&= ~FILE_NON_DIRECTORY_FILE
;
7446 create_options
|= FILE_DIRECTORY_FILE
;
7449 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7450 smb_fname_str_dbg(smb_fname
),
7451 (unsigned int)wire_open_mode
,
7452 (unsigned int)unixmode
));
7454 status
= SMB_VFS_CREATE_FILE(
7457 0, /* root_dir_fid */
7458 smb_fname
, /* fname */
7459 access_mask
, /* access_mask */
7460 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7462 create_disp
, /* create_disposition*/
7463 create_options
, /* create_options */
7464 mod_unixmode
, /* file_attributes */
7465 oplock_request
, /* oplock_request */
7466 0, /* allocation_size */
7467 0, /* private_flags */
7473 if (!NT_STATUS_IS_OK(status
)) {
7477 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
7478 extended_oplock_granted
= True
;
7481 if(oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
7482 extended_oplock_granted
= True
;
7485 info_level_return
= SVAL(pdata
,16);
7487 /* Allocate the correct return size. */
7489 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7490 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7491 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7492 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7494 *pdata_return_size
= 12;
7497 /* Realloc the data size */
7498 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7499 if (*ppdata
== NULL
) {
7500 close_file(req
, fsp
, ERROR_CLOSE
);
7501 *pdata_return_size
= 0;
7502 return NT_STATUS_NO_MEMORY
;
7506 if (extended_oplock_granted
) {
7507 if (flags
& REQUEST_BATCH_OPLOCK
) {
7508 SSVAL(pdata
,0, BATCH_OPLOCK_RETURN
);
7510 SSVAL(pdata
,0, EXCLUSIVE_OPLOCK_RETURN
);
7512 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
7513 SSVAL(pdata
,0, LEVEL_II_OPLOCK_RETURN
);
7515 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7518 SSVAL(pdata
,2,fsp
->fnum
);
7519 SIVAL(pdata
,4,info
); /* Was file created etc. */
7521 switch (info_level_return
) {
7522 case SMB_QUERY_FILE_UNIX_BASIC
:
7523 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7524 SSVAL(pdata
,10,0); /* padding. */
7525 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7528 case SMB_QUERY_FILE_UNIX_INFO2
:
7529 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7530 SSVAL(pdata
,10,0); /* padding. */
7531 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7535 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7536 SSVAL(pdata
,10,0); /* padding. */
7539 return NT_STATUS_OK
;
7542 /****************************************************************************
7543 Delete a file with POSIX semantics.
7544 ****************************************************************************/
7546 static NTSTATUS
smb_posix_unlink(connection_struct
*conn
,
7547 struct smb_request
*req
,
7550 struct smb_filename
*smb_fname
)
7552 NTSTATUS status
= NT_STATUS_OK
;
7553 files_struct
*fsp
= NULL
;
7557 int create_options
= 0;
7559 struct share_mode_lock
*lck
= NULL
;
7561 if (total_data
< 2) {
7562 return NT_STATUS_INVALID_PARAMETER
;
7565 flags
= SVAL(pdata
,0);
7567 if (!VALID_STAT(smb_fname
->st
)) {
7568 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
7571 if ((flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) &&
7572 !VALID_STAT_OF_DIR(smb_fname
->st
)) {
7573 return NT_STATUS_NOT_A_DIRECTORY
;
7576 DEBUG(10,("smb_posix_unlink: %s %s\n",
7577 (flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) ? "directory" : "file",
7578 smb_fname_str_dbg(smb_fname
)));
7580 if (VALID_STAT_OF_DIR(smb_fname
->st
)) {
7581 create_options
|= FILE_DIRECTORY_FILE
;
7584 status
= SMB_VFS_CREATE_FILE(
7587 0, /* root_dir_fid */
7588 smb_fname
, /* fname */
7589 DELETE_ACCESS
, /* access_mask */
7590 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7592 FILE_OPEN
, /* create_disposition*/
7593 create_options
, /* create_options */
7594 FILE_FLAG_POSIX_SEMANTICS
|0777, /* file_attributes */
7595 0, /* oplock_request */
7596 0, /* allocation_size */
7597 0, /* private_flags */
7603 if (!NT_STATUS_IS_OK(status
)) {
7608 * Don't lie to client. If we can't really delete due to
7609 * non-POSIX opens return SHARING_VIOLATION.
7612 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
, NULL
, NULL
,
7615 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7616 "lock for file %s\n", fsp_str_dbg(fsp
)));
7617 close_file(req
, fsp
, NORMAL_CLOSE
);
7618 return NT_STATUS_INVALID_PARAMETER
;
7622 * See if others still have the file open. If this is the case, then
7623 * don't delete. If all opens are POSIX delete we can set the delete
7624 * on close disposition.
7626 for (i
=0; i
<lck
->num_share_modes
; i
++) {
7627 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
7628 if (is_valid_share_mode_entry(e
)) {
7629 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
7632 /* Fail with sharing violation. */
7634 close_file(req
, fsp
, NORMAL_CLOSE
);
7635 return NT_STATUS_SHARING_VIOLATION
;
7640 * Set the delete on close.
7642 status
= smb_set_file_disposition_info(conn
,
7650 if (!NT_STATUS_IS_OK(status
)) {
7651 close_file(req
, fsp
, NORMAL_CLOSE
);
7654 return close_file(req
, fsp
, NORMAL_CLOSE
);
7657 NTSTATUS
smbd_do_setfilepathinfo(connection_struct
*conn
,
7658 struct smb_request
*req
,
7659 TALLOC_CTX
*mem_ctx
,
7660 uint16_t info_level
,
7662 struct smb_filename
*smb_fname
,
7663 char **ppdata
, int total_data
,
7666 char *pdata
= *ppdata
;
7667 NTSTATUS status
= NT_STATUS_OK
;
7668 int data_return_size
= 0;
7672 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
7673 return NT_STATUS_INVALID_LEVEL
;
7676 if (!CAN_WRITE(conn
)) {
7677 /* Allow POSIX opens. The open path will deny
7678 * any non-readonly opens. */
7679 if (info_level
!= SMB_POSIX_PATH_OPEN
) {
7680 return NT_STATUS_DOS(ERRSRV
, ERRaccess
);
7684 DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
7685 "totdata=%d\n", smb_fname_str_dbg(smb_fname
),
7686 fsp
? fsp
->fnum
: -1, info_level
, total_data
));
7688 switch (info_level
) {
7690 case SMB_INFO_STANDARD
:
7692 status
= smb_set_info_standard(conn
,
7700 case SMB_INFO_SET_EA
:
7702 status
= smb_info_set_ea(conn
,
7710 case SMB_SET_FILE_BASIC_INFO
:
7711 case SMB_FILE_BASIC_INFORMATION
:
7713 status
= smb_set_file_basic_info(conn
,
7721 case SMB_FILE_ALLOCATION_INFORMATION
:
7722 case SMB_SET_FILE_ALLOCATION_INFO
:
7724 status
= smb_set_file_allocation_info(conn
, req
,
7732 case SMB_FILE_END_OF_FILE_INFORMATION
:
7733 case SMB_SET_FILE_END_OF_FILE_INFO
:
7736 * XP/Win7 both fail after the createfile with
7737 * SMB_SET_FILE_END_OF_FILE_INFO but not
7738 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7739 * The level is known here, so pass it down
7743 (info_level
== SMB_SET_FILE_END_OF_FILE_INFO
);
7745 status
= smb_set_file_end_of_file_info(conn
, req
,
7754 case SMB_FILE_DISPOSITION_INFORMATION
:
7755 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
7758 /* JRA - We used to just ignore this on a path ?
7759 * Shouldn't this be invalid level on a pathname
7762 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
7763 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
7766 status
= smb_set_file_disposition_info(conn
,
7774 case SMB_FILE_POSITION_INFORMATION
:
7776 status
= smb_file_position_information(conn
,
7783 case SMB_FILE_FULL_EA_INFORMATION
:
7785 status
= smb_set_file_full_ea_info(conn
,
7792 /* From tridge Samba4 :
7793 * MODE_INFORMATION in setfileinfo (I have no
7794 * idea what "mode information" on a file is - it takes a value of 0,
7795 * 2, 4 or 6. What could it be?).
7798 case SMB_FILE_MODE_INFORMATION
:
7800 status
= smb_file_mode_information(conn
,
7807 * CIFS UNIX extensions.
7810 case SMB_SET_FILE_UNIX_BASIC
:
7812 status
= smb_set_file_unix_basic(conn
, req
,
7820 case SMB_SET_FILE_UNIX_INFO2
:
7822 status
= smb_set_file_unix_info2(conn
, req
,
7830 case SMB_SET_FILE_UNIX_LINK
:
7833 /* We must have a pathname for this. */
7834 return NT_STATUS_INVALID_LEVEL
;
7836 status
= smb_set_file_unix_link(conn
, req
, pdata
,
7837 total_data
, smb_fname
);
7841 case SMB_SET_FILE_UNIX_HLINK
:
7844 /* We must have a pathname for this. */
7845 return NT_STATUS_INVALID_LEVEL
;
7847 status
= smb_set_file_unix_hlink(conn
, req
,
7853 case SMB_FILE_RENAME_INFORMATION
:
7855 status
= smb_file_rename_information(conn
, req
,
7861 case SMB2_FILE_RENAME_INFORMATION_INTERNAL
:
7863 /* SMB2 rename information. */
7864 status
= smb2_file_rename_information(conn
, req
,
7870 case SMB_FILE_LINK_INFORMATION
:
7872 status
= smb_file_link_information(conn
, req
,
7878 #if defined(HAVE_POSIX_ACLS)
7879 case SMB_SET_POSIX_ACL
:
7881 status
= smb_set_posix_acl(conn
,
7890 case SMB_SET_POSIX_LOCK
:
7893 return NT_STATUS_INVALID_LEVEL
;
7895 status
= smb_set_posix_lock(conn
, req
,
7896 pdata
, total_data
, fsp
);
7900 case SMB_POSIX_PATH_OPEN
:
7903 /* We must have a pathname for this. */
7904 return NT_STATUS_INVALID_LEVEL
;
7907 status
= smb_posix_open(conn
, req
,
7915 case SMB_POSIX_PATH_UNLINK
:
7918 /* We must have a pathname for this. */
7919 return NT_STATUS_INVALID_LEVEL
;
7922 status
= smb_posix_unlink(conn
, req
,
7930 return NT_STATUS_INVALID_LEVEL
;
7933 if (!NT_STATUS_IS_OK(status
)) {
7937 *ret_data_size
= data_return_size
;
7938 return NT_STATUS_OK
;
7941 /****************************************************************************
7942 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
7943 ****************************************************************************/
7945 static void call_trans2setfilepathinfo(connection_struct
*conn
,
7946 struct smb_request
*req
,
7947 unsigned int tran_call
,
7948 char **pparams
, int total_params
,
7949 char **ppdata
, int total_data
,
7950 unsigned int max_data_bytes
)
7952 char *params
= *pparams
;
7953 char *pdata
= *ppdata
;
7955 struct smb_filename
*smb_fname
= NULL
;
7956 files_struct
*fsp
= NULL
;
7957 NTSTATUS status
= NT_STATUS_OK
;
7958 int data_return_size
= 0;
7961 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7965 if (tran_call
== TRANSACT2_SETFILEINFO
) {
7966 if (total_params
< 4) {
7967 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7971 fsp
= file_fsp(req
, SVAL(params
,0));
7972 /* Basic check for non-null fsp. */
7973 if (!check_fsp_open(conn
, req
, fsp
)) {
7976 info_level
= SVAL(params
,2);
7978 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
7980 if (!NT_STATUS_IS_OK(status
)) {
7981 reply_nterror(req
, status
);
7985 if(fsp
->fh
->fd
== -1) {
7987 * This is actually a SETFILEINFO on a directory
7988 * handle (returned from an NT SMB). NT5.0 seems
7989 * to do this call. JRA.
7991 if (INFO_LEVEL_IS_UNIX(info_level
)) {
7992 /* Always do lstat for UNIX calls. */
7993 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
7994 DEBUG(3,("call_trans2setfilepathinfo: "
7995 "SMB_VFS_LSTAT of %s failed "
7997 smb_fname_str_dbg(smb_fname
),
7999 reply_nterror(req
, map_nt_error_from_unix(errno
));
8003 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
8004 DEBUG(3,("call_trans2setfilepathinfo: "
8005 "fileinfo of %s failed (%s)\n",
8006 smb_fname_str_dbg(smb_fname
),
8008 reply_nterror(req
, map_nt_error_from_unix(errno
));
8012 } else if (fsp
->print_file
) {
8014 * Doing a DELETE_ON_CLOSE should cancel a print job.
8016 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
8017 fsp
->fh
->private_options
|= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE
;
8019 DEBUG(3,("call_trans2setfilepathinfo: "
8020 "Cancelling print job (%s)\n",
8024 send_trans2_replies(conn
, req
, params
, 2,
8030 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
8035 * Original code - this is an open file.
8037 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
8038 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8039 "of fnum %d failed (%s)\n", fsp
->fnum
,
8041 reply_nterror(req
, map_nt_error_from_unix(errno
));
8047 uint32_t ucf_flags
= 0;
8050 if (total_params
< 7) {
8051 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8055 info_level
= SVAL(params
,0);
8056 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
8057 total_params
- 6, STR_TERMINATE
,
8059 if (!NT_STATUS_IS_OK(status
)) {
8060 reply_nterror(req
, status
);
8064 if (info_level
== SMB_SET_FILE_UNIX_BASIC
||
8065 info_level
== SMB_SET_FILE_UNIX_INFO2
||
8066 info_level
== SMB_FILE_RENAME_INFORMATION
||
8067 info_level
== SMB_POSIX_PATH_UNLINK
) {
8068 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
8071 status
= filename_convert(req
, conn
,
8072 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8077 if (!NT_STATUS_IS_OK(status
)) {
8078 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8079 reply_botherror(req
,
8080 NT_STATUS_PATH_NOT_COVERED
,
8081 ERRSRV
, ERRbadpath
);
8084 reply_nterror(req
, status
);
8088 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8090 * For CIFS UNIX extensions the target name may not exist.
8093 /* Always do lstat for UNIX calls. */
8094 SMB_VFS_LSTAT(conn
, smb_fname
);
8096 } else if (!VALID_STAT(smb_fname
->st
) &&
8097 SMB_VFS_STAT(conn
, smb_fname
)) {
8098 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8100 smb_fname_str_dbg(smb_fname
),
8102 reply_nterror(req
, map_nt_error_from_unix(errno
));
8107 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
8108 "totdata=%d\n", tran_call
, smb_fname_str_dbg(smb_fname
),
8109 fsp
? fsp
->fnum
: -1, info_level
,total_data
));
8111 /* Realloc the parameter size */
8112 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8113 if (*pparams
== NULL
) {
8114 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8121 status
= smbd_do_setfilepathinfo(conn
, req
, req
,
8127 if (!NT_STATUS_IS_OK(status
)) {
8128 if (open_was_deferred(req
->mid
)) {
8129 /* We have re-scheduled this call. */
8132 if (blocking_lock_was_deferred_smb1(req
->sconn
, req
->mid
)) {
8133 /* We have re-scheduled this call. */
8136 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8137 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
8138 ERRSRV
, ERRbadpath
);
8141 if (info_level
== SMB_POSIX_PATH_OPEN
) {
8142 reply_openerror(req
, status
);
8146 reply_nterror(req
, status
);
8150 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, data_return_size
,
8156 /****************************************************************************
8157 Reply to a TRANS2_MKDIR (make directory with extended attributes).
8158 ****************************************************************************/
8160 static void call_trans2mkdir(connection_struct
*conn
, struct smb_request
*req
,
8161 char **pparams
, int total_params
,
8162 char **ppdata
, int total_data
,
8163 unsigned int max_data_bytes
)
8165 struct smb_filename
*smb_dname
= NULL
;
8166 char *params
= *pparams
;
8167 char *pdata
= *ppdata
;
8168 char *directory
= NULL
;
8169 NTSTATUS status
= NT_STATUS_OK
;
8170 struct ea_list
*ea_list
= NULL
;
8171 TALLOC_CTX
*ctx
= talloc_tos();
8173 if (!CAN_WRITE(conn
)) {
8174 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8178 if (total_params
< 5) {
8179 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8183 srvstr_get_path(ctx
, params
, req
->flags2
, &directory
, ¶ms
[4],
8184 total_params
- 4, STR_TERMINATE
,
8186 if (!NT_STATUS_IS_OK(status
)) {
8187 reply_nterror(req
, status
);
8191 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
8193 status
= filename_convert(ctx
,
8195 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8201 if (!NT_STATUS_IS_OK(status
)) {
8202 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8203 reply_botherror(req
,
8204 NT_STATUS_PATH_NOT_COVERED
,
8205 ERRSRV
, ERRbadpath
);
8208 reply_nterror(req
, status
);
8213 * OS/2 workplace shell seems to send SET_EA requests of "null"
8214 * length (4 bytes containing IVAL 4).
8215 * They seem to have no effect. Bug #3212. JRA.
8218 if (total_data
&& (total_data
!= 4)) {
8219 /* Any data in this call is an EA list. */
8220 if (total_data
< 10) {
8221 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8225 if (IVAL(pdata
,0) > total_data
) {
8226 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8227 IVAL(pdata
,0), (unsigned int)total_data
));
8228 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8232 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
8235 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8239 if (!lp_ea_support(SNUM(conn
))) {
8240 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
8244 /* If total_data == 4 Windows doesn't care what values
8245 * are placed in that field, it just ignores them.
8246 * The System i QNTC IBM SMB client puts bad values here,
8247 * so ignore them. */
8249 status
= create_directory(conn
, req
, smb_dname
);
8251 if (!NT_STATUS_IS_OK(status
)) {
8252 reply_nterror(req
, status
);
8256 /* Try and set any given EA. */
8258 status
= set_ea(conn
, NULL
, smb_dname
, ea_list
);
8259 if (!NT_STATUS_IS_OK(status
)) {
8260 reply_nterror(req
, status
);
8265 /* Realloc the parameter and data sizes */
8266 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8267 if(*pparams
== NULL
) {
8268 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8275 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, 0, max_data_bytes
);
8278 TALLOC_FREE(smb_dname
);
8282 /****************************************************************************
8283 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8284 We don't actually do this - we just send a null response.
8285 ****************************************************************************/
8287 static void call_trans2findnotifyfirst(connection_struct
*conn
,
8288 struct smb_request
*req
,
8289 char **pparams
, int total_params
,
8290 char **ppdata
, int total_data
,
8291 unsigned int max_data_bytes
)
8293 char *params
= *pparams
;
8296 if (total_params
< 6) {
8297 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8301 info_level
= SVAL(params
,4);
8302 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
8304 switch (info_level
) {
8309 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
8313 /* Realloc the parameter and data sizes */
8314 *pparams
= (char *)SMB_REALLOC(*pparams
,6);
8315 if (*pparams
== NULL
) {
8316 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8321 SSVAL(params
,0,fnf_handle
);
8322 SSVAL(params
,2,0); /* No changes */
8323 SSVAL(params
,4,0); /* No EA errors */
8330 send_trans2_replies(conn
, req
, params
, 6, *ppdata
, 0, max_data_bytes
);
8335 /****************************************************************************
8336 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
8337 changes). Currently this does nothing.
8338 ****************************************************************************/
8340 static void call_trans2findnotifynext(connection_struct
*conn
,
8341 struct smb_request
*req
,
8342 char **pparams
, int total_params
,
8343 char **ppdata
, int total_data
,
8344 unsigned int max_data_bytes
)
8346 char *params
= *pparams
;
8348 DEBUG(3,("call_trans2findnotifynext\n"));
8350 /* Realloc the parameter and data sizes */
8351 *pparams
= (char *)SMB_REALLOC(*pparams
,4);
8352 if (*pparams
== NULL
) {
8353 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8358 SSVAL(params
,0,0); /* No changes */
8359 SSVAL(params
,2,0); /* No EA errors */
8361 send_trans2_replies(conn
, req
, params
, 4, *ppdata
, 0, max_data_bytes
);
8366 /****************************************************************************
8367 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8368 ****************************************************************************/
8370 static void call_trans2getdfsreferral(connection_struct
*conn
,
8371 struct smb_request
*req
,
8372 char **pparams
, int total_params
,
8373 char **ppdata
, int total_data
,
8374 unsigned int max_data_bytes
)
8376 char *params
= *pparams
;
8377 char *pathname
= NULL
;
8379 int max_referral_level
;
8380 NTSTATUS status
= NT_STATUS_OK
;
8381 TALLOC_CTX
*ctx
= talloc_tos();
8383 DEBUG(10,("call_trans2getdfsreferral\n"));
8385 if (total_params
< 3) {
8386 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8390 max_referral_level
= SVAL(params
,0);
8392 if(!lp_host_msdfs()) {
8393 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8397 srvstr_pull_talloc(ctx
, params
, req
->flags2
, &pathname
, ¶ms
[2],
8398 total_params
- 2, STR_TERMINATE
);
8400 reply_nterror(req
, NT_STATUS_NOT_FOUND
);
8403 if((reply_size
= setup_dfs_referral(conn
, pathname
, max_referral_level
,
8404 ppdata
,&status
)) < 0) {
8405 reply_nterror(req
, status
);
8409 SSVAL(req
->inbuf
, smb_flg2
,
8410 SVAL(req
->inbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
8411 send_trans2_replies(conn
, req
,0,0,*ppdata
,reply_size
, max_data_bytes
);
8416 #define LMCAT_SPL 0x53
8417 #define LMFUNC_GETJOBID 0x60
8419 /****************************************************************************
8420 Reply to a TRANS2_IOCTL - used for OS/2 printing.
8421 ****************************************************************************/
8423 static void call_trans2ioctl(connection_struct
*conn
,
8424 struct smb_request
*req
,
8425 char **pparams
, int total_params
,
8426 char **ppdata
, int total_data
,
8427 unsigned int max_data_bytes
)
8429 char *pdata
= *ppdata
;
8430 files_struct
*fsp
= file_fsp(req
, SVAL(req
->vwv
+15, 0));
8432 /* check for an invalid fid before proceeding */
8435 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8439 if ((SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8440 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8441 *ppdata
= (char *)SMB_REALLOC(*ppdata
, 32);
8442 if (*ppdata
== NULL
) {
8443 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8448 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8449 CAN ACCEPT THIS IN UNICODE. JRA. */
8452 if (fsp
->print_file
) {
8453 SSVAL(pdata
, 0, fsp
->print_file
->rap_jobid
);
8457 srvstr_push(pdata
, req
->flags2
, pdata
+ 2,
8458 global_myname(), 15,
8459 STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
8460 srvstr_push(pdata
, req
->flags2
, pdata
+18,
8461 lp_servicename(SNUM(conn
)), 13,
8462 STR_ASCII
|STR_TERMINATE
); /* Service name */
8463 send_trans2_replies(conn
, req
, *pparams
, 0, *ppdata
, 32,
8468 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8469 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8472 /****************************************************************************
8473 Reply to a SMBfindclose (stop trans2 directory search).
8474 ****************************************************************************/
8476 void reply_findclose(struct smb_request
*req
)
8479 struct smbd_server_connection
*sconn
= req
->sconn
;
8481 START_PROFILE(SMBfindclose
);
8484 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8485 END_PROFILE(SMBfindclose
);
8489 dptr_num
= SVALS(req
->vwv
+0, 0);
8491 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
8493 dptr_close(sconn
, &dptr_num
);
8495 reply_outbuf(req
, 0, 0);
8497 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
8499 END_PROFILE(SMBfindclose
);
8503 /****************************************************************************
8504 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8505 ****************************************************************************/
8507 void reply_findnclose(struct smb_request
*req
)
8511 START_PROFILE(SMBfindnclose
);
8514 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8515 END_PROFILE(SMBfindnclose
);
8519 dptr_num
= SVAL(req
->vwv
+0, 0);
8521 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
8523 /* We never give out valid handles for a
8524 findnotifyfirst - so any dptr_num is ok here.
8527 reply_outbuf(req
, 0, 0);
8529 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
8531 END_PROFILE(SMBfindnclose
);
8535 static void handle_trans2(connection_struct
*conn
, struct smb_request
*req
,
8536 struct trans_state
*state
)
8538 if (get_Protocol() >= PROTOCOL_NT1
) {
8539 req
->flags2
|= 0x40; /* IS_LONG_NAME */
8540 SSVAL(req
->inbuf
,smb_flg2
,req
->flags2
);
8543 if (conn
->encrypt_level
== Required
&& !req
->encrypted
) {
8544 if (state
->call
!= TRANSACT2_QFSINFO
&&
8545 state
->call
!= TRANSACT2_SETFSINFO
) {
8546 DEBUG(0,("handle_trans2: encryption required "
8548 (unsigned int)state
->call
));
8549 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8554 SMB_PERFCOUNT_SET_SUBOP(&req
->pcd
, state
->call
);
8556 /* Now we must call the relevant TRANS2 function */
8557 switch(state
->call
) {
8558 case TRANSACT2_OPEN
:
8560 START_PROFILE(Trans2_open
);
8561 call_trans2open(conn
, req
,
8562 &state
->param
, state
->total_param
,
8563 &state
->data
, state
->total_data
,
8564 state
->max_data_return
);
8565 END_PROFILE(Trans2_open
);
8569 case TRANSACT2_FINDFIRST
:
8571 START_PROFILE(Trans2_findfirst
);
8572 call_trans2findfirst(conn
, req
,
8573 &state
->param
, state
->total_param
,
8574 &state
->data
, state
->total_data
,
8575 state
->max_data_return
);
8576 END_PROFILE(Trans2_findfirst
);
8580 case TRANSACT2_FINDNEXT
:
8582 START_PROFILE(Trans2_findnext
);
8583 call_trans2findnext(conn
, req
,
8584 &state
->param
, state
->total_param
,
8585 &state
->data
, state
->total_data
,
8586 state
->max_data_return
);
8587 END_PROFILE(Trans2_findnext
);
8591 case TRANSACT2_QFSINFO
:
8593 START_PROFILE(Trans2_qfsinfo
);
8594 call_trans2qfsinfo(conn
, req
,
8595 &state
->param
, state
->total_param
,
8596 &state
->data
, state
->total_data
,
8597 state
->max_data_return
);
8598 END_PROFILE(Trans2_qfsinfo
);
8602 case TRANSACT2_SETFSINFO
:
8604 START_PROFILE(Trans2_setfsinfo
);
8605 call_trans2setfsinfo(conn
, req
,
8606 &state
->param
, state
->total_param
,
8607 &state
->data
, state
->total_data
,
8608 state
->max_data_return
);
8609 END_PROFILE(Trans2_setfsinfo
);
8613 case TRANSACT2_QPATHINFO
:
8614 case TRANSACT2_QFILEINFO
:
8616 START_PROFILE(Trans2_qpathinfo
);
8617 call_trans2qfilepathinfo(conn
, req
, state
->call
,
8618 &state
->param
, state
->total_param
,
8619 &state
->data
, state
->total_data
,
8620 state
->max_data_return
);
8621 END_PROFILE(Trans2_qpathinfo
);
8625 case TRANSACT2_SETPATHINFO
:
8626 case TRANSACT2_SETFILEINFO
:
8628 START_PROFILE(Trans2_setpathinfo
);
8629 call_trans2setfilepathinfo(conn
, req
, state
->call
,
8630 &state
->param
, state
->total_param
,
8631 &state
->data
, state
->total_data
,
8632 state
->max_data_return
);
8633 END_PROFILE(Trans2_setpathinfo
);
8637 case TRANSACT2_FINDNOTIFYFIRST
:
8639 START_PROFILE(Trans2_findnotifyfirst
);
8640 call_trans2findnotifyfirst(conn
, req
,
8641 &state
->param
, state
->total_param
,
8642 &state
->data
, state
->total_data
,
8643 state
->max_data_return
);
8644 END_PROFILE(Trans2_findnotifyfirst
);
8648 case TRANSACT2_FINDNOTIFYNEXT
:
8650 START_PROFILE(Trans2_findnotifynext
);
8651 call_trans2findnotifynext(conn
, req
,
8652 &state
->param
, state
->total_param
,
8653 &state
->data
, state
->total_data
,
8654 state
->max_data_return
);
8655 END_PROFILE(Trans2_findnotifynext
);
8659 case TRANSACT2_MKDIR
:
8661 START_PROFILE(Trans2_mkdir
);
8662 call_trans2mkdir(conn
, req
,
8663 &state
->param
, state
->total_param
,
8664 &state
->data
, state
->total_data
,
8665 state
->max_data_return
);
8666 END_PROFILE(Trans2_mkdir
);
8670 case TRANSACT2_GET_DFS_REFERRAL
:
8672 START_PROFILE(Trans2_get_dfs_referral
);
8673 call_trans2getdfsreferral(conn
, req
,
8674 &state
->param
, state
->total_param
,
8675 &state
->data
, state
->total_data
,
8676 state
->max_data_return
);
8677 END_PROFILE(Trans2_get_dfs_referral
);
8681 case TRANSACT2_IOCTL
:
8683 START_PROFILE(Trans2_ioctl
);
8684 call_trans2ioctl(conn
, req
,
8685 &state
->param
, state
->total_param
,
8686 &state
->data
, state
->total_data
,
8687 state
->max_data_return
);
8688 END_PROFILE(Trans2_ioctl
);
8693 /* Error in request */
8694 DEBUG(2,("Unknown request %d in trans2 call\n", state
->call
));
8695 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8699 /****************************************************************************
8700 Reply to a SMBtrans2.
8701 ****************************************************************************/
8703 void reply_trans2(struct smb_request
*req
)
8705 connection_struct
*conn
= req
->conn
;
8710 unsigned int tran_call
;
8711 struct trans_state
*state
;
8714 START_PROFILE(SMBtrans2
);
8716 if (req
->wct
< 14) {
8717 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8718 END_PROFILE(SMBtrans2
);
8722 dsoff
= SVAL(req
->vwv
+12, 0);
8723 dscnt
= SVAL(req
->vwv
+11, 0);
8724 psoff
= SVAL(req
->vwv
+10, 0);
8725 pscnt
= SVAL(req
->vwv
+9, 0);
8726 tran_call
= SVAL(req
->vwv
+14, 0);
8728 result
= allow_new_trans(conn
->pending_trans
, req
->mid
);
8729 if (!NT_STATUS_IS_OK(result
)) {
8730 DEBUG(2, ("Got invalid trans2 request: %s\n",
8731 nt_errstr(result
)));
8732 reply_nterror(req
, result
);
8733 END_PROFILE(SMBtrans2
);
8738 switch (tran_call
) {
8739 /* List the allowed trans2 calls on IPC$ */
8740 case TRANSACT2_OPEN
:
8741 case TRANSACT2_GET_DFS_REFERRAL
:
8742 case TRANSACT2_QFILEINFO
:
8743 case TRANSACT2_QFSINFO
:
8744 case TRANSACT2_SETFSINFO
:
8747 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8748 END_PROFILE(SMBtrans2
);
8753 if ((state
= TALLOC_P(conn
, struct trans_state
)) == NULL
) {
8754 DEBUG(0, ("talloc failed\n"));
8755 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8756 END_PROFILE(SMBtrans2
);
8760 state
->cmd
= SMBtrans2
;
8762 state
->mid
= req
->mid
;
8763 state
->vuid
= req
->vuid
;
8764 state
->setup_count
= SVAL(req
->vwv
+13, 0);
8765 state
->setup
= NULL
;
8766 state
->total_param
= SVAL(req
->vwv
+0, 0);
8767 state
->param
= NULL
;
8768 state
->total_data
= SVAL(req
->vwv
+1, 0);
8770 state
->max_param_return
= SVAL(req
->vwv
+2, 0);
8771 state
->max_data_return
= SVAL(req
->vwv
+3, 0);
8772 state
->max_setup_return
= SVAL(req
->vwv
+4, 0);
8773 state
->close_on_completion
= BITSETW(req
->vwv
+5, 0);
8774 state
->one_way
= BITSETW(req
->vwv
+5, 1);
8776 state
->call
= tran_call
;
8778 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8779 is so as a sanity check */
8780 if (state
->setup_count
!= 1) {
8782 * Need to have rc=0 for ioctl to get job id for OS/2.
8783 * Network printing will fail if function is not successful.
8784 * Similar function in reply.c will be used if protocol
8785 * is LANMAN1.0 instead of LM1.2X002.
8786 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
8787 * outbuf doesn't have to be set(only job id is used).
8789 if ( (state
->setup_count
== 4)
8790 && (tran_call
== TRANSACT2_IOCTL
)
8791 && (SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8792 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8793 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8795 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state
->setup_count
));
8796 DEBUG(2,("Transaction is %d\n",tran_call
));
8798 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8799 END_PROFILE(SMBtrans2
);
8804 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
8807 if (state
->total_data
) {
8809 if (trans_oob(state
->total_data
, 0, dscnt
)
8810 || trans_oob(smb_len(req
->inbuf
), dsoff
, dscnt
)) {
8814 /* Can't use talloc here, the core routines do realloc on the
8815 * params and data. */
8816 state
->data
= (char *)SMB_MALLOC(state
->total_data
);
8817 if (state
->data
== NULL
) {
8818 DEBUG(0,("reply_trans2: data malloc fail for %u "
8819 "bytes !\n", (unsigned int)state
->total_data
));
8821 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8822 END_PROFILE(SMBtrans2
);
8826 memcpy(state
->data
,smb_base(req
->inbuf
)+dsoff
,dscnt
);
8829 if (state
->total_param
) {
8831 if (trans_oob(state
->total_param
, 0, pscnt
)
8832 || trans_oob(smb_len(req
->inbuf
), psoff
, pscnt
)) {
8836 /* Can't use talloc here, the core routines do realloc on the
8837 * params and data. */
8838 state
->param
= (char *)SMB_MALLOC(state
->total_param
);
8839 if (state
->param
== NULL
) {
8840 DEBUG(0,("reply_trans: param malloc fail for %u "
8841 "bytes !\n", (unsigned int)state
->total_param
));
8842 SAFE_FREE(state
->data
);
8844 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8845 END_PROFILE(SMBtrans2
);
8849 memcpy(state
->param
,smb_base(req
->inbuf
)+psoff
,pscnt
);
8852 state
->received_data
= dscnt
;
8853 state
->received_param
= pscnt
;
8855 if ((state
->received_param
== state
->total_param
) &&
8856 (state
->received_data
== state
->total_data
)) {
8858 handle_trans2(conn
, req
, state
);
8860 SAFE_FREE(state
->data
);
8861 SAFE_FREE(state
->param
);
8863 END_PROFILE(SMBtrans2
);
8867 DLIST_ADD(conn
->pending_trans
, state
);
8869 /* We need to send an interim response then receive the rest
8870 of the parameter/data bytes */
8871 reply_outbuf(req
, 0, 0);
8872 show_msg((char *)req
->outbuf
);
8873 END_PROFILE(SMBtrans2
);
8878 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8879 SAFE_FREE(state
->data
);
8880 SAFE_FREE(state
->param
);
8882 END_PROFILE(SMBtrans2
);
8883 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8887 /****************************************************************************
8888 Reply to a SMBtranss2
8889 ****************************************************************************/
8891 void reply_transs2(struct smb_request
*req
)
8893 connection_struct
*conn
= req
->conn
;
8894 unsigned int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
8895 struct trans_state
*state
;
8897 START_PROFILE(SMBtranss2
);
8899 show_msg((char *)req
->inbuf
);
8901 /* Windows clients expect all replies to
8902 a transact secondary (SMBtranss2 0x33)
8903 to have a command code of transact
8904 (SMBtrans2 0x32). See bug #8989
8905 and also [MS-CIFS] section 2.2.4.47.2
8908 req
->cmd
= SMBtrans2
;
8911 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8912 END_PROFILE(SMBtranss2
);
8916 for (state
= conn
->pending_trans
; state
!= NULL
;
8917 state
= state
->next
) {
8918 if (state
->mid
== req
->mid
) {
8923 if ((state
== NULL
) || (state
->cmd
!= SMBtrans2
)) {
8924 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8925 END_PROFILE(SMBtranss2
);
8929 /* Revise state->total_param and state->total_data in case they have
8930 changed downwards */
8932 if (SVAL(req
->vwv
+0, 0) < state
->total_param
)
8933 state
->total_param
= SVAL(req
->vwv
+0, 0);
8934 if (SVAL(req
->vwv
+1, 0) < state
->total_data
)
8935 state
->total_data
= SVAL(req
->vwv
+1, 0);
8937 pcnt
= SVAL(req
->vwv
+2, 0);
8938 poff
= SVAL(req
->vwv
+3, 0);
8939 pdisp
= SVAL(req
->vwv
+4, 0);
8941 dcnt
= SVAL(req
->vwv
+5, 0);
8942 doff
= SVAL(req
->vwv
+6, 0);
8943 ddisp
= SVAL(req
->vwv
+7, 0);
8945 state
->received_param
+= pcnt
;
8946 state
->received_data
+= dcnt
;
8948 if ((state
->received_data
> state
->total_data
) ||
8949 (state
->received_param
> state
->total_param
))
8953 if (trans_oob(state
->total_param
, pdisp
, pcnt
)
8954 || trans_oob(smb_len(req
->inbuf
), poff
, pcnt
)) {
8957 memcpy(state
->param
+pdisp
,smb_base(req
->inbuf
)+poff
,pcnt
);
8961 if (trans_oob(state
->total_data
, ddisp
, dcnt
)
8962 || trans_oob(smb_len(req
->inbuf
), doff
, dcnt
)) {
8965 memcpy(state
->data
+ddisp
, smb_base(req
->inbuf
)+doff
,dcnt
);
8968 if ((state
->received_param
< state
->total_param
) ||
8969 (state
->received_data
< state
->total_data
)) {
8970 END_PROFILE(SMBtranss2
);
8974 handle_trans2(conn
, req
, state
);
8976 DLIST_REMOVE(conn
->pending_trans
, state
);
8977 SAFE_FREE(state
->data
);
8978 SAFE_FREE(state
->param
);
8981 END_PROFILE(SMBtranss2
);
8986 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
8987 DLIST_REMOVE(conn
->pending_trans
, state
);
8988 SAFE_FREE(state
->data
);
8989 SAFE_FREE(state
->param
);
8991 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8992 END_PROFILE(SMBtranss2
);