2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2007
5 Copyright (C) Stefan (metze) Metzmacher 2003
6 Copyright (C) Volker Lendecke 2005-2007
7 Copyright (C) Steve French 2005
8 Copyright (C) James Peach 2006-2007
10 Extensively modified by Andrew Tridgell, 1995
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include "system/filesys.h"
30 #include "smbd/smbd.h"
31 #include "smbd/globals.h"
32 #include "../libcli/auth/libcli_auth.h"
33 #include "../librpc/gen_ndr/xattr.h"
34 #include "../librpc/gen_ndr/ndr_security.h"
35 #include "libcli/security/security.h"
38 #include "smbprofile.h"
39 #include "rpc_server/srv_pipe_hnd.h"
40 #include "libsmb/libsmb.h"
42 #define DIR_ENTRY_SAFETY_MARGIN 4096
44 static char *store_file_unix_basic(connection_struct
*conn
,
47 const SMB_STRUCT_STAT
*psbuf
);
49 static char *store_file_unix_basic_info2(connection_struct
*conn
,
52 const SMB_STRUCT_STAT
*psbuf
);
54 /********************************************************************
55 Roundup a value to the nearest allocation roundup size boundary.
56 Only do this for Windows clients.
57 ********************************************************************/
59 uint64_t smb_roundup(connection_struct
*conn
, uint64_t val
)
61 uint64_t rval
= lp_allocation_roundup_size(SNUM(conn
));
63 /* Only roundup for Windows clients. */
64 enum remote_arch_types ra_type
= get_remote_arch();
65 if (rval
&& (ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
66 val
= SMB_ROUNDUP(val
,rval
);
71 /********************************************************************
72 Create a 64 bit FileIndex. If the file is on the same device as
73 the root of the share, just return the 64-bit inode. If it isn't,
74 mangle as we used to do.
75 ********************************************************************/
77 uint64_t get_FileIndex(connection_struct
*conn
, const SMB_STRUCT_STAT
*psbuf
)
80 if (conn
->base_share_dev
== psbuf
->st_ex_dev
) {
81 return (uint64_t)psbuf
->st_ex_ino
;
83 file_index
= ((psbuf
->st_ex_ino
) & UINT32_MAX
); /* FileIndexLow */
84 file_index
|= ((uint64_t)((psbuf
->st_ex_dev
) & UINT32_MAX
)) << 32; /* FileIndexHigh */
88 /****************************************************************************
89 Utility functions for dealing with extended attributes.
90 ****************************************************************************/
92 /****************************************************************************
93 Refuse to allow clients to overwrite our private xattrs.
94 ****************************************************************************/
96 static bool samba_private_attr_name(const char *unix_ea_name
)
98 static const char * const prohibited_ea_names
[] = {
99 SAMBA_POSIX_INHERITANCE_EA_NAME
,
100 SAMBA_XATTR_DOS_ATTRIB
,
108 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
109 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
112 if (StrnCaseCmp(unix_ea_name
, SAMBA_XATTR_DOSSTREAM_PREFIX
,
113 strlen(SAMBA_XATTR_DOSSTREAM_PREFIX
)) == 0) {
119 /****************************************************************************
120 Get one EA value. Fill in a struct ea_struct.
121 ****************************************************************************/
123 NTSTATUS
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
124 files_struct
*fsp
, const char *fname
,
125 const char *ea_name
, struct ea_struct
*pea
)
127 /* Get the value of this xattr. Max size is 64k. */
128 size_t attr_size
= 256;
134 val
= TALLOC_REALLOC_ARRAY(mem_ctx
, val
, char, attr_size
);
136 return NT_STATUS_NO_MEMORY
;
139 if (fsp
&& fsp
->fh
->fd
!= -1) {
140 sizeret
= SMB_VFS_FGETXATTR(fsp
, ea_name
, val
, attr_size
);
142 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
145 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
151 return map_nt_error_from_unix(errno
);
154 DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name
, (unsigned int)sizeret
));
155 dump_data(10, (uint8
*)val
, sizeret
);
158 if (strnequal(ea_name
, "user.", 5)) {
159 pea
->name
= talloc_strdup(mem_ctx
, &ea_name
[5]);
161 pea
->name
= talloc_strdup(mem_ctx
, ea_name
);
163 if (pea
->name
== NULL
) {
165 return NT_STATUS_NO_MEMORY
;
167 pea
->value
.data
= (unsigned char *)val
;
168 pea
->value
.length
= (size_t)sizeret
;
172 NTSTATUS
get_ea_names_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
,
173 files_struct
*fsp
, const char *fname
,
174 char ***pnames
, size_t *pnum_names
)
176 /* Get a list of all xattrs. Max namesize is 64k. */
177 size_t ea_namelist_size
= 1024;
178 char *ea_namelist
= NULL
;
183 ssize_t sizeret
= -1;
185 if (!lp_ea_support(SNUM(conn
))) {
194 * TALLOC the result early to get the talloc hierarchy right.
197 names
= TALLOC_ARRAY(mem_ctx
, char *, 1);
199 DEBUG(0, ("talloc failed\n"));
200 return NT_STATUS_NO_MEMORY
;
203 while (ea_namelist_size
<= 65536) {
205 ea_namelist
= TALLOC_REALLOC_ARRAY(
206 names
, ea_namelist
, char, ea_namelist_size
);
207 if (ea_namelist
== NULL
) {
208 DEBUG(0, ("talloc failed\n"));
210 return NT_STATUS_NO_MEMORY
;
213 if (fsp
&& fsp
->fh
->fd
!= -1) {
214 sizeret
= SMB_VFS_FLISTXATTR(fsp
, ea_namelist
,
217 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
,
221 if ((sizeret
== -1) && (errno
== ERANGE
)) {
222 ea_namelist_size
*= 2;
231 return map_nt_error_from_unix(errno
);
234 DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n",
235 (unsigned int)sizeret
));
247 * Ensure the result is 0-terminated
250 if (ea_namelist
[sizeret
-1] != '\0') {
252 return NT_STATUS_INTERNAL_ERROR
;
260 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
264 tmp
= TALLOC_REALLOC_ARRAY(mem_ctx
, names
, char *, num_names
);
266 DEBUG(0, ("talloc failed\n"));
268 return NT_STATUS_NO_MEMORY
;
274 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
)+1) {
275 names
[num_names
++] = p
;
283 *pnum_names
= num_names
;
287 /****************************************************************************
288 Return a linked list of the total EA's. Plus the total size
289 ****************************************************************************/
291 static struct ea_list
*get_ea_list_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
292 const char *fname
, size_t *pea_total_len
)
294 /* Get a list of all xattrs. Max namesize is 64k. */
297 struct ea_list
*ea_list_head
= NULL
;
302 if (!lp_ea_support(SNUM(conn
))) {
306 status
= get_ea_names_from_file(talloc_tos(), conn
, fsp
, fname
,
309 if (!NT_STATUS_IS_OK(status
) || (num_names
== 0)) {
313 for (i
=0; i
<num_names
; i
++) {
314 struct ea_list
*listp
;
317 if (strnequal(names
[i
], "system.", 7)
318 || samba_private_attr_name(names
[i
]))
321 listp
= TALLOC_P(mem_ctx
, struct ea_list
);
326 if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx
, conn
, fsp
,
332 if (listp
->ea
.value
.length
== 0) {
334 * We can never return a zero length EA.
335 * Windows reports the EA's as corrupted.
341 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
344 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
346 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
347 "= %u\n", (unsigned int)*pea_total_len
, dos_ea_name
,
348 (unsigned int)listp
->ea
.value
.length
));
350 DLIST_ADD_END(ea_list_head
, listp
, struct ea_list
*);
354 /* Add on 4 for total length. */
355 if (*pea_total_len
) {
359 DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
360 (unsigned int)*pea_total_len
));
365 /****************************************************************************
366 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
368 ****************************************************************************/
370 static unsigned int fill_ea_buffer(TALLOC_CTX
*mem_ctx
, char *pdata
, unsigned int total_data_size
,
371 connection_struct
*conn
, struct ea_list
*ea_list
)
373 unsigned int ret_data_size
= 4;
376 SMB_ASSERT(total_data_size
>= 4);
378 if (!lp_ea_support(SNUM(conn
))) {
383 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
386 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
387 dos_namelen
= strlen(dos_ea_name
);
388 if (dos_namelen
> 255 || dos_namelen
== 0) {
391 if (ea_list
->ea
.value
.length
> 65535) {
394 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
398 /* We know we have room. */
399 SCVAL(p
,0,ea_list
->ea
.flags
);
400 SCVAL(p
,1,dos_namelen
);
401 SSVAL(p
,2,ea_list
->ea
.value
.length
);
402 fstrcpy(p
+4, dos_ea_name
);
403 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
405 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
406 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
409 ret_data_size
= PTR_DIFF(p
, pdata
);
410 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size
));
411 SIVAL(pdata
,0,ret_data_size
);
412 return ret_data_size
;
415 static NTSTATUS
fill_ea_chained_buffer(TALLOC_CTX
*mem_ctx
,
417 unsigned int total_data_size
,
418 unsigned int *ret_data_size
,
419 connection_struct
*conn
,
420 struct ea_list
*ea_list
)
422 uint8_t *p
= (uint8_t *)pdata
;
423 uint8_t *last_start
= NULL
;
424 bool store_data
= (pdata
!= NULL
);
428 if (!lp_ea_support(SNUM(conn
))) {
429 return NT_STATUS_NO_EAS_ON_FILE
;
432 for (; ea_list
; ea_list
= ea_list
->next
) {
438 if (last_start
&& store_data
) {
439 SIVAL(last_start
, 0, PTR_DIFF(p
, last_start
));
443 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
444 dos_namelen
= strlen(dos_ea_name
);
445 if (dos_namelen
> 255 || dos_namelen
== 0) {
446 return NT_STATUS_INTERNAL_ERROR
;
448 if (ea_list
->ea
.value
.length
> 65535) {
449 return NT_STATUS_INTERNAL_ERROR
;
452 this_size
= 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
455 pad
= (4 - (this_size
% 4)) % 4;
459 if (this_size
> total_data_size
) {
460 return NT_STATUS_INFO_LENGTH_MISMATCH
;
463 /* We know we have room. */
465 SIVAL(p
, 0x00, 0); /* next offset */
466 SCVAL(p
, 0x04, ea_list
->ea
.flags
);
467 SCVAL(p
, 0x05, dos_namelen
);
468 SSVAL(p
, 0x06, ea_list
->ea
.value
.length
);
469 fstrcpy((char *)(p
+0x08), dos_ea_name
);
470 memcpy(p
+ 0x08 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
472 memset(p
+ 0x08 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
,
478 total_data_size
-= this_size
;
482 *ret_data_size
= PTR_DIFF(p
, pdata
);
483 DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size
));
487 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
489 size_t total_ea_len
= 0;
490 struct ea_list
*ea_list
= NULL
;
491 TALLOC_CTX
*mem_ctx
= NULL
;
493 if (!lp_ea_support(SNUM(conn
))) {
496 mem_ctx
= talloc_tos();
497 ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
498 if (ea_list
== NULL
) {
501 if(conn
->sconn
->using_smb2
) {
503 unsigned int ret_data_size
;
505 * We're going to be using fill_ea_chained_buffer() to
506 * marshall EA's - this size is significantly larger
507 * than the SMB1 buffer. Re-calculate the size without
510 status
= fill_ea_chained_buffer(mem_ctx
,
516 if (!NT_STATUS_IS_OK(status
)) {
519 total_ea_len
= ret_data_size
;
525 /****************************************************************************
526 Ensure the EA name is case insensitive by matching any existing EA name.
527 ****************************************************************************/
529 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
532 TALLOC_CTX
*mem_ctx
= talloc_tos();
533 struct ea_list
*ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
535 for (; ea_list
; ea_list
= ea_list
->next
) {
536 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
537 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
538 &unix_ea_name
[5], ea_list
->ea
.name
));
539 safe_strcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-6);
545 /****************************************************************************
546 Set or delete an extended attribute.
547 ****************************************************************************/
549 NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
,
550 const struct smb_filename
*smb_fname
, struct ea_list
*ea_list
)
554 if (!lp_ea_support(SNUM(conn
))) {
555 return NT_STATUS_EAS_NOT_SUPPORTED
;
558 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_EA
)) {
559 return NT_STATUS_ACCESS_DENIED
;
562 /* For now setting EAs on streams isn't supported. */
563 fname
= smb_fname
->base_name
;
565 for (;ea_list
; ea_list
= ea_list
->next
) {
567 fstring unix_ea_name
;
569 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
570 fstrcat(unix_ea_name
, ea_list
->ea
.name
);
572 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
574 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, (unsigned int)ea_list
->ea
.value
.length
));
576 if (samba_private_attr_name(unix_ea_name
)) {
577 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
578 return NT_STATUS_ACCESS_DENIED
;
581 if (ea_list
->ea
.value
.length
== 0) {
582 /* Remove the attribute. */
583 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
584 DEBUG(10,("set_ea: deleting ea name %s on "
585 "file %s by file descriptor.\n",
586 unix_ea_name
, fsp_str_dbg(fsp
)));
587 ret
= SMB_VFS_FREMOVEXATTR(fsp
, unix_ea_name
);
589 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
590 unix_ea_name
, fname
));
591 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
594 /* Removing a non existent attribute always succeeds. */
595 if (ret
== -1 && errno
== ENOATTR
) {
596 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
602 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
603 DEBUG(10,("set_ea: setting ea name %s on file "
604 "%s by file descriptor.\n",
605 unix_ea_name
, fsp_str_dbg(fsp
)));
606 ret
= SMB_VFS_FSETXATTR(fsp
, unix_ea_name
,
607 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
609 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
610 unix_ea_name
, fname
));
611 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
,
612 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
618 if (errno
== ENOTSUP
) {
619 return NT_STATUS_EAS_NOT_SUPPORTED
;
622 return map_nt_error_from_unix(errno
);
628 /****************************************************************************
629 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
630 ****************************************************************************/
632 static struct ea_list
*read_ea_name_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
634 struct ea_list
*ea_list_head
= NULL
;
635 size_t converted_size
, offset
= 0;
637 while (offset
+ 2 < data_size
) {
638 struct ea_list
*eal
= TALLOC_ZERO_P(ctx
, struct ea_list
);
639 unsigned int namelen
= CVAL(pdata
,offset
);
641 offset
++; /* Go past the namelen byte. */
643 /* integer wrap paranioa. */
644 if ((offset
+ namelen
< offset
) || (offset
+ namelen
< namelen
) ||
645 (offset
> data_size
) || (namelen
> data_size
) ||
646 (offset
+ namelen
>= data_size
)) {
649 /* Ensure the name is null terminated. */
650 if (pdata
[offset
+ namelen
] != '\0') {
653 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, &pdata
[offset
],
655 DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
656 "failed: %s", strerror(errno
)));
662 offset
+= (namelen
+ 1); /* Go past the name + terminating zero. */
663 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
664 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal
->ea
.name
));
670 /****************************************************************************
671 Read one EA list entry from the buffer.
672 ****************************************************************************/
674 struct ea_list
*read_ea_list_entry(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
, size_t *pbytes_used
)
676 struct ea_list
*eal
= TALLOC_ZERO_P(ctx
, struct ea_list
);
678 unsigned int namelen
;
679 size_t converted_size
;
689 eal
->ea
.flags
= CVAL(pdata
,0);
690 namelen
= CVAL(pdata
,1);
691 val_len
= SVAL(pdata
,2);
693 if (4 + namelen
+ 1 + val_len
> data_size
) {
697 /* Ensure the name is null terminated. */
698 if (pdata
[namelen
+ 4] != '\0') {
701 if (!pull_ascii_talloc(ctx
, &eal
->ea
.name
, pdata
+ 4, &converted_size
)) {
702 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
709 eal
->ea
.value
= data_blob_talloc(eal
, NULL
, (size_t)val_len
+ 1);
710 if (!eal
->ea
.value
.data
) {
714 memcpy(eal
->ea
.value
.data
, pdata
+ 4 + namelen
+ 1, val_len
);
716 /* Ensure we're null terminated just in case we print the value. */
717 eal
->ea
.value
.data
[val_len
] = '\0';
718 /* But don't count the null. */
719 eal
->ea
.value
.length
--;
722 *pbytes_used
= 4 + namelen
+ 1 + val_len
;
725 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal
->ea
.name
));
726 dump_data(10, eal
->ea
.value
.data
, eal
->ea
.value
.length
);
731 /****************************************************************************
732 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
733 ****************************************************************************/
735 static struct ea_list
*read_ea_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
737 struct ea_list
*ea_list_head
= NULL
;
739 size_t bytes_used
= 0;
741 while (offset
< data_size
) {
742 struct ea_list
*eal
= read_ea_list_entry(ctx
, pdata
+ offset
, data_size
- offset
, &bytes_used
);
748 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
749 offset
+= bytes_used
;
755 /****************************************************************************
756 Count the total EA size needed.
757 ****************************************************************************/
759 static size_t ea_list_size(struct ea_list
*ealist
)
762 struct ea_list
*listp
;
765 for (listp
= ealist
; listp
; listp
= listp
->next
) {
766 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
767 ret
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
769 /* Add on 4 for total length. */
777 /****************************************************************************
778 Return a union of EA's from a file list and a list of names.
779 The TALLOC context for the two lists *MUST* be identical as we steal
780 memory from one list to add to another. JRA.
781 ****************************************************************************/
783 static struct ea_list
*ea_list_union(struct ea_list
*name_list
, struct ea_list
*file_list
, size_t *total_ea_len
)
785 struct ea_list
*nlistp
, *flistp
;
787 for (nlistp
= name_list
; nlistp
; nlistp
= nlistp
->next
) {
788 for (flistp
= file_list
; flistp
; flistp
= flistp
->next
) {
789 if (strequal(nlistp
->ea
.name
, flistp
->ea
.name
)) {
795 /* Copy the data from this entry. */
796 nlistp
->ea
.flags
= flistp
->ea
.flags
;
797 nlistp
->ea
.value
= flistp
->ea
.value
;
800 nlistp
->ea
.flags
= 0;
801 ZERO_STRUCT(nlistp
->ea
.value
);
805 *total_ea_len
= ea_list_size(name_list
);
809 /****************************************************************************
810 Send the required number of replies back.
811 We assume all fields other than the data fields are
812 set correctly for the type of call.
813 HACK ! Always assumes smb_setup field is zero.
814 ****************************************************************************/
816 void send_trans2_replies(connection_struct
*conn
,
817 struct smb_request
*req
,
824 /* As we are using a protocol > LANMAN1 then the max_send
825 variable must have been set in the sessetupX call.
826 This takes precedence over the max_xmit field in the
827 global struct. These different max_xmit variables should
828 be merged as this is now too confusing */
830 int data_to_send
= datasize
;
831 int params_to_send
= paramsize
;
833 const char *pp
= params
;
834 const char *pd
= pdata
;
835 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
836 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
837 int data_alignment_offset
= 0;
838 bool overflow
= False
;
839 struct smbd_server_connection
*sconn
= req
->sconn
;
840 int max_send
= sconn
->smb1
.sessions
.max_send
;
842 /* Modify the data_to_send and datasize and set the error if
843 we're trying to send more than max_data_bytes. We still send
844 the part of the packet(s) that fit. Strange, but needed
847 if (max_data_bytes
> 0 && datasize
> max_data_bytes
) {
848 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
849 max_data_bytes
, datasize
));
850 datasize
= data_to_send
= max_data_bytes
;
854 /* If there genuinely are no parameters or data to send just send the empty packet */
856 if(params_to_send
== 0 && data_to_send
== 0) {
857 reply_outbuf(req
, 10, 0);
858 show_msg((char *)req
->outbuf
);
859 if (!srv_send_smb(sconn
,
862 IS_CONN_ENCRYPTED(conn
),
864 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
866 TALLOC_FREE(req
->outbuf
);
870 /* When sending params and data ensure that both are nicely aligned */
871 /* Only do this alignment when there is also data to send - else
872 can cause NT redirector problems. */
874 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
875 data_alignment_offset
= 4 - (params_to_send
% 4);
877 /* Space is bufsize minus Netbios over TCP header minus SMB header */
878 /* The alignment_offset is to align the param bytes on an even byte
879 boundary. NT 4.0 Beta needs this to work correctly. */
881 useable_space
= max_send
- (smb_size
884 + data_alignment_offset
);
886 if (useable_space
< 0) {
887 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
888 "= %d!!!", useable_space
));
889 exit_server_cleanly("send_trans2_replies: Not enough space");
892 while (params_to_send
|| data_to_send
) {
893 /* Calculate whether we will totally or partially fill this packet */
895 total_sent_thistime
= params_to_send
+ data_to_send
;
897 /* We can never send more than useable_space */
899 * Note that 'useable_space' does not include the alignment offsets,
900 * but we must include the alignment offsets in the calculation of
901 * the length of the data we send over the wire, as the alignment offsets
902 * are sent here. Fix from Marc_Jacobsen@hp.com.
905 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
);
907 reply_outbuf(req
, 10, total_sent_thistime
+ alignment_offset
908 + data_alignment_offset
);
910 /* Set total params and data to be sent */
911 SSVAL(req
->outbuf
,smb_tprcnt
,paramsize
);
912 SSVAL(req
->outbuf
,smb_tdrcnt
,datasize
);
914 /* Calculate how many parameters and data we can fit into
915 * this packet. Parameters get precedence
918 params_sent_thistime
= MIN(params_to_send
,useable_space
);
919 data_sent_thistime
= useable_space
- params_sent_thistime
;
920 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
922 SSVAL(req
->outbuf
,smb_prcnt
, params_sent_thistime
);
924 /* smb_proff is the offset from the start of the SMB header to the
925 parameter bytes, however the first 4 bytes of outbuf are
926 the Netbios over TCP header. Thus use smb_base() to subtract
927 them from the calculation */
929 SSVAL(req
->outbuf
,smb_proff
,
930 ((smb_buf(req
->outbuf
)+alignment_offset
)
931 - smb_base(req
->outbuf
)));
933 if(params_sent_thistime
== 0)
934 SSVAL(req
->outbuf
,smb_prdisp
,0);
936 /* Absolute displacement of param bytes sent in this packet */
937 SSVAL(req
->outbuf
,smb_prdisp
,pp
- params
);
939 SSVAL(req
->outbuf
,smb_drcnt
, data_sent_thistime
);
940 if(data_sent_thistime
== 0) {
941 SSVAL(req
->outbuf
,smb_droff
,0);
942 SSVAL(req
->outbuf
,smb_drdisp
, 0);
944 /* The offset of the data bytes is the offset of the
945 parameter bytes plus the number of parameters being sent this time */
946 SSVAL(req
->outbuf
, smb_droff
,
947 ((smb_buf(req
->outbuf
)+alignment_offset
)
948 - smb_base(req
->outbuf
))
949 + params_sent_thistime
+ data_alignment_offset
);
950 SSVAL(req
->outbuf
,smb_drdisp
, pd
- pdata
);
953 /* Initialize the padding for alignment */
955 if (alignment_offset
!= 0) {
956 memset(smb_buf(req
->outbuf
), 0, alignment_offset
);
959 /* Copy the param bytes into the packet */
961 if(params_sent_thistime
) {
962 memcpy((smb_buf(req
->outbuf
)+alignment_offset
), pp
,
963 params_sent_thistime
);
966 /* Copy in the data bytes */
967 if(data_sent_thistime
) {
968 if (data_alignment_offset
!= 0) {
969 memset((smb_buf(req
->outbuf
)+alignment_offset
+
970 params_sent_thistime
), 0,
971 data_alignment_offset
);
973 memcpy(smb_buf(req
->outbuf
)+alignment_offset
974 +params_sent_thistime
+data_alignment_offset
,
975 pd
,data_sent_thistime
);
978 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
979 params_sent_thistime
, data_sent_thistime
, useable_space
));
980 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
981 params_to_send
, data_to_send
, paramsize
, datasize
));
984 error_packet_set((char *)req
->outbuf
,
985 ERRDOS
,ERRbufferoverflow
,
986 STATUS_BUFFER_OVERFLOW
,
990 /* Send the packet */
991 show_msg((char *)req
->outbuf
);
992 if (!srv_send_smb(sconn
,
995 IS_CONN_ENCRYPTED(conn
),
997 exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
999 TALLOC_FREE(req
->outbuf
);
1001 pp
+= params_sent_thistime
;
1002 pd
+= data_sent_thistime
;
1004 params_to_send
-= params_sent_thistime
;
1005 data_to_send
-= data_sent_thistime
;
1008 if(params_to_send
< 0 || data_to_send
< 0) {
1009 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
1010 params_to_send
, data_to_send
));
1018 /****************************************************************************
1019 Reply to a TRANSACT2_OPEN.
1020 ****************************************************************************/
1022 static void call_trans2open(connection_struct
*conn
,
1023 struct smb_request
*req
,
1024 char **pparams
, int total_params
,
1025 char **ppdata
, int total_data
,
1026 unsigned int max_data_bytes
)
1028 struct smb_filename
*smb_fname
= NULL
;
1029 char *params
= *pparams
;
1030 char *pdata
= *ppdata
;
1033 bool oplock_request
;
1035 bool return_additional_info
;
1044 int fattr
=0,mtime
=0;
1045 SMB_INO_T inode
= 0;
1048 struct ea_list
*ea_list
= NULL
;
1053 uint32 create_disposition
;
1054 uint32 create_options
= 0;
1055 uint32_t private_flags
= 0;
1056 TALLOC_CTX
*ctx
= talloc_tos();
1059 * Ensure we have enough parameters to perform the operation.
1062 if (total_params
< 29) {
1063 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1067 flags
= SVAL(params
, 0);
1068 deny_mode
= SVAL(params
, 2);
1069 open_attr
= SVAL(params
,6);
1070 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
1071 if (oplock_request
) {
1072 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
1076 return_additional_info
= BITSETW(params
,0);
1077 open_sattr
= SVAL(params
, 4);
1078 open_time
= make_unix_date3(params
+8);
1080 open_ofun
= SVAL(params
,12);
1081 open_size
= IVAL(params
,14);
1082 pname
= ¶ms
[28];
1085 reply_nterror(req
, NT_STATUS_NETWORK_ACCESS_DENIED
);
1089 srvstr_get_path(ctx
, params
, req
->flags2
, &fname
, pname
,
1090 total_params
- 28, STR_TERMINATE
,
1092 if (!NT_STATUS_IS_OK(status
)) {
1093 reply_nterror(req
, status
);
1097 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1098 fname
, (unsigned int)deny_mode
, (unsigned int)open_attr
,
1099 (unsigned int)open_ofun
, open_size
));
1101 status
= filename_convert(ctx
,
1103 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
1108 if (!NT_STATUS_IS_OK(status
)) {
1109 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
1110 reply_botherror(req
,
1111 NT_STATUS_PATH_NOT_COVERED
,
1112 ERRSRV
, ERRbadpath
);
1115 reply_nterror(req
, status
);
1119 if (open_ofun
== 0) {
1120 reply_nterror(req
, NT_STATUS_OBJECT_NAME_COLLISION
);
1124 if (!map_open_params_to_ntcreate(smb_fname
->base_name
, deny_mode
,
1126 &access_mask
, &share_mode
,
1127 &create_disposition
,
1130 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1134 /* Any data in this call is an EA list. */
1135 if (total_data
&& (total_data
!= 4)) {
1136 if (total_data
< 10) {
1137 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1141 if (IVAL(pdata
,0) > total_data
) {
1142 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1143 IVAL(pdata
,0), (unsigned int)total_data
));
1144 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1148 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
1151 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
1155 if (!lp_ea_support(SNUM(conn
))) {
1156 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
1161 status
= SMB_VFS_CREATE_FILE(
1164 0, /* root_dir_fid */
1165 smb_fname
, /* fname */
1166 access_mask
, /* access_mask */
1167 share_mode
, /* share_access */
1168 create_disposition
, /* create_disposition*/
1169 create_options
, /* create_options */
1170 open_attr
, /* file_attributes */
1171 oplock_request
, /* oplock_request */
1172 open_size
, /* allocation_size */
1175 ea_list
, /* ea_list */
1177 &smb_action
); /* psbuf */
1179 if (!NT_STATUS_IS_OK(status
)) {
1180 if (open_was_deferred(req
->mid
)) {
1181 /* We have re-scheduled this call. */
1184 reply_openerror(req
, status
);
1188 size
= get_file_size_stat(&smb_fname
->st
);
1189 fattr
= dos_mode(conn
, smb_fname
);
1190 mtime
= convert_timespec_to_time_t(smb_fname
->st
.st_ex_mtime
);
1191 inode
= smb_fname
->st
.st_ex_ino
;
1192 if (fattr
& FILE_ATTRIBUTE_DIRECTORY
) {
1193 close_file(req
, fsp
, ERROR_CLOSE
);
1194 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1198 /* Realloc the size of parameters and data we will return */
1199 *pparams
= (char *)SMB_REALLOC(*pparams
, 30);
1200 if(*pparams
== NULL
) {
1201 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
1206 SSVAL(params
,0,fsp
->fnum
);
1207 SSVAL(params
,2,fattr
);
1208 srv_put_dos_date2(params
,4, mtime
);
1209 SIVAL(params
,8, (uint32
)size
);
1210 SSVAL(params
,12,deny_mode
);
1211 SSVAL(params
,14,0); /* open_type - file or directory. */
1212 SSVAL(params
,16,0); /* open_state - only valid for IPC device. */
1214 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
1215 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1218 SSVAL(params
,18,smb_action
);
1221 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1223 SIVAL(params
,20,inode
);
1224 SSVAL(params
,24,0); /* Padding. */
1226 uint32 ea_size
= estimate_ea_size(conn
, fsp
,
1227 fsp
->fsp_name
->base_name
);
1228 SIVAL(params
, 26, ea_size
);
1230 SIVAL(params
, 26, 0);
1233 /* Send the required number of replies */
1234 send_trans2_replies(conn
, req
, params
, 30, *ppdata
, 0, max_data_bytes
);
1236 TALLOC_FREE(smb_fname
);
1239 /*********************************************************
1240 Routine to check if a given string matches exactly.
1241 as a special case a mask of "." does NOT match. That
1242 is required for correct wildcard semantics
1243 Case can be significant or not.
1244 **********************************************************/
1246 static bool exact_match(bool has_wild
,
1247 bool case_sensitive
,
1251 if (mask
[0] == '.' && mask
[1] == 0) {
1259 if (case_sensitive
) {
1260 return strcmp(str
,mask
)==0;
1262 return StrCaseCmp(str
,mask
) == 0;
1266 /****************************************************************************
1267 Return the filetype for UNIX extensions.
1268 ****************************************************************************/
1270 static uint32
unix_filetype(mode_t mode
)
1273 return UNIX_TYPE_FILE
;
1274 else if(S_ISDIR(mode
))
1275 return UNIX_TYPE_DIR
;
1277 else if(S_ISLNK(mode
))
1278 return UNIX_TYPE_SYMLINK
;
1281 else if(S_ISCHR(mode
))
1282 return UNIX_TYPE_CHARDEV
;
1285 else if(S_ISBLK(mode
))
1286 return UNIX_TYPE_BLKDEV
;
1289 else if(S_ISFIFO(mode
))
1290 return UNIX_TYPE_FIFO
;
1293 else if(S_ISSOCK(mode
))
1294 return UNIX_TYPE_SOCKET
;
1297 DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode
));
1298 return UNIX_TYPE_UNKNOWN
;
1301 /****************************************************************************
1302 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1303 ****************************************************************************/
1305 enum perm_type
{ PERM_NEW_FILE
, PERM_NEW_DIR
, PERM_EXISTING_FILE
, PERM_EXISTING_DIR
};
1307 static NTSTATUS
unix_perms_from_wire( connection_struct
*conn
,
1308 const SMB_STRUCT_STAT
*psbuf
,
1310 enum perm_type ptype
,
1315 if (perms
== SMB_MODE_NO_CHANGE
) {
1316 if (!VALID_STAT(*psbuf
)) {
1317 return NT_STATUS_INVALID_PARAMETER
;
1319 *ret_perms
= psbuf
->st_ex_mode
;
1320 return NT_STATUS_OK
;
1324 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
1325 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
1326 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
1327 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
1328 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
1329 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
1330 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
1331 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
1332 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
1334 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
1337 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
1340 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
1345 /* Apply mode mask */
1346 ret
&= lp_create_mask(SNUM(conn
));
1347 /* Add in force bits */
1348 ret
|= lp_force_create_mode(SNUM(conn
));
1351 ret
&= lp_dir_mask(SNUM(conn
));
1352 /* Add in force bits */
1353 ret
|= lp_force_dir_mode(SNUM(conn
));
1355 case PERM_EXISTING_FILE
:
1356 /* Apply mode mask */
1357 ret
&= lp_security_mask(SNUM(conn
));
1358 /* Add in force bits */
1359 ret
|= lp_force_security_mode(SNUM(conn
));
1361 case PERM_EXISTING_DIR
:
1362 /* Apply mode mask */
1363 ret
&= lp_dir_security_mask(SNUM(conn
));
1364 /* Add in force bits */
1365 ret
|= lp_force_dir_security_mode(SNUM(conn
));
1370 return NT_STATUS_OK
;
1373 /****************************************************************************
1374 Needed to show the msdfs symlinks as directories. Modifies psbuf
1375 to be a directory if it's a msdfs link.
1376 ****************************************************************************/
1378 static bool check_msdfs_link(connection_struct
*conn
,
1379 const char *pathname
,
1380 SMB_STRUCT_STAT
*psbuf
)
1382 int saved_errno
= errno
;
1383 if(lp_host_msdfs() &&
1384 lp_msdfs_root(SNUM(conn
)) &&
1385 is_msdfs_link(conn
, pathname
, psbuf
)) {
1387 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1390 psbuf
->st_ex_mode
= (psbuf
->st_ex_mode
& 0xFFF) | S_IFDIR
;
1391 errno
= saved_errno
;
1394 errno
= saved_errno
;
1399 /****************************************************************************
1400 Get a level dependent lanman2 dir entry.
1401 ****************************************************************************/
1403 struct smbd_dirptr_lanman2_state
{
1404 connection_struct
*conn
;
1405 uint32_t info_level
;
1406 bool check_mangled_names
;
1408 bool got_exact_match
;
1411 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX
*ctx
,
1417 struct smbd_dirptr_lanman2_state
*state
=
1418 (struct smbd_dirptr_lanman2_state
*)private_data
;
1420 char mangled_name
[13]; /* mangled 8.3 name. */
1424 /* Mangle fname if it's an illegal name. */
1425 if (mangle_must_mangle(dname
, state
->conn
->params
)) {
1426 ok
= name_to_8_3(dname
, mangled_name
,
1427 true, state
->conn
->params
);
1431 fname
= mangled_name
;
1436 got_match
= exact_match(state
->has_wild
,
1437 state
->conn
->case_sensitive
,
1439 state
->got_exact_match
= got_match
;
1441 got_match
= mask_match(fname
, mask
,
1442 state
->conn
->case_sensitive
);
1445 if(!got_match
&& state
->check_mangled_names
&&
1446 !mangle_is_8_3(fname
, false, state
->conn
->params
)) {
1448 * It turns out that NT matches wildcards against
1449 * both long *and* short names. This may explain some
1450 * of the wildcard wierdness from old DOS clients
1451 * that some people have been seeing.... JRA.
1453 /* Force the mangling into 8.3. */
1454 ok
= name_to_8_3(fname
, mangled_name
,
1455 false, state
->conn
->params
);
1460 got_match
= exact_match(state
->has_wild
,
1461 state
->conn
->case_sensitive
,
1462 mangled_name
, mask
);
1463 state
->got_exact_match
= got_match
;
1465 got_match
= mask_match(mangled_name
, mask
,
1466 state
->conn
->case_sensitive
);
1474 *_fname
= talloc_strdup(ctx
, fname
);
1475 if (*_fname
== NULL
) {
1482 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX
*ctx
,
1484 struct smb_filename
*smb_fname
,
1487 struct smbd_dirptr_lanman2_state
*state
=
1488 (struct smbd_dirptr_lanman2_state
*)private_data
;
1489 bool ms_dfs_link
= false;
1492 if (INFO_LEVEL_IS_UNIX(state
->info_level
)) {
1493 if (SMB_VFS_LSTAT(state
->conn
, smb_fname
) != 0) {
1494 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1495 "Couldn't lstat [%s] (%s)\n",
1496 smb_fname_str_dbg(smb_fname
),
1500 } else if (!VALID_STAT(smb_fname
->st
) &&
1501 SMB_VFS_STAT(state
->conn
, smb_fname
) != 0) {
1502 /* Needed to show the msdfs symlinks as
1505 ms_dfs_link
= check_msdfs_link(state
->conn
,
1506 smb_fname
->base_name
,
1509 DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1510 "Couldn't stat [%s] (%s)\n",
1511 smb_fname_str_dbg(smb_fname
),
1518 mode
= dos_mode_msdfs(state
->conn
, smb_fname
);
1520 mode
= dos_mode(state
->conn
, smb_fname
);
1527 static bool smbd_marshall_dir_entry(TALLOC_CTX
*ctx
,
1528 connection_struct
*conn
,
1530 uint32_t info_level
,
1531 struct ea_list
*name_list
,
1532 bool check_mangled_names
,
1533 bool requires_resume_key
,
1536 const struct smb_filename
*smb_fname
,
1537 int space_remaining
,
1544 uint64_t *last_entry_off
)
1546 char *p
, *q
, *pdata
= *ppdata
;
1548 uint64_t file_size
= 0;
1549 uint64_t allocation_size
= 0;
1550 uint64_t file_index
= 0;
1552 struct timespec mdate_ts
, adate_ts
, cdate_ts
, create_date_ts
;
1553 time_t mdate
= (time_t)0, adate
= (time_t)0, create_date
= (time_t)0;
1554 time_t c_date
= (time_t)0;
1556 char *last_entry_ptr
;
1561 *out_of_space
= false;
1563 ZERO_STRUCT(mdate_ts
);
1564 ZERO_STRUCT(adate_ts
);
1565 ZERO_STRUCT(create_date_ts
);
1566 ZERO_STRUCT(cdate_ts
);
1568 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
1569 file_size
= get_file_size_stat(&smb_fname
->st
);
1571 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, NULL
, &smb_fname
->st
);
1573 file_index
= get_FileIndex(conn
, &smb_fname
->st
);
1575 mdate_ts
= smb_fname
->st
.st_ex_mtime
;
1576 adate_ts
= smb_fname
->st
.st_ex_atime
;
1577 create_date_ts
= get_create_timespec(conn
, NULL
, smb_fname
);
1578 cdate_ts
= get_change_timespec(conn
, NULL
, smb_fname
);
1580 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1581 dos_filetime_timespec(&create_date_ts
);
1582 dos_filetime_timespec(&mdate_ts
);
1583 dos_filetime_timespec(&adate_ts
);
1584 dos_filetime_timespec(&cdate_ts
);
1587 create_date
= convert_timespec_to_time_t(create_date_ts
);
1588 mdate
= convert_timespec_to_time_t(mdate_ts
);
1589 adate
= convert_timespec_to_time_t(adate_ts
);
1590 c_date
= convert_timespec_to_time_t(cdate_ts
);
1592 /* align the record */
1593 SMB_ASSERT(align
>= 1);
1595 off
= (int)PTR_DIFF(pdata
, base_data
);
1596 pad
= (off
+ (align
-1)) & ~(align
-1);
1599 if (pad
&& pad
> space_remaining
) {
1600 *out_of_space
= true;
1601 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1602 "for padding (wanted %u, had %d)\n",
1605 return false; /* Not finished - just out of space */
1609 /* initialize padding to 0 */
1611 memset(pdata
, 0, pad
);
1613 space_remaining
-= pad
;
1615 DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1625 switch (info_level
) {
1626 case SMB_FIND_INFO_STANDARD
:
1627 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1628 if(requires_resume_key
) {
1632 srv_put_dos_date2(p
,0,create_date
);
1633 srv_put_dos_date2(p
,4,adate
);
1634 srv_put_dos_date2(p
,8,mdate
);
1635 SIVAL(p
,12,(uint32
)file_size
);
1636 SIVAL(p
,16,(uint32
)allocation_size
);
1640 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1641 p
+= ucs2_align(base_data
, p
, 0);
1643 len
= srvstr_push(base_data
, flags2
, p
,
1644 fname
, PTR_DIFF(end_data
, p
),
1646 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1648 SCVAL(nameptr
, -1, len
- 2);
1650 SCVAL(nameptr
, -1, 0);
1654 SCVAL(nameptr
, -1, len
- 1);
1656 SCVAL(nameptr
, -1, 0);
1662 case SMB_FIND_EA_SIZE
:
1663 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1664 if (requires_resume_key
) {
1668 srv_put_dos_date2(p
,0,create_date
);
1669 srv_put_dos_date2(p
,4,adate
);
1670 srv_put_dos_date2(p
,8,mdate
);
1671 SIVAL(p
,12,(uint32
)file_size
);
1672 SIVAL(p
,16,(uint32
)allocation_size
);
1675 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1676 smb_fname
->base_name
);
1677 SIVAL(p
,22,ea_size
); /* Extended attributes */
1681 len
= srvstr_push(base_data
, flags2
,
1682 p
, fname
, PTR_DIFF(end_data
, p
),
1683 STR_TERMINATE
| STR_NOALIGN
);
1684 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1697 SCVAL(nameptr
,0,len
);
1699 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1702 case SMB_FIND_EA_LIST
:
1704 struct ea_list
*file_list
= NULL
;
1707 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1711 if (requires_resume_key
) {
1715 srv_put_dos_date2(p
,0,create_date
);
1716 srv_put_dos_date2(p
,4,adate
);
1717 srv_put_dos_date2(p
,8,mdate
);
1718 SIVAL(p
,12,(uint32
)file_size
);
1719 SIVAL(p
,16,(uint32
)allocation_size
);
1721 p
+= 22; /* p now points to the EA area. */
1723 file_list
= get_ea_list_from_file(ctx
, conn
, NULL
,
1724 smb_fname
->base_name
,
1726 name_list
= ea_list_union(name_list
, file_list
, &ea_len
);
1728 /* We need to determine if this entry will fit in the space available. */
1729 /* Max string size is 255 bytes. */
1730 if (PTR_DIFF(p
+ 255 + ea_len
,pdata
) > space_remaining
) {
1731 *out_of_space
= true;
1732 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1733 "(wanted %u, had %d)\n",
1734 (unsigned int)PTR_DIFF(p
+ 255 + ea_len
,pdata
),
1736 return False
; /* Not finished - just out of space */
1739 /* Push the ea_data followed by the name. */
1740 p
+= fill_ea_buffer(ctx
, p
, space_remaining
, conn
, name_list
);
1742 len
= srvstr_push(base_data
, flags2
,
1743 p
+ 1, fname
, PTR_DIFF(end_data
, p
+1),
1744 STR_TERMINATE
| STR_NOALIGN
);
1745 if (flags2
& FLAGS2_UNICODE_STRINGS
) {
1758 SCVAL(nameptr
,0,len
);
1760 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1764 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1765 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1766 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1768 SIVAL(p
,0,reskey
); p
+= 4;
1769 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1770 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1771 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1772 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1773 SOFF_T(p
,0,file_size
); p
+= 8;
1774 SOFF_T(p
,0,allocation_size
); p
+= 8;
1775 SIVAL(p
,0,mode
); p
+= 4;
1776 q
= p
; p
+= 4; /* q is placeholder for name length. */
1777 if (mode
& FILE_ATTRIBUTE_REPARSE_POINT
) {
1778 SIVAL(p
, 0, IO_REPARSE_TAG_DFS
);
1780 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1781 smb_fname
->base_name
);
1782 SIVAL(p
,0,ea_size
); /* Extended attributes */
1785 /* Clear the short name buffer. This is
1786 * IMPORTANT as not doing so will trigger
1787 * a Win2k client bug. JRA.
1789 if (!was_8_3
&& check_mangled_names
) {
1790 char mangled_name
[13]; /* mangled 8.3 name. */
1791 if (!name_to_8_3(fname
,mangled_name
,True
,
1793 /* Error - mangle failed ! */
1794 memset(mangled_name
,'\0',12);
1796 mangled_name
[12] = 0;
1797 len
= srvstr_push(base_data
, flags2
,
1798 p
+2, mangled_name
, 24,
1799 STR_UPPER
|STR_UNICODE
);
1801 memset(p
+ 2 + len
,'\0',24 - len
);
1808 len
= srvstr_push(base_data
, flags2
, p
,
1809 fname
, PTR_DIFF(end_data
, p
),
1810 STR_TERMINATE_ASCII
);
1814 len
= PTR_DIFF(p
, pdata
);
1815 pad
= (len
+ (align
-1)) & ~(align
-1);
1817 * offset to the next entry, the caller
1818 * will overwrite it for the last entry
1819 * that's why we always include the padding
1823 * set padding to zero
1826 memset(p
, 0, pad
- len
);
1833 case SMB_FIND_FILE_DIRECTORY_INFO
:
1834 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1836 SIVAL(p
,0,reskey
); p
+= 4;
1837 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1838 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1839 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1840 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1841 SOFF_T(p
,0,file_size
); p
+= 8;
1842 SOFF_T(p
,0,allocation_size
); p
+= 8;
1843 SIVAL(p
,0,mode
); p
+= 4;
1844 len
= srvstr_push(base_data
, flags2
,
1845 p
+ 4, fname
, PTR_DIFF(end_data
, p
+4),
1846 STR_TERMINATE_ASCII
);
1850 len
= PTR_DIFF(p
, pdata
);
1851 pad
= (len
+ (align
-1)) & ~(align
-1);
1853 * offset to the next entry, the caller
1854 * will overwrite it for the last entry
1855 * that's why we always include the padding
1859 * set padding to zero
1862 memset(p
, 0, pad
- len
);
1869 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1870 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1872 SIVAL(p
,0,reskey
); p
+= 4;
1873 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1874 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1875 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1876 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1877 SOFF_T(p
,0,file_size
); p
+= 8;
1878 SOFF_T(p
,0,allocation_size
); p
+= 8;
1879 SIVAL(p
,0,mode
); p
+= 4;
1880 q
= p
; p
+= 4; /* q is placeholder for name length. */
1882 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1883 smb_fname
->base_name
);
1884 SIVAL(p
,0,ea_size
); /* Extended attributes */
1887 len
= srvstr_push(base_data
, flags2
, p
,
1888 fname
, PTR_DIFF(end_data
, p
),
1889 STR_TERMINATE_ASCII
);
1893 len
= PTR_DIFF(p
, pdata
);
1894 pad
= (len
+ (align
-1)) & ~(align
-1);
1896 * offset to the next entry, the caller
1897 * will overwrite it for the last entry
1898 * that's why we always include the padding
1902 * set padding to zero
1905 memset(p
, 0, pad
- len
);
1912 case SMB_FIND_FILE_NAMES_INFO
:
1913 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1915 SIVAL(p
,0,reskey
); p
+= 4;
1917 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1918 acl on a dir (tridge) */
1919 len
= srvstr_push(base_data
, flags2
, p
,
1920 fname
, PTR_DIFF(end_data
, p
),
1921 STR_TERMINATE_ASCII
);
1925 len
= PTR_DIFF(p
, pdata
);
1926 pad
= (len
+ (align
-1)) & ~(align
-1);
1928 * offset to the next entry, the caller
1929 * will overwrite it for the last entry
1930 * that's why we always include the padding
1934 * set padding to zero
1937 memset(p
, 0, pad
- len
);
1944 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1945 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1947 SIVAL(p
,0,reskey
); p
+= 4;
1948 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1949 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1950 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1951 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
1952 SOFF_T(p
,0,file_size
); p
+= 8;
1953 SOFF_T(p
,0,allocation_size
); p
+= 8;
1954 SIVAL(p
,0,mode
); p
+= 4;
1955 q
= p
; p
+= 4; /* q is placeholder for name length. */
1956 if (mode
& FILE_ATTRIBUTE_REPARSE_POINT
) {
1957 SIVAL(p
, 0, IO_REPARSE_TAG_DFS
);
1959 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
1960 smb_fname
->base_name
);
1961 SIVAL(p
,0,ea_size
); /* Extended attributes */
1964 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
1965 SBVAL(p
,0,file_index
); p
+= 8;
1966 len
= srvstr_push(base_data
, flags2
, p
,
1967 fname
, PTR_DIFF(end_data
, p
),
1968 STR_TERMINATE_ASCII
);
1972 len
= PTR_DIFF(p
, pdata
);
1973 pad
= (len
+ (align
-1)) & ~(align
-1);
1975 * offset to the next entry, the caller
1976 * will overwrite it for the last entry
1977 * that's why we always include the padding
1981 * set padding to zero
1984 memset(p
, 0, pad
- len
);
1991 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1992 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1993 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1995 SIVAL(p
,0,reskey
); p
+= 4;
1996 put_long_date_timespec(conn
->ts_res
,p
,create_date_ts
); p
+= 8;
1997 put_long_date_timespec(conn
->ts_res
,p
,adate_ts
); p
+= 8;
1998 put_long_date_timespec(conn
->ts_res
,p
,mdate_ts
); p
+= 8;
1999 put_long_date_timespec(conn
->ts_res
,p
,cdate_ts
); p
+= 8;
2000 SOFF_T(p
,0,file_size
); p
+= 8;
2001 SOFF_T(p
,0,allocation_size
); p
+= 8;
2002 SIVAL(p
,0,mode
); p
+= 4;
2003 q
= p
; p
+= 4; /* q is placeholder for name length */
2004 if (mode
& FILE_ATTRIBUTE_REPARSE_POINT
) {
2005 SIVAL(p
, 0, IO_REPARSE_TAG_DFS
);
2007 unsigned int ea_size
= estimate_ea_size(conn
, NULL
,
2008 smb_fname
->base_name
);
2009 SIVAL(p
,0,ea_size
); /* Extended attributes */
2012 /* Clear the short name buffer. This is
2013 * IMPORTANT as not doing so will trigger
2014 * a Win2k client bug. JRA.
2016 if (!was_8_3
&& check_mangled_names
) {
2017 char mangled_name
[13]; /* mangled 8.3 name. */
2018 if (!name_to_8_3(fname
,mangled_name
,True
,
2020 /* Error - mangle failed ! */
2021 memset(mangled_name
,'\0',12);
2023 mangled_name
[12] = 0;
2024 len
= srvstr_push(base_data
, flags2
,
2025 p
+2, mangled_name
, 24,
2026 STR_UPPER
|STR_UNICODE
);
2029 memset(p
+ 2 + len
,'\0',24 - len
);
2036 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
2037 SBVAL(p
,0,file_index
); p
+= 8;
2038 len
= srvstr_push(base_data
, flags2
, p
,
2039 fname
, PTR_DIFF(end_data
, p
),
2040 STR_TERMINATE_ASCII
);
2044 len
= PTR_DIFF(p
, pdata
);
2045 pad
= (len
+ (align
-1)) & ~(align
-1);
2047 * offset to the next entry, the caller
2048 * will overwrite it for the last entry
2049 * that's why we always include the padding
2053 * set padding to zero
2056 memset(p
, 0, pad
- len
);
2063 /* CIFS UNIX Extension. */
2065 case SMB_FIND_FILE_UNIX
:
2066 case SMB_FIND_FILE_UNIX_INFO2
:
2068 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
2070 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2072 if (info_level
== SMB_FIND_FILE_UNIX
) {
2073 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2074 p
= store_file_unix_basic(conn
, p
,
2075 NULL
, &smb_fname
->st
);
2076 len
= srvstr_push(base_data
, flags2
, p
,
2077 fname
, PTR_DIFF(end_data
, p
),
2080 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2081 p
= store_file_unix_basic_info2(conn
, p
,
2082 NULL
, &smb_fname
->st
);
2085 len
= srvstr_push(base_data
, flags2
, p
, fname
,
2086 PTR_DIFF(end_data
, p
), 0);
2087 SIVAL(nameptr
, 0, len
);
2092 len
= PTR_DIFF(p
, pdata
);
2093 pad
= (len
+ (align
-1)) & ~(align
-1);
2095 * offset to the next entry, the caller
2096 * will overwrite it for the last entry
2097 * that's why we always include the padding
2101 * set padding to zero
2104 memset(p
, 0, pad
- len
);
2109 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2117 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
2118 *out_of_space
= true;
2119 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2120 "(wanted %u, had %d)\n",
2121 (unsigned int)PTR_DIFF(p
,pdata
),
2123 return false; /* Not finished - just out of space */
2126 /* Setup the last entry pointer, as an offset from base_data */
2127 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
2128 /* Advance the data pointer to the next slot */
2134 bool smbd_dirptr_lanman2_entry(TALLOC_CTX
*ctx
,
2135 connection_struct
*conn
,
2136 struct dptr_struct
*dirptr
,
2138 const char *path_mask
,
2141 int requires_resume_key
,
2149 int space_remaining
,
2151 bool *got_exact_match
,
2152 int *_last_entry_off
,
2153 struct ea_list
*name_list
)
2156 const char *mask
= NULL
;
2157 long prev_dirpos
= 0;
2160 struct smb_filename
*smb_fname
= NULL
;
2161 struct smbd_dirptr_lanman2_state state
;
2163 uint64_t last_entry_off
= 0;
2167 state
.info_level
= info_level
;
2168 state
.check_mangled_names
= lp_manglednames(conn
->params
);
2169 state
.has_wild
= dptr_has_wild(dirptr
);
2170 state
.got_exact_match
= false;
2172 *out_of_space
= false;
2173 *got_exact_match
= false;
2175 p
= strrchr_m(path_mask
,'/');
2186 ok
= smbd_dirptr_get_entry(ctx
,
2192 smbd_dirptr_lanman2_match_fn
,
2193 smbd_dirptr_lanman2_mode_fn
,
2203 *got_exact_match
= state
.got_exact_match
;
2205 ok
= smbd_marshall_dir_entry(ctx
,
2210 state
.check_mangled_names
,
2211 requires_resume_key
,
2224 TALLOC_FREE(smb_fname
);
2225 if (*out_of_space
) {
2226 dptr_SeekDir(dirptr
, prev_dirpos
);
2233 *_last_entry_off
= last_entry_off
;
2237 static bool get_lanman2_dir_entry(TALLOC_CTX
*ctx
,
2238 connection_struct
*conn
,
2239 struct dptr_struct
*dirptr
,
2241 const char *path_mask
,
2244 bool requires_resume_key
,
2250 int space_remaining
,
2252 bool *got_exact_match
,
2253 int *last_entry_off
,
2254 struct ea_list
*name_list
)
2257 const bool do_pad
= true;
2259 if (info_level
>= 1 && info_level
<= 3) {
2260 /* No alignment on earlier info levels. */
2264 return smbd_dirptr_lanman2_entry(ctx
, conn
, dirptr
, flags2
,
2265 path_mask
, dirtype
, info_level
,
2266 requires_resume_key
, dont_descend
, ask_sharemode
,
2268 ppdata
, base_data
, end_data
,
2270 out_of_space
, got_exact_match
,
2271 last_entry_off
, name_list
);
2274 /****************************************************************************
2275 Reply to a TRANS2_FINDFIRST.
2276 ****************************************************************************/
2278 static void call_trans2findfirst(connection_struct
*conn
,
2279 struct smb_request
*req
,
2280 char **pparams
, int total_params
,
2281 char **ppdata
, int total_data
,
2282 unsigned int max_data_bytes
)
2284 /* We must be careful here that we don't return more than the
2285 allowed number of data bytes. If this means returning fewer than
2286 maxentries then so be it. We assume that the redirector has
2287 enough room for the fixed number of parameter bytes it has
2289 struct smb_filename
*smb_dname
= NULL
;
2290 char *params
= *pparams
;
2291 char *pdata
= *ppdata
;
2295 uint16 findfirst_flags
;
2296 bool close_after_first
;
2298 bool requires_resume_key
;
2300 char *directory
= NULL
;
2303 int last_entry_off
=0;
2307 bool finished
= False
;
2308 bool dont_descend
= False
;
2309 bool out_of_space
= False
;
2310 int space_remaining
;
2311 bool mask_contains_wcard
= False
;
2312 struct ea_list
*ea_list
= NULL
;
2313 NTSTATUS ntstatus
= NT_STATUS_OK
;
2314 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2315 TALLOC_CTX
*ctx
= talloc_tos();
2316 struct dptr_struct
*dirptr
= NULL
;
2317 struct smbd_server_connection
*sconn
= req
->sconn
;
2318 uint32_t ucf_flags
= (UCF_SAVE_LCOMP
| UCF_ALWAYS_ALLOW_WCARD_LCOMP
);
2320 if (total_params
< 13) {
2321 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2325 dirtype
= SVAL(params
,0);
2326 maxentries
= SVAL(params
,2);
2327 findfirst_flags
= SVAL(params
,4);
2328 close_after_first
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE
);
2329 close_if_end
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2330 requires_resume_key
= (findfirst_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2331 info_level
= SVAL(params
,6);
2333 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2334 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
2335 (unsigned int)dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
2336 info_level
, max_data_bytes
));
2339 /* W2K3 seems to treat zero as 1. */
2343 switch (info_level
) {
2344 case SMB_FIND_INFO_STANDARD
:
2345 case SMB_FIND_EA_SIZE
:
2346 case SMB_FIND_EA_LIST
:
2347 case SMB_FIND_FILE_DIRECTORY_INFO
:
2348 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2349 case SMB_FIND_FILE_NAMES_INFO
:
2350 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2351 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2352 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2354 case SMB_FIND_FILE_UNIX
:
2355 case SMB_FIND_FILE_UNIX_INFO2
:
2356 /* Always use filesystem for UNIX mtime query. */
2357 ask_sharemode
= false;
2358 if (!lp_unix_extensions()) {
2359 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2362 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
2365 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2369 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &directory
,
2370 params
+12, total_params
- 12,
2371 STR_TERMINATE
, &ntstatus
, &mask_contains_wcard
);
2372 if (!NT_STATUS_IS_OK(ntstatus
)) {
2373 reply_nterror(req
, ntstatus
);
2377 ntstatus
= filename_convert(ctx
, conn
,
2378 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
2381 &mask_contains_wcard
,
2383 if (!NT_STATUS_IS_OK(ntstatus
)) {
2384 if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_PATH_NOT_COVERED
)) {
2385 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
2386 ERRSRV
, ERRbadpath
);
2389 reply_nterror(req
, ntstatus
);
2393 mask
= smb_dname
->original_lcomp
;
2395 directory
= smb_dname
->base_name
;
2397 p
= strrchr_m(directory
,'/');
2399 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2400 if((directory
[0] == '.') && (directory
[1] == '\0')) {
2401 mask
= talloc_strdup(ctx
,"*");
2403 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2406 mask_contains_wcard
= True
;
2412 if (p
== NULL
|| p
== directory
) {
2413 /* Ensure we don't have a directory name of "". */
2414 directory
= talloc_strdup(talloc_tos(), ".");
2416 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2421 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
2423 if (info_level
== SMB_FIND_EA_LIST
) {
2426 if (total_data
< 4) {
2427 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2431 ea_size
= IVAL(pdata
,0);
2432 if (ea_size
!= total_data
) {
2433 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2434 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2435 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2439 if (!lp_ea_support(SNUM(conn
))) {
2440 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2444 /* Pull out the list of names. */
2445 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2447 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2452 *ppdata
= (char *)SMB_REALLOC(
2453 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2454 if(*ppdata
== NULL
) {
2455 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2459 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2461 /* Realloc the params space */
2462 *pparams
= (char *)SMB_REALLOC(*pparams
, 10);
2463 if (*pparams
== NULL
) {
2464 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2469 /* Save the wildcard match and attribs we are using on this directory -
2470 needed as lanman2 assumes these are being saved between calls */
2472 ntstatus
= dptr_create(conn
,
2479 mask_contains_wcard
,
2483 if (!NT_STATUS_IS_OK(ntstatus
)) {
2484 reply_nterror(req
, ntstatus
);
2488 dptr_num
= dptr_dnum(dirptr
);
2489 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num
, mask
, dirtype
));
2491 /* Initialize per TRANS2_FIND_FIRST operation data */
2492 dptr_init_search_op(dirptr
);
2494 /* We don't need to check for VOL here as this is returned by
2495 a different TRANS2 call. */
2497 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2498 directory
,lp_dontdescend(SNUM(conn
))));
2499 if (in_list(directory
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
2500 dont_descend
= True
;
2503 space_remaining
= max_data_bytes
;
2504 out_of_space
= False
;
2506 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
2507 bool got_exact_match
= False
;
2509 /* this is a heuristic to avoid seeking the dirptr except when
2510 absolutely necessary. It allows for a filename of about 40 chars */
2511 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2512 out_of_space
= True
;
2515 finished
= !get_lanman2_dir_entry(ctx
,
2519 mask
,dirtype
,info_level
,
2520 requires_resume_key
,dont_descend
,
2523 space_remaining
, &out_of_space
,
2525 &last_entry_off
, ea_list
);
2528 if (finished
&& out_of_space
)
2531 if (!finished
&& !out_of_space
)
2535 * As an optimisation if we know we aren't looking
2536 * for a wildcard name (ie. the name matches the wildcard exactly)
2537 * then we can finish on any (first) match.
2538 * This speeds up large directory searches. JRA.
2544 /* Ensure space_remaining never goes -ve. */
2545 if (PTR_DIFF(p
,pdata
) > max_data_bytes
) {
2546 space_remaining
= 0;
2547 out_of_space
= true;
2549 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2553 /* Check if we can close the dirptr */
2554 if(close_after_first
|| (finished
&& close_if_end
)) {
2555 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
2556 dptr_close(sconn
, &dptr_num
);
2560 * If there are no matching entries we must return ERRDOS/ERRbadfile -
2561 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2562 * the protocol level is less than NT1. Tested with smbclient. JRA.
2563 * This should fix the OS/2 client bug #2335.
2566 if(numentries
== 0) {
2567 dptr_close(sconn
, &dptr_num
);
2568 if (get_Protocol() < PROTOCOL_NT1
) {
2569 reply_force_doserror(req
, ERRDOS
, ERRnofiles
);
2572 reply_botherror(req
, NT_STATUS_NO_SUCH_FILE
,
2573 ERRDOS
, ERRbadfile
);
2578 /* At this point pdata points to numentries directory entries. */
2580 /* Set up the return parameter block */
2581 SSVAL(params
,0,dptr_num
);
2582 SSVAL(params
,2,numentries
);
2583 SSVAL(params
,4,finished
);
2584 SSVAL(params
,6,0); /* Never an EA error */
2585 SSVAL(params
,8,last_entry_off
);
2587 send_trans2_replies(conn
, req
, params
, 10, pdata
, PTR_DIFF(p
,pdata
),
2590 if ((! *directory
) && dptr_path(sconn
, dptr_num
)) {
2591 directory
= talloc_strdup(talloc_tos(),dptr_path(sconn
, dptr_num
));
2593 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2597 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2598 smb_fn_name(req
->cmd
),
2599 mask
, directory
, dirtype
, numentries
) );
2602 * Force a name mangle here to ensure that the
2603 * mask as an 8.3 name is top of the mangled cache.
2604 * The reasons for this are subtle. Don't remove
2605 * this code unless you know what you are doing
2606 * (see PR#13758). JRA.
2609 if(!mangle_is_8_3_wildcards( mask
, False
, conn
->params
)) {
2610 char mangled_name
[13];
2611 name_to_8_3(mask
, mangled_name
, True
, conn
->params
);
2614 TALLOC_FREE(smb_dname
);
2618 /****************************************************************************
2619 Reply to a TRANS2_FINDNEXT.
2620 ****************************************************************************/
2622 static void call_trans2findnext(connection_struct
*conn
,
2623 struct smb_request
*req
,
2624 char **pparams
, int total_params
,
2625 char **ppdata
, int total_data
,
2626 unsigned int max_data_bytes
)
2628 /* We must be careful here that we don't return more than the
2629 allowed number of data bytes. If this means returning fewer than
2630 maxentries then so be it. We assume that the redirector has
2631 enough room for the fixed number of parameter bytes it has
2633 char *params
= *pparams
;
2634 char *pdata
= *ppdata
;
2640 uint16 findnext_flags
;
2641 bool close_after_request
;
2643 bool requires_resume_key
;
2645 bool mask_contains_wcard
= False
;
2646 char *resume_name
= NULL
;
2647 const char *mask
= NULL
;
2648 const char *directory
= NULL
;
2652 int i
, last_entry_off
=0;
2653 bool finished
= False
;
2654 bool dont_descend
= False
;
2655 bool out_of_space
= False
;
2656 int space_remaining
;
2657 struct ea_list
*ea_list
= NULL
;
2658 NTSTATUS ntstatus
= NT_STATUS_OK
;
2659 bool ask_sharemode
= lp_parm_bool(SNUM(conn
), "smbd", "search ask sharemode", true);
2660 TALLOC_CTX
*ctx
= talloc_tos();
2661 struct dptr_struct
*dirptr
;
2662 struct smbd_server_connection
*sconn
= req
->sconn
;
2664 if (total_params
< 13) {
2665 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2669 dptr_num
= SVAL(params
,0);
2670 maxentries
= SVAL(params
,2);
2671 info_level
= SVAL(params
,4);
2672 resume_key
= IVAL(params
,6);
2673 findnext_flags
= SVAL(params
,10);
2674 close_after_request
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE
);
2675 close_if_end
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
2676 requires_resume_key
= (findnext_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
2677 continue_bit
= (findnext_flags
& FLAG_TRANS2_FIND_CONTINUE
);
2679 if (!continue_bit
) {
2680 /* We only need resume_name if continue_bit is zero. */
2681 srvstr_get_path_wcard(ctx
, params
, req
->flags2
, &resume_name
,
2683 total_params
- 12, STR_TERMINATE
, &ntstatus
,
2684 &mask_contains_wcard
);
2685 if (!NT_STATUS_IS_OK(ntstatus
)) {
2686 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2687 complain (it thinks we're asking for the directory above the shared
2688 path or an invalid name). Catch this as the resume name is only compared, never used in
2689 a file access. JRA. */
2690 srvstr_pull_talloc(ctx
, params
, req
->flags2
,
2691 &resume_name
, params
+12,
2695 if (!resume_name
|| !(ISDOT(resume_name
) || ISDOTDOT(resume_name
))) {
2696 reply_nterror(req
, ntstatus
);
2702 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2703 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2704 resume_key = %d resume name = %s continue=%d level = %d\n",
2705 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
2706 requires_resume_key
, resume_key
,
2707 resume_name
? resume_name
: "(NULL)", continue_bit
, info_level
));
2710 /* W2K3 seems to treat zero as 1. */
2714 switch (info_level
) {
2715 case SMB_FIND_INFO_STANDARD
:
2716 case SMB_FIND_EA_SIZE
:
2717 case SMB_FIND_EA_LIST
:
2718 case SMB_FIND_FILE_DIRECTORY_INFO
:
2719 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2720 case SMB_FIND_FILE_NAMES_INFO
:
2721 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2722 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2723 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2725 case SMB_FIND_FILE_UNIX
:
2726 case SMB_FIND_FILE_UNIX_INFO2
:
2727 /* Always use filesystem for UNIX mtime query. */
2728 ask_sharemode
= false;
2729 if (!lp_unix_extensions()) {
2730 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2735 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
2739 if (info_level
== SMB_FIND_EA_LIST
) {
2742 if (total_data
< 4) {
2743 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2747 ea_size
= IVAL(pdata
,0);
2748 if (ea_size
!= total_data
) {
2749 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2750 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2751 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2755 if (!lp_ea_support(SNUM(conn
))) {
2756 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
2760 /* Pull out the list of names. */
2761 ea_list
= read_ea_name_list(ctx
, pdata
+ 4, ea_size
- 4);
2763 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
2768 *ppdata
= (char *)SMB_REALLOC(
2769 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2770 if(*ppdata
== NULL
) {
2771 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2776 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2778 /* Realloc the params space */
2779 *pparams
= (char *)SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
2780 if(*pparams
== NULL
) {
2781 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
2787 /* Check that the dptr is valid */
2788 if(!(dirptr
= dptr_fetch_lanman2(sconn
, dptr_num
))) {
2789 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2793 directory
= dptr_path(sconn
, dptr_num
);
2795 /* Get the wildcard mask from the dptr */
2796 if((p
= dptr_wcard(sconn
, dptr_num
))== NULL
) {
2797 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
2798 reply_nterror(req
, STATUS_NO_MORE_FILES
);
2804 /* Get the attr mask from the dptr */
2805 dirtype
= dptr_attr(sconn
, dptr_num
);
2807 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2808 dptr_num
, mask
, dirtype
,
2810 dptr_TellDir(dirptr
)));
2812 /* Initialize per TRANS2_FIND_NEXT operation data */
2813 dptr_init_search_op(dirptr
);
2815 /* We don't need to check for VOL here as this is returned by
2816 a different TRANS2 call. */
2818 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2819 directory
,lp_dontdescend(SNUM(conn
))));
2820 if (in_list(directory
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
2821 dont_descend
= True
;
2824 space_remaining
= max_data_bytes
;
2825 out_of_space
= False
;
2828 * Seek to the correct position. We no longer use the resume key but
2829 * depend on the last file name instead.
2832 if(!continue_bit
&& resume_name
&& *resume_name
) {
2835 long current_pos
= 0;
2837 * Remember, name_to_8_3 is called by
2838 * get_lanman2_dir_entry(), so the resume name
2839 * could be mangled. Ensure we check the unmangled name.
2842 if (mangle_is_mangled(resume_name
, conn
->params
)) {
2843 char *new_resume_name
= NULL
;
2844 mangle_lookup_name_from_8_3(ctx
,
2848 if (new_resume_name
) {
2849 resume_name
= new_resume_name
;
2854 * Fix for NT redirector problem triggered by resume key indexes
2855 * changing between directory scans. We now return a resume key of 0
2856 * and instead look for the filename to continue from (also given
2857 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2858 * findfirst/findnext (as is usual) then the directory pointer
2859 * should already be at the correct place.
2862 finished
= !dptr_SearchDir(dirptr
, resume_name
, ¤t_pos
, &st
);
2863 } /* end if resume_name && !continue_bit */
2865 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
2866 bool got_exact_match
= False
;
2868 /* this is a heuristic to avoid seeking the dirptr except when
2869 absolutely necessary. It allows for a filename of about 40 chars */
2870 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2871 out_of_space
= True
;
2874 finished
= !get_lanman2_dir_entry(ctx
,
2878 mask
,dirtype
,info_level
,
2879 requires_resume_key
,dont_descend
,
2882 space_remaining
, &out_of_space
,
2884 &last_entry_off
, ea_list
);
2887 if (finished
&& out_of_space
)
2890 if (!finished
&& !out_of_space
)
2894 * As an optimisation if we know we aren't looking
2895 * for a wildcard name (ie. the name matches the wildcard exactly)
2896 * then we can finish on any (first) match.
2897 * This speeds up large directory searches. JRA.
2903 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2906 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2907 smb_fn_name(req
->cmd
),
2908 mask
, directory
, dirtype
, numentries
) );
2910 /* Check if we can close the dirptr */
2911 if(close_after_request
|| (finished
&& close_if_end
)) {
2912 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
2913 dptr_close(sconn
, &dptr_num
); /* This frees up the saved mask */
2916 /* Set up the return parameter block */
2917 SSVAL(params
,0,numentries
);
2918 SSVAL(params
,2,finished
);
2919 SSVAL(params
,4,0); /* Never an EA error */
2920 SSVAL(params
,6,last_entry_off
);
2922 send_trans2_replies(conn
, req
, params
, 8, pdata
, PTR_DIFF(p
,pdata
),
2928 unsigned char *create_volume_objectid(connection_struct
*conn
, unsigned char objid
[16])
2930 E_md4hash(lp_servicename(SNUM(conn
)),objid
);
2934 static void samba_extended_info_version(struct smb_extended_info
*extended_info
)
2936 SMB_ASSERT(extended_info
!= NULL
);
2938 extended_info
->samba_magic
= SAMBA_EXTENDED_INFO_MAGIC
;
2939 extended_info
->samba_version
= ((SAMBA_VERSION_MAJOR
& 0xff) << 24)
2940 | ((SAMBA_VERSION_MINOR
& 0xff) << 16)
2941 | ((SAMBA_VERSION_RELEASE
& 0xff) << 8);
2942 #ifdef SAMBA_VERSION_REVISION
2943 extended_info
->samba_version
|= (tolower(*SAMBA_VERSION_REVISION
) - 'a' + 1) & 0xff;
2945 extended_info
->samba_subversion
= 0;
2946 #ifdef SAMBA_VERSION_RC_RELEASE
2947 extended_info
->samba_subversion
|= (SAMBA_VERSION_RC_RELEASE
& 0xff) << 24;
2949 #ifdef SAMBA_VERSION_PRE_RELEASE
2950 extended_info
->samba_subversion
|= (SAMBA_VERSION_PRE_RELEASE
& 0xff) << 16;
2953 #ifdef SAMBA_VERSION_VENDOR_PATCH
2954 extended_info
->samba_subversion
|= (SAMBA_VERSION_VENDOR_PATCH
& 0xffff);
2956 extended_info
->samba_gitcommitdate
= 0;
2957 #ifdef SAMBA_VERSION_COMMIT_TIME
2958 unix_to_nt_time(&extended_info
->samba_gitcommitdate
, SAMBA_VERSION_COMMIT_TIME
);
2961 memset(extended_info
->samba_version_string
, 0,
2962 sizeof(extended_info
->samba_version_string
));
2964 snprintf (extended_info
->samba_version_string
,
2965 sizeof(extended_info
->samba_version_string
),
2966 "%s", samba_version_string());
2969 NTSTATUS
smbd_do_qfsinfo(connection_struct
*conn
,
2970 TALLOC_CTX
*mem_ctx
,
2971 uint16_t info_level
,
2973 unsigned int max_data_bytes
,
2974 struct smb_filename
*fname
,
2978 char *pdata
, *end_data
;
2979 int data_len
= 0, len
;
2980 const char *vname
= volume_label(SNUM(conn
));
2981 int snum
= SNUM(conn
);
2982 char *fstype
= lp_fstype(SNUM(conn
));
2983 const char *filename
= NULL
;
2984 uint32 additional_flags
= 0;
2985 struct smb_filename smb_fname
;
2987 NTSTATUS status
= NT_STATUS_OK
;
2989 if (fname
== NULL
|| fname
->base_name
== NULL
) {
2992 filename
= fname
->base_name
;
2996 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
2997 DEBUG(0,("smbd_do_qfsinfo: not an allowed "
2998 "info level (0x%x) on IPC$.\n",
2999 (unsigned int)info_level
));
3000 return NT_STATUS_ACCESS_DENIED
;
3004 DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level
));
3006 ZERO_STRUCT(smb_fname
);
3007 smb_fname
.base_name
= discard_const_p(char, filename
);
3009 if(SMB_VFS_STAT(conn
, &smb_fname
) != 0) {
3010 DEBUG(2,("stat of . failed (%s)\n", strerror(errno
)));
3011 return map_nt_error_from_unix(errno
);
3016 *ppdata
= (char *)SMB_REALLOC(
3017 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3018 if (*ppdata
== NULL
) {
3019 return NT_STATUS_NO_MEMORY
;
3023 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
3024 end_data
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
3026 switch (info_level
) {
3027 case SMB_INFO_ALLOCATION
:
3029 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3031 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3032 return map_nt_error_from_unix(errno
);
3035 block_size
= lp_block_size(snum
);
3036 if (bsize
< block_size
) {
3037 uint64_t factor
= block_size
/bsize
;
3042 if (bsize
> block_size
) {
3043 uint64_t factor
= bsize
/block_size
;
3048 bytes_per_sector
= 512;
3049 sectors_per_unit
= bsize
/bytes_per_sector
;
3051 DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3052 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_ex_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3053 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3055 SIVAL(pdata
,l1_idFileSystem
,st
.st_ex_dev
);
3056 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
3057 SIVAL(pdata
,l1_cUnit
,dsize
);
3058 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
3059 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
3063 case SMB_INFO_VOLUME
:
3064 /* Return volume name */
3066 * Add volume serial number - hash of a combination of
3067 * the called hostname and the service name.
3069 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
3071 * Win2k3 and previous mess this up by sending a name length
3072 * one byte short. I believe only older clients (OS/2 Win9x) use
3073 * this call so try fixing this by adding a terminating null to
3074 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3078 pdata
+l2_vol_szVolLabel
, vname
,
3079 PTR_DIFF(end_data
, pdata
+l2_vol_szVolLabel
),
3080 STR_NOALIGN
|STR_TERMINATE
);
3081 SCVAL(pdata
,l2_vol_cch
,len
);
3082 data_len
= l2_vol_szVolLabel
+ len
;
3083 DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
3084 (unsigned)convert_timespec_to_time_t(st
.st_ex_ctime
),
3088 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
3089 case SMB_FS_ATTRIBUTE_INFORMATION
:
3091 additional_flags
= 0;
3092 #if defined(HAVE_SYS_QUOTAS)
3093 additional_flags
|= FILE_VOLUME_QUOTAS
;
3096 if(lp_nt_acl_support(SNUM(conn
))) {
3097 additional_flags
|= FILE_PERSISTENT_ACLS
;
3100 /* Capabilities are filled in at connection time through STATVFS call */
3101 additional_flags
|= conn
->fs_capabilities
;
3102 additional_flags
|= lp_parm_int(conn
->params
->service
,
3103 "share", "fake_fscaps",
3106 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
3107 FILE_SUPPORTS_OBJECT_IDS
|FILE_UNICODE_ON_DISK
|
3108 additional_flags
); /* FS ATTRIBUTES */
3110 SIVAL(pdata
,4,255); /* Max filename component length */
3111 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3112 and will think we can't do long filenames */
3113 len
= srvstr_push(pdata
, flags2
, pdata
+12, fstype
,
3114 PTR_DIFF(end_data
, pdata
+12),
3117 data_len
= 12 + len
;
3120 case SMB_QUERY_FS_LABEL_INFO
:
3121 case SMB_FS_LABEL_INFORMATION
:
3122 len
= srvstr_push(pdata
, flags2
, pdata
+4, vname
,
3123 PTR_DIFF(end_data
, pdata
+4), 0);
3128 case SMB_QUERY_FS_VOLUME_INFO
:
3129 case SMB_FS_VOLUME_INFORMATION
:
3132 * Add volume serial number - hash of a combination of
3133 * the called hostname and the service name.
3135 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
3136 (str_checksum(get_local_machine_name())<<16));
3138 /* Max label len is 32 characters. */
3139 len
= srvstr_push(pdata
, flags2
, pdata
+18, vname
,
3140 PTR_DIFF(end_data
, pdata
+18),
3142 SIVAL(pdata
,12,len
);
3145 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3146 (int)strlen(vname
),vname
, lp_servicename(snum
)));
3147 if (max_data_bytes
>= 24 && data_len
> max_data_bytes
) {
3148 /* the client only requested a portion of the
3150 data_len
= max_data_bytes
;
3151 status
= STATUS_BUFFER_OVERFLOW
;
3156 case SMB_QUERY_FS_SIZE_INFO
:
3157 case SMB_FS_SIZE_INFORMATION
:
3159 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3161 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3162 return map_nt_error_from_unix(errno
);
3164 block_size
= lp_block_size(snum
);
3165 if (bsize
< block_size
) {
3166 uint64_t factor
= block_size
/bsize
;
3171 if (bsize
> block_size
) {
3172 uint64_t factor
= bsize
/block_size
;
3177 bytes_per_sector
= 512;
3178 sectors_per_unit
= bsize
/bytes_per_sector
;
3179 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3180 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3181 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3182 SBIG_UINT(pdata
,0,dsize
);
3183 SBIG_UINT(pdata
,8,dfree
);
3184 SIVAL(pdata
,16,sectors_per_unit
);
3185 SIVAL(pdata
,20,bytes_per_sector
);
3189 case SMB_FS_FULL_SIZE_INFORMATION
:
3191 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3193 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3194 return map_nt_error_from_unix(errno
);
3196 block_size
= lp_block_size(snum
);
3197 if (bsize
< block_size
) {
3198 uint64_t factor
= block_size
/bsize
;
3203 if (bsize
> block_size
) {
3204 uint64_t factor
= bsize
/block_size
;
3209 bytes_per_sector
= 512;
3210 sectors_per_unit
= bsize
/bytes_per_sector
;
3211 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3212 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3213 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3214 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
3215 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
3216 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
3217 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
3218 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
3222 case SMB_QUERY_FS_DEVICE_INFO
:
3223 case SMB_FS_DEVICE_INFORMATION
:
3225 uint32_t characteristics
= FILE_DEVICE_IS_MOUNTED
;
3227 if (!CAN_WRITE(conn
)) {
3228 characteristics
|= FILE_READ_ONLY_DEVICE
;
3231 SIVAL(pdata
,0,FILE_DEVICE_DISK
); /* dev type */
3232 SIVAL(pdata
,4,characteristics
);
3236 #ifdef HAVE_SYS_QUOTAS
3237 case SMB_FS_QUOTA_INFORMATION
:
3239 * what we have to send --metze:
3241 * Unknown1: 24 NULL bytes
3242 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3243 * Hard Quota Limit: 8 bytes seems like uint64_t or so
3244 * Quota Flags: 2 byte :
3245 * Unknown3: 6 NULL bytes
3249 * details for Quota Flags:
3251 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3252 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
3253 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3254 * 0x0001 Enable Quotas: enable quota for this fs
3258 /* we need to fake up a fsp here,
3259 * because its not send in this call
3262 SMB_NTQUOTA_STRUCT quotas
;
3265 ZERO_STRUCT(quotas
);
3271 if (get_current_uid(conn
) != 0) {
3272 DEBUG(0,("set_user_quota: access_denied "
3273 "service [%s] user [%s]\n",
3274 lp_servicename(SNUM(conn
)),
3275 conn
->session_info
->unix_name
));
3276 return NT_STATUS_ACCESS_DENIED
;
3279 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3280 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3281 return map_nt_error_from_unix(errno
);
3286 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3287 lp_servicename(SNUM(conn
))));
3289 /* Unknown1 24 NULL bytes*/
3290 SBIG_UINT(pdata
,0,(uint64_t)0);
3291 SBIG_UINT(pdata
,8,(uint64_t)0);
3292 SBIG_UINT(pdata
,16,(uint64_t)0);
3294 /* Default Soft Quota 8 bytes */
3295 SBIG_UINT(pdata
,24,quotas
.softlim
);
3297 /* Default Hard Quota 8 bytes */
3298 SBIG_UINT(pdata
,32,quotas
.hardlim
);
3300 /* Quota flag 2 bytes */
3301 SSVAL(pdata
,40,quotas
.qflags
);
3303 /* Unknown3 6 NULL bytes */
3309 #endif /* HAVE_SYS_QUOTAS */
3310 case SMB_FS_OBJECTID_INFORMATION
:
3312 unsigned char objid
[16];
3313 struct smb_extended_info extended_info
;
3314 memcpy(pdata
,create_volume_objectid(conn
, objid
),16);
3315 samba_extended_info_version (&extended_info
);
3316 SIVAL(pdata
,16,extended_info
.samba_magic
);
3317 SIVAL(pdata
,20,extended_info
.samba_version
);
3318 SIVAL(pdata
,24,extended_info
.samba_subversion
);
3319 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
3320 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
3326 * Query the version and capabilities of the CIFS UNIX extensions
3330 case SMB_QUERY_CIFS_UNIX_INFO
:
3332 bool large_write
= lp_min_receive_file_size() &&
3333 !srv_is_signing_active(conn
->sconn
);
3334 bool large_read
= !srv_is_signing_active(conn
->sconn
);
3335 int encrypt_caps
= 0;
3337 if (!lp_unix_extensions()) {
3338 return NT_STATUS_INVALID_LEVEL
;
3341 switch (conn
->encrypt_level
) {
3347 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
;
3350 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
|
3351 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP
;
3352 large_write
= false;
3358 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
3359 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
3361 /* We have POSIX ACLs, pathname, encryption,
3362 * large read/write, and locking capability. */
3364 SBIG_UINT(pdata
,4,((uint64_t)(
3365 CIFS_UNIX_POSIX_ACLS_CAP
|
3366 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
3367 CIFS_UNIX_FCNTL_LOCKS_CAP
|
3368 CIFS_UNIX_EXTATTR_CAP
|
3369 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
|
3371 (large_read
? CIFS_UNIX_LARGE_READ_CAP
: 0) |
3373 CIFS_UNIX_LARGE_WRITE_CAP
: 0))));
3377 case SMB_QUERY_POSIX_FS_INFO
:
3380 vfs_statvfs_struct svfs
;
3382 if (!lp_unix_extensions()) {
3383 return NT_STATUS_INVALID_LEVEL
;
3386 rc
= SMB_VFS_STATVFS(conn
, filename
, &svfs
);
3390 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
3391 SIVAL(pdata
,4,svfs
.BlockSize
);
3392 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
3393 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
3394 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
3395 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
3396 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
3397 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
3398 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3400 } else if (rc
== EOPNOTSUPP
) {
3401 return NT_STATUS_INVALID_LEVEL
;
3402 #endif /* EOPNOTSUPP */
3404 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3405 return NT_STATUS_DOS(ERRSRV
, ERRerror
);
3410 case SMB_QUERY_POSIX_WHOAMI
:
3416 if (!lp_unix_extensions()) {
3417 return NT_STATUS_INVALID_LEVEL
;
3420 if (max_data_bytes
< 40) {
3421 return NT_STATUS_BUFFER_TOO_SMALL
;
3424 /* We ARE guest if global_sid_Builtin_Guests is
3425 * in our list of SIDs.
3427 if (nt_token_check_sid(&global_sid_Builtin_Guests
,
3428 conn
->session_info
->security_token
)) {
3429 flags
|= SMB_WHOAMI_GUEST
;
3432 /* We are NOT guest if global_sid_Authenticated_Users
3433 * is in our list of SIDs.
3435 if (nt_token_check_sid(&global_sid_Authenticated_Users
,
3436 conn
->session_info
->security_token
)) {
3437 flags
&= ~SMB_WHOAMI_GUEST
;
3440 /* NOTE: 8 bytes for UID/GID, irrespective of native
3441 * platform size. This matches
3442 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3444 data_len
= 4 /* flags */
3451 + 4 /* pad/reserved */
3452 + (conn
->session_info
->utok
.ngroups
* 8)
3454 + (conn
->session_info
->security_token
->num_sids
*
3458 SIVAL(pdata
, 0, flags
);
3459 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
3461 (uint64_t)conn
->session_info
->utok
.uid
);
3462 SBIG_UINT(pdata
, 16,
3463 (uint64_t)conn
->session_info
->utok
.gid
);
3466 if (data_len
>= max_data_bytes
) {
3467 /* Potential overflow, skip the GIDs and SIDs. */
3469 SIVAL(pdata
, 24, 0); /* num_groups */
3470 SIVAL(pdata
, 28, 0); /* num_sids */
3471 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
3472 SIVAL(pdata
, 36, 0); /* reserved */
3478 SIVAL(pdata
, 24, conn
->session_info
->utok
.ngroups
);
3479 SIVAL(pdata
, 28, conn
->session_info
->security_token
->num_sids
);
3481 /* We walk the SID list twice, but this call is fairly
3482 * infrequent, and I don't expect that it's performance
3483 * sensitive -- jpeach
3485 for (i
= 0, sid_bytes
= 0;
3486 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3487 sid_bytes
+= ndr_size_dom_sid(
3488 &conn
->session_info
->security_token
->sids
[i
],
3492 /* SID list byte count */
3493 SIVAL(pdata
, 32, sid_bytes
);
3495 /* 4 bytes pad/reserved - must be zero */
3496 SIVAL(pdata
, 36, 0);
3500 for (i
= 0; i
< conn
->session_info
->utok
.ngroups
; ++i
) {
3501 SBIG_UINT(pdata
, data_len
,
3502 (uint64_t)conn
->session_info
->utok
.groups
[i
]);
3508 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3509 int sid_len
= ndr_size_dom_sid(
3510 &conn
->session_info
->security_token
->sids
[i
],
3513 sid_linearize(pdata
+ data_len
, sid_len
,
3514 &conn
->session_info
->security_token
->sids
[i
]);
3515 data_len
+= sid_len
;
3521 case SMB_MAC_QUERY_FS_INFO
:
3523 * Thursby MAC extension... ONLY on NTFS filesystems
3524 * once we do streams then we don't need this
3526 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
3528 SIVAL(pdata
,84,0x100); /* Don't support mac... */
3533 return NT_STATUS_INVALID_LEVEL
;
3536 *ret_data_len
= data_len
;
3540 /****************************************************************************
3541 Reply to a TRANS2_QFSINFO (query filesystem info).
3542 ****************************************************************************/
3544 static void call_trans2qfsinfo(connection_struct
*conn
,
3545 struct smb_request
*req
,
3546 char **pparams
, int total_params
,
3547 char **ppdata
, int total_data
,
3548 unsigned int max_data_bytes
)
3550 char *params
= *pparams
;
3551 uint16_t info_level
;
3555 if (total_params
< 2) {
3556 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3560 info_level
= SVAL(params
,0);
3562 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3563 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3564 DEBUG(0,("call_trans2qfsinfo: encryption required "
3565 "and info level 0x%x sent.\n",
3566 (unsigned int)info_level
));
3567 exit_server_cleanly("encryption required "
3573 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
3575 status
= smbd_do_qfsinfo(conn
, req
,
3581 if (!NT_STATUS_IS_OK(status
)) {
3582 reply_nterror(req
, status
);
3586 send_trans2_replies(conn
, req
, params
, 0, *ppdata
, data_len
,
3589 DEBUG( 4, ( "%s info_level = %d\n",
3590 smb_fn_name(req
->cmd
), info_level
) );
3595 /****************************************************************************
3596 Reply to a TRANS2_SETFSINFO (set filesystem info).
3597 ****************************************************************************/
3599 static void call_trans2setfsinfo(connection_struct
*conn
,
3600 struct smb_request
*req
,
3601 char **pparams
, int total_params
,
3602 char **ppdata
, int total_data
,
3603 unsigned int max_data_bytes
)
3605 char *pdata
= *ppdata
;
3606 char *params
= *pparams
;
3609 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn
))));
3612 if (total_params
< 4) {
3613 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3615 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3619 info_level
= SVAL(params
,2);
3622 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
&&
3623 info_level
!= SMB_SET_CIFS_UNIX_INFO
) {
3624 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3625 "info level (0x%x) on IPC$.\n",
3626 (unsigned int)info_level
));
3627 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3632 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3633 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
) {
3634 DEBUG(0,("call_trans2setfsinfo: encryption required "
3635 "and info level 0x%x sent.\n",
3636 (unsigned int)info_level
));
3637 exit_server_cleanly("encryption required "
3643 switch(info_level
) {
3644 case SMB_SET_CIFS_UNIX_INFO
:
3646 uint16 client_unix_major
;
3647 uint16 client_unix_minor
;
3648 uint32 client_unix_cap_low
;
3649 uint32 client_unix_cap_high
;
3651 if (!lp_unix_extensions()) {
3653 NT_STATUS_INVALID_LEVEL
);
3657 /* There should be 12 bytes of capabilities set. */
3658 if (total_data
< 8) {
3661 NT_STATUS_INVALID_PARAMETER
);
3664 client_unix_major
= SVAL(pdata
,0);
3665 client_unix_minor
= SVAL(pdata
,2);
3666 client_unix_cap_low
= IVAL(pdata
,4);
3667 client_unix_cap_high
= IVAL(pdata
,8);
3668 /* Just print these values for now. */
3669 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
3670 cap_low = 0x%x, cap_high = 0x%x\n",
3671 (unsigned int)client_unix_major
,
3672 (unsigned int)client_unix_minor
,
3673 (unsigned int)client_unix_cap_low
,
3674 (unsigned int)client_unix_cap_high
));
3676 /* Here is where we must switch to posix pathname processing... */
3677 if (client_unix_cap_low
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
3678 lp_set_posix_pathnames();
3679 mangle_change_to_posix();
3682 if ((client_unix_cap_low
& CIFS_UNIX_FCNTL_LOCKS_CAP
) &&
3683 !(client_unix_cap_low
& CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)) {
3684 /* Client that knows how to do posix locks,
3685 * but not posix open/mkdir operations. Set a
3686 * default type for read/write checks. */
3688 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK
);
3694 case SMB_REQUEST_TRANSPORT_ENCRYPTION
:
3697 size_t param_len
= 0;
3698 size_t data_len
= total_data
;
3700 if (!lp_unix_extensions()) {
3703 NT_STATUS_INVALID_LEVEL
);
3707 if (lp_smb_encrypt(SNUM(conn
)) == false) {
3710 NT_STATUS_NOT_SUPPORTED
);
3714 if (req
->sconn
->smb1
.echo_handler
.trusted_fde
) {
3715 DEBUG( 2,("call_trans2setfsinfo: "
3716 "request transport encryption disabled"
3717 "with 'fork echo handler = yes'\n"));
3720 NT_STATUS_NOT_SUPPORTED
);
3724 DEBUG( 4,("call_trans2setfsinfo: "
3725 "request transport encryption.\n"));
3727 status
= srv_request_encryption_setup(conn
,
3728 (unsigned char **)ppdata
,
3730 (unsigned char **)pparams
,
3733 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
3734 !NT_STATUS_IS_OK(status
)) {
3735 reply_nterror(req
, status
);
3739 send_trans2_replies(conn
, req
,
3746 if (NT_STATUS_IS_OK(status
)) {
3747 /* Server-side transport
3748 * encryption is now *on*. */
3749 status
= srv_encryption_start(conn
);
3750 if (!NT_STATUS_IS_OK(status
)) {
3751 exit_server_cleanly(
3752 "Failure in setting "
3753 "up encrypted transport");
3759 case SMB_FS_QUOTA_INFORMATION
:
3761 files_struct
*fsp
= NULL
;
3762 SMB_NTQUOTA_STRUCT quotas
;
3764 ZERO_STRUCT(quotas
);
3767 if ((get_current_uid(conn
) != 0) || !CAN_WRITE(conn
)) {
3768 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3769 lp_servicename(SNUM(conn
)),
3770 conn
->session_info
->unix_name
));
3771 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3775 /* note: normaly there're 48 bytes,
3776 * but we didn't use the last 6 bytes for now
3779 fsp
= file_fsp(req
, SVAL(params
,0));
3781 if (!check_fsp_ntquota_handle(conn
, req
,
3783 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3785 req
, NT_STATUS_INVALID_HANDLE
);
3789 if (total_data
< 42) {
3790 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3794 NT_STATUS_INVALID_PARAMETER
);
3798 /* unknown_1 24 NULL bytes in pdata*/
3800 /* the soft quotas 8 bytes (uint64_t)*/
3801 quotas
.softlim
= BVAL(pdata
,24);
3803 /* the hard quotas 8 bytes (uint64_t)*/
3804 quotas
.hardlim
= BVAL(pdata
,32);
3806 /* quota_flags 2 bytes **/
3807 quotas
.qflags
= SVAL(pdata
,40);
3809 /* unknown_2 6 NULL bytes follow*/
3811 /* now set the quotas */
3812 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3813 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3814 reply_nterror(req
, map_nt_error_from_unix(errno
));
3821 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3823 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
3829 * sending this reply works fine,
3830 * but I'm not sure it's the same
3831 * like windows do...
3834 reply_outbuf(req
, 10, 0);
3837 #if defined(HAVE_POSIX_ACLS)
3838 /****************************************************************************
3839 Utility function to count the number of entries in a POSIX acl.
3840 ****************************************************************************/
3842 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
3844 unsigned int ace_count
= 0;
3845 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3846 SMB_ACL_ENTRY_T entry
;
3848 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
3850 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3851 entry_id
= SMB_ACL_NEXT_ENTRY
;
3858 /****************************************************************************
3859 Utility function to marshall a POSIX acl into wire format.
3860 ****************************************************************************/
3862 static bool marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
3864 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3865 SMB_ACL_ENTRY_T entry
;
3867 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
3868 SMB_ACL_TAG_T tagtype
;
3869 SMB_ACL_PERMSET_T permset
;
3870 unsigned char perms
= 0;
3871 unsigned int own_grp
;
3874 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3875 entry_id
= SMB_ACL_NEXT_ENTRY
;
3878 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn
, entry
, &tagtype
) == -1) {
3879 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3883 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn
, entry
, &permset
) == -1) {
3884 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3888 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
3889 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
3890 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
3892 SCVAL(pdata
,1,perms
);
3895 case SMB_ACL_USER_OBJ
:
3896 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
3897 own_grp
= (unsigned int)pst
->st_ex_uid
;
3898 SIVAL(pdata
,2,own_grp
);
3903 uid_t
*puid
= (uid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
3905 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3908 own_grp
= (unsigned int)*puid
;
3909 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)puid
,tagtype
);
3910 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
3911 SIVAL(pdata
,2,own_grp
);
3915 case SMB_ACL_GROUP_OBJ
:
3916 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
3917 own_grp
= (unsigned int)pst
->st_ex_gid
;
3918 SIVAL(pdata
,2,own_grp
);
3923 gid_t
*pgid
= (gid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
3925 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3928 own_grp
= (unsigned int)*pgid
;
3929 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)pgid
,tagtype
);
3930 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
3931 SIVAL(pdata
,2,own_grp
);
3936 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
3937 SIVAL(pdata
,2,0xFFFFFFFF);
3938 SIVAL(pdata
,6,0xFFFFFFFF);
3941 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
3942 SIVAL(pdata
,2,0xFFFFFFFF);
3943 SIVAL(pdata
,6,0xFFFFFFFF);
3946 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
3949 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
3956 /****************************************************************************
3957 Store the FILE_UNIX_BASIC info.
3958 ****************************************************************************/
3960 static char *store_file_unix_basic(connection_struct
*conn
,
3963 const SMB_STRUCT_STAT
*psbuf
)
3965 uint64_t file_index
= get_FileIndex(conn
, psbuf
);
3967 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
3968 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_ex_mode
));
3970 SOFF_T(pdata
,0,get_file_size_stat(psbuf
)); /* File size 64 Bit */
3973 SOFF_T(pdata
,0,SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
3976 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
, psbuf
->st_ex_ctime
); /* Change Time 64 Bit */
3977 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
+8, psbuf
->st_ex_atime
); /* Last access time 64 Bit */
3978 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
+16, psbuf
->st_ex_mtime
); /* Last modification time 64 Bit */
3981 SIVAL(pdata
,0,psbuf
->st_ex_uid
); /* user id for the owner */
3985 SIVAL(pdata
,0,psbuf
->st_ex_gid
); /* group id of owner */
3989 SIVAL(pdata
,0,unix_filetype(psbuf
->st_ex_mode
));
3992 SIVAL(pdata
,0,unix_dev_major(psbuf
->st_ex_rdev
)); /* Major device number if type is device */
3996 SIVAL(pdata
,0,unix_dev_minor(psbuf
->st_ex_rdev
)); /* Minor device number if type is device */
4000 SINO_T_VAL(pdata
,0,(SMB_INO_T
)file_index
); /* inode number */
4003 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_ex_mode
)); /* Standard UNIX file permissions */
4007 SIVAL(pdata
,0,psbuf
->st_ex_nlink
); /* number of hard links */
4014 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4015 * the chflags(2) (or equivalent) flags.
4017 * XXX: this really should be behind the VFS interface. To do this, we would
4018 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4019 * Each VFS module could then implement its own mapping as appropriate for the
4020 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4022 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
4026 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
4030 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
4034 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
4038 { UF_HIDDEN
, EXT_HIDDEN
},
4041 /* Do not remove. We need to guarantee that this array has at least one
4042 * entry to build on HP-UX.
4048 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4049 uint32
*smb_fflags
, uint32
*smb_fmask
)
4053 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4054 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
4055 if (psbuf
->st_ex_flags
& info2_flags_map
[i
].stat_fflag
) {
4056 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
4061 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4062 const uint32 smb_fflags
,
4063 const uint32 smb_fmask
,
4066 uint32 max_fmask
= 0;
4069 *stat_fflags
= psbuf
->st_ex_flags
;
4071 /* For each flags requested in smb_fmask, check the state of the
4072 * corresponding flag in smb_fflags and set or clear the matching
4076 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4077 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
4078 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
4079 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
4080 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
4082 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
4087 /* If smb_fmask is asking to set any bits that are not supported by
4088 * our flag mappings, we should fail.
4090 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
4098 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4099 * of file flags and birth (create) time.
4101 static char *store_file_unix_basic_info2(connection_struct
*conn
,
4104 const SMB_STRUCT_STAT
*psbuf
)
4106 uint32 file_flags
= 0;
4107 uint32 flags_mask
= 0;
4109 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4111 /* Create (birth) time 64 bit */
4112 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
, psbuf
->st_ex_btime
);
4115 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
4116 SIVAL(pdata
, 0, file_flags
); /* flags */
4117 SIVAL(pdata
, 4, flags_mask
); /* mask */
4123 static NTSTATUS
marshall_stream_info(unsigned int num_streams
,
4124 const struct stream_struct
*streams
,
4126 unsigned int max_data_bytes
,
4127 unsigned int *data_size
)
4130 unsigned int ofs
= 0;
4132 for (i
= 0; i
< num_streams
; i
++) {
4133 unsigned int next_offset
;
4135 smb_ucs2_t
*namebuf
;
4137 if (!push_ucs2_talloc(talloc_tos(), &namebuf
,
4138 streams
[i
].name
, &namelen
) ||
4141 return NT_STATUS_INVALID_PARAMETER
;
4145 * name_buf is now null-terminated, we need to marshall as not
4152 * We cannot overflow ...
4154 if ((ofs
+ 24 + namelen
) > max_data_bytes
) {
4155 DEBUG(10, ("refusing to overflow reply at stream %u\n",
4157 TALLOC_FREE(namebuf
);
4158 return STATUS_BUFFER_OVERFLOW
;
4161 SIVAL(data
, ofs
+4, namelen
);
4162 SOFF_T(data
, ofs
+8, streams
[i
].size
);
4163 SOFF_T(data
, ofs
+16, streams
[i
].alloc_size
);
4164 memcpy(data
+ofs
+24, namebuf
, namelen
);
4165 TALLOC_FREE(namebuf
);
4167 next_offset
= ofs
+ 24 + namelen
;
4169 if (i
== num_streams
-1) {
4170 SIVAL(data
, ofs
, 0);
4173 unsigned int align
= ndr_align_size(next_offset
, 8);
4175 if ((next_offset
+ align
) > max_data_bytes
) {
4176 DEBUG(10, ("refusing to overflow align "
4177 "reply at stream %u\n",
4179 TALLOC_FREE(namebuf
);
4180 return STATUS_BUFFER_OVERFLOW
;
4183 memset(data
+next_offset
, 0, align
);
4184 next_offset
+= align
;
4186 SIVAL(data
, ofs
, next_offset
- ofs
);
4193 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes
, ofs
));
4197 return NT_STATUS_OK
;
4200 /****************************************************************************
4201 Reply to a TRANSACT2_QFILEINFO on a PIPE !
4202 ****************************************************************************/
4204 static void call_trans2qpipeinfo(connection_struct
*conn
,
4205 struct smb_request
*req
,
4206 unsigned int tran_call
,
4207 char **pparams
, int total_params
,
4208 char **ppdata
, int total_data
,
4209 unsigned int max_data_bytes
)
4211 char *params
= *pparams
;
4212 char *pdata
= *ppdata
;
4213 unsigned int data_size
= 0;
4214 unsigned int param_size
= 2;
4219 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4223 if (total_params
< 4) {
4224 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4228 fsp
= file_fsp(req
, SVAL(params
,0));
4229 if (!fsp_is_np(fsp
)) {
4230 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
4234 info_level
= SVAL(params
,2);
4236 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
4237 if (*pparams
== NULL
) {
4238 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4243 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4244 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4245 if (*ppdata
== NULL
) {
4246 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4251 switch (info_level
) {
4252 case SMB_FILE_STANDARD_INFORMATION
:
4254 SOFF_T(pdata
,0,4096LL);
4261 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
4265 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
4271 NTSTATUS
smbd_do_qfilepathinfo(connection_struct
*conn
,
4272 TALLOC_CTX
*mem_ctx
,
4273 uint16_t info_level
,
4275 struct smb_filename
*smb_fname
,
4276 bool delete_pending
,
4277 struct timespec write_time_ts
,
4278 struct ea_list
*ea_list
,
4279 int lock_data_count
,
4282 unsigned int max_data_bytes
,
4284 unsigned int *pdata_size
)
4286 char *pdata
= *ppdata
;
4287 char *dstart
, *dend
;
4288 unsigned int data_size
;
4289 struct timespec create_time_ts
, mtime_ts
, atime_ts
, ctime_ts
;
4290 time_t create_time
, mtime
, atime
, c_time
;
4291 SMB_STRUCT_STAT
*psbuf
= &smb_fname
->st
;
4298 uint64_t file_size
= 0;
4300 uint64_t allocation_size
= 0;
4301 uint64_t file_index
= 0;
4302 uint32_t access_mask
= 0;
4304 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
4305 return NT_STATUS_INVALID_LEVEL
;
4308 DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
4309 smb_fname_str_dbg(smb_fname
), fsp
? fsp
->fnum
: -1,
4310 info_level
, max_data_bytes
));
4312 mode
= dos_mode(conn
, smb_fname
);
4313 nlink
= psbuf
->st_ex_nlink
;
4315 if (nlink
&& (mode
&FILE_ATTRIBUTE_DIRECTORY
)) {
4319 if ((nlink
> 0) && delete_pending
) {
4323 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4324 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4325 if (*ppdata
== NULL
) {
4326 return NT_STATUS_NO_MEMORY
;
4330 dend
= dstart
+ data_size
- 1;
4332 if (!null_timespec(write_time_ts
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
4333 update_stat_ex_mtime(psbuf
, write_time_ts
);
4336 create_time_ts
= get_create_timespec(conn
, fsp
, smb_fname
);
4337 mtime_ts
= psbuf
->st_ex_mtime
;
4338 atime_ts
= psbuf
->st_ex_atime
;
4339 ctime_ts
= get_change_timespec(conn
, fsp
, smb_fname
);
4341 if (lp_dos_filetime_resolution(SNUM(conn
))) {
4342 dos_filetime_timespec(&create_time_ts
);
4343 dos_filetime_timespec(&mtime_ts
);
4344 dos_filetime_timespec(&atime_ts
);
4345 dos_filetime_timespec(&ctime_ts
);
4348 create_time
= convert_timespec_to_time_t(create_time_ts
);
4349 mtime
= convert_timespec_to_time_t(mtime_ts
);
4350 atime
= convert_timespec_to_time_t(atime_ts
);
4351 c_time
= convert_timespec_to_time_t(ctime_ts
);
4353 p
= strrchr_m(smb_fname
->base_name
,'/');
4355 base_name
= smb_fname
->base_name
;
4359 /* NT expects the name to be in an exact form of the *full*
4360 filename. See the trans2 torture test */
4361 if (ISDOT(base_name
)) {
4362 dos_fname
= talloc_strdup(mem_ctx
, "\\");
4364 return NT_STATUS_NO_MEMORY
;
4367 dos_fname
= talloc_asprintf(mem_ctx
,
4369 smb_fname
->base_name
);
4371 return NT_STATUS_NO_MEMORY
;
4373 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4374 dos_fname
= talloc_asprintf(dos_fname
, "%s",
4375 smb_fname
->stream_name
);
4377 return NT_STATUS_NO_MEMORY
;
4381 string_replace(dos_fname
, '/', '\\');
4384 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, psbuf
);
4387 /* Do we have this path open ? */
4389 struct file_id fileid
= vfs_file_id_from_sbuf(conn
, psbuf
);
4390 fsp1
= file_find_di_first(conn
->sconn
, fileid
);
4391 if (fsp1
&& fsp1
->initial_allocation_size
) {
4392 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp1
, psbuf
);
4396 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
4397 file_size
= get_file_size_stat(psbuf
);
4401 pos
= fsp
->fh
->position_information
;
4405 access_mask
= fsp
->access_mask
;
4407 /* GENERIC_EXECUTE mapping from Windows */
4408 access_mask
= 0x12019F;
4411 /* This should be an index number - looks like
4414 I think this causes us to fail the IFSKIT
4415 BasicFileInformationTest. -tpot */
4416 file_index
= get_FileIndex(conn
, psbuf
);
4418 switch (info_level
) {
4419 case SMB_INFO_STANDARD
:
4420 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4422 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
4423 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
4424 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
4425 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
4426 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
4427 SSVAL(pdata
,l1_attrFile
,mode
);
4430 case SMB_INFO_QUERY_EA_SIZE
:
4432 unsigned int ea_size
=
4433 estimate_ea_size(conn
, fsp
,
4434 smb_fname
->base_name
);
4435 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4437 srv_put_dos_date2(pdata
,0,create_time
);
4438 srv_put_dos_date2(pdata
,4,atime
);
4439 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
4440 SIVAL(pdata
,12,(uint32
)file_size
);
4441 SIVAL(pdata
,16,(uint32
)allocation_size
);
4442 SSVAL(pdata
,20,mode
);
4443 SIVAL(pdata
,22,ea_size
);
4447 case SMB_INFO_IS_NAME_VALID
:
4448 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4450 /* os/2 needs this ? really ?*/
4451 return NT_STATUS_DOS(ERRDOS
, ERRbadfunc
);
4453 /* This is only reached for qpathinfo */
4457 case SMB_INFO_QUERY_EAS_FROM_LIST
:
4459 size_t total_ea_len
= 0;
4460 struct ea_list
*ea_file_list
= NULL
;
4462 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4465 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4466 smb_fname
->base_name
,
4468 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
4470 if (!ea_list
|| (total_ea_len
> data_size
)) {
4472 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4476 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4480 case SMB_INFO_QUERY_ALL_EAS
:
4482 /* We have data_size bytes to put EA's into. */
4483 size_t total_ea_len
= 0;
4485 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4487 ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4488 smb_fname
->base_name
,
4490 if (!ea_list
|| (total_ea_len
> data_size
)) {
4492 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4496 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4500 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4502 /* This is FileFullEaInformation - 0xF which maps to
4503 * 1015 (decimal) in smbd_do_setfilepathinfo. */
4505 /* We have data_size bytes to put EA's into. */
4506 size_t total_ea_len
= 0;
4507 struct ea_list
*ea_file_list
= NULL
;
4509 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4511 /*TODO: add filtering and index handling */
4514 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4515 smb_fname
->base_name
,
4517 if (!ea_file_list
) {
4518 return NT_STATUS_NO_EAS_ON_FILE
;
4521 status
= fill_ea_chained_buffer(mem_ctx
,
4525 conn
, ea_file_list
);
4526 if (!NT_STATUS_IS_OK(status
)) {
4532 case SMB_FILE_BASIC_INFORMATION
:
4533 case SMB_QUERY_FILE_BASIC_INFO
:
4535 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
4536 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4537 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
4539 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4543 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4544 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4545 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4546 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4547 SIVAL(pdata
,32,mode
);
4549 DEBUG(5,("SMB_QFBI - "));
4550 DEBUG(5,("create: %s ", ctime(&create_time
)));
4551 DEBUG(5,("access: %s ", ctime(&atime
)));
4552 DEBUG(5,("write: %s ", ctime(&mtime
)));
4553 DEBUG(5,("change: %s ", ctime(&c_time
)));
4554 DEBUG(5,("mode: %x\n", mode
));
4557 case SMB_FILE_STANDARD_INFORMATION
:
4558 case SMB_QUERY_FILE_STANDARD_INFO
:
4560 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4562 SOFF_T(pdata
,0,allocation_size
);
4563 SOFF_T(pdata
,8,file_size
);
4564 SIVAL(pdata
,16,nlink
);
4565 SCVAL(pdata
,20,delete_pending
?1:0);
4566 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4567 SSVAL(pdata
,22,0); /* Padding. */
4570 case SMB_FILE_EA_INFORMATION
:
4571 case SMB_QUERY_FILE_EA_INFO
:
4573 unsigned int ea_size
=
4574 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4575 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4577 SIVAL(pdata
,0,ea_size
);
4581 /* Get the 8.3 name - used if NT SMB was negotiated. */
4582 case SMB_QUERY_FILE_ALT_NAME_INFO
:
4583 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
4586 char mangled_name
[13];
4587 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4588 if (!name_to_8_3(base_name
,mangled_name
,
4589 True
,conn
->params
)) {
4590 return NT_STATUS_NO_MEMORY
;
4592 len
= srvstr_push(dstart
, flags2
,
4593 pdata
+4, mangled_name
,
4594 PTR_DIFF(dend
, pdata
+4),
4596 data_size
= 4 + len
;
4601 case SMB_QUERY_FILE_NAME_INFO
:
4605 this must be *exactly* right for ACLs on mapped drives to work
4607 len
= srvstr_push(dstart
, flags2
,
4609 PTR_DIFF(dend
, pdata
+4),
4611 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4612 data_size
= 4 + len
;
4617 case SMB_FILE_ALLOCATION_INFORMATION
:
4618 case SMB_QUERY_FILE_ALLOCATION_INFO
:
4619 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4621 SOFF_T(pdata
,0,allocation_size
);
4624 case SMB_FILE_END_OF_FILE_INFORMATION
:
4625 case SMB_QUERY_FILE_END_OF_FILEINFO
:
4626 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4628 SOFF_T(pdata
,0,file_size
);
4631 case SMB_QUERY_FILE_ALL_INFO
:
4632 case SMB_FILE_ALL_INFORMATION
:
4635 unsigned int ea_size
=
4636 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4637 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4638 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4639 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4640 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4641 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4642 SIVAL(pdata
,32,mode
);
4643 SIVAL(pdata
,36,0); /* padding. */
4645 SOFF_T(pdata
,0,allocation_size
);
4646 SOFF_T(pdata
,8,file_size
);
4647 SIVAL(pdata
,16,nlink
);
4648 SCVAL(pdata
,20,delete_pending
);
4649 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4652 SIVAL(pdata
,0,ea_size
);
4653 pdata
+= 4; /* EA info */
4654 len
= srvstr_push(dstart
, flags2
,
4656 PTR_DIFF(dend
, pdata
+4),
4660 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4664 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4667 unsigned int ea_size
=
4668 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4669 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4670 put_long_date_timespec(conn
->ts_res
,pdata
+0x00,create_time_ts
);
4671 put_long_date_timespec(conn
->ts_res
,pdata
+0x08,atime_ts
);
4672 put_long_date_timespec(conn
->ts_res
,pdata
+0x10,mtime_ts
); /* write time */
4673 put_long_date_timespec(conn
->ts_res
,pdata
+0x18,ctime_ts
); /* change time */
4674 SIVAL(pdata
, 0x20, mode
);
4675 SIVAL(pdata
, 0x24, 0); /* padding. */
4676 SBVAL(pdata
, 0x28, allocation_size
);
4677 SBVAL(pdata
, 0x30, file_size
);
4678 SIVAL(pdata
, 0x38, nlink
);
4679 SCVAL(pdata
, 0x3C, delete_pending
);
4680 SCVAL(pdata
, 0x3D, (mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4681 SSVAL(pdata
, 0x3E, 0); /* padding */
4682 SBVAL(pdata
, 0x40, file_index
);
4683 SIVAL(pdata
, 0x48, ea_size
);
4684 SIVAL(pdata
, 0x4C, access_mask
);
4685 SBVAL(pdata
, 0x50, pos
);
4686 SIVAL(pdata
, 0x58, mode
); /*TODO: mode != mode fix this!!! */
4687 SIVAL(pdata
, 0x5C, 0); /* No alignment needed. */
4691 len
= srvstr_push(dstart
, flags2
,
4693 PTR_DIFF(dend
, pdata
+4),
4697 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4700 case SMB_FILE_INTERNAL_INFORMATION
:
4702 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4703 SBVAL(pdata
, 0, file_index
);
4707 case SMB_FILE_ACCESS_INFORMATION
:
4708 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4709 SIVAL(pdata
, 0, access_mask
);
4713 case SMB_FILE_NAME_INFORMATION
:
4714 /* Pathname with leading '\'. */
4717 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
4718 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4719 SIVAL(pdata
,0,byte_len
);
4720 data_size
= 4 + byte_len
;
4724 case SMB_FILE_DISPOSITION_INFORMATION
:
4725 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4727 SCVAL(pdata
,0,delete_pending
);
4730 case SMB_FILE_POSITION_INFORMATION
:
4731 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4733 SOFF_T(pdata
,0,pos
);
4736 case SMB_FILE_MODE_INFORMATION
:
4737 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4738 SIVAL(pdata
,0,mode
);
4742 case SMB_FILE_ALIGNMENT_INFORMATION
:
4743 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4744 SIVAL(pdata
,0,0); /* No alignment needed. */
4749 * NT4 server just returns "invalid query" to this - if we try
4750 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4753 /* The first statement above is false - verified using Thursby
4754 * client against NT4 -- gcolley.
4756 case SMB_QUERY_FILE_STREAM_INFO
:
4757 case SMB_FILE_STREAM_INFORMATION
: {
4758 unsigned int num_streams
= 0;
4759 struct stream_struct
*streams
= NULL
;
4761 DEBUG(10,("smbd_do_qfilepathinfo: "
4762 "SMB_FILE_STREAM_INFORMATION\n"));
4764 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4765 return NT_STATUS_INVALID_PARAMETER
;
4768 status
= vfs_streaminfo(conn
, fsp
, smb_fname
->base_name
,
4769 talloc_tos(), &num_streams
, &streams
);
4771 if (!NT_STATUS_IS_OK(status
)) {
4772 DEBUG(10, ("could not get stream info: %s\n",
4773 nt_errstr(status
)));
4777 status
= marshall_stream_info(num_streams
, streams
,
4778 pdata
, max_data_bytes
,
4781 if (!NT_STATUS_IS_OK(status
)) {
4782 DEBUG(10, ("marshall_stream_info failed: %s\n",
4783 nt_errstr(status
)));
4784 TALLOC_FREE(streams
);
4788 TALLOC_FREE(streams
);
4792 case SMB_QUERY_COMPRESSION_INFO
:
4793 case SMB_FILE_COMPRESSION_INFORMATION
:
4794 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4795 SOFF_T(pdata
,0,file_size
);
4796 SIVAL(pdata
,8,0); /* ??? */
4797 SIVAL(pdata
,12,0); /* ??? */
4801 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
4802 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4803 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4804 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4805 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4806 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4807 SOFF_T(pdata
,32,allocation_size
);
4808 SOFF_T(pdata
,40,file_size
);
4809 SIVAL(pdata
,48,mode
);
4810 SIVAL(pdata
,52,0); /* ??? */
4814 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
4815 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4816 SIVAL(pdata
,0,mode
);
4822 * CIFS UNIX Extensions.
4825 case SMB_QUERY_FILE_UNIX_BASIC
:
4827 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4828 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4830 DEBUG(4,("smbd_do_qfilepathinfo: "
4831 "SMB_QUERY_FILE_UNIX_BASIC\n"));
4832 dump_data(4, (uint8_t *)(*ppdata
), data_size
);
4836 case SMB_QUERY_FILE_UNIX_INFO2
:
4838 pdata
= store_file_unix_basic_info2(conn
, pdata
, fsp
, psbuf
);
4839 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4843 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4845 for (i
=0; i
<100; i
++)
4846 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
4852 case SMB_QUERY_FILE_UNIX_LINK
:
4855 char *buffer
= TALLOC_ARRAY(mem_ctx
, char, PATH_MAX
+1);
4858 return NT_STATUS_NO_MEMORY
;
4861 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4863 if(!S_ISLNK(psbuf
->st_ex_mode
)) {
4864 return NT_STATUS_DOS(ERRSRV
, ERRbadlink
);
4867 return NT_STATUS_DOS(ERRDOS
, ERRbadlink
);
4869 len
= SMB_VFS_READLINK(conn
,
4870 smb_fname
->base_name
,
4873 return map_nt_error_from_unix(errno
);
4876 len
= srvstr_push(dstart
, flags2
,
4878 PTR_DIFF(dend
, pdata
),
4881 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4886 #if defined(HAVE_POSIX_ACLS)
4887 case SMB_QUERY_POSIX_ACL
:
4889 SMB_ACL_T file_acl
= NULL
;
4890 SMB_ACL_T def_acl
= NULL
;
4891 uint16 num_file_acls
= 0;
4892 uint16 num_def_acls
= 0;
4894 if (fsp
&& fsp
->fh
->fd
!= -1) {
4895 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
);
4898 SMB_VFS_SYS_ACL_GET_FILE(conn
,
4899 smb_fname
->base_name
,
4900 SMB_ACL_TYPE_ACCESS
);
4903 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
4904 DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4905 "not implemented on "
4906 "filesystem containing %s\n",
4907 smb_fname
->base_name
));
4908 return NT_STATUS_NOT_IMPLEMENTED
;
4911 if (S_ISDIR(psbuf
->st_ex_mode
)) {
4912 if (fsp
&& fsp
->is_directory
) {
4914 SMB_VFS_SYS_ACL_GET_FILE(
4916 fsp
->fsp_name
->base_name
,
4917 SMB_ACL_TYPE_DEFAULT
);
4920 SMB_VFS_SYS_ACL_GET_FILE(
4922 smb_fname
->base_name
,
4923 SMB_ACL_TYPE_DEFAULT
);
4925 def_acl
= free_empty_sys_acl(conn
, def_acl
);
4928 num_file_acls
= count_acl_entries(conn
, file_acl
);
4929 num_def_acls
= count_acl_entries(conn
, def_acl
);
4931 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
4932 DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
4934 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
4935 SMB_POSIX_ACL_HEADER_SIZE
) ));
4937 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4940 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4942 return NT_STATUS_BUFFER_TOO_SMALL
;
4945 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
4946 SSVAL(pdata
,2,num_file_acls
);
4947 SSVAL(pdata
,4,num_def_acls
);
4948 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, psbuf
, file_acl
)) {
4950 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4953 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4955 return NT_STATUS_INTERNAL_ERROR
;
4957 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), psbuf
, def_acl
)) {
4959 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4962 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4964 return NT_STATUS_INTERNAL_ERROR
;
4968 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4971 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4973 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
4979 case SMB_QUERY_POSIX_LOCK
:
4984 enum brl_type lock_type
;
4986 /* We need an open file with a real fd for this. */
4987 if (!fsp
|| fsp
->fh
->fd
== -1) {
4988 return NT_STATUS_INVALID_LEVEL
;
4991 if (lock_data_count
!= POSIX_LOCK_DATA_SIZE
) {
4992 return NT_STATUS_INVALID_PARAMETER
;
4995 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
4996 case POSIX_LOCK_TYPE_READ
:
4997 lock_type
= READ_LOCK
;
4999 case POSIX_LOCK_TYPE_WRITE
:
5000 lock_type
= WRITE_LOCK
;
5002 case POSIX_LOCK_TYPE_UNLOCK
:
5004 /* There's no point in asking for an unlock... */
5005 return NT_STATUS_INVALID_PARAMETER
;
5008 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
5009 #if defined(HAVE_LONGLONG)
5010 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
5011 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
5012 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
5013 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
5014 #else /* HAVE_LONGLONG */
5015 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
5016 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
5017 #endif /* HAVE_LONGLONG */
5019 status
= query_lock(fsp
,
5026 if (ERROR_WAS_LOCK_DENIED(status
)) {
5027 /* Here we need to report who has it locked... */
5028 data_size
= POSIX_LOCK_DATA_SIZE
;
5030 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, lock_type
);
5031 SSVAL(pdata
, POSIX_LOCK_FLAGS_OFFSET
, 0);
5032 SIVAL(pdata
, POSIX_LOCK_PID_OFFSET
, (uint32_t)smblctx
);
5033 #if defined(HAVE_LONGLONG)
5034 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, (uint32
)(offset
& 0xFFFFFFFF));
5035 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
+ 4, (uint32
)((offset
>> 32) & 0xFFFFFFFF));
5036 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, (uint32
)(count
& 0xFFFFFFFF));
5037 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
+ 4, (uint32
)((count
>> 32) & 0xFFFFFFFF));
5038 #else /* HAVE_LONGLONG */
5039 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, offset
);
5040 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, count
);
5041 #endif /* HAVE_LONGLONG */
5043 } else if (NT_STATUS_IS_OK(status
)) {
5044 /* For success we just return a copy of what we sent
5045 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5046 data_size
= POSIX_LOCK_DATA_SIZE
;
5047 memcpy(pdata
, lock_data
, POSIX_LOCK_DATA_SIZE
);
5048 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
5056 return NT_STATUS_INVALID_LEVEL
;
5059 *pdata_size
= data_size
;
5060 return NT_STATUS_OK
;
5063 /****************************************************************************
5064 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5065 file name or file id).
5066 ****************************************************************************/
5068 static void call_trans2qfilepathinfo(connection_struct
*conn
,
5069 struct smb_request
*req
,
5070 unsigned int tran_call
,
5071 char **pparams
, int total_params
,
5072 char **ppdata
, int total_data
,
5073 unsigned int max_data_bytes
)
5075 char *params
= *pparams
;
5076 char *pdata
= *ppdata
;
5078 unsigned int data_size
= 0;
5079 unsigned int param_size
= 2;
5080 struct smb_filename
*smb_fname
= NULL
;
5081 bool delete_pending
= False
;
5082 struct timespec write_time_ts
;
5083 files_struct
*fsp
= NULL
;
5084 struct file_id fileid
;
5085 struct ea_list
*ea_list
= NULL
;
5086 int lock_data_count
= 0;
5087 char *lock_data
= NULL
;
5088 NTSTATUS status
= NT_STATUS_OK
;
5091 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5095 ZERO_STRUCT(write_time_ts
);
5097 if (tran_call
== TRANSACT2_QFILEINFO
) {
5098 if (total_params
< 4) {
5099 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5104 call_trans2qpipeinfo(conn
, req
, tran_call
,
5105 pparams
, total_params
,
5111 fsp
= file_fsp(req
, SVAL(params
,0));
5112 info_level
= SVAL(params
,2);
5114 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
5116 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
5117 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5121 /* Initial check for valid fsp ptr. */
5122 if (!check_fsp_open(conn
, req
, fsp
)) {
5126 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
5128 if (!NT_STATUS_IS_OK(status
)) {
5129 reply_nterror(req
, status
);
5133 if(fsp
->fake_file_handle
) {
5135 * This is actually for the QUOTA_FAKE_FILE --metze
5138 /* We know this name is ok, it's already passed the checks. */
5140 } else if(fsp
->fh
->fd
== -1) {
5142 * This is actually a QFILEINFO on a directory
5143 * handle (returned from an NT SMB). NT5.0 seems
5144 * to do this call. JRA.
5147 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5148 /* Always do lstat for UNIX calls. */
5149 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5150 DEBUG(3,("call_trans2qfilepathinfo: "
5151 "SMB_VFS_LSTAT of %s failed "
5153 smb_fname_str_dbg(smb_fname
),
5156 map_nt_error_from_unix(errno
));
5159 } else if (SMB_VFS_STAT(conn
, smb_fname
)) {
5160 DEBUG(3,("call_trans2qfilepathinfo: "
5161 "SMB_VFS_STAT of %s failed (%s)\n",
5162 smb_fname_str_dbg(smb_fname
),
5165 map_nt_error_from_unix(errno
));
5169 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5170 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5173 * Original code - this is an open file.
5175 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
5176 DEBUG(3, ("fstat of fnum %d failed (%s)\n",
5177 fsp
->fnum
, strerror(errno
)));
5179 map_nt_error_from_unix(errno
));
5182 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5183 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5189 uint32_t ucf_flags
= 0;
5192 if (total_params
< 7) {
5193 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5197 info_level
= SVAL(params
,0);
5199 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
5201 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5202 if (!lp_unix_extensions()) {
5203 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5206 if (info_level
== SMB_QUERY_FILE_UNIX_BASIC
||
5207 info_level
== SMB_QUERY_FILE_UNIX_INFO2
||
5208 info_level
== SMB_QUERY_FILE_UNIX_LINK
) {
5209 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
5213 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
5215 STR_TERMINATE
, &status
);
5216 if (!NT_STATUS_IS_OK(status
)) {
5217 reply_nterror(req
, status
);
5221 status
= filename_convert(req
,
5223 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5228 if (!NT_STATUS_IS_OK(status
)) {
5229 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5230 reply_botherror(req
,
5231 NT_STATUS_PATH_NOT_COVERED
,
5232 ERRSRV
, ERRbadpath
);
5235 reply_nterror(req
, status
);
5239 /* If this is a stream, check if there is a delete_pending. */
5240 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5241 && is_ntfs_stream_smb_fname(smb_fname
)) {
5242 struct smb_filename
*smb_fname_base
= NULL
;
5244 /* Create an smb_filename with stream_name == NULL. */
5246 create_synthetic_smb_fname(talloc_tos(),
5247 smb_fname
->base_name
,
5250 if (!NT_STATUS_IS_OK(status
)) {
5251 reply_nterror(req
, status
);
5255 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5256 /* Always do lstat for UNIX calls. */
5257 if (SMB_VFS_LSTAT(conn
, smb_fname_base
) != 0) {
5258 DEBUG(3,("call_trans2qfilepathinfo: "
5259 "SMB_VFS_LSTAT of %s failed "
5261 smb_fname_str_dbg(smb_fname_base
),
5263 TALLOC_FREE(smb_fname_base
);
5265 map_nt_error_from_unix(errno
));
5269 if (SMB_VFS_STAT(conn
, smb_fname_base
) != 0) {
5270 DEBUG(3,("call_trans2qfilepathinfo: "
5271 "fileinfo of %s failed "
5273 smb_fname_str_dbg(smb_fname_base
),
5275 TALLOC_FREE(smb_fname_base
);
5277 map_nt_error_from_unix(errno
));
5282 status
= file_name_hash(conn
,
5283 smb_fname_str_dbg(smb_fname_base
),
5285 if (!NT_STATUS_IS_OK(status
)) {
5286 TALLOC_FREE(smb_fname_base
);
5287 reply_nterror(req
, status
);
5291 fileid
= vfs_file_id_from_sbuf(conn
,
5292 &smb_fname_base
->st
);
5293 TALLOC_FREE(smb_fname_base
);
5294 get_file_infos(fileid
, name_hash
, &delete_pending
, NULL
);
5295 if (delete_pending
) {
5296 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5301 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5302 /* Always do lstat for UNIX calls. */
5303 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5304 DEBUG(3,("call_trans2qfilepathinfo: "
5305 "SMB_VFS_LSTAT of %s failed (%s)\n",
5306 smb_fname_str_dbg(smb_fname
),
5309 map_nt_error_from_unix(errno
));
5314 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
5315 DEBUG(3,("call_trans2qfilepathinfo: "
5316 "SMB_VFS_STAT of %s failed (%s)\n",
5317 smb_fname_str_dbg(smb_fname
),
5320 map_nt_error_from_unix(errno
));
5325 status
= file_name_hash(conn
,
5326 smb_fname_str_dbg(smb_fname
),
5328 if (!NT_STATUS_IS_OK(status
)) {
5329 reply_nterror(req
, status
);
5333 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5334 get_file_infos(fileid
, name_hash
, &delete_pending
, &write_time_ts
);
5335 if (delete_pending
) {
5336 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5341 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
5342 "total_data=%d\n", smb_fname_str_dbg(smb_fname
),
5343 fsp
? fsp
->fnum
: -1, info_level
,tran_call
,total_data
));
5345 /* Pull out any data sent here before we realloc. */
5346 switch (info_level
) {
5347 case SMB_INFO_QUERY_EAS_FROM_LIST
:
5349 /* Pull any EA list from the data portion. */
5352 if (total_data
< 4) {
5354 req
, NT_STATUS_INVALID_PARAMETER
);
5357 ea_size
= IVAL(pdata
,0);
5359 if (total_data
> 0 && ea_size
!= total_data
) {
5360 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5361 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
5363 req
, NT_STATUS_INVALID_PARAMETER
);
5367 if (!lp_ea_support(SNUM(conn
))) {
5368 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
5372 /* Pull out the list of names. */
5373 ea_list
= read_ea_name_list(req
, pdata
+ 4, ea_size
- 4);
5376 req
, NT_STATUS_INVALID_PARAMETER
);
5382 case SMB_QUERY_POSIX_LOCK
:
5384 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
5385 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
5389 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
5391 req
, NT_STATUS_INVALID_PARAMETER
);
5395 /* Copy the lock range data. */
5396 lock_data
= (char *)TALLOC_MEMDUP(
5397 req
, pdata
, total_data
);
5399 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5402 lock_data_count
= total_data
;
5408 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
5409 if (*pparams
== NULL
) {
5410 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5417 * draft-leach-cifs-v1-spec-02.txt
5418 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5421 * The requested information is placed in the Data portion of the
5422 * transaction response. For the information levels greater than 0x100,
5423 * the transaction response has 1 parameter word which should be
5424 * ignored by the client.
5426 * However Windows only follows this rule for the IS_NAME_VALID call.
5428 switch (info_level
) {
5429 case SMB_INFO_IS_NAME_VALID
:
5434 if ((info_level
& 0xFF00) == 0xFF00) {
5436 * We use levels that start with 0xFF00
5437 * internally to represent SMB2 specific levels
5439 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5443 status
= smbd_do_qfilepathinfo(conn
, req
, info_level
,
5445 delete_pending
, write_time_ts
,
5447 lock_data_count
, lock_data
,
5448 req
->flags2
, max_data_bytes
,
5449 ppdata
, &data_size
);
5450 if (!NT_STATUS_IS_OK(status
)) {
5451 reply_nterror(req
, status
);
5455 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
5461 /****************************************************************************
5462 Set a hard link (called by UNIX extensions and by NT rename with HARD link
5464 ****************************************************************************/
5466 NTSTATUS
hardlink_internals(TALLOC_CTX
*ctx
,
5467 connection_struct
*conn
,
5468 struct smb_request
*req
,
5469 bool overwrite_if_exists
,
5470 const struct smb_filename
*smb_fname_old
,
5471 struct smb_filename
*smb_fname_new
)
5473 NTSTATUS status
= NT_STATUS_OK
;
5475 /* source must already exist. */
5476 if (!VALID_STAT(smb_fname_old
->st
)) {
5477 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5480 if (VALID_STAT(smb_fname_new
->st
)) {
5481 if (overwrite_if_exists
) {
5482 if (S_ISDIR(smb_fname_new
->st
.st_ex_mode
)) {
5483 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5485 status
= unlink_internals(conn
,
5487 FILE_ATTRIBUTE_NORMAL
,
5490 if (!NT_STATUS_IS_OK(status
)) {
5494 /* Disallow if newname already exists. */
5495 return NT_STATUS_OBJECT_NAME_COLLISION
;
5499 /* No links from a directory. */
5500 if (S_ISDIR(smb_fname_old
->st
.st_ex_mode
)) {
5501 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5504 /* Setting a hardlink to/from a stream isn't currently supported. */
5505 if (is_ntfs_stream_smb_fname(smb_fname_old
) ||
5506 is_ntfs_stream_smb_fname(smb_fname_new
)) {
5507 return NT_STATUS_INVALID_PARAMETER
;
5510 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5511 smb_fname_old
->base_name
, smb_fname_new
->base_name
));
5513 if (SMB_VFS_LINK(conn
, smb_fname_old
->base_name
,
5514 smb_fname_new
->base_name
) != 0) {
5515 status
= map_nt_error_from_unix(errno
);
5516 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5517 nt_errstr(status
), smb_fname_old
->base_name
,
5518 smb_fname_new
->base_name
));
5523 /****************************************************************************
5524 Deal with setting the time from any of the setfilepathinfo functions.
5525 ****************************************************************************/
5527 NTSTATUS
smb_set_file_time(connection_struct
*conn
,
5529 const struct smb_filename
*smb_fname
,
5530 struct smb_file_time
*ft
,
5531 bool setting_write_time
)
5533 struct smb_filename smb_fname_base
;
5535 FILE_NOTIFY_CHANGE_LAST_ACCESS
5536 |FILE_NOTIFY_CHANGE_LAST_WRITE
5537 |FILE_NOTIFY_CHANGE_CREATION
;
5539 if (!VALID_STAT(smb_fname
->st
)) {
5540 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5543 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
5544 return NT_STATUS_ACCESS_DENIED
;
5547 /* get some defaults (no modifications) if any info is zero or -1. */
5548 if (null_timespec(ft
->create_time
)) {
5549 action
&= ~FILE_NOTIFY_CHANGE_CREATION
;
5552 if (null_timespec(ft
->atime
)) {
5553 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
5556 if (null_timespec(ft
->mtime
)) {
5557 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5560 if (!setting_write_time
) {
5561 /* ft->mtime comes from change time, not write time. */
5562 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5565 /* Ensure the resolution is the correct for
5566 * what we can store on this filesystem. */
5568 round_timespec(conn
->ts_res
, &ft
->create_time
);
5569 round_timespec(conn
->ts_res
, &ft
->ctime
);
5570 round_timespec(conn
->ts_res
, &ft
->atime
);
5571 round_timespec(conn
->ts_res
, &ft
->mtime
);
5573 DEBUG(5,("smb_set_filetime: actime: %s\n ",
5574 time_to_asc(convert_timespec_to_time_t(ft
->atime
))));
5575 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5576 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5577 DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5578 time_to_asc(convert_timespec_to_time_t(ft
->ctime
))));
5579 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5580 time_to_asc(convert_timespec_to_time_t(ft
->create_time
))));
5582 if (setting_write_time
) {
5584 * This was a Windows setfileinfo on an open file.
5585 * NT does this a lot. We also need to
5586 * set the time here, as it can be read by
5587 * FindFirst/FindNext and with the patch for bug #2045
5588 * in smbd/fileio.c it ensures that this timestamp is
5589 * kept sticky even after a write. We save the request
5590 * away and will set it on file close and after a write. JRA.
5593 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5594 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5597 if (fsp
->base_fsp
) {
5598 set_sticky_write_time_fsp(fsp
->base_fsp
,
5601 set_sticky_write_time_fsp(fsp
, ft
->mtime
);
5604 set_sticky_write_time_path(
5605 vfs_file_id_from_sbuf(conn
, &smb_fname
->st
),
5610 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5612 /* Always call ntimes on the base, even if a stream was passed in. */
5613 smb_fname_base
= *smb_fname
;
5614 smb_fname_base
.stream_name
= NULL
;
5616 if(file_ntimes(conn
, &smb_fname_base
, ft
)!=0) {
5617 return map_nt_error_from_unix(errno
);
5620 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
,
5621 smb_fname
->base_name
);
5622 return NT_STATUS_OK
;
5625 /****************************************************************************
5626 Deal with setting the dosmode from any of the setfilepathinfo functions.
5627 ****************************************************************************/
5629 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
5630 const struct smb_filename
*smb_fname
,
5633 struct smb_filename
*smb_fname_base
= NULL
;
5636 if (!VALID_STAT(smb_fname
->st
)) {
5637 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5640 /* Always operate on the base_name, even if a stream was passed in. */
5641 status
= create_synthetic_smb_fname(talloc_tos(), smb_fname
->base_name
,
5642 NULL
, &smb_fname
->st
,
5644 if (!NT_STATUS_IS_OK(status
)) {
5649 if (S_ISDIR(smb_fname_base
->st
.st_ex_mode
)) {
5650 dosmode
|= FILE_ATTRIBUTE_DIRECTORY
;
5652 dosmode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
5656 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode
));
5658 /* check the mode isn't different, before changing it */
5659 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, smb_fname_base
))) {
5660 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5661 "0x%x\n", smb_fname_str_dbg(smb_fname_base
),
5662 (unsigned int)dosmode
));
5664 if(file_set_dosmode(conn
, smb_fname_base
, dosmode
, NULL
,
5666 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5668 smb_fname_str_dbg(smb_fname_base
),
5670 status
= map_nt_error_from_unix(errno
);
5674 status
= NT_STATUS_OK
;
5676 TALLOC_FREE(smb_fname_base
);
5680 /****************************************************************************
5681 Deal with setting the size from any of the setfilepathinfo functions.
5682 ****************************************************************************/
5684 static NTSTATUS
smb_set_file_size(connection_struct
*conn
,
5685 struct smb_request
*req
,
5687 const struct smb_filename
*smb_fname
,
5688 const SMB_STRUCT_STAT
*psbuf
,
5690 bool fail_after_createfile
)
5692 NTSTATUS status
= NT_STATUS_OK
;
5693 struct smb_filename
*smb_fname_tmp
= NULL
;
5694 files_struct
*new_fsp
= NULL
;
5696 if (!VALID_STAT(*psbuf
)) {
5697 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5700 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
5701 return NT_STATUS_ACCESS_DENIED
;
5704 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size
));
5706 if (size
== get_file_size_stat(psbuf
)) {
5707 return NT_STATUS_OK
;
5710 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5711 smb_fname_str_dbg(smb_fname
), (double)size
));
5713 if (fsp
&& fsp
->fh
->fd
!= -1) {
5714 /* Handle based call. */
5715 if (vfs_set_filelen(fsp
, size
) == -1) {
5716 return map_nt_error_from_unix(errno
);
5718 trigger_write_time_update_immediate(fsp
);
5719 return NT_STATUS_OK
;
5722 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
5723 if (!NT_STATUS_IS_OK(status
)) {
5727 smb_fname_tmp
->st
= *psbuf
;
5729 status
= SMB_VFS_CREATE_FILE(
5732 0, /* root_dir_fid */
5733 smb_fname_tmp
, /* fname */
5734 FILE_WRITE_DATA
, /* access_mask */
5735 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5737 FILE_OPEN
, /* create_disposition*/
5738 0, /* create_options */
5739 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5740 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
5741 0, /* allocation_size */
5742 0, /* private_flags */
5745 &new_fsp
, /* result */
5748 TALLOC_FREE(smb_fname_tmp
);
5750 if (!NT_STATUS_IS_OK(status
)) {
5751 /* NB. We check for open_was_deferred in the caller. */
5755 /* See RAW-SFILEINFO-END-OF-FILE */
5756 if (fail_after_createfile
) {
5757 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5758 return NT_STATUS_INVALID_LEVEL
;
5761 if (vfs_set_filelen(new_fsp
, size
) == -1) {
5762 status
= map_nt_error_from_unix(errno
);
5763 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5767 trigger_write_time_update_immediate(new_fsp
);
5768 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5769 return NT_STATUS_OK
;
5772 /****************************************************************************
5773 Deal with SMB_INFO_SET_EA.
5774 ****************************************************************************/
5776 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
5780 const struct smb_filename
*smb_fname
)
5782 struct ea_list
*ea_list
= NULL
;
5783 TALLOC_CTX
*ctx
= NULL
;
5784 NTSTATUS status
= NT_STATUS_OK
;
5786 if (total_data
< 10) {
5788 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5789 length. They seem to have no effect. Bug #3212. JRA */
5791 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
5792 /* We're done. We only get EA info in this call. */
5793 return NT_STATUS_OK
;
5796 return NT_STATUS_INVALID_PARAMETER
;
5799 if (IVAL(pdata
,0) > total_data
) {
5800 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5801 IVAL(pdata
,0), (unsigned int)total_data
));
5802 return NT_STATUS_INVALID_PARAMETER
;
5806 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
5808 return NT_STATUS_INVALID_PARAMETER
;
5811 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_EA
)) {
5812 return NT_STATUS_ACCESS_DENIED
;
5815 status
= set_ea(conn
, fsp
, smb_fname
, ea_list
);
5820 /****************************************************************************
5821 Deal with SMB_FILE_FULL_EA_INFORMATION set.
5822 ****************************************************************************/
5824 static NTSTATUS
smb_set_file_full_ea_info(connection_struct
*conn
,
5829 struct ea_list
*ea_list
= NULL
;
5833 return NT_STATUS_INVALID_HANDLE
;
5836 if (!lp_ea_support(SNUM(conn
))) {
5837 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5838 "EA's not supported.\n",
5839 (unsigned int)total_data
));
5840 return NT_STATUS_EAS_NOT_SUPPORTED
;
5843 if (total_data
< 10) {
5844 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5846 (unsigned int)total_data
));
5847 return NT_STATUS_INVALID_PARAMETER
;
5850 ea_list
= read_nttrans_ea_list(talloc_tos(),
5855 return NT_STATUS_INVALID_PARAMETER
;
5858 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_EA
)) {
5859 return NT_STATUS_ACCESS_DENIED
;
5862 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
5864 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5865 smb_fname_str_dbg(fsp
->fsp_name
),
5866 nt_errstr(status
) ));
5872 /****************************************************************************
5873 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5874 ****************************************************************************/
5876 static NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
5880 struct smb_filename
*smb_fname
)
5882 NTSTATUS status
= NT_STATUS_OK
;
5883 bool delete_on_close
;
5886 if (total_data
< 1) {
5887 return NT_STATUS_INVALID_PARAMETER
;
5891 return NT_STATUS_INVALID_HANDLE
;
5894 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
5895 dosmode
= dos_mode(conn
, smb_fname
);
5897 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5898 "delete_on_close = %u\n",
5899 smb_fname_str_dbg(smb_fname
),
5900 (unsigned int)dosmode
,
5901 (unsigned int)delete_on_close
));
5903 if (delete_on_close
) {
5904 status
= can_set_delete_on_close(fsp
, dosmode
);
5905 if (!NT_STATUS_IS_OK(status
)) {
5910 /* The set is across all open files on this dev/inode pair. */
5911 if (!set_delete_on_close(fsp
, delete_on_close
,
5912 conn
->session_info
->security_token
,
5913 &conn
->session_info
->utok
)) {
5914 return NT_STATUS_ACCESS_DENIED
;
5916 return NT_STATUS_OK
;
5919 /****************************************************************************
5920 Deal with SMB_FILE_POSITION_INFORMATION.
5921 ****************************************************************************/
5923 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
5928 uint64_t position_information
;
5930 if (total_data
< 8) {
5931 return NT_STATUS_INVALID_PARAMETER
;
5935 /* Ignore on pathname based set. */
5936 return NT_STATUS_OK
;
5939 position_information
= (uint64_t)IVAL(pdata
,0);
5940 #ifdef LARGE_SMB_OFF_T
5941 position_information
|= (((uint64_t)IVAL(pdata
,4)) << 32);
5942 #else /* LARGE_SMB_OFF_T */
5943 if (IVAL(pdata
,4) != 0) {
5944 /* more than 32 bits? */
5945 return NT_STATUS_INVALID_PARAMETER
;
5947 #endif /* LARGE_SMB_OFF_T */
5949 DEBUG(10,("smb_file_position_information: Set file position "
5950 "information for file %s to %.0f\n", fsp_str_dbg(fsp
),
5951 (double)position_information
));
5952 fsp
->fh
->position_information
= position_information
;
5953 return NT_STATUS_OK
;
5956 /****************************************************************************
5957 Deal with SMB_FILE_MODE_INFORMATION.
5958 ****************************************************************************/
5960 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
5966 if (total_data
< 4) {
5967 return NT_STATUS_INVALID_PARAMETER
;
5969 mode
= IVAL(pdata
,0);
5970 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
5971 return NT_STATUS_INVALID_PARAMETER
;
5973 return NT_STATUS_OK
;
5976 /****************************************************************************
5977 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
5978 ****************************************************************************/
5980 static NTSTATUS
smb_set_file_unix_link(connection_struct
*conn
,
5981 struct smb_request
*req
,
5984 const struct smb_filename
*smb_fname
)
5986 char *link_target
= NULL
;
5987 const char *newname
= smb_fname
->base_name
;
5988 TALLOC_CTX
*ctx
= talloc_tos();
5990 /* Set a symbolic link. */
5991 /* Don't allow this if follow links is false. */
5993 if (total_data
== 0) {
5994 return NT_STATUS_INVALID_PARAMETER
;
5997 if (!lp_symlinks(SNUM(conn
))) {
5998 return NT_STATUS_ACCESS_DENIED
;
6001 srvstr_pull_talloc(ctx
, pdata
, req
->flags2
, &link_target
, pdata
,
6002 total_data
, STR_TERMINATE
);
6005 return NT_STATUS_INVALID_PARAMETER
;
6008 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
6009 newname
, link_target
));
6011 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0) {
6012 return map_nt_error_from_unix(errno
);
6015 return NT_STATUS_OK
;
6018 /****************************************************************************
6019 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
6020 ****************************************************************************/
6022 static NTSTATUS
smb_set_file_unix_hlink(connection_struct
*conn
,
6023 struct smb_request
*req
,
6024 const char *pdata
, int total_data
,
6025 struct smb_filename
*smb_fname_new
)
6027 char *oldname
= NULL
;
6028 struct smb_filename
*smb_fname_old
= NULL
;
6029 TALLOC_CTX
*ctx
= talloc_tos();
6030 NTSTATUS status
= NT_STATUS_OK
;
6032 /* Set a hard link. */
6033 if (total_data
== 0) {
6034 return NT_STATUS_INVALID_PARAMETER
;
6037 srvstr_get_path(ctx
, pdata
, req
->flags2
, &oldname
, pdata
,
6038 total_data
, STR_TERMINATE
, &status
);
6039 if (!NT_STATUS_IS_OK(status
)) {
6043 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6044 smb_fname_str_dbg(smb_fname_new
), oldname
));
6046 status
= filename_convert(ctx
,
6048 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6053 if (!NT_STATUS_IS_OK(status
)) {
6057 return hardlink_internals(ctx
, conn
, req
, false,
6058 smb_fname_old
, smb_fname_new
);
6061 /****************************************************************************
6062 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6063 ****************************************************************************/
6065 static NTSTATUS
smb2_file_rename_information(connection_struct
*conn
,
6066 struct smb_request
*req
,
6070 struct smb_filename
*smb_fname_src
)
6074 char *newname
= NULL
;
6075 struct smb_filename
*smb_fname_dst
= NULL
;
6076 NTSTATUS status
= NT_STATUS_OK
;
6077 TALLOC_CTX
*ctx
= talloc_tos();
6080 return NT_STATUS_INVALID_HANDLE
;
6083 if (total_data
< 20) {
6084 return NT_STATUS_INVALID_PARAMETER
;
6087 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6088 len
= IVAL(pdata
,16);
6090 if (len
> (total_data
- 20) || (len
== 0)) {
6091 return NT_STATUS_INVALID_PARAMETER
;
6094 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6095 &pdata
[20], len
, STR_TERMINATE
,
6097 if (!NT_STATUS_IS_OK(status
)) {
6101 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
6104 status
= filename_convert(ctx
,
6106 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6111 if (!NT_STATUS_IS_OK(status
)) {
6115 if (fsp
->base_fsp
) {
6116 /* newname must be a stream name. */
6117 if (newname
[0] != ':') {
6118 return NT_STATUS_NOT_SUPPORTED
;
6121 /* Create an smb_fname to call rename_internals_fsp() with. */
6122 status
= create_synthetic_smb_fname(talloc_tos(),
6123 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6125 if (!NT_STATUS_IS_OK(status
)) {
6130 * Set the original last component, since
6131 * rename_internals_fsp() requires it.
6133 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6135 if (smb_fname_dst
->original_lcomp
== NULL
) {
6136 status
= NT_STATUS_NO_MEMORY
;
6142 DEBUG(10,("smb2_file_rename_information: "
6143 "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6144 fsp
->fnum
, fsp_str_dbg(fsp
),
6145 smb_fname_str_dbg(smb_fname_dst
)));
6146 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6147 (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
),
6151 TALLOC_FREE(smb_fname_dst
);
6155 static NTSTATUS
smb_file_link_information(connection_struct
*conn
,
6156 struct smb_request
*req
,
6160 struct smb_filename
*smb_fname_src
)
6164 char *newname
= NULL
;
6165 struct smb_filename
*smb_fname_dst
= NULL
;
6166 NTSTATUS status
= NT_STATUS_OK
;
6167 TALLOC_CTX
*ctx
= talloc_tos();
6170 return NT_STATUS_INVALID_HANDLE
;
6173 if (total_data
< 20) {
6174 return NT_STATUS_INVALID_PARAMETER
;
6177 overwrite
= (CVAL(pdata
,0) ? true : false);
6178 len
= IVAL(pdata
,16);
6180 if (len
> (total_data
- 20) || (len
== 0)) {
6181 return NT_STATUS_INVALID_PARAMETER
;
6184 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6185 &pdata
[20], len
, STR_TERMINATE
,
6187 if (!NT_STATUS_IS_OK(status
)) {
6191 DEBUG(10,("smb_file_link_information: got name |%s|\n",
6194 status
= filename_convert(ctx
,
6196 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6201 if (!NT_STATUS_IS_OK(status
)) {
6205 if (fsp
->base_fsp
) {
6206 /* No stream names. */
6207 return NT_STATUS_NOT_SUPPORTED
;
6210 DEBUG(10,("smb_file_link_information: "
6211 "SMB_FILE_LINK_INFORMATION (fnum %d) %s -> %s\n",
6212 fsp
->fnum
, fsp_str_dbg(fsp
),
6213 smb_fname_str_dbg(smb_fname_dst
)));
6214 status
= hardlink_internals(ctx
,
6221 TALLOC_FREE(smb_fname_dst
);
6225 /****************************************************************************
6226 Deal with SMB_FILE_RENAME_INFORMATION.
6227 ****************************************************************************/
6229 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
6230 struct smb_request
*req
,
6234 struct smb_filename
*smb_fname_src
)
6239 char *newname
= NULL
;
6240 struct smb_filename
*smb_fname_dst
= NULL
;
6241 bool dest_has_wcard
= False
;
6242 NTSTATUS status
= NT_STATUS_OK
;
6244 TALLOC_CTX
*ctx
= talloc_tos();
6246 if (total_data
< 13) {
6247 return NT_STATUS_INVALID_PARAMETER
;
6250 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6251 root_fid
= IVAL(pdata
,4);
6252 len
= IVAL(pdata
,8);
6254 if (len
> (total_data
- 12) || (len
== 0) || (root_fid
!= 0)) {
6255 return NT_STATUS_INVALID_PARAMETER
;
6258 srvstr_get_path_wcard(ctx
, pdata
, req
->flags2
, &newname
, &pdata
[12],
6261 if (!NT_STATUS_IS_OK(status
)) {
6265 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6268 status
= resolve_dfspath_wcard(ctx
, conn
,
6269 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6274 if (!NT_STATUS_IS_OK(status
)) {
6278 /* Check the new name has no '/' characters. */
6279 if (strchr_m(newname
, '/')) {
6280 return NT_STATUS_NOT_SUPPORTED
;
6283 if (fsp
&& fsp
->base_fsp
) {
6284 /* newname must be a stream name. */
6285 if (newname
[0] != ':') {
6286 return NT_STATUS_NOT_SUPPORTED
;
6289 /* Create an smb_fname to call rename_internals_fsp() with. */
6290 status
= create_synthetic_smb_fname(talloc_tos(),
6291 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6293 if (!NT_STATUS_IS_OK(status
)) {
6298 * Set the original last component, since
6299 * rename_internals_fsp() requires it.
6301 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6303 if (smb_fname_dst
->original_lcomp
== NULL
) {
6304 status
= NT_STATUS_NO_MEMORY
;
6310 * Build up an smb_fname_dst based on the filename passed in.
6311 * We basically just strip off the last component, and put on
6312 * the newname instead.
6314 char *base_name
= NULL
;
6316 /* newname must *not* be a stream name. */
6317 if (newname
[0] == ':') {
6318 return NT_STATUS_NOT_SUPPORTED
;
6322 * Strip off the last component (filename) of the path passed
6325 base_name
= talloc_strdup(ctx
, smb_fname_src
->base_name
);
6327 return NT_STATUS_NO_MEMORY
;
6329 p
= strrchr_m(base_name
, '/');
6333 base_name
= talloc_strdup(ctx
, "");
6335 return NT_STATUS_NO_MEMORY
;
6338 /* Append the new name. */
6339 base_name
= talloc_asprintf_append(base_name
,
6343 return NT_STATUS_NO_MEMORY
;
6346 status
= unix_convert(ctx
, conn
, base_name
, &smb_fname_dst
,
6349 UCF_ALWAYS_ALLOW_WCARD_LCOMP
:
6352 /* If an error we expect this to be
6353 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6355 if (!NT_STATUS_IS_OK(status
)) {
6356 if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND
,
6360 /* Create an smb_fname to call rename_internals_fsp() */
6361 status
= create_synthetic_smb_fname(ctx
,
6365 if (!NT_STATUS_IS_OK(status
)) {
6372 DEBUG(10,("smb_file_rename_information: "
6373 "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6374 fsp
->fnum
, fsp_str_dbg(fsp
),
6375 smb_fname_str_dbg(smb_fname_dst
)));
6376 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
, 0,
6379 DEBUG(10,("smb_file_rename_information: "
6380 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6381 smb_fname_str_dbg(smb_fname_src
),
6382 smb_fname_str_dbg(smb_fname_dst
)));
6383 status
= rename_internals(ctx
, conn
, req
, smb_fname_src
,
6384 smb_fname_dst
, 0, overwrite
, false,
6386 FILE_WRITE_ATTRIBUTES
);
6389 TALLOC_FREE(smb_fname_dst
);
6393 /****************************************************************************
6394 Deal with SMB_SET_POSIX_ACL.
6395 ****************************************************************************/
6397 #if defined(HAVE_POSIX_ACLS)
6398 static NTSTATUS
smb_set_posix_acl(connection_struct
*conn
,
6402 const struct smb_filename
*smb_fname
)
6404 uint16 posix_acl_version
;
6405 uint16 num_file_acls
;
6406 uint16 num_def_acls
;
6407 bool valid_file_acls
= True
;
6408 bool valid_def_acls
= True
;
6410 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
6411 return NT_STATUS_INVALID_PARAMETER
;
6413 posix_acl_version
= SVAL(pdata
,0);
6414 num_file_acls
= SVAL(pdata
,2);
6415 num_def_acls
= SVAL(pdata
,4);
6417 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6418 valid_file_acls
= False
;
6422 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6423 valid_def_acls
= False
;
6427 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
6428 return NT_STATUS_INVALID_PARAMETER
;
6431 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
6432 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
6433 return NT_STATUS_INVALID_PARAMETER
;
6436 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6437 smb_fname
? smb_fname_str_dbg(smb_fname
) : fsp_str_dbg(fsp
),
6438 (unsigned int)num_file_acls
,
6439 (unsigned int)num_def_acls
));
6441 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
,
6442 smb_fname
->base_name
, num_file_acls
,
6443 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
6444 return map_nt_error_from_unix(errno
);
6447 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
,
6448 smb_fname
->base_name
, &smb_fname
->st
, num_def_acls
,
6449 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
6450 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
6451 return map_nt_error_from_unix(errno
);
6453 return NT_STATUS_OK
;
6457 /****************************************************************************
6458 Deal with SMB_SET_POSIX_LOCK.
6459 ****************************************************************************/
6461 static NTSTATUS
smb_set_posix_lock(connection_struct
*conn
,
6462 struct smb_request
*req
,
6470 bool blocking_lock
= False
;
6471 enum brl_type lock_type
;
6473 NTSTATUS status
= NT_STATUS_OK
;
6475 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
6476 return NT_STATUS_INVALID_HANDLE
;
6479 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
6480 return NT_STATUS_INVALID_PARAMETER
;
6483 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
6484 case POSIX_LOCK_TYPE_READ
:
6485 lock_type
= READ_LOCK
;
6487 case POSIX_LOCK_TYPE_WRITE
:
6488 /* Return the right POSIX-mappable error code for files opened read-only. */
6489 if (!fsp
->can_write
) {
6490 return NT_STATUS_INVALID_HANDLE
;
6492 lock_type
= WRITE_LOCK
;
6494 case POSIX_LOCK_TYPE_UNLOCK
:
6495 lock_type
= UNLOCK_LOCK
;
6498 return NT_STATUS_INVALID_PARAMETER
;
6501 if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_NOWAIT
) {
6502 blocking_lock
= False
;
6503 } else if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_WAIT
) {
6504 blocking_lock
= True
;
6506 return NT_STATUS_INVALID_PARAMETER
;
6509 if (!lp_blocking_locks(SNUM(conn
))) {
6510 blocking_lock
= False
;
6513 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
6514 #if defined(HAVE_LONGLONG)
6515 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
6516 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
6517 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
6518 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
6519 #else /* HAVE_LONGLONG */
6520 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
6521 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
6522 #endif /* HAVE_LONGLONG */
6524 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6525 "smblctx = %llu, count = %.0f, offset = %.0f\n",
6527 (unsigned int)lock_type
,
6528 (unsigned long long)smblctx
,
6532 if (lock_type
== UNLOCK_LOCK
) {
6533 status
= do_unlock(req
->sconn
->msg_ctx
,
6540 uint64_t block_smblctx
;
6542 struct byte_range_lock
*br_lck
= do_lock(req
->sconn
->msg_ctx
,
6554 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
6556 * A blocking lock was requested. Package up
6557 * this smb into a queued request and push it
6558 * onto the blocking lock queue.
6560 if(push_blocking_lock_request(br_lck
,
6563 -1, /* infinite timeout. */
6571 TALLOC_FREE(br_lck
);
6575 TALLOC_FREE(br_lck
);
6581 /****************************************************************************
6582 Deal with SMB_SET_FILE_BASIC_INFO.
6583 ****************************************************************************/
6585 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
6589 const struct smb_filename
*smb_fname
)
6591 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6592 struct smb_file_time ft
;
6594 NTSTATUS status
= NT_STATUS_OK
;
6598 if (total_data
< 36) {
6599 return NT_STATUS_INVALID_PARAMETER
;
6602 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
6603 return NT_STATUS_ACCESS_DENIED
;
6606 /* Set the attributes */
6607 dosmode
= IVAL(pdata
,32);
6608 status
= smb_set_file_dosmode(conn
, smb_fname
, dosmode
);
6609 if (!NT_STATUS_IS_OK(status
)) {
6614 ft
.create_time
= interpret_long_date(pdata
);
6617 ft
.atime
= interpret_long_date(pdata
+8);
6620 ft
.mtime
= interpret_long_date(pdata
+16);
6623 ft
.ctime
= interpret_long_date(pdata
+24);
6625 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6626 smb_fname_str_dbg(smb_fname
)));
6628 return smb_set_file_time(conn
, fsp
, smb_fname
, &ft
,
6632 /****************************************************************************
6633 Deal with SMB_INFO_STANDARD.
6634 ****************************************************************************/
6636 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
6640 const struct smb_filename
*smb_fname
)
6642 struct smb_file_time ft
;
6646 if (total_data
< 12) {
6647 return NT_STATUS_INVALID_PARAMETER
;
6650 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
6651 return NT_STATUS_ACCESS_DENIED
;
6655 ft
.create_time
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
));
6657 ft
.atime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+4));
6659 ft
.mtime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+8));
6661 DEBUG(10,("smb_set_info_standard: file %s\n",
6662 smb_fname_str_dbg(smb_fname
)));
6664 return smb_set_file_time(conn
,
6671 /****************************************************************************
6672 Deal with SMB_SET_FILE_ALLOCATION_INFO.
6673 ****************************************************************************/
6675 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
6676 struct smb_request
*req
,
6680 struct smb_filename
*smb_fname
)
6682 uint64_t allocation_size
= 0;
6683 NTSTATUS status
= NT_STATUS_OK
;
6684 files_struct
*new_fsp
= NULL
;
6686 if (!VALID_STAT(smb_fname
->st
)) {
6687 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6690 if (total_data
< 8) {
6691 return NT_STATUS_INVALID_PARAMETER
;
6694 allocation_size
= (uint64_t)IVAL(pdata
,0);
6695 #ifdef LARGE_SMB_OFF_T
6696 allocation_size
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6697 #else /* LARGE_SMB_OFF_T */
6698 if (IVAL(pdata
,4) != 0) {
6699 /* more than 32 bits? */
6700 return NT_STATUS_INVALID_PARAMETER
;
6702 #endif /* LARGE_SMB_OFF_T */
6704 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6705 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6706 (double)allocation_size
));
6708 if (allocation_size
) {
6709 allocation_size
= smb_roundup(conn
, allocation_size
);
6712 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6713 return NT_STATUS_ACCESS_DENIED
;
6716 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6717 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname
),
6718 (double)allocation_size
));
6720 if (fsp
&& fsp
->fh
->fd
!= -1) {
6721 /* Open file handle. */
6722 /* Only change if needed. */
6723 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6724 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
6725 return map_nt_error_from_unix(errno
);
6728 /* But always update the time. */
6730 * This is equivalent to a write. Ensure it's seen immediately
6731 * if there are no pending writes.
6733 trigger_write_time_update_immediate(fsp
);
6734 return NT_STATUS_OK
;
6737 /* Pathname or stat or directory file. */
6738 status
= SMB_VFS_CREATE_FILE(
6741 0, /* root_dir_fid */
6742 smb_fname
, /* fname */
6743 FILE_WRITE_DATA
, /* access_mask */
6744 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
6746 FILE_OPEN
, /* create_disposition*/
6747 0, /* create_options */
6748 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
6749 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
6750 0, /* allocation_size */
6751 0, /* private_flags */
6754 &new_fsp
, /* result */
6757 if (!NT_STATUS_IS_OK(status
)) {
6758 /* NB. We check for open_was_deferred in the caller. */
6762 /* Only change if needed. */
6763 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6764 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
6765 status
= map_nt_error_from_unix(errno
);
6766 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6771 /* Changing the allocation size should set the last mod time. */
6773 * This is equivalent to a write. Ensure it's seen immediately
6774 * if there are no pending writes.
6776 trigger_write_time_update_immediate(new_fsp
);
6778 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6779 return NT_STATUS_OK
;
6782 /****************************************************************************
6783 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6784 ****************************************************************************/
6786 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
6787 struct smb_request
*req
,
6791 const struct smb_filename
*smb_fname
,
6792 bool fail_after_createfile
)
6796 if (total_data
< 8) {
6797 return NT_STATUS_INVALID_PARAMETER
;
6800 size
= IVAL(pdata
,0);
6801 #ifdef LARGE_SMB_OFF_T
6802 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
6803 #else /* LARGE_SMB_OFF_T */
6804 if (IVAL(pdata
,4) != 0) {
6805 /* more than 32 bits? */
6806 return NT_STATUS_INVALID_PARAMETER
;
6808 #endif /* LARGE_SMB_OFF_T */
6809 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6810 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6813 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6814 return NT_STATUS_ACCESS_DENIED
;
6817 return smb_set_file_size(conn
, req
,
6822 fail_after_createfile
);
6825 /****************************************************************************
6826 Allow a UNIX info mknod.
6827 ****************************************************************************/
6829 static NTSTATUS
smb_unix_mknod(connection_struct
*conn
,
6832 const struct smb_filename
*smb_fname
)
6834 uint32 file_type
= IVAL(pdata
,56);
6835 #if defined(HAVE_MAKEDEV)
6836 uint32 dev_major
= IVAL(pdata
,60);
6837 uint32 dev_minor
= IVAL(pdata
,68);
6839 SMB_DEV_T dev
= (SMB_DEV_T
)0;
6840 uint32 raw_unixmode
= IVAL(pdata
,84);
6844 if (total_data
< 100) {
6845 return NT_STATUS_INVALID_PARAMETER
;
6848 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6849 PERM_NEW_FILE
, &unixmode
);
6850 if (!NT_STATUS_IS_OK(status
)) {
6854 #if defined(HAVE_MAKEDEV)
6855 dev
= makedev(dev_major
, dev_minor
);
6858 switch (file_type
) {
6859 #if defined(S_IFIFO)
6860 case UNIX_TYPE_FIFO
:
6861 unixmode
|= S_IFIFO
;
6864 #if defined(S_IFSOCK)
6865 case UNIX_TYPE_SOCKET
:
6866 unixmode
|= S_IFSOCK
;
6869 #if defined(S_IFCHR)
6870 case UNIX_TYPE_CHARDEV
:
6871 unixmode
|= S_IFCHR
;
6874 #if defined(S_IFBLK)
6875 case UNIX_TYPE_BLKDEV
:
6876 unixmode
|= S_IFBLK
;
6880 return NT_STATUS_INVALID_PARAMETER
;
6883 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6884 "%.0f mode 0%o for file %s\n", (double)dev
,
6885 (unsigned int)unixmode
, smb_fname_str_dbg(smb_fname
)));
6887 /* Ok - do the mknod. */
6888 if (SMB_VFS_MKNOD(conn
, smb_fname
->base_name
, unixmode
, dev
) != 0) {
6889 return map_nt_error_from_unix(errno
);
6892 /* If any of the other "set" calls fail we
6893 * don't want to end up with a half-constructed mknod.
6896 if (lp_inherit_perms(SNUM(conn
))) {
6898 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
,
6900 return NT_STATUS_NO_MEMORY
;
6902 inherit_access_posix_acl(conn
, parent
, smb_fname
->base_name
,
6904 TALLOC_FREE(parent
);
6907 return NT_STATUS_OK
;
6910 /****************************************************************************
6911 Deal with SMB_SET_FILE_UNIX_BASIC.
6912 ****************************************************************************/
6914 static NTSTATUS
smb_set_file_unix_basic(connection_struct
*conn
,
6915 struct smb_request
*req
,
6919 const struct smb_filename
*smb_fname
)
6921 struct smb_file_time ft
;
6922 uint32 raw_unixmode
;
6925 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
6926 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
6927 NTSTATUS status
= NT_STATUS_OK
;
6928 bool delete_on_fail
= False
;
6929 enum perm_type ptype
;
6930 files_struct
*all_fsps
= NULL
;
6931 bool modify_mtime
= true;
6933 struct smb_filename
*smb_fname_tmp
= NULL
;
6934 SMB_STRUCT_STAT sbuf
;
6938 if (total_data
< 100) {
6939 return NT_STATUS_INVALID_PARAMETER
;
6942 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
6943 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
6944 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
6945 #ifdef LARGE_SMB_OFF_T
6946 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
6947 #else /* LARGE_SMB_OFF_T */
6948 if (IVAL(pdata
,4) != 0) {
6949 /* more than 32 bits? */
6950 return NT_STATUS_INVALID_PARAMETER
;
6952 #endif /* LARGE_SMB_OFF_T */
6955 ft
.atime
= interpret_long_date(pdata
+24); /* access_time */
6956 ft
.mtime
= interpret_long_date(pdata
+32); /* modification_time */
6957 set_owner
= (uid_t
)IVAL(pdata
,40);
6958 set_grp
= (gid_t
)IVAL(pdata
,48);
6959 raw_unixmode
= IVAL(pdata
,84);
6961 if (VALID_STAT(smb_fname
->st
)) {
6962 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
6963 ptype
= PERM_EXISTING_DIR
;
6965 ptype
= PERM_EXISTING_FILE
;
6968 ptype
= PERM_NEW_FILE
;
6971 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6973 if (!NT_STATUS_IS_OK(status
)) {
6977 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
6978 "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
6979 smb_fname_str_dbg(smb_fname
), (double)size
,
6980 (unsigned int)set_owner
, (unsigned int)set_grp
,
6981 (int)raw_unixmode
));
6983 sbuf
= smb_fname
->st
;
6985 if (!VALID_STAT(sbuf
)) {
6987 * The only valid use of this is to create character and block
6988 * devices, and named pipes. This is deprecated (IMHO) and
6989 * a new info level should be used for mknod. JRA.
6992 status
= smb_unix_mknod(conn
,
6996 if (!NT_STATUS_IS_OK(status
)) {
7000 status
= copy_smb_filename(talloc_tos(), smb_fname
,
7002 if (!NT_STATUS_IS_OK(status
)) {
7006 if (SMB_VFS_STAT(conn
, smb_fname_tmp
) != 0) {
7007 status
= map_nt_error_from_unix(errno
);
7008 TALLOC_FREE(smb_fname_tmp
);
7009 SMB_VFS_UNLINK(conn
, smb_fname
);
7013 sbuf
= smb_fname_tmp
->st
;
7014 smb_fname
= smb_fname_tmp
;
7016 /* Ensure we don't try and change anything else. */
7017 raw_unixmode
= SMB_MODE_NO_CHANGE
;
7018 size
= get_file_size_stat(&sbuf
);
7019 ft
.atime
= sbuf
.st_ex_atime
;
7020 ft
.mtime
= sbuf
.st_ex_mtime
;
7022 * We continue here as we might want to change the
7025 delete_on_fail
= True
;
7029 /* Horrible backwards compatibility hack as an old server bug
7030 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
7034 size
= get_file_size_stat(&sbuf
);
7039 * Deal with the UNIX specific mode set.
7042 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
7043 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7044 "setting mode 0%o for file %s\n",
7045 (unsigned int)unixmode
,
7046 smb_fname_str_dbg(smb_fname
)));
7047 if (SMB_VFS_CHMOD(conn
, smb_fname
->base_name
, unixmode
) != 0) {
7048 return map_nt_error_from_unix(errno
);
7053 * Deal with the UNIX specific uid set.
7056 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) &&
7057 (sbuf
.st_ex_uid
!= set_owner
)) {
7060 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7061 "changing owner %u for path %s\n",
7062 (unsigned int)set_owner
,
7063 smb_fname_str_dbg(smb_fname
)));
7065 if (S_ISLNK(sbuf
.st_ex_mode
)) {
7066 ret
= SMB_VFS_LCHOWN(conn
, smb_fname
->base_name
,
7067 set_owner
, (gid_t
)-1);
7069 ret
= SMB_VFS_CHOWN(conn
, smb_fname
->base_name
,
7070 set_owner
, (gid_t
)-1);
7074 status
= map_nt_error_from_unix(errno
);
7075 if (delete_on_fail
) {
7076 SMB_VFS_UNLINK(conn
, smb_fname
);
7083 * Deal with the UNIX specific gid set.
7086 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) &&
7087 (sbuf
.st_ex_gid
!= set_grp
)) {
7088 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7089 "changing group %u for file %s\n",
7090 (unsigned int)set_owner
,
7091 smb_fname_str_dbg(smb_fname
)));
7092 if (SMB_VFS_CHOWN(conn
, smb_fname
->base_name
, (uid_t
)-1,
7094 status
= map_nt_error_from_unix(errno
);
7095 if (delete_on_fail
) {
7096 SMB_VFS_UNLINK(conn
, smb_fname
);
7102 /* Deal with any size changes. */
7104 status
= smb_set_file_size(conn
, req
,
7110 if (!NT_STATUS_IS_OK(status
)) {
7114 /* Deal with any time changes. */
7115 if (null_timespec(ft
.mtime
) && null_timespec(ft
.atime
)) {
7116 /* No change, don't cancel anything. */
7120 id
= vfs_file_id_from_sbuf(conn
, &sbuf
);
7121 for(all_fsps
= file_find_di_first(conn
->sconn
, id
); all_fsps
;
7122 all_fsps
= file_find_di_next(all_fsps
)) {
7124 * We're setting the time explicitly for UNIX.
7125 * Cancel any pending changes over all handles.
7127 all_fsps
->update_write_time_on_close
= false;
7128 TALLOC_FREE(all_fsps
->update_write_time_event
);
7132 * Override the "setting_write_time"
7133 * parameter here as it almost does what
7134 * we need. Just remember if we modified
7135 * mtime and send the notify ourselves.
7137 if (null_timespec(ft
.mtime
)) {
7138 modify_mtime
= false;
7141 status
= smb_set_file_time(conn
,
7147 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
7148 FILE_NOTIFY_CHANGE_LAST_WRITE
, smb_fname
->base_name
);
7153 /****************************************************************************
7154 Deal with SMB_SET_FILE_UNIX_INFO2.
7155 ****************************************************************************/
7157 static NTSTATUS
smb_set_file_unix_info2(connection_struct
*conn
,
7158 struct smb_request
*req
,
7162 const struct smb_filename
*smb_fname
)
7168 if (total_data
< 116) {
7169 return NT_STATUS_INVALID_PARAMETER
;
7172 /* Start by setting all the fields that are common between UNIX_BASIC
7175 status
= smb_set_file_unix_basic(conn
, req
, pdata
, total_data
,
7177 if (!NT_STATUS_IS_OK(status
)) {
7181 smb_fflags
= IVAL(pdata
, 108);
7182 smb_fmask
= IVAL(pdata
, 112);
7184 /* NB: We should only attempt to alter the file flags if the client
7185 * sends a non-zero mask.
7187 if (smb_fmask
!= 0) {
7188 int stat_fflags
= 0;
7190 if (!map_info2_flags_to_sbuf(&smb_fname
->st
, smb_fflags
,
7191 smb_fmask
, &stat_fflags
)) {
7192 /* Client asked to alter a flag we don't understand. */
7193 return NT_STATUS_INVALID_PARAMETER
;
7196 if (fsp
&& fsp
->fh
->fd
!= -1) {
7197 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
7198 return NT_STATUS_NOT_SUPPORTED
;
7200 if (SMB_VFS_CHFLAGS(conn
, smb_fname
->base_name
,
7201 stat_fflags
) != 0) {
7202 return map_nt_error_from_unix(errno
);
7207 /* XXX: need to add support for changing the create_time here. You
7208 * can do this for paths on Darwin with setattrlist(2). The right way
7209 * to hook this up is probably by extending the VFS utimes interface.
7212 return NT_STATUS_OK
;
7215 /****************************************************************************
7216 Create a directory with POSIX semantics.
7217 ****************************************************************************/
7219 static NTSTATUS
smb_posix_mkdir(connection_struct
*conn
,
7220 struct smb_request
*req
,
7223 struct smb_filename
*smb_fname
,
7224 int *pdata_return_size
)
7226 NTSTATUS status
= NT_STATUS_OK
;
7227 uint32 raw_unixmode
= 0;
7228 uint32 mod_unixmode
= 0;
7229 mode_t unixmode
= (mode_t
)0;
7230 files_struct
*fsp
= NULL
;
7231 uint16 info_level_return
= 0;
7233 char *pdata
= *ppdata
;
7235 if (total_data
< 18) {
7236 return NT_STATUS_INVALID_PARAMETER
;
7239 raw_unixmode
= IVAL(pdata
,8);
7240 /* Next 4 bytes are not yet defined. */
7242 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7243 PERM_NEW_DIR
, &unixmode
);
7244 if (!NT_STATUS_IS_OK(status
)) {
7248 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7250 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7251 smb_fname_str_dbg(smb_fname
), (unsigned int)unixmode
));
7253 status
= SMB_VFS_CREATE_FILE(
7256 0, /* root_dir_fid */
7257 smb_fname
, /* fname */
7258 FILE_READ_ATTRIBUTES
, /* access_mask */
7259 FILE_SHARE_NONE
, /* share_access */
7260 FILE_CREATE
, /* create_disposition*/
7261 FILE_DIRECTORY_FILE
, /* create_options */
7262 mod_unixmode
, /* file_attributes */
7263 0, /* oplock_request */
7264 0, /* allocation_size */
7265 0, /* private_flags */
7271 if (NT_STATUS_IS_OK(status
)) {
7272 close_file(req
, fsp
, NORMAL_CLOSE
);
7275 info_level_return
= SVAL(pdata
,16);
7277 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7278 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7279 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7280 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7282 *pdata_return_size
= 12;
7285 /* Realloc the data size */
7286 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7287 if (*ppdata
== NULL
) {
7288 *pdata_return_size
= 0;
7289 return NT_STATUS_NO_MEMORY
;
7293 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7294 SSVAL(pdata
,2,0); /* No fnum. */
7295 SIVAL(pdata
,4,info
); /* Was directory created. */
7297 switch (info_level_return
) {
7298 case SMB_QUERY_FILE_UNIX_BASIC
:
7299 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7300 SSVAL(pdata
,10,0); /* Padding. */
7301 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7304 case SMB_QUERY_FILE_UNIX_INFO2
:
7305 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7306 SSVAL(pdata
,10,0); /* Padding. */
7307 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7311 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7312 SSVAL(pdata
,10,0); /* Padding. */
7319 /****************************************************************************
7320 Open/Create a file with POSIX semantics.
7321 ****************************************************************************/
7323 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7324 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7326 static NTSTATUS
smb_posix_open(connection_struct
*conn
,
7327 struct smb_request
*req
,
7330 struct smb_filename
*smb_fname
,
7331 int *pdata_return_size
)
7333 bool extended_oplock_granted
= False
;
7334 char *pdata
= *ppdata
;
7336 uint32 wire_open_mode
= 0;
7337 uint32 raw_unixmode
= 0;
7338 uint32 mod_unixmode
= 0;
7339 uint32 create_disp
= 0;
7340 uint32 access_mask
= 0;
7341 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
7342 NTSTATUS status
= NT_STATUS_OK
;
7343 mode_t unixmode
= (mode_t
)0;
7344 files_struct
*fsp
= NULL
;
7345 int oplock_request
= 0;
7347 uint16 info_level_return
= 0;
7349 if (total_data
< 18) {
7350 return NT_STATUS_INVALID_PARAMETER
;
7353 flags
= IVAL(pdata
,0);
7354 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
7355 if (oplock_request
) {
7356 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
7359 wire_open_mode
= IVAL(pdata
,4);
7361 if (wire_open_mode
== (SMB_O_CREAT
|SMB_O_DIRECTORY
)) {
7362 return smb_posix_mkdir(conn
, req
,
7369 switch (wire_open_mode
& SMB_ACCMODE
) {
7371 access_mask
= SMB_O_RDONLY_MAPPING
;
7374 access_mask
= SMB_O_WRONLY_MAPPING
;
7377 access_mask
= (SMB_O_RDONLY_MAPPING
|
7378 SMB_O_WRONLY_MAPPING
);
7381 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7382 (unsigned int)wire_open_mode
));
7383 return NT_STATUS_INVALID_PARAMETER
;
7386 wire_open_mode
&= ~SMB_ACCMODE
;
7388 /* First take care of O_CREAT|O_EXCL interactions. */
7389 switch (wire_open_mode
& (SMB_O_CREAT
| SMB_O_EXCL
)) {
7390 case (SMB_O_CREAT
| SMB_O_EXCL
):
7391 /* File exists fail. File not exist create. */
7392 create_disp
= FILE_CREATE
;
7395 /* File exists open. File not exist create. */
7396 create_disp
= FILE_OPEN_IF
;
7399 /* O_EXCL on its own without O_CREAT is undefined.
7400 We deliberately ignore it as some versions of
7401 Linux CIFSFS can send a bare O_EXCL on the
7402 wire which other filesystems in the kernel
7403 ignore. See bug 9519 for details. */
7408 /* File exists open. File not exist fail. */
7409 create_disp
= FILE_OPEN
;
7412 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7413 (unsigned int)wire_open_mode
));
7414 return NT_STATUS_INVALID_PARAMETER
;
7417 /* Next factor in the effects of O_TRUNC. */
7418 wire_open_mode
&= ~(SMB_O_CREAT
| SMB_O_EXCL
);
7420 if (wire_open_mode
& SMB_O_TRUNC
) {
7421 switch (create_disp
) {
7423 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7424 /* Leave create_disp alone as
7425 (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7427 /* File exists fail. File not exist create. */
7430 /* SMB_O_CREAT | SMB_O_TRUNC */
7431 /* File exists overwrite. File not exist create. */
7432 create_disp
= FILE_OVERWRITE_IF
;
7436 /* File exists overwrite. File not exist fail. */
7437 create_disp
= FILE_OVERWRITE
;
7440 /* Cannot get here. */
7441 smb_panic("smb_posix_open: logic error");
7442 return NT_STATUS_INVALID_PARAMETER
;
7446 raw_unixmode
= IVAL(pdata
,8);
7447 /* Next 4 bytes are not yet defined. */
7449 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7450 (VALID_STAT(smb_fname
->st
) ?
7451 PERM_EXISTING_FILE
: PERM_NEW_FILE
),
7454 if (!NT_STATUS_IS_OK(status
)) {
7458 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7460 if (wire_open_mode
& SMB_O_SYNC
) {
7461 create_options
|= FILE_WRITE_THROUGH
;
7463 if (wire_open_mode
& SMB_O_APPEND
) {
7464 access_mask
|= FILE_APPEND_DATA
;
7466 if (wire_open_mode
& SMB_O_DIRECT
) {
7467 mod_unixmode
|= FILE_FLAG_NO_BUFFERING
;
7470 if ((wire_open_mode
& SMB_O_DIRECTORY
) ||
7471 VALID_STAT_OF_DIR(smb_fname
->st
)) {
7472 if (access_mask
!= SMB_O_RDONLY_MAPPING
) {
7473 return NT_STATUS_FILE_IS_A_DIRECTORY
;
7475 create_options
&= ~FILE_NON_DIRECTORY_FILE
;
7476 create_options
|= FILE_DIRECTORY_FILE
;
7479 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7480 smb_fname_str_dbg(smb_fname
),
7481 (unsigned int)wire_open_mode
,
7482 (unsigned int)unixmode
));
7484 status
= SMB_VFS_CREATE_FILE(
7487 0, /* root_dir_fid */
7488 smb_fname
, /* fname */
7489 access_mask
, /* access_mask */
7490 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7492 create_disp
, /* create_disposition*/
7493 create_options
, /* create_options */
7494 mod_unixmode
, /* file_attributes */
7495 oplock_request
, /* oplock_request */
7496 0, /* allocation_size */
7497 0, /* private_flags */
7503 if (!NT_STATUS_IS_OK(status
)) {
7507 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
7508 extended_oplock_granted
= True
;
7511 if(oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
7512 extended_oplock_granted
= True
;
7515 info_level_return
= SVAL(pdata
,16);
7517 /* Allocate the correct return size. */
7519 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7520 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7521 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7522 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7524 *pdata_return_size
= 12;
7527 /* Realloc the data size */
7528 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7529 if (*ppdata
== NULL
) {
7530 close_file(req
, fsp
, ERROR_CLOSE
);
7531 *pdata_return_size
= 0;
7532 return NT_STATUS_NO_MEMORY
;
7536 if (extended_oplock_granted
) {
7537 if (flags
& REQUEST_BATCH_OPLOCK
) {
7538 SSVAL(pdata
,0, BATCH_OPLOCK_RETURN
);
7540 SSVAL(pdata
,0, EXCLUSIVE_OPLOCK_RETURN
);
7542 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
7543 SSVAL(pdata
,0, LEVEL_II_OPLOCK_RETURN
);
7545 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7548 SSVAL(pdata
,2,fsp
->fnum
);
7549 SIVAL(pdata
,4,info
); /* Was file created etc. */
7551 switch (info_level_return
) {
7552 case SMB_QUERY_FILE_UNIX_BASIC
:
7553 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7554 SSVAL(pdata
,10,0); /* padding. */
7555 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7558 case SMB_QUERY_FILE_UNIX_INFO2
:
7559 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7560 SSVAL(pdata
,10,0); /* padding. */
7561 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7565 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7566 SSVAL(pdata
,10,0); /* padding. */
7569 return NT_STATUS_OK
;
7572 /****************************************************************************
7573 Delete a file with POSIX semantics.
7574 ****************************************************************************/
7576 static NTSTATUS
smb_posix_unlink(connection_struct
*conn
,
7577 struct smb_request
*req
,
7580 struct smb_filename
*smb_fname
)
7582 NTSTATUS status
= NT_STATUS_OK
;
7583 files_struct
*fsp
= NULL
;
7587 int create_options
= 0;
7589 struct share_mode_lock
*lck
= NULL
;
7591 if (total_data
< 2) {
7592 return NT_STATUS_INVALID_PARAMETER
;
7595 flags
= SVAL(pdata
,0);
7597 if (!VALID_STAT(smb_fname
->st
)) {
7598 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
7601 if ((flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) &&
7602 !VALID_STAT_OF_DIR(smb_fname
->st
)) {
7603 return NT_STATUS_NOT_A_DIRECTORY
;
7606 DEBUG(10,("smb_posix_unlink: %s %s\n",
7607 (flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) ? "directory" : "file",
7608 smb_fname_str_dbg(smb_fname
)));
7610 if (VALID_STAT_OF_DIR(smb_fname
->st
)) {
7611 create_options
|= FILE_DIRECTORY_FILE
;
7614 status
= SMB_VFS_CREATE_FILE(
7617 0, /* root_dir_fid */
7618 smb_fname
, /* fname */
7619 DELETE_ACCESS
, /* access_mask */
7620 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7622 FILE_OPEN
, /* create_disposition*/
7623 create_options
, /* create_options */
7624 FILE_FLAG_POSIX_SEMANTICS
|0777, /* file_attributes */
7625 0, /* oplock_request */
7626 0, /* allocation_size */
7627 0, /* private_flags */
7633 if (!NT_STATUS_IS_OK(status
)) {
7638 * Don't lie to client. If we can't really delete due to
7639 * non-POSIX opens return SHARING_VIOLATION.
7642 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
, NULL
, NULL
,
7645 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7646 "lock for file %s\n", fsp_str_dbg(fsp
)));
7647 close_file(req
, fsp
, NORMAL_CLOSE
);
7648 return NT_STATUS_INVALID_PARAMETER
;
7652 * See if others still have the file open. If this is the case, then
7653 * don't delete. If all opens are POSIX delete we can set the delete
7654 * on close disposition.
7656 for (i
=0; i
<lck
->num_share_modes
; i
++) {
7657 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
7658 if (is_valid_share_mode_entry(e
)) {
7659 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
7662 /* Fail with sharing violation. */
7664 close_file(req
, fsp
, NORMAL_CLOSE
);
7665 return NT_STATUS_SHARING_VIOLATION
;
7670 * Set the delete on close.
7672 status
= smb_set_file_disposition_info(conn
,
7680 if (!NT_STATUS_IS_OK(status
)) {
7681 close_file(req
, fsp
, NORMAL_CLOSE
);
7684 return close_file(req
, fsp
, NORMAL_CLOSE
);
7687 NTSTATUS
smbd_do_setfilepathinfo(connection_struct
*conn
,
7688 struct smb_request
*req
,
7689 TALLOC_CTX
*mem_ctx
,
7690 uint16_t info_level
,
7692 struct smb_filename
*smb_fname
,
7693 char **ppdata
, int total_data
,
7696 char *pdata
= *ppdata
;
7697 NTSTATUS status
= NT_STATUS_OK
;
7698 int data_return_size
= 0;
7702 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
7703 return NT_STATUS_INVALID_LEVEL
;
7706 if (!CAN_WRITE(conn
)) {
7707 /* Allow POSIX opens. The open path will deny
7708 * any non-readonly opens. */
7709 if (info_level
!= SMB_POSIX_PATH_OPEN
) {
7710 return NT_STATUS_DOS(ERRSRV
, ERRaccess
);
7714 DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
7715 "totdata=%d\n", smb_fname_str_dbg(smb_fname
),
7716 fsp
? fsp
->fnum
: -1, info_level
, total_data
));
7718 switch (info_level
) {
7720 case SMB_INFO_STANDARD
:
7722 status
= smb_set_info_standard(conn
,
7730 case SMB_INFO_SET_EA
:
7732 status
= smb_info_set_ea(conn
,
7740 case SMB_SET_FILE_BASIC_INFO
:
7741 case SMB_FILE_BASIC_INFORMATION
:
7743 status
= smb_set_file_basic_info(conn
,
7751 case SMB_FILE_ALLOCATION_INFORMATION
:
7752 case SMB_SET_FILE_ALLOCATION_INFO
:
7754 status
= smb_set_file_allocation_info(conn
, req
,
7762 case SMB_FILE_END_OF_FILE_INFORMATION
:
7763 case SMB_SET_FILE_END_OF_FILE_INFO
:
7766 * XP/Win7 both fail after the createfile with
7767 * SMB_SET_FILE_END_OF_FILE_INFO but not
7768 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7769 * The level is known here, so pass it down
7773 (info_level
== SMB_SET_FILE_END_OF_FILE_INFO
);
7775 status
= smb_set_file_end_of_file_info(conn
, req
,
7784 case SMB_FILE_DISPOSITION_INFORMATION
:
7785 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
7788 /* JRA - We used to just ignore this on a path ?
7789 * Shouldn't this be invalid level on a pathname
7792 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
7793 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
7796 status
= smb_set_file_disposition_info(conn
,
7804 case SMB_FILE_POSITION_INFORMATION
:
7806 status
= smb_file_position_information(conn
,
7813 case SMB_FILE_FULL_EA_INFORMATION
:
7815 status
= smb_set_file_full_ea_info(conn
,
7822 /* From tridge Samba4 :
7823 * MODE_INFORMATION in setfileinfo (I have no
7824 * idea what "mode information" on a file is - it takes a value of 0,
7825 * 2, 4 or 6. What could it be?).
7828 case SMB_FILE_MODE_INFORMATION
:
7830 status
= smb_file_mode_information(conn
,
7837 * CIFS UNIX extensions.
7840 case SMB_SET_FILE_UNIX_BASIC
:
7842 status
= smb_set_file_unix_basic(conn
, req
,
7850 case SMB_SET_FILE_UNIX_INFO2
:
7852 status
= smb_set_file_unix_info2(conn
, req
,
7860 case SMB_SET_FILE_UNIX_LINK
:
7863 /* We must have a pathname for this. */
7864 return NT_STATUS_INVALID_LEVEL
;
7866 status
= smb_set_file_unix_link(conn
, req
, pdata
,
7867 total_data
, smb_fname
);
7871 case SMB_SET_FILE_UNIX_HLINK
:
7874 /* We must have a pathname for this. */
7875 return NT_STATUS_INVALID_LEVEL
;
7877 status
= smb_set_file_unix_hlink(conn
, req
,
7883 case SMB_FILE_RENAME_INFORMATION
:
7885 status
= smb_file_rename_information(conn
, req
,
7891 case SMB2_FILE_RENAME_INFORMATION_INTERNAL
:
7893 /* SMB2 rename information. */
7894 status
= smb2_file_rename_information(conn
, req
,
7900 case SMB_FILE_LINK_INFORMATION
:
7902 status
= smb_file_link_information(conn
, req
,
7908 #if defined(HAVE_POSIX_ACLS)
7909 case SMB_SET_POSIX_ACL
:
7911 status
= smb_set_posix_acl(conn
,
7920 case SMB_SET_POSIX_LOCK
:
7923 return NT_STATUS_INVALID_LEVEL
;
7925 status
= smb_set_posix_lock(conn
, req
,
7926 pdata
, total_data
, fsp
);
7930 case SMB_POSIX_PATH_OPEN
:
7933 /* We must have a pathname for this. */
7934 return NT_STATUS_INVALID_LEVEL
;
7937 status
= smb_posix_open(conn
, req
,
7945 case SMB_POSIX_PATH_UNLINK
:
7948 /* We must have a pathname for this. */
7949 return NT_STATUS_INVALID_LEVEL
;
7952 status
= smb_posix_unlink(conn
, req
,
7960 return NT_STATUS_INVALID_LEVEL
;
7963 if (!NT_STATUS_IS_OK(status
)) {
7967 *ret_data_size
= data_return_size
;
7968 return NT_STATUS_OK
;
7971 /****************************************************************************
7972 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
7973 ****************************************************************************/
7975 static void call_trans2setfilepathinfo(connection_struct
*conn
,
7976 struct smb_request
*req
,
7977 unsigned int tran_call
,
7978 char **pparams
, int total_params
,
7979 char **ppdata
, int total_data
,
7980 unsigned int max_data_bytes
)
7982 char *params
= *pparams
;
7983 char *pdata
= *ppdata
;
7985 struct smb_filename
*smb_fname
= NULL
;
7986 files_struct
*fsp
= NULL
;
7987 NTSTATUS status
= NT_STATUS_OK
;
7988 int data_return_size
= 0;
7991 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7995 if (tran_call
== TRANSACT2_SETFILEINFO
) {
7996 if (total_params
< 4) {
7997 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8001 fsp
= file_fsp(req
, SVAL(params
,0));
8002 /* Basic check for non-null fsp. */
8003 if (!check_fsp_open(conn
, req
, fsp
)) {
8006 info_level
= SVAL(params
,2);
8008 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
8010 if (!NT_STATUS_IS_OK(status
)) {
8011 reply_nterror(req
, status
);
8015 if(fsp
->fh
->fd
== -1) {
8017 * This is actually a SETFILEINFO on a directory
8018 * handle (returned from an NT SMB). NT5.0 seems
8019 * to do this call. JRA.
8021 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8022 /* Always do lstat for UNIX calls. */
8023 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
8024 DEBUG(3,("call_trans2setfilepathinfo: "
8025 "SMB_VFS_LSTAT of %s failed "
8027 smb_fname_str_dbg(smb_fname
),
8029 reply_nterror(req
, map_nt_error_from_unix(errno
));
8033 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
8034 DEBUG(3,("call_trans2setfilepathinfo: "
8035 "fileinfo of %s failed (%s)\n",
8036 smb_fname_str_dbg(smb_fname
),
8038 reply_nterror(req
, map_nt_error_from_unix(errno
));
8042 } else if (fsp
->print_file
) {
8044 * Doing a DELETE_ON_CLOSE should cancel a print job.
8046 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
8047 fsp
->fh
->private_options
|= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE
;
8049 DEBUG(3,("call_trans2setfilepathinfo: "
8050 "Cancelling print job (%s)\n",
8054 send_trans2_replies(conn
, req
, params
, 2,
8060 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
8065 * Original code - this is an open file.
8067 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
8068 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8069 "of fnum %d failed (%s)\n", fsp
->fnum
,
8071 reply_nterror(req
, map_nt_error_from_unix(errno
));
8077 uint32_t ucf_flags
= 0;
8080 if (total_params
< 7) {
8081 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8085 info_level
= SVAL(params
,0);
8086 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
8087 total_params
- 6, STR_TERMINATE
,
8089 if (!NT_STATUS_IS_OK(status
)) {
8090 reply_nterror(req
, status
);
8094 if (info_level
== SMB_SET_FILE_UNIX_BASIC
||
8095 info_level
== SMB_SET_FILE_UNIX_INFO2
||
8096 info_level
== SMB_FILE_RENAME_INFORMATION
||
8097 info_level
== SMB_POSIX_PATH_UNLINK
) {
8098 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
8101 status
= filename_convert(req
, conn
,
8102 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8107 if (!NT_STATUS_IS_OK(status
)) {
8108 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8109 reply_botherror(req
,
8110 NT_STATUS_PATH_NOT_COVERED
,
8111 ERRSRV
, ERRbadpath
);
8114 reply_nterror(req
, status
);
8118 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8120 * For CIFS UNIX extensions the target name may not exist.
8123 /* Always do lstat for UNIX calls. */
8124 SMB_VFS_LSTAT(conn
, smb_fname
);
8126 } else if (!VALID_STAT(smb_fname
->st
) &&
8127 SMB_VFS_STAT(conn
, smb_fname
)) {
8128 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8130 smb_fname_str_dbg(smb_fname
),
8132 reply_nterror(req
, map_nt_error_from_unix(errno
));
8137 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
8138 "totdata=%d\n", tran_call
, smb_fname_str_dbg(smb_fname
),
8139 fsp
? fsp
->fnum
: -1, info_level
,total_data
));
8141 /* Realloc the parameter size */
8142 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8143 if (*pparams
== NULL
) {
8144 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8151 status
= smbd_do_setfilepathinfo(conn
, req
, req
,
8157 if (!NT_STATUS_IS_OK(status
)) {
8158 if (open_was_deferred(req
->mid
)) {
8159 /* We have re-scheduled this call. */
8162 if (blocking_lock_was_deferred_smb1(req
->sconn
, req
->mid
)) {
8163 /* We have re-scheduled this call. */
8166 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8167 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
8168 ERRSRV
, ERRbadpath
);
8171 if (info_level
== SMB_POSIX_PATH_OPEN
) {
8172 reply_openerror(req
, status
);
8176 reply_nterror(req
, status
);
8180 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, data_return_size
,
8186 /****************************************************************************
8187 Reply to a TRANS2_MKDIR (make directory with extended attributes).
8188 ****************************************************************************/
8190 static void call_trans2mkdir(connection_struct
*conn
, struct smb_request
*req
,
8191 char **pparams
, int total_params
,
8192 char **ppdata
, int total_data
,
8193 unsigned int max_data_bytes
)
8195 struct smb_filename
*smb_dname
= NULL
;
8196 char *params
= *pparams
;
8197 char *pdata
= *ppdata
;
8198 char *directory
= NULL
;
8199 NTSTATUS status
= NT_STATUS_OK
;
8200 struct ea_list
*ea_list
= NULL
;
8201 TALLOC_CTX
*ctx
= talloc_tos();
8203 if (!CAN_WRITE(conn
)) {
8204 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8208 if (total_params
< 5) {
8209 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8213 srvstr_get_path(ctx
, params
, req
->flags2
, &directory
, ¶ms
[4],
8214 total_params
- 4, STR_TERMINATE
,
8216 if (!NT_STATUS_IS_OK(status
)) {
8217 reply_nterror(req
, status
);
8221 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
8223 status
= filename_convert(ctx
,
8225 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8231 if (!NT_STATUS_IS_OK(status
)) {
8232 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8233 reply_botherror(req
,
8234 NT_STATUS_PATH_NOT_COVERED
,
8235 ERRSRV
, ERRbadpath
);
8238 reply_nterror(req
, status
);
8243 * OS/2 workplace shell seems to send SET_EA requests of "null"
8244 * length (4 bytes containing IVAL 4).
8245 * They seem to have no effect. Bug #3212. JRA.
8248 if (total_data
&& (total_data
!= 4)) {
8249 /* Any data in this call is an EA list. */
8250 if (total_data
< 10) {
8251 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8255 if (IVAL(pdata
,0) > total_data
) {
8256 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8257 IVAL(pdata
,0), (unsigned int)total_data
));
8258 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8262 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
8265 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8269 if (!lp_ea_support(SNUM(conn
))) {
8270 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
8274 /* If total_data == 4 Windows doesn't care what values
8275 * are placed in that field, it just ignores them.
8276 * The System i QNTC IBM SMB client puts bad values here,
8277 * so ignore them. */
8279 status
= create_directory(conn
, req
, smb_dname
);
8281 if (!NT_STATUS_IS_OK(status
)) {
8282 reply_nterror(req
, status
);
8286 /* Try and set any given EA. */
8288 status
= set_ea(conn
, NULL
, smb_dname
, ea_list
);
8289 if (!NT_STATUS_IS_OK(status
)) {
8290 reply_nterror(req
, status
);
8295 /* Realloc the parameter and data sizes */
8296 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8297 if(*pparams
== NULL
) {
8298 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8305 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, 0, max_data_bytes
);
8308 TALLOC_FREE(smb_dname
);
8312 /****************************************************************************
8313 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8314 We don't actually do this - we just send a null response.
8315 ****************************************************************************/
8317 static void call_trans2findnotifyfirst(connection_struct
*conn
,
8318 struct smb_request
*req
,
8319 char **pparams
, int total_params
,
8320 char **ppdata
, int total_data
,
8321 unsigned int max_data_bytes
)
8323 char *params
= *pparams
;
8326 if (total_params
< 6) {
8327 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8331 info_level
= SVAL(params
,4);
8332 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
8334 switch (info_level
) {
8339 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
8343 /* Realloc the parameter and data sizes */
8344 *pparams
= (char *)SMB_REALLOC(*pparams
,6);
8345 if (*pparams
== NULL
) {
8346 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8351 SSVAL(params
,0,fnf_handle
);
8352 SSVAL(params
,2,0); /* No changes */
8353 SSVAL(params
,4,0); /* No EA errors */
8360 send_trans2_replies(conn
, req
, params
, 6, *ppdata
, 0, max_data_bytes
);
8365 /****************************************************************************
8366 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
8367 changes). Currently this does nothing.
8368 ****************************************************************************/
8370 static void call_trans2findnotifynext(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
;
8378 DEBUG(3,("call_trans2findnotifynext\n"));
8380 /* Realloc the parameter and data sizes */
8381 *pparams
= (char *)SMB_REALLOC(*pparams
,4);
8382 if (*pparams
== NULL
) {
8383 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8388 SSVAL(params
,0,0); /* No changes */
8389 SSVAL(params
,2,0); /* No EA errors */
8391 send_trans2_replies(conn
, req
, params
, 4, *ppdata
, 0, max_data_bytes
);
8396 /****************************************************************************
8397 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8398 ****************************************************************************/
8400 static void call_trans2getdfsreferral(connection_struct
*conn
,
8401 struct smb_request
*req
,
8402 char **pparams
, int total_params
,
8403 char **ppdata
, int total_data
,
8404 unsigned int max_data_bytes
)
8406 char *params
= *pparams
;
8407 char *pathname
= NULL
;
8409 int max_referral_level
;
8410 NTSTATUS status
= NT_STATUS_OK
;
8411 TALLOC_CTX
*ctx
= talloc_tos();
8413 DEBUG(10,("call_trans2getdfsreferral\n"));
8415 if (total_params
< 3) {
8416 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8420 max_referral_level
= SVAL(params
,0);
8422 if(!lp_host_msdfs()) {
8423 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8427 srvstr_pull_talloc(ctx
, params
, req
->flags2
, &pathname
, ¶ms
[2],
8428 total_params
- 2, STR_TERMINATE
);
8430 reply_nterror(req
, NT_STATUS_NOT_FOUND
);
8433 if((reply_size
= setup_dfs_referral(conn
, pathname
, max_referral_level
,
8434 ppdata
,&status
)) < 0) {
8435 reply_nterror(req
, status
);
8439 SSVAL(req
->inbuf
, smb_flg2
,
8440 SVAL(req
->inbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
8441 send_trans2_replies(conn
, req
,0,0,*ppdata
,reply_size
, max_data_bytes
);
8446 #define LMCAT_SPL 0x53
8447 #define LMFUNC_GETJOBID 0x60
8449 /****************************************************************************
8450 Reply to a TRANS2_IOCTL - used for OS/2 printing.
8451 ****************************************************************************/
8453 static void call_trans2ioctl(connection_struct
*conn
,
8454 struct smb_request
*req
,
8455 char **pparams
, int total_params
,
8456 char **ppdata
, int total_data
,
8457 unsigned int max_data_bytes
)
8459 char *pdata
= *ppdata
;
8460 files_struct
*fsp
= file_fsp(req
, SVAL(req
->vwv
+15, 0));
8462 /* check for an invalid fid before proceeding */
8465 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8469 if ((SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8470 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8471 *ppdata
= (char *)SMB_REALLOC(*ppdata
, 32);
8472 if (*ppdata
== NULL
) {
8473 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8478 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8479 CAN ACCEPT THIS IN UNICODE. JRA. */
8482 if (fsp
->print_file
) {
8483 SSVAL(pdata
, 0, fsp
->print_file
->rap_jobid
);
8487 srvstr_push(pdata
, req
->flags2
, pdata
+ 2,
8488 global_myname(), 15,
8489 STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
8490 srvstr_push(pdata
, req
->flags2
, pdata
+18,
8491 lp_servicename(SNUM(conn
)), 13,
8492 STR_ASCII
|STR_TERMINATE
); /* Service name */
8493 send_trans2_replies(conn
, req
, *pparams
, 0, *ppdata
, 32,
8498 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8499 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8502 /****************************************************************************
8503 Reply to a SMBfindclose (stop trans2 directory search).
8504 ****************************************************************************/
8506 void reply_findclose(struct smb_request
*req
)
8509 struct smbd_server_connection
*sconn
= req
->sconn
;
8511 START_PROFILE(SMBfindclose
);
8514 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8515 END_PROFILE(SMBfindclose
);
8519 dptr_num
= SVALS(req
->vwv
+0, 0);
8521 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
8523 dptr_close(sconn
, &dptr_num
);
8525 reply_outbuf(req
, 0, 0);
8527 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
8529 END_PROFILE(SMBfindclose
);
8533 /****************************************************************************
8534 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8535 ****************************************************************************/
8537 void reply_findnclose(struct smb_request
*req
)
8541 START_PROFILE(SMBfindnclose
);
8544 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8545 END_PROFILE(SMBfindnclose
);
8549 dptr_num
= SVAL(req
->vwv
+0, 0);
8551 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
8553 /* We never give out valid handles for a
8554 findnotifyfirst - so any dptr_num is ok here.
8557 reply_outbuf(req
, 0, 0);
8559 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
8561 END_PROFILE(SMBfindnclose
);
8565 static void handle_trans2(connection_struct
*conn
, struct smb_request
*req
,
8566 struct trans_state
*state
)
8568 if (get_Protocol() >= PROTOCOL_NT1
) {
8569 req
->flags2
|= 0x40; /* IS_LONG_NAME */
8570 SSVAL(req
->inbuf
,smb_flg2
,req
->flags2
);
8573 if (conn
->encrypt_level
== Required
&& !req
->encrypted
) {
8574 if (state
->call
!= TRANSACT2_QFSINFO
&&
8575 state
->call
!= TRANSACT2_SETFSINFO
) {
8576 DEBUG(0,("handle_trans2: encryption required "
8578 (unsigned int)state
->call
));
8579 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8584 SMB_PERFCOUNT_SET_SUBOP(&req
->pcd
, state
->call
);
8586 /* Now we must call the relevant TRANS2 function */
8587 switch(state
->call
) {
8588 case TRANSACT2_OPEN
:
8590 START_PROFILE(Trans2_open
);
8591 call_trans2open(conn
, req
,
8592 &state
->param
, state
->total_param
,
8593 &state
->data
, state
->total_data
,
8594 state
->max_data_return
);
8595 END_PROFILE(Trans2_open
);
8599 case TRANSACT2_FINDFIRST
:
8601 START_PROFILE(Trans2_findfirst
);
8602 call_trans2findfirst(conn
, req
,
8603 &state
->param
, state
->total_param
,
8604 &state
->data
, state
->total_data
,
8605 state
->max_data_return
);
8606 END_PROFILE(Trans2_findfirst
);
8610 case TRANSACT2_FINDNEXT
:
8612 START_PROFILE(Trans2_findnext
);
8613 call_trans2findnext(conn
, req
,
8614 &state
->param
, state
->total_param
,
8615 &state
->data
, state
->total_data
,
8616 state
->max_data_return
);
8617 END_PROFILE(Trans2_findnext
);
8621 case TRANSACT2_QFSINFO
:
8623 START_PROFILE(Trans2_qfsinfo
);
8624 call_trans2qfsinfo(conn
, req
,
8625 &state
->param
, state
->total_param
,
8626 &state
->data
, state
->total_data
,
8627 state
->max_data_return
);
8628 END_PROFILE(Trans2_qfsinfo
);
8632 case TRANSACT2_SETFSINFO
:
8634 START_PROFILE(Trans2_setfsinfo
);
8635 call_trans2setfsinfo(conn
, req
,
8636 &state
->param
, state
->total_param
,
8637 &state
->data
, state
->total_data
,
8638 state
->max_data_return
);
8639 END_PROFILE(Trans2_setfsinfo
);
8643 case TRANSACT2_QPATHINFO
:
8644 case TRANSACT2_QFILEINFO
:
8646 START_PROFILE(Trans2_qpathinfo
);
8647 call_trans2qfilepathinfo(conn
, req
, state
->call
,
8648 &state
->param
, state
->total_param
,
8649 &state
->data
, state
->total_data
,
8650 state
->max_data_return
);
8651 END_PROFILE(Trans2_qpathinfo
);
8655 case TRANSACT2_SETPATHINFO
:
8656 case TRANSACT2_SETFILEINFO
:
8658 START_PROFILE(Trans2_setpathinfo
);
8659 call_trans2setfilepathinfo(conn
, req
, state
->call
,
8660 &state
->param
, state
->total_param
,
8661 &state
->data
, state
->total_data
,
8662 state
->max_data_return
);
8663 END_PROFILE(Trans2_setpathinfo
);
8667 case TRANSACT2_FINDNOTIFYFIRST
:
8669 START_PROFILE(Trans2_findnotifyfirst
);
8670 call_trans2findnotifyfirst(conn
, req
,
8671 &state
->param
, state
->total_param
,
8672 &state
->data
, state
->total_data
,
8673 state
->max_data_return
);
8674 END_PROFILE(Trans2_findnotifyfirst
);
8678 case TRANSACT2_FINDNOTIFYNEXT
:
8680 START_PROFILE(Trans2_findnotifynext
);
8681 call_trans2findnotifynext(conn
, req
,
8682 &state
->param
, state
->total_param
,
8683 &state
->data
, state
->total_data
,
8684 state
->max_data_return
);
8685 END_PROFILE(Trans2_findnotifynext
);
8689 case TRANSACT2_MKDIR
:
8691 START_PROFILE(Trans2_mkdir
);
8692 call_trans2mkdir(conn
, req
,
8693 &state
->param
, state
->total_param
,
8694 &state
->data
, state
->total_data
,
8695 state
->max_data_return
);
8696 END_PROFILE(Trans2_mkdir
);
8700 case TRANSACT2_GET_DFS_REFERRAL
:
8702 START_PROFILE(Trans2_get_dfs_referral
);
8703 call_trans2getdfsreferral(conn
, req
,
8704 &state
->param
, state
->total_param
,
8705 &state
->data
, state
->total_data
,
8706 state
->max_data_return
);
8707 END_PROFILE(Trans2_get_dfs_referral
);
8711 case TRANSACT2_IOCTL
:
8713 START_PROFILE(Trans2_ioctl
);
8714 call_trans2ioctl(conn
, req
,
8715 &state
->param
, state
->total_param
,
8716 &state
->data
, state
->total_data
,
8717 state
->max_data_return
);
8718 END_PROFILE(Trans2_ioctl
);
8723 /* Error in request */
8724 DEBUG(2,("Unknown request %d in trans2 call\n", state
->call
));
8725 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8729 /****************************************************************************
8730 Reply to a SMBtrans2.
8731 ****************************************************************************/
8733 void reply_trans2(struct smb_request
*req
)
8735 connection_struct
*conn
= req
->conn
;
8740 unsigned int tran_call
;
8741 struct trans_state
*state
;
8744 START_PROFILE(SMBtrans2
);
8746 if (req
->wct
< 14) {
8747 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8748 END_PROFILE(SMBtrans2
);
8752 dsoff
= SVAL(req
->vwv
+12, 0);
8753 dscnt
= SVAL(req
->vwv
+11, 0);
8754 psoff
= SVAL(req
->vwv
+10, 0);
8755 pscnt
= SVAL(req
->vwv
+9, 0);
8756 tran_call
= SVAL(req
->vwv
+14, 0);
8758 result
= allow_new_trans(conn
->pending_trans
, req
->mid
);
8759 if (!NT_STATUS_IS_OK(result
)) {
8760 DEBUG(2, ("Got invalid trans2 request: %s\n",
8761 nt_errstr(result
)));
8762 reply_nterror(req
, result
);
8763 END_PROFILE(SMBtrans2
);
8768 switch (tran_call
) {
8769 /* List the allowed trans2 calls on IPC$ */
8770 case TRANSACT2_OPEN
:
8771 case TRANSACT2_GET_DFS_REFERRAL
:
8772 case TRANSACT2_QFILEINFO
:
8773 case TRANSACT2_QFSINFO
:
8774 case TRANSACT2_SETFSINFO
:
8777 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8778 END_PROFILE(SMBtrans2
);
8783 if ((state
= TALLOC_P(conn
, struct trans_state
)) == NULL
) {
8784 DEBUG(0, ("talloc failed\n"));
8785 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8786 END_PROFILE(SMBtrans2
);
8790 state
->cmd
= SMBtrans2
;
8792 state
->mid
= req
->mid
;
8793 state
->vuid
= req
->vuid
;
8794 state
->setup_count
= SVAL(req
->vwv
+13, 0);
8795 state
->setup
= NULL
;
8796 state
->total_param
= SVAL(req
->vwv
+0, 0);
8797 state
->param
= NULL
;
8798 state
->total_data
= SVAL(req
->vwv
+1, 0);
8800 state
->max_param_return
= SVAL(req
->vwv
+2, 0);
8801 state
->max_data_return
= SVAL(req
->vwv
+3, 0);
8802 state
->max_setup_return
= SVAL(req
->vwv
+4, 0);
8803 state
->close_on_completion
= BITSETW(req
->vwv
+5, 0);
8804 state
->one_way
= BITSETW(req
->vwv
+5, 1);
8806 state
->call
= tran_call
;
8808 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8809 is so as a sanity check */
8810 if (state
->setup_count
!= 1) {
8812 * Need to have rc=0 for ioctl to get job id for OS/2.
8813 * Network printing will fail if function is not successful.
8814 * Similar function in reply.c will be used if protocol
8815 * is LANMAN1.0 instead of LM1.2X002.
8816 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
8817 * outbuf doesn't have to be set(only job id is used).
8819 if ( (state
->setup_count
== 4)
8820 && (tran_call
== TRANSACT2_IOCTL
)
8821 && (SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8822 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8823 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8825 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state
->setup_count
));
8826 DEBUG(2,("Transaction is %d\n",tran_call
));
8828 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8829 END_PROFILE(SMBtrans2
);
8834 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
8837 if (state
->total_data
) {
8839 if (trans_oob(state
->total_data
, 0, dscnt
)
8840 || trans_oob(smb_len(req
->inbuf
), dsoff
, dscnt
)) {
8844 /* Can't use talloc here, the core routines do realloc on the
8845 * params and data. */
8846 state
->data
= (char *)SMB_MALLOC(state
->total_data
);
8847 if (state
->data
== NULL
) {
8848 DEBUG(0,("reply_trans2: data malloc fail for %u "
8849 "bytes !\n", (unsigned int)state
->total_data
));
8851 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8852 END_PROFILE(SMBtrans2
);
8856 memcpy(state
->data
,smb_base(req
->inbuf
)+dsoff
,dscnt
);
8859 if (state
->total_param
) {
8861 if (trans_oob(state
->total_param
, 0, pscnt
)
8862 || trans_oob(smb_len(req
->inbuf
), psoff
, pscnt
)) {
8866 /* Can't use talloc here, the core routines do realloc on the
8867 * params and data. */
8868 state
->param
= (char *)SMB_MALLOC(state
->total_param
);
8869 if (state
->param
== NULL
) {
8870 DEBUG(0,("reply_trans: param malloc fail for %u "
8871 "bytes !\n", (unsigned int)state
->total_param
));
8872 SAFE_FREE(state
->data
);
8874 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8875 END_PROFILE(SMBtrans2
);
8879 memcpy(state
->param
,smb_base(req
->inbuf
)+psoff
,pscnt
);
8882 state
->received_data
= dscnt
;
8883 state
->received_param
= pscnt
;
8885 if ((state
->received_param
== state
->total_param
) &&
8886 (state
->received_data
== state
->total_data
)) {
8888 handle_trans2(conn
, req
, state
);
8890 SAFE_FREE(state
->data
);
8891 SAFE_FREE(state
->param
);
8893 END_PROFILE(SMBtrans2
);
8897 DLIST_ADD(conn
->pending_trans
, state
);
8899 /* We need to send an interim response then receive the rest
8900 of the parameter/data bytes */
8901 reply_outbuf(req
, 0, 0);
8902 show_msg((char *)req
->outbuf
);
8903 END_PROFILE(SMBtrans2
);
8908 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8909 SAFE_FREE(state
->data
);
8910 SAFE_FREE(state
->param
);
8912 END_PROFILE(SMBtrans2
);
8913 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8917 /****************************************************************************
8918 Reply to a SMBtranss2
8919 ****************************************************************************/
8921 void reply_transs2(struct smb_request
*req
)
8923 connection_struct
*conn
= req
->conn
;
8924 unsigned int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
8925 struct trans_state
*state
;
8927 START_PROFILE(SMBtranss2
);
8929 show_msg((char *)req
->inbuf
);
8931 /* Windows clients expect all replies to
8932 a transact secondary (SMBtranss2 0x33)
8933 to have a command code of transact
8934 (SMBtrans2 0x32). See bug #8989
8935 and also [MS-CIFS] section 2.2.4.47.2
8938 req
->cmd
= SMBtrans2
;
8941 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8942 END_PROFILE(SMBtranss2
);
8946 for (state
= conn
->pending_trans
; state
!= NULL
;
8947 state
= state
->next
) {
8948 if (state
->mid
== req
->mid
) {
8953 if ((state
== NULL
) || (state
->cmd
!= SMBtrans2
)) {
8954 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8955 END_PROFILE(SMBtranss2
);
8959 /* Revise state->total_param and state->total_data in case they have
8960 changed downwards */
8962 if (SVAL(req
->vwv
+0, 0) < state
->total_param
)
8963 state
->total_param
= SVAL(req
->vwv
+0, 0);
8964 if (SVAL(req
->vwv
+1, 0) < state
->total_data
)
8965 state
->total_data
= SVAL(req
->vwv
+1, 0);
8967 pcnt
= SVAL(req
->vwv
+2, 0);
8968 poff
= SVAL(req
->vwv
+3, 0);
8969 pdisp
= SVAL(req
->vwv
+4, 0);
8971 dcnt
= SVAL(req
->vwv
+5, 0);
8972 doff
= SVAL(req
->vwv
+6, 0);
8973 ddisp
= SVAL(req
->vwv
+7, 0);
8975 state
->received_param
+= pcnt
;
8976 state
->received_data
+= dcnt
;
8978 if ((state
->received_data
> state
->total_data
) ||
8979 (state
->received_param
> state
->total_param
))
8983 if (trans_oob(state
->total_param
, pdisp
, pcnt
)
8984 || trans_oob(smb_len(req
->inbuf
), poff
, pcnt
)) {
8987 memcpy(state
->param
+pdisp
,smb_base(req
->inbuf
)+poff
,pcnt
);
8991 if (trans_oob(state
->total_data
, ddisp
, dcnt
)
8992 || trans_oob(smb_len(req
->inbuf
), doff
, dcnt
)) {
8995 memcpy(state
->data
+ddisp
, smb_base(req
->inbuf
)+doff
,dcnt
);
8998 if ((state
->received_param
< state
->total_param
) ||
8999 (state
->received_data
< state
->total_data
)) {
9000 END_PROFILE(SMBtranss2
);
9004 handle_trans2(conn
, req
, state
);
9006 DLIST_REMOVE(conn
->pending_trans
, state
);
9007 SAFE_FREE(state
->data
);
9008 SAFE_FREE(state
->param
);
9011 END_PROFILE(SMBtranss2
);
9016 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
9017 DLIST_REMOVE(conn
->pending_trans
, state
);
9018 SAFE_FREE(state
->data
);
9019 SAFE_FREE(state
->param
);
9021 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9022 END_PROFILE(SMBtranss2
);