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
)));
3149 case SMB_QUERY_FS_SIZE_INFO
:
3150 case SMB_FS_SIZE_INFORMATION
:
3152 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3154 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3155 return map_nt_error_from_unix(errno
);
3157 block_size
= lp_block_size(snum
);
3158 if (bsize
< block_size
) {
3159 uint64_t factor
= block_size
/bsize
;
3164 if (bsize
> block_size
) {
3165 uint64_t factor
= bsize
/block_size
;
3170 bytes_per_sector
= 512;
3171 sectors_per_unit
= bsize
/bytes_per_sector
;
3172 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3173 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3174 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3175 SBIG_UINT(pdata
,0,dsize
);
3176 SBIG_UINT(pdata
,8,dfree
);
3177 SIVAL(pdata
,16,sectors_per_unit
);
3178 SIVAL(pdata
,20,bytes_per_sector
);
3182 case SMB_FS_FULL_SIZE_INFORMATION
:
3184 uint64_t dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
3186 if (get_dfree_info(conn
,filename
,False
,&bsize
,&dfree
,&dsize
) == (uint64_t)-1) {
3187 return map_nt_error_from_unix(errno
);
3189 block_size
= lp_block_size(snum
);
3190 if (bsize
< block_size
) {
3191 uint64_t factor
= block_size
/bsize
;
3196 if (bsize
> block_size
) {
3197 uint64_t factor
= bsize
/block_size
;
3202 bytes_per_sector
= 512;
3203 sectors_per_unit
= bsize
/bytes_per_sector
;
3204 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3205 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
3206 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
3207 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
3208 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
3209 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
3210 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
3211 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
3215 case SMB_QUERY_FS_DEVICE_INFO
:
3216 case SMB_FS_DEVICE_INFORMATION
:
3218 uint32_t characteristics
= FILE_DEVICE_IS_MOUNTED
;
3220 if (!CAN_WRITE(conn
)) {
3221 characteristics
|= FILE_READ_ONLY_DEVICE
;
3224 SIVAL(pdata
,0,FILE_DEVICE_DISK
); /* dev type */
3225 SIVAL(pdata
,4,characteristics
);
3229 #ifdef HAVE_SYS_QUOTAS
3230 case SMB_FS_QUOTA_INFORMATION
:
3232 * what we have to send --metze:
3234 * Unknown1: 24 NULL bytes
3235 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3236 * Hard Quota Limit: 8 bytes seems like uint64_t or so
3237 * Quota Flags: 2 byte :
3238 * Unknown3: 6 NULL bytes
3242 * details for Quota Flags:
3244 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3245 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
3246 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3247 * 0x0001 Enable Quotas: enable quota for this fs
3251 /* we need to fake up a fsp here,
3252 * because its not send in this call
3255 SMB_NTQUOTA_STRUCT quotas
;
3258 ZERO_STRUCT(quotas
);
3264 if (get_current_uid(conn
) != 0) {
3265 DEBUG(0,("set_user_quota: access_denied "
3266 "service [%s] user [%s]\n",
3267 lp_servicename(SNUM(conn
)),
3268 conn
->session_info
->unix_name
));
3269 return NT_STATUS_ACCESS_DENIED
;
3272 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3273 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3274 return map_nt_error_from_unix(errno
);
3279 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3280 lp_servicename(SNUM(conn
))));
3282 /* Unknown1 24 NULL bytes*/
3283 SBIG_UINT(pdata
,0,(uint64_t)0);
3284 SBIG_UINT(pdata
,8,(uint64_t)0);
3285 SBIG_UINT(pdata
,16,(uint64_t)0);
3287 /* Default Soft Quota 8 bytes */
3288 SBIG_UINT(pdata
,24,quotas
.softlim
);
3290 /* Default Hard Quota 8 bytes */
3291 SBIG_UINT(pdata
,32,quotas
.hardlim
);
3293 /* Quota flag 2 bytes */
3294 SSVAL(pdata
,40,quotas
.qflags
);
3296 /* Unknown3 6 NULL bytes */
3302 #endif /* HAVE_SYS_QUOTAS */
3303 case SMB_FS_OBJECTID_INFORMATION
:
3305 unsigned char objid
[16];
3306 struct smb_extended_info extended_info
;
3307 memcpy(pdata
,create_volume_objectid(conn
, objid
),16);
3308 samba_extended_info_version (&extended_info
);
3309 SIVAL(pdata
,16,extended_info
.samba_magic
);
3310 SIVAL(pdata
,20,extended_info
.samba_version
);
3311 SIVAL(pdata
,24,extended_info
.samba_subversion
);
3312 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
3313 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
3319 * Query the version and capabilities of the CIFS UNIX extensions
3323 case SMB_QUERY_CIFS_UNIX_INFO
:
3325 bool large_write
= lp_min_receive_file_size() &&
3326 !srv_is_signing_active(conn
->sconn
);
3327 bool large_read
= !srv_is_signing_active(conn
->sconn
);
3328 int encrypt_caps
= 0;
3330 if (!lp_unix_extensions()) {
3331 return NT_STATUS_INVALID_LEVEL
;
3334 switch (conn
->encrypt_level
) {
3340 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
;
3343 encrypt_caps
= CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
|
3344 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP
;
3345 large_write
= false;
3351 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
3352 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
3354 /* We have POSIX ACLs, pathname, encryption,
3355 * large read/write, and locking capability. */
3357 SBIG_UINT(pdata
,4,((uint64_t)(
3358 CIFS_UNIX_POSIX_ACLS_CAP
|
3359 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
3360 CIFS_UNIX_FCNTL_LOCKS_CAP
|
3361 CIFS_UNIX_EXTATTR_CAP
|
3362 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
|
3364 (large_read
? CIFS_UNIX_LARGE_READ_CAP
: 0) |
3366 CIFS_UNIX_LARGE_WRITE_CAP
: 0))));
3370 case SMB_QUERY_POSIX_FS_INFO
:
3373 vfs_statvfs_struct svfs
;
3375 if (!lp_unix_extensions()) {
3376 return NT_STATUS_INVALID_LEVEL
;
3379 rc
= SMB_VFS_STATVFS(conn
, filename
, &svfs
);
3383 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
3384 SIVAL(pdata
,4,svfs
.BlockSize
);
3385 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
3386 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
3387 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
3388 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
3389 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
3390 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
3391 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3393 } else if (rc
== EOPNOTSUPP
) {
3394 return NT_STATUS_INVALID_LEVEL
;
3395 #endif /* EOPNOTSUPP */
3397 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3398 return NT_STATUS_DOS(ERRSRV
, ERRerror
);
3403 case SMB_QUERY_POSIX_WHOAMI
:
3409 if (!lp_unix_extensions()) {
3410 return NT_STATUS_INVALID_LEVEL
;
3413 if (max_data_bytes
< 40) {
3414 return NT_STATUS_BUFFER_TOO_SMALL
;
3417 /* We ARE guest if global_sid_Builtin_Guests is
3418 * in our list of SIDs.
3420 if (nt_token_check_sid(&global_sid_Builtin_Guests
,
3421 conn
->session_info
->security_token
)) {
3422 flags
|= SMB_WHOAMI_GUEST
;
3425 /* We are NOT guest if global_sid_Authenticated_Users
3426 * is in our list of SIDs.
3428 if (nt_token_check_sid(&global_sid_Authenticated_Users
,
3429 conn
->session_info
->security_token
)) {
3430 flags
&= ~SMB_WHOAMI_GUEST
;
3433 /* NOTE: 8 bytes for UID/GID, irrespective of native
3434 * platform size. This matches
3435 * SMB_QUERY_FILE_UNIX_BASIC and friends.
3437 data_len
= 4 /* flags */
3444 + 4 /* pad/reserved */
3445 + (conn
->session_info
->utok
.ngroups
* 8)
3447 + (conn
->session_info
->security_token
->num_sids
*
3451 SIVAL(pdata
, 0, flags
);
3452 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
3454 (uint64_t)conn
->session_info
->utok
.uid
);
3455 SBIG_UINT(pdata
, 16,
3456 (uint64_t)conn
->session_info
->utok
.gid
);
3459 if (data_len
>= max_data_bytes
) {
3460 /* Potential overflow, skip the GIDs and SIDs. */
3462 SIVAL(pdata
, 24, 0); /* num_groups */
3463 SIVAL(pdata
, 28, 0); /* num_sids */
3464 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
3465 SIVAL(pdata
, 36, 0); /* reserved */
3471 SIVAL(pdata
, 24, conn
->session_info
->utok
.ngroups
);
3472 SIVAL(pdata
, 28, conn
->session_info
->security_token
->num_sids
);
3474 /* We walk the SID list twice, but this call is fairly
3475 * infrequent, and I don't expect that it's performance
3476 * sensitive -- jpeach
3478 for (i
= 0, sid_bytes
= 0;
3479 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3480 sid_bytes
+= ndr_size_dom_sid(
3481 &conn
->session_info
->security_token
->sids
[i
],
3485 /* SID list byte count */
3486 SIVAL(pdata
, 32, sid_bytes
);
3488 /* 4 bytes pad/reserved - must be zero */
3489 SIVAL(pdata
, 36, 0);
3493 for (i
= 0; i
< conn
->session_info
->utok
.ngroups
; ++i
) {
3494 SBIG_UINT(pdata
, data_len
,
3495 (uint64_t)conn
->session_info
->utok
.groups
[i
]);
3501 i
< conn
->session_info
->security_token
->num_sids
; ++i
) {
3502 int sid_len
= ndr_size_dom_sid(
3503 &conn
->session_info
->security_token
->sids
[i
],
3506 sid_linearize(pdata
+ data_len
, sid_len
,
3507 &conn
->session_info
->security_token
->sids
[i
]);
3508 data_len
+= sid_len
;
3514 case SMB_MAC_QUERY_FS_INFO
:
3516 * Thursby MAC extension... ONLY on NTFS filesystems
3517 * once we do streams then we don't need this
3519 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
3521 SIVAL(pdata
,84,0x100); /* Don't support mac... */
3526 return NT_STATUS_INVALID_LEVEL
;
3529 *ret_data_len
= data_len
;
3533 /****************************************************************************
3534 Reply to a TRANS2_QFSINFO (query filesystem info).
3535 ****************************************************************************/
3537 static void call_trans2qfsinfo(connection_struct
*conn
,
3538 struct smb_request
*req
,
3539 char **pparams
, int total_params
,
3540 char **ppdata
, int total_data
,
3541 unsigned int max_data_bytes
)
3543 char *params
= *pparams
;
3544 uint16_t info_level
;
3548 if (total_params
< 2) {
3549 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3553 info_level
= SVAL(params
,0);
3555 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3556 if (info_level
!= SMB_QUERY_CIFS_UNIX_INFO
) {
3557 DEBUG(0,("call_trans2qfsinfo: encryption required "
3558 "and info level 0x%x sent.\n",
3559 (unsigned int)info_level
));
3560 exit_server_cleanly("encryption required "
3566 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
3568 status
= smbd_do_qfsinfo(conn
, req
,
3574 if (!NT_STATUS_IS_OK(status
)) {
3575 reply_nterror(req
, status
);
3579 send_trans2_replies(conn
, req
, params
, 0, *ppdata
, data_len
,
3582 DEBUG( 4, ( "%s info_level = %d\n",
3583 smb_fn_name(req
->cmd
), info_level
) );
3588 /****************************************************************************
3589 Reply to a TRANS2_SETFSINFO (set filesystem info).
3590 ****************************************************************************/
3592 static void call_trans2setfsinfo(connection_struct
*conn
,
3593 struct smb_request
*req
,
3594 char **pparams
, int total_params
,
3595 char **ppdata
, int total_data
,
3596 unsigned int max_data_bytes
)
3598 char *pdata
= *ppdata
;
3599 char *params
= *pparams
;
3602 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn
))));
3605 if (total_params
< 4) {
3606 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3608 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
3612 info_level
= SVAL(params
,2);
3615 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
&&
3616 info_level
!= SMB_SET_CIFS_UNIX_INFO
) {
3617 DEBUG(0,("call_trans2setfsinfo: not an allowed "
3618 "info level (0x%x) on IPC$.\n",
3619 (unsigned int)info_level
));
3620 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3625 if (ENCRYPTION_REQUIRED(conn
) && !req
->encrypted
) {
3626 if (info_level
!= SMB_REQUEST_TRANSPORT_ENCRYPTION
) {
3627 DEBUG(0,("call_trans2setfsinfo: encryption required "
3628 "and info level 0x%x sent.\n",
3629 (unsigned int)info_level
));
3630 exit_server_cleanly("encryption required "
3636 switch(info_level
) {
3637 case SMB_SET_CIFS_UNIX_INFO
:
3639 uint16 client_unix_major
;
3640 uint16 client_unix_minor
;
3641 uint32 client_unix_cap_low
;
3642 uint32 client_unix_cap_high
;
3644 if (!lp_unix_extensions()) {
3646 NT_STATUS_INVALID_LEVEL
);
3650 /* There should be 12 bytes of capabilities set. */
3651 if (total_data
< 8) {
3654 NT_STATUS_INVALID_PARAMETER
);
3657 client_unix_major
= SVAL(pdata
,0);
3658 client_unix_minor
= SVAL(pdata
,2);
3659 client_unix_cap_low
= IVAL(pdata
,4);
3660 client_unix_cap_high
= IVAL(pdata
,8);
3661 /* Just print these values for now. */
3662 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
3663 cap_low = 0x%x, cap_high = 0x%x\n",
3664 (unsigned int)client_unix_major
,
3665 (unsigned int)client_unix_minor
,
3666 (unsigned int)client_unix_cap_low
,
3667 (unsigned int)client_unix_cap_high
));
3669 /* Here is where we must switch to posix pathname processing... */
3670 if (client_unix_cap_low
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
3671 lp_set_posix_pathnames();
3672 mangle_change_to_posix();
3675 if ((client_unix_cap_low
& CIFS_UNIX_FCNTL_LOCKS_CAP
) &&
3676 !(client_unix_cap_low
& CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)) {
3677 /* Client that knows how to do posix locks,
3678 * but not posix open/mkdir operations. Set a
3679 * default type for read/write checks. */
3681 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK
);
3687 case SMB_REQUEST_TRANSPORT_ENCRYPTION
:
3690 size_t param_len
= 0;
3691 size_t data_len
= total_data
;
3693 if (!lp_unix_extensions()) {
3696 NT_STATUS_INVALID_LEVEL
);
3700 if (lp_smb_encrypt(SNUM(conn
)) == false) {
3703 NT_STATUS_NOT_SUPPORTED
);
3707 if (req
->sconn
->smb1
.echo_handler
.trusted_fde
) {
3708 DEBUG( 2,("call_trans2setfsinfo: "
3709 "request transport encryption disabled"
3710 "with 'fork echo handler = yes'\n"));
3713 NT_STATUS_NOT_SUPPORTED
);
3717 DEBUG( 4,("call_trans2setfsinfo: "
3718 "request transport encryption.\n"));
3720 status
= srv_request_encryption_setup(conn
,
3721 (unsigned char **)ppdata
,
3723 (unsigned char **)pparams
,
3726 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
3727 !NT_STATUS_IS_OK(status
)) {
3728 reply_nterror(req
, status
);
3732 send_trans2_replies(conn
, req
,
3739 if (NT_STATUS_IS_OK(status
)) {
3740 /* Server-side transport
3741 * encryption is now *on*. */
3742 status
= srv_encryption_start(conn
);
3743 if (!NT_STATUS_IS_OK(status
)) {
3744 exit_server_cleanly(
3745 "Failure in setting "
3746 "up encrypted transport");
3752 case SMB_FS_QUOTA_INFORMATION
:
3754 files_struct
*fsp
= NULL
;
3755 SMB_NTQUOTA_STRUCT quotas
;
3757 ZERO_STRUCT(quotas
);
3760 if ((get_current_uid(conn
) != 0) || !CAN_WRITE(conn
)) {
3761 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3762 lp_servicename(SNUM(conn
)),
3763 conn
->session_info
->unix_name
));
3764 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
3768 /* note: normaly there're 48 bytes,
3769 * but we didn't use the last 6 bytes for now
3772 fsp
= file_fsp(req
, SVAL(params
,0));
3774 if (!check_fsp_ntquota_handle(conn
, req
,
3776 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3778 req
, NT_STATUS_INVALID_HANDLE
);
3782 if (total_data
< 42) {
3783 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3787 NT_STATUS_INVALID_PARAMETER
);
3791 /* unknown_1 24 NULL bytes in pdata*/
3793 /* the soft quotas 8 bytes (uint64_t)*/
3794 quotas
.softlim
= BVAL(pdata
,24);
3796 /* the hard quotas 8 bytes (uint64_t)*/
3797 quotas
.hardlim
= BVAL(pdata
,32);
3799 /* quota_flags 2 bytes **/
3800 quotas
.qflags
= SVAL(pdata
,40);
3802 /* unknown_2 6 NULL bytes follow*/
3804 /* now set the quotas */
3805 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
3806 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
3807 reply_nterror(req
, map_nt_error_from_unix(errno
));
3814 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3816 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
3822 * sending this reply works fine,
3823 * but I'm not sure it's the same
3824 * like windows do...
3827 reply_outbuf(req
, 10, 0);
3830 #if defined(HAVE_POSIX_ACLS)
3831 /****************************************************************************
3832 Utility function to count the number of entries in a POSIX acl.
3833 ****************************************************************************/
3835 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
3837 unsigned int ace_count
= 0;
3838 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3839 SMB_ACL_ENTRY_T entry
;
3841 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
3843 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3844 entry_id
= SMB_ACL_NEXT_ENTRY
;
3851 /****************************************************************************
3852 Utility function to marshall a POSIX acl into wire format.
3853 ****************************************************************************/
3855 static bool marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
3857 int entry_id
= SMB_ACL_FIRST_ENTRY
;
3858 SMB_ACL_ENTRY_T entry
;
3860 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
3861 SMB_ACL_TAG_T tagtype
;
3862 SMB_ACL_PERMSET_T permset
;
3863 unsigned char perms
= 0;
3864 unsigned int own_grp
;
3867 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
3868 entry_id
= SMB_ACL_NEXT_ENTRY
;
3871 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn
, entry
, &tagtype
) == -1) {
3872 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3876 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn
, entry
, &permset
) == -1) {
3877 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3881 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
3882 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
3883 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
3885 SCVAL(pdata
,1,perms
);
3888 case SMB_ACL_USER_OBJ
:
3889 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
3890 own_grp
= (unsigned int)pst
->st_ex_uid
;
3891 SIVAL(pdata
,2,own_grp
);
3896 uid_t
*puid
= (uid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
3898 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3901 own_grp
= (unsigned int)*puid
;
3902 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)puid
,tagtype
);
3903 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
3904 SIVAL(pdata
,2,own_grp
);
3908 case SMB_ACL_GROUP_OBJ
:
3909 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
3910 own_grp
= (unsigned int)pst
->st_ex_gid
;
3911 SIVAL(pdata
,2,own_grp
);
3916 gid_t
*pgid
= (gid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
3918 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3921 own_grp
= (unsigned int)*pgid
;
3922 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)pgid
,tagtype
);
3923 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
3924 SIVAL(pdata
,2,own_grp
);
3929 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
3930 SIVAL(pdata
,2,0xFFFFFFFF);
3931 SIVAL(pdata
,6,0xFFFFFFFF);
3934 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
3935 SIVAL(pdata
,2,0xFFFFFFFF);
3936 SIVAL(pdata
,6,0xFFFFFFFF);
3939 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
3942 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
3949 /****************************************************************************
3950 Store the FILE_UNIX_BASIC info.
3951 ****************************************************************************/
3953 static char *store_file_unix_basic(connection_struct
*conn
,
3956 const SMB_STRUCT_STAT
*psbuf
)
3958 uint64_t file_index
= get_FileIndex(conn
, psbuf
);
3960 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
3961 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_ex_mode
));
3963 SOFF_T(pdata
,0,get_file_size_stat(psbuf
)); /* File size 64 Bit */
3966 SOFF_T(pdata
,0,SMB_VFS_GET_ALLOC_SIZE(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
3969 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
, psbuf
->st_ex_ctime
); /* Change Time 64 Bit */
3970 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
+8, psbuf
->st_ex_atime
); /* Last access time 64 Bit */
3971 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
, pdata
+16, psbuf
->st_ex_mtime
); /* Last modification time 64 Bit */
3974 SIVAL(pdata
,0,psbuf
->st_ex_uid
); /* user id for the owner */
3978 SIVAL(pdata
,0,psbuf
->st_ex_gid
); /* group id of owner */
3982 SIVAL(pdata
,0,unix_filetype(psbuf
->st_ex_mode
));
3985 SIVAL(pdata
,0,unix_dev_major(psbuf
->st_ex_rdev
)); /* Major device number if type is device */
3989 SIVAL(pdata
,0,unix_dev_minor(psbuf
->st_ex_rdev
)); /* Minor device number if type is device */
3993 SINO_T_VAL(pdata
,0,(SMB_INO_T
)file_index
); /* inode number */
3996 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_ex_mode
)); /* Standard UNIX file permissions */
4000 SIVAL(pdata
,0,psbuf
->st_ex_nlink
); /* number of hard links */
4007 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4008 * the chflags(2) (or equivalent) flags.
4010 * XXX: this really should be behind the VFS interface. To do this, we would
4011 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4012 * Each VFS module could then implement its own mapping as appropriate for the
4013 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4015 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
4019 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
4023 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
4027 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
4031 { UF_HIDDEN
, EXT_HIDDEN
},
4034 /* Do not remove. We need to guarantee that this array has at least one
4035 * entry to build on HP-UX.
4041 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4042 uint32
*smb_fflags
, uint32
*smb_fmask
)
4046 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4047 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
4048 if (psbuf
->st_ex_flags
& info2_flags_map
[i
].stat_fflag
) {
4049 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
4054 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
4055 const uint32 smb_fflags
,
4056 const uint32 smb_fmask
,
4059 uint32 max_fmask
= 0;
4062 *stat_fflags
= psbuf
->st_ex_flags
;
4064 /* For each flags requested in smb_fmask, check the state of the
4065 * corresponding flag in smb_fflags and set or clear the matching
4069 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
4070 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
4071 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
4072 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
4073 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
4075 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
4080 /* If smb_fmask is asking to set any bits that are not supported by
4081 * our flag mappings, we should fail.
4083 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
4091 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4092 * of file flags and birth (create) time.
4094 static char *store_file_unix_basic_info2(connection_struct
*conn
,
4097 const SMB_STRUCT_STAT
*psbuf
)
4099 uint32 file_flags
= 0;
4100 uint32 flags_mask
= 0;
4102 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4104 /* Create (birth) time 64 bit */
4105 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER
,pdata
, psbuf
->st_ex_btime
);
4108 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
4109 SIVAL(pdata
, 0, file_flags
); /* flags */
4110 SIVAL(pdata
, 4, flags_mask
); /* mask */
4116 static NTSTATUS
marshall_stream_info(unsigned int num_streams
,
4117 const struct stream_struct
*streams
,
4119 unsigned int max_data_bytes
,
4120 unsigned int *data_size
)
4123 unsigned int ofs
= 0;
4125 for (i
= 0; i
< num_streams
; i
++) {
4126 unsigned int next_offset
;
4128 smb_ucs2_t
*namebuf
;
4130 if (!push_ucs2_talloc(talloc_tos(), &namebuf
,
4131 streams
[i
].name
, &namelen
) ||
4134 return NT_STATUS_INVALID_PARAMETER
;
4138 * name_buf is now null-terminated, we need to marshall as not
4145 * We cannot overflow ...
4147 if ((ofs
+ 24 + namelen
) > max_data_bytes
) {
4148 DEBUG(10, ("refusing to overflow reply at stream %u\n",
4150 TALLOC_FREE(namebuf
);
4151 return STATUS_BUFFER_OVERFLOW
;
4154 SIVAL(data
, ofs
+4, namelen
);
4155 SOFF_T(data
, ofs
+8, streams
[i
].size
);
4156 SOFF_T(data
, ofs
+16, streams
[i
].alloc_size
);
4157 memcpy(data
+ofs
+24, namebuf
, namelen
);
4158 TALLOC_FREE(namebuf
);
4160 next_offset
= ofs
+ 24 + namelen
;
4162 if (i
== num_streams
-1) {
4163 SIVAL(data
, ofs
, 0);
4166 unsigned int align
= ndr_align_size(next_offset
, 8);
4168 if ((next_offset
+ align
) > max_data_bytes
) {
4169 DEBUG(10, ("refusing to overflow align "
4170 "reply at stream %u\n",
4172 TALLOC_FREE(namebuf
);
4173 return STATUS_BUFFER_OVERFLOW
;
4176 memset(data
+next_offset
, 0, align
);
4177 next_offset
+= align
;
4179 SIVAL(data
, ofs
, next_offset
- ofs
);
4186 DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes
, ofs
));
4190 return NT_STATUS_OK
;
4193 /****************************************************************************
4194 Reply to a TRANSACT2_QFILEINFO on a PIPE !
4195 ****************************************************************************/
4197 static void call_trans2qpipeinfo(connection_struct
*conn
,
4198 struct smb_request
*req
,
4199 unsigned int tran_call
,
4200 char **pparams
, int total_params
,
4201 char **ppdata
, int total_data
,
4202 unsigned int max_data_bytes
)
4204 char *params
= *pparams
;
4205 char *pdata
= *ppdata
;
4206 unsigned int data_size
= 0;
4207 unsigned int param_size
= 2;
4212 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4216 if (total_params
< 4) {
4217 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
4221 fsp
= file_fsp(req
, SVAL(params
,0));
4222 if (!fsp_is_np(fsp
)) {
4223 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
4227 info_level
= SVAL(params
,2);
4229 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
4230 if (*pparams
== NULL
) {
4231 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4236 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4237 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4238 if (*ppdata
== NULL
) {
4239 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
4244 switch (info_level
) {
4245 case SMB_FILE_STANDARD_INFORMATION
:
4247 SOFF_T(pdata
,0,4096LL);
4254 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
4258 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
4264 NTSTATUS
smbd_do_qfilepathinfo(connection_struct
*conn
,
4265 TALLOC_CTX
*mem_ctx
,
4266 uint16_t info_level
,
4268 struct smb_filename
*smb_fname
,
4269 bool delete_pending
,
4270 struct timespec write_time_ts
,
4271 struct ea_list
*ea_list
,
4272 int lock_data_count
,
4275 unsigned int max_data_bytes
,
4277 unsigned int *pdata_size
)
4279 char *pdata
= *ppdata
;
4280 char *dstart
, *dend
;
4281 unsigned int data_size
;
4282 struct timespec create_time_ts
, mtime_ts
, atime_ts
, ctime_ts
;
4283 time_t create_time
, mtime
, atime
, c_time
;
4284 SMB_STRUCT_STAT
*psbuf
= &smb_fname
->st
;
4291 uint64_t file_size
= 0;
4293 uint64_t allocation_size
= 0;
4294 uint64_t file_index
= 0;
4295 uint32_t access_mask
= 0;
4297 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
4298 return NT_STATUS_INVALID_LEVEL
;
4301 DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
4302 smb_fname_str_dbg(smb_fname
), fsp
? fsp
->fnum
: -1,
4303 info_level
, max_data_bytes
));
4305 mode
= dos_mode(conn
, smb_fname
);
4306 nlink
= psbuf
->st_ex_nlink
;
4308 if (nlink
&& (mode
&FILE_ATTRIBUTE_DIRECTORY
)) {
4312 if ((nlink
> 0) && delete_pending
) {
4316 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
4317 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
4318 if (*ppdata
== NULL
) {
4319 return NT_STATUS_NO_MEMORY
;
4323 dend
= dstart
+ data_size
- 1;
4325 if (!null_timespec(write_time_ts
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
4326 update_stat_ex_mtime(psbuf
, write_time_ts
);
4329 create_time_ts
= get_create_timespec(conn
, fsp
, smb_fname
);
4330 mtime_ts
= psbuf
->st_ex_mtime
;
4331 atime_ts
= psbuf
->st_ex_atime
;
4332 ctime_ts
= get_change_timespec(conn
, fsp
, smb_fname
);
4334 if (lp_dos_filetime_resolution(SNUM(conn
))) {
4335 dos_filetime_timespec(&create_time_ts
);
4336 dos_filetime_timespec(&mtime_ts
);
4337 dos_filetime_timespec(&atime_ts
);
4338 dos_filetime_timespec(&ctime_ts
);
4341 create_time
= convert_timespec_to_time_t(create_time_ts
);
4342 mtime
= convert_timespec_to_time_t(mtime_ts
);
4343 atime
= convert_timespec_to_time_t(atime_ts
);
4344 c_time
= convert_timespec_to_time_t(ctime_ts
);
4346 p
= strrchr_m(smb_fname
->base_name
,'/');
4348 base_name
= smb_fname
->base_name
;
4352 /* NT expects the name to be in an exact form of the *full*
4353 filename. See the trans2 torture test */
4354 if (ISDOT(base_name
)) {
4355 dos_fname
= talloc_strdup(mem_ctx
, "\\");
4357 return NT_STATUS_NO_MEMORY
;
4360 dos_fname
= talloc_asprintf(mem_ctx
,
4362 smb_fname
->base_name
);
4364 return NT_STATUS_NO_MEMORY
;
4366 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4367 dos_fname
= talloc_asprintf(dos_fname
, "%s",
4368 smb_fname
->stream_name
);
4370 return NT_STATUS_NO_MEMORY
;
4374 string_replace(dos_fname
, '/', '\\');
4377 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp
, psbuf
);
4380 /* Do we have this path open ? */
4382 struct file_id fileid
= vfs_file_id_from_sbuf(conn
, psbuf
);
4383 fsp1
= file_find_di_first(conn
->sconn
, fileid
);
4384 if (fsp1
&& fsp1
->initial_allocation_size
) {
4385 allocation_size
= SMB_VFS_GET_ALLOC_SIZE(conn
, fsp1
, psbuf
);
4389 if (!(mode
& FILE_ATTRIBUTE_DIRECTORY
)) {
4390 file_size
= get_file_size_stat(psbuf
);
4394 pos
= fsp
->fh
->position_information
;
4398 access_mask
= fsp
->access_mask
;
4400 /* GENERIC_EXECUTE mapping from Windows */
4401 access_mask
= 0x12019F;
4404 /* This should be an index number - looks like
4407 I think this causes us to fail the IFSKIT
4408 BasicFileInformationTest. -tpot */
4409 file_index
= get_FileIndex(conn
, psbuf
);
4411 switch (info_level
) {
4412 case SMB_INFO_STANDARD
:
4413 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4415 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
4416 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
4417 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
4418 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
4419 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
4420 SSVAL(pdata
,l1_attrFile
,mode
);
4423 case SMB_INFO_QUERY_EA_SIZE
:
4425 unsigned int ea_size
=
4426 estimate_ea_size(conn
, fsp
,
4427 smb_fname
->base_name
);
4428 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4430 srv_put_dos_date2(pdata
,0,create_time
);
4431 srv_put_dos_date2(pdata
,4,atime
);
4432 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
4433 SIVAL(pdata
,12,(uint32
)file_size
);
4434 SIVAL(pdata
,16,(uint32
)allocation_size
);
4435 SSVAL(pdata
,20,mode
);
4436 SIVAL(pdata
,22,ea_size
);
4440 case SMB_INFO_IS_NAME_VALID
:
4441 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4443 /* os/2 needs this ? really ?*/
4444 return NT_STATUS_DOS(ERRDOS
, ERRbadfunc
);
4446 /* This is only reached for qpathinfo */
4450 case SMB_INFO_QUERY_EAS_FROM_LIST
:
4452 size_t total_ea_len
= 0;
4453 struct ea_list
*ea_file_list
= NULL
;
4455 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4458 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4459 smb_fname
->base_name
,
4461 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
4463 if (!ea_list
|| (total_ea_len
> data_size
)) {
4465 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4469 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4473 case SMB_INFO_QUERY_ALL_EAS
:
4475 /* We have data_size bytes to put EA's into. */
4476 size_t total_ea_len
= 0;
4478 DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4480 ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4481 smb_fname
->base_name
,
4483 if (!ea_list
|| (total_ea_len
> data_size
)) {
4485 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
4489 data_size
= fill_ea_buffer(mem_ctx
, pdata
, data_size
, conn
, ea_list
);
4493 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4495 /* This is FileFullEaInformation - 0xF which maps to
4496 * 1015 (decimal) in smbd_do_setfilepathinfo. */
4498 /* We have data_size bytes to put EA's into. */
4499 size_t total_ea_len
= 0;
4500 struct ea_list
*ea_file_list
= NULL
;
4502 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4504 /*TODO: add filtering and index handling */
4507 get_ea_list_from_file(mem_ctx
, conn
, fsp
,
4508 smb_fname
->base_name
,
4510 if (!ea_file_list
) {
4511 return NT_STATUS_NO_EAS_ON_FILE
;
4514 status
= fill_ea_chained_buffer(mem_ctx
,
4518 conn
, ea_file_list
);
4519 if (!NT_STATUS_IS_OK(status
)) {
4525 case SMB_FILE_BASIC_INFORMATION
:
4526 case SMB_QUERY_FILE_BASIC_INFO
:
4528 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
4529 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4530 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
4532 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4536 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4537 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4538 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4539 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4540 SIVAL(pdata
,32,mode
);
4542 DEBUG(5,("SMB_QFBI - "));
4543 DEBUG(5,("create: %s ", ctime(&create_time
)));
4544 DEBUG(5,("access: %s ", ctime(&atime
)));
4545 DEBUG(5,("write: %s ", ctime(&mtime
)));
4546 DEBUG(5,("change: %s ", ctime(&c_time
)));
4547 DEBUG(5,("mode: %x\n", mode
));
4550 case SMB_FILE_STANDARD_INFORMATION
:
4551 case SMB_QUERY_FILE_STANDARD_INFO
:
4553 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4555 SOFF_T(pdata
,0,allocation_size
);
4556 SOFF_T(pdata
,8,file_size
);
4557 SIVAL(pdata
,16,nlink
);
4558 SCVAL(pdata
,20,delete_pending
?1:0);
4559 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4560 SSVAL(pdata
,22,0); /* Padding. */
4563 case SMB_FILE_EA_INFORMATION
:
4564 case SMB_QUERY_FILE_EA_INFO
:
4566 unsigned int ea_size
=
4567 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4568 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4570 SIVAL(pdata
,0,ea_size
);
4574 /* Get the 8.3 name - used if NT SMB was negotiated. */
4575 case SMB_QUERY_FILE_ALT_NAME_INFO
:
4576 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
4579 char mangled_name
[13];
4580 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4581 if (!name_to_8_3(base_name
,mangled_name
,
4582 True
,conn
->params
)) {
4583 return NT_STATUS_NO_MEMORY
;
4585 len
= srvstr_push(dstart
, flags2
,
4586 pdata
+4, mangled_name
,
4587 PTR_DIFF(dend
, pdata
+4),
4589 data_size
= 4 + len
;
4594 case SMB_QUERY_FILE_NAME_INFO
:
4598 this must be *exactly* right for ACLs on mapped drives to work
4600 len
= srvstr_push(dstart
, flags2
,
4602 PTR_DIFF(dend
, pdata
+4),
4604 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4605 data_size
= 4 + len
;
4610 case SMB_FILE_ALLOCATION_INFORMATION
:
4611 case SMB_QUERY_FILE_ALLOCATION_INFO
:
4612 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4614 SOFF_T(pdata
,0,allocation_size
);
4617 case SMB_FILE_END_OF_FILE_INFORMATION
:
4618 case SMB_QUERY_FILE_END_OF_FILEINFO
:
4619 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4621 SOFF_T(pdata
,0,file_size
);
4624 case SMB_QUERY_FILE_ALL_INFO
:
4625 case SMB_FILE_ALL_INFORMATION
:
4628 unsigned int ea_size
=
4629 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4630 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4631 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4632 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4633 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4634 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4635 SIVAL(pdata
,32,mode
);
4636 SIVAL(pdata
,36,0); /* padding. */
4638 SOFF_T(pdata
,0,allocation_size
);
4639 SOFF_T(pdata
,8,file_size
);
4640 SIVAL(pdata
,16,nlink
);
4641 SCVAL(pdata
,20,delete_pending
);
4642 SCVAL(pdata
,21,(mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4645 SIVAL(pdata
,0,ea_size
);
4646 pdata
+= 4; /* EA info */
4647 len
= srvstr_push(dstart
, flags2
,
4649 PTR_DIFF(dend
, pdata
+4),
4653 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4657 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4660 unsigned int ea_size
=
4661 estimate_ea_size(conn
, fsp
, smb_fname
->base_name
);
4662 DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4663 put_long_date_timespec(conn
->ts_res
,pdata
+0x00,create_time_ts
);
4664 put_long_date_timespec(conn
->ts_res
,pdata
+0x08,atime_ts
);
4665 put_long_date_timespec(conn
->ts_res
,pdata
+0x10,mtime_ts
); /* write time */
4666 put_long_date_timespec(conn
->ts_res
,pdata
+0x18,ctime_ts
); /* change time */
4667 SIVAL(pdata
, 0x20, mode
);
4668 SIVAL(pdata
, 0x24, 0); /* padding. */
4669 SBVAL(pdata
, 0x28, allocation_size
);
4670 SBVAL(pdata
, 0x30, file_size
);
4671 SIVAL(pdata
, 0x38, nlink
);
4672 SCVAL(pdata
, 0x3C, delete_pending
);
4673 SCVAL(pdata
, 0x3D, (mode
&FILE_ATTRIBUTE_DIRECTORY
)?1:0);
4674 SSVAL(pdata
, 0x3E, 0); /* padding */
4675 SBVAL(pdata
, 0x40, file_index
);
4676 SIVAL(pdata
, 0x48, ea_size
);
4677 SIVAL(pdata
, 0x4C, access_mask
);
4678 SBVAL(pdata
, 0x50, pos
);
4679 SIVAL(pdata
, 0x58, mode
); /*TODO: mode != mode fix this!!! */
4680 SIVAL(pdata
, 0x5C, 0); /* No alignment needed. */
4684 len
= srvstr_push(dstart
, flags2
,
4686 PTR_DIFF(dend
, pdata
+4),
4690 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4693 case SMB_FILE_INTERNAL_INFORMATION
:
4695 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4696 SBVAL(pdata
, 0, file_index
);
4700 case SMB_FILE_ACCESS_INFORMATION
:
4701 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4702 SIVAL(pdata
, 0, access_mask
);
4706 case SMB_FILE_NAME_INFORMATION
:
4707 /* Pathname with leading '\'. */
4710 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
4711 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4712 SIVAL(pdata
,0,byte_len
);
4713 data_size
= 4 + byte_len
;
4717 case SMB_FILE_DISPOSITION_INFORMATION
:
4718 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4720 SCVAL(pdata
,0,delete_pending
);
4723 case SMB_FILE_POSITION_INFORMATION
:
4724 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4726 SOFF_T(pdata
,0,pos
);
4729 case SMB_FILE_MODE_INFORMATION
:
4730 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4731 SIVAL(pdata
,0,mode
);
4735 case SMB_FILE_ALIGNMENT_INFORMATION
:
4736 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4737 SIVAL(pdata
,0,0); /* No alignment needed. */
4742 * NT4 server just returns "invalid query" to this - if we try
4743 * to answer it then NTws gets a BSOD! (tridge). W2K seems to
4746 /* The first statement above is false - verified using Thursby
4747 * client against NT4 -- gcolley.
4749 case SMB_QUERY_FILE_STREAM_INFO
:
4750 case SMB_FILE_STREAM_INFORMATION
: {
4751 unsigned int num_streams
= 0;
4752 struct stream_struct
*streams
= NULL
;
4754 DEBUG(10,("smbd_do_qfilepathinfo: "
4755 "SMB_FILE_STREAM_INFORMATION\n"));
4757 if (is_ntfs_stream_smb_fname(smb_fname
)) {
4758 return NT_STATUS_INVALID_PARAMETER
;
4761 status
= vfs_streaminfo(conn
, fsp
, smb_fname
->base_name
,
4762 talloc_tos(), &num_streams
, &streams
);
4764 if (!NT_STATUS_IS_OK(status
)) {
4765 DEBUG(10, ("could not get stream info: %s\n",
4766 nt_errstr(status
)));
4770 status
= marshall_stream_info(num_streams
, streams
,
4771 pdata
, max_data_bytes
,
4774 if (!NT_STATUS_IS_OK(status
)) {
4775 DEBUG(10, ("marshall_stream_info failed: %s\n",
4776 nt_errstr(status
)));
4777 TALLOC_FREE(streams
);
4781 TALLOC_FREE(streams
);
4785 case SMB_QUERY_COMPRESSION_INFO
:
4786 case SMB_FILE_COMPRESSION_INFORMATION
:
4787 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4788 SOFF_T(pdata
,0,file_size
);
4789 SIVAL(pdata
,8,0); /* ??? */
4790 SIVAL(pdata
,12,0); /* ??? */
4794 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
4795 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4796 put_long_date_timespec(conn
->ts_res
,pdata
,create_time_ts
);
4797 put_long_date_timespec(conn
->ts_res
,pdata
+8,atime_ts
);
4798 put_long_date_timespec(conn
->ts_res
,pdata
+16,mtime_ts
); /* write time */
4799 put_long_date_timespec(conn
->ts_res
,pdata
+24,ctime_ts
); /* change time */
4800 SOFF_T(pdata
,32,allocation_size
);
4801 SOFF_T(pdata
,40,file_size
);
4802 SIVAL(pdata
,48,mode
);
4803 SIVAL(pdata
,52,0); /* ??? */
4807 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
4808 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4809 SIVAL(pdata
,0,mode
);
4815 * CIFS UNIX Extensions.
4818 case SMB_QUERY_FILE_UNIX_BASIC
:
4820 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
4821 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4823 DEBUG(4,("smbd_do_qfilepathinfo: "
4824 "SMB_QUERY_FILE_UNIX_BASIC\n"));
4825 dump_data(4, (uint8_t *)(*ppdata
), data_size
);
4829 case SMB_QUERY_FILE_UNIX_INFO2
:
4831 pdata
= store_file_unix_basic_info2(conn
, pdata
, fsp
, psbuf
);
4832 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4836 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4838 for (i
=0; i
<100; i
++)
4839 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
4845 case SMB_QUERY_FILE_UNIX_LINK
:
4848 char *buffer
= TALLOC_ARRAY(mem_ctx
, char, PATH_MAX
+1);
4851 return NT_STATUS_NO_MEMORY
;
4854 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4856 if(!S_ISLNK(psbuf
->st_ex_mode
)) {
4857 return NT_STATUS_DOS(ERRSRV
, ERRbadlink
);
4860 return NT_STATUS_DOS(ERRDOS
, ERRbadlink
);
4862 len
= SMB_VFS_READLINK(conn
,
4863 smb_fname
->base_name
,
4866 return map_nt_error_from_unix(errno
);
4869 len
= srvstr_push(dstart
, flags2
,
4871 PTR_DIFF(dend
, pdata
),
4874 data_size
= PTR_DIFF(pdata
,(*ppdata
));
4879 #if defined(HAVE_POSIX_ACLS)
4880 case SMB_QUERY_POSIX_ACL
:
4882 SMB_ACL_T file_acl
= NULL
;
4883 SMB_ACL_T def_acl
= NULL
;
4884 uint16 num_file_acls
= 0;
4885 uint16 num_def_acls
= 0;
4887 if (fsp
&& fsp
->fh
->fd
!= -1) {
4888 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
);
4891 SMB_VFS_SYS_ACL_GET_FILE(conn
,
4892 smb_fname
->base_name
,
4893 SMB_ACL_TYPE_ACCESS
);
4896 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
4897 DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4898 "not implemented on "
4899 "filesystem containing %s\n",
4900 smb_fname
->base_name
));
4901 return NT_STATUS_NOT_IMPLEMENTED
;
4904 if (S_ISDIR(psbuf
->st_ex_mode
)) {
4905 if (fsp
&& fsp
->is_directory
) {
4907 SMB_VFS_SYS_ACL_GET_FILE(
4909 fsp
->fsp_name
->base_name
,
4910 SMB_ACL_TYPE_DEFAULT
);
4913 SMB_VFS_SYS_ACL_GET_FILE(
4915 smb_fname
->base_name
,
4916 SMB_ACL_TYPE_DEFAULT
);
4918 def_acl
= free_empty_sys_acl(conn
, def_acl
);
4921 num_file_acls
= count_acl_entries(conn
, file_acl
);
4922 num_def_acls
= count_acl_entries(conn
, def_acl
);
4924 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
4925 DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
4927 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
4928 SMB_POSIX_ACL_HEADER_SIZE
) ));
4930 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4933 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4935 return NT_STATUS_BUFFER_TOO_SMALL
;
4938 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
4939 SSVAL(pdata
,2,num_file_acls
);
4940 SSVAL(pdata
,4,num_def_acls
);
4941 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, psbuf
, file_acl
)) {
4943 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4946 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4948 return NT_STATUS_INTERNAL_ERROR
;
4950 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), psbuf
, def_acl
)) {
4952 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4955 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4957 return NT_STATUS_INTERNAL_ERROR
;
4961 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
4964 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
4966 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
4972 case SMB_QUERY_POSIX_LOCK
:
4977 enum brl_type lock_type
;
4979 /* We need an open file with a real fd for this. */
4980 if (!fsp
|| fsp
->fh
->fd
== -1) {
4981 return NT_STATUS_INVALID_LEVEL
;
4984 if (lock_data_count
!= POSIX_LOCK_DATA_SIZE
) {
4985 return NT_STATUS_INVALID_PARAMETER
;
4988 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
4989 case POSIX_LOCK_TYPE_READ
:
4990 lock_type
= READ_LOCK
;
4992 case POSIX_LOCK_TYPE_WRITE
:
4993 lock_type
= WRITE_LOCK
;
4995 case POSIX_LOCK_TYPE_UNLOCK
:
4997 /* There's no point in asking for an unlock... */
4998 return NT_STATUS_INVALID_PARAMETER
;
5001 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
5002 #if defined(HAVE_LONGLONG)
5003 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
5004 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
5005 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
5006 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
5007 #else /* HAVE_LONGLONG */
5008 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
5009 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
5010 #endif /* HAVE_LONGLONG */
5012 status
= query_lock(fsp
,
5019 if (ERROR_WAS_LOCK_DENIED(status
)) {
5020 /* Here we need to report who has it locked... */
5021 data_size
= POSIX_LOCK_DATA_SIZE
;
5023 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, lock_type
);
5024 SSVAL(pdata
, POSIX_LOCK_FLAGS_OFFSET
, 0);
5025 SIVAL(pdata
, POSIX_LOCK_PID_OFFSET
, (uint32_t)smblctx
);
5026 #if defined(HAVE_LONGLONG)
5027 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, (uint32
)(offset
& 0xFFFFFFFF));
5028 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
+ 4, (uint32
)((offset
>> 32) & 0xFFFFFFFF));
5029 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, (uint32
)(count
& 0xFFFFFFFF));
5030 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
+ 4, (uint32
)((count
>> 32) & 0xFFFFFFFF));
5031 #else /* HAVE_LONGLONG */
5032 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, offset
);
5033 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, count
);
5034 #endif /* HAVE_LONGLONG */
5036 } else if (NT_STATUS_IS_OK(status
)) {
5037 /* For success we just return a copy of what we sent
5038 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5039 data_size
= POSIX_LOCK_DATA_SIZE
;
5040 memcpy(pdata
, lock_data
, POSIX_LOCK_DATA_SIZE
);
5041 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
5049 return NT_STATUS_INVALID_LEVEL
;
5052 *pdata_size
= data_size
;
5053 return NT_STATUS_OK
;
5056 /****************************************************************************
5057 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5058 file name or file id).
5059 ****************************************************************************/
5061 static void call_trans2qfilepathinfo(connection_struct
*conn
,
5062 struct smb_request
*req
,
5063 unsigned int tran_call
,
5064 char **pparams
, int total_params
,
5065 char **ppdata
, int total_data
,
5066 unsigned int max_data_bytes
)
5068 char *params
= *pparams
;
5069 char *pdata
= *ppdata
;
5071 unsigned int data_size
= 0;
5072 unsigned int param_size
= 2;
5073 struct smb_filename
*smb_fname
= NULL
;
5074 bool delete_pending
= False
;
5075 struct timespec write_time_ts
;
5076 files_struct
*fsp
= NULL
;
5077 struct file_id fileid
;
5078 struct ea_list
*ea_list
= NULL
;
5079 int lock_data_count
= 0;
5080 char *lock_data
= NULL
;
5081 NTSTATUS status
= NT_STATUS_OK
;
5084 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5088 ZERO_STRUCT(write_time_ts
);
5090 if (tran_call
== TRANSACT2_QFILEINFO
) {
5091 if (total_params
< 4) {
5092 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5097 call_trans2qpipeinfo(conn
, req
, tran_call
,
5098 pparams
, total_params
,
5104 fsp
= file_fsp(req
, SVAL(params
,0));
5105 info_level
= SVAL(params
,2);
5107 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
5109 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
5110 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5114 /* Initial check for valid fsp ptr. */
5115 if (!check_fsp_open(conn
, req
, fsp
)) {
5119 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
5121 if (!NT_STATUS_IS_OK(status
)) {
5122 reply_nterror(req
, status
);
5126 if(fsp
->fake_file_handle
) {
5128 * This is actually for the QUOTA_FAKE_FILE --metze
5131 /* We know this name is ok, it's already passed the checks. */
5133 } else if(fsp
->fh
->fd
== -1) {
5135 * This is actually a QFILEINFO on a directory
5136 * handle (returned from an NT SMB). NT5.0 seems
5137 * to do this call. JRA.
5140 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5141 /* Always do lstat for UNIX calls. */
5142 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5143 DEBUG(3,("call_trans2qfilepathinfo: "
5144 "SMB_VFS_LSTAT of %s failed "
5146 smb_fname_str_dbg(smb_fname
),
5149 map_nt_error_from_unix(errno
));
5152 } else if (SMB_VFS_STAT(conn
, smb_fname
)) {
5153 DEBUG(3,("call_trans2qfilepathinfo: "
5154 "SMB_VFS_STAT of %s failed (%s)\n",
5155 smb_fname_str_dbg(smb_fname
),
5158 map_nt_error_from_unix(errno
));
5162 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5163 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5166 * Original code - this is an open file.
5168 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
5169 DEBUG(3, ("fstat of fnum %d failed (%s)\n",
5170 fsp
->fnum
, strerror(errno
)));
5172 map_nt_error_from_unix(errno
));
5175 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5176 get_file_infos(fileid
, fsp
->name_hash
, &delete_pending
, &write_time_ts
);
5182 uint32_t ucf_flags
= 0;
5185 if (total_params
< 7) {
5186 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
5190 info_level
= SVAL(params
,0);
5192 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
5194 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5195 if (!lp_unix_extensions()) {
5196 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5199 if (info_level
== SMB_QUERY_FILE_UNIX_BASIC
||
5200 info_level
== SMB_QUERY_FILE_UNIX_INFO2
||
5201 info_level
== SMB_QUERY_FILE_UNIX_LINK
) {
5202 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
5206 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
5208 STR_TERMINATE
, &status
);
5209 if (!NT_STATUS_IS_OK(status
)) {
5210 reply_nterror(req
, status
);
5214 status
= filename_convert(req
,
5216 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5221 if (!NT_STATUS_IS_OK(status
)) {
5222 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5223 reply_botherror(req
,
5224 NT_STATUS_PATH_NOT_COVERED
,
5225 ERRSRV
, ERRbadpath
);
5228 reply_nterror(req
, status
);
5232 /* If this is a stream, check if there is a delete_pending. */
5233 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5234 && is_ntfs_stream_smb_fname(smb_fname
)) {
5235 struct smb_filename
*smb_fname_base
= NULL
;
5237 /* Create an smb_filename with stream_name == NULL. */
5239 create_synthetic_smb_fname(talloc_tos(),
5240 smb_fname
->base_name
,
5243 if (!NT_STATUS_IS_OK(status
)) {
5244 reply_nterror(req
, status
);
5248 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5249 /* Always do lstat for UNIX calls. */
5250 if (SMB_VFS_LSTAT(conn
, smb_fname_base
) != 0) {
5251 DEBUG(3,("call_trans2qfilepathinfo: "
5252 "SMB_VFS_LSTAT of %s failed "
5254 smb_fname_str_dbg(smb_fname_base
),
5256 TALLOC_FREE(smb_fname_base
);
5258 map_nt_error_from_unix(errno
));
5262 if (SMB_VFS_STAT(conn
, smb_fname_base
) != 0) {
5263 DEBUG(3,("call_trans2qfilepathinfo: "
5264 "fileinfo of %s failed "
5266 smb_fname_str_dbg(smb_fname_base
),
5268 TALLOC_FREE(smb_fname_base
);
5270 map_nt_error_from_unix(errno
));
5275 status
= file_name_hash(conn
,
5276 smb_fname_str_dbg(smb_fname_base
),
5278 if (!NT_STATUS_IS_OK(status
)) {
5279 TALLOC_FREE(smb_fname_base
);
5280 reply_nterror(req
, status
);
5284 fileid
= vfs_file_id_from_sbuf(conn
,
5285 &smb_fname_base
->st
);
5286 TALLOC_FREE(smb_fname_base
);
5287 get_file_infos(fileid
, name_hash
, &delete_pending
, NULL
);
5288 if (delete_pending
) {
5289 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5294 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5295 /* Always do lstat for UNIX calls. */
5296 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
5297 DEBUG(3,("call_trans2qfilepathinfo: "
5298 "SMB_VFS_LSTAT of %s failed (%s)\n",
5299 smb_fname_str_dbg(smb_fname
),
5302 map_nt_error_from_unix(errno
));
5307 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
5308 DEBUG(3,("call_trans2qfilepathinfo: "
5309 "SMB_VFS_STAT of %s failed (%s)\n",
5310 smb_fname_str_dbg(smb_fname
),
5313 map_nt_error_from_unix(errno
));
5318 status
= file_name_hash(conn
,
5319 smb_fname_str_dbg(smb_fname
),
5321 if (!NT_STATUS_IS_OK(status
)) {
5322 reply_nterror(req
, status
);
5326 fileid
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
5327 get_file_infos(fileid
, name_hash
, &delete_pending
, &write_time_ts
);
5328 if (delete_pending
) {
5329 reply_nterror(req
, NT_STATUS_DELETE_PENDING
);
5334 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
5335 "total_data=%d\n", smb_fname_str_dbg(smb_fname
),
5336 fsp
? fsp
->fnum
: -1, info_level
,tran_call
,total_data
));
5338 /* Pull out any data sent here before we realloc. */
5339 switch (info_level
) {
5340 case SMB_INFO_QUERY_EAS_FROM_LIST
:
5342 /* Pull any EA list from the data portion. */
5345 if (total_data
< 4) {
5347 req
, NT_STATUS_INVALID_PARAMETER
);
5350 ea_size
= IVAL(pdata
,0);
5352 if (total_data
> 0 && ea_size
!= total_data
) {
5353 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5354 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
5356 req
, NT_STATUS_INVALID_PARAMETER
);
5360 if (!lp_ea_support(SNUM(conn
))) {
5361 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
5365 /* Pull out the list of names. */
5366 ea_list
= read_ea_name_list(req
, pdata
+ 4, ea_size
- 4);
5369 req
, NT_STATUS_INVALID_PARAMETER
);
5375 case SMB_QUERY_POSIX_LOCK
:
5377 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
5378 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
5382 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
5384 req
, NT_STATUS_INVALID_PARAMETER
);
5388 /* Copy the lock range data. */
5389 lock_data
= (char *)TALLOC_MEMDUP(
5390 req
, pdata
, total_data
);
5392 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5395 lock_data_count
= total_data
;
5401 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
5402 if (*pparams
== NULL
) {
5403 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
5410 * draft-leach-cifs-v1-spec-02.txt
5411 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5414 * The requested information is placed in the Data portion of the
5415 * transaction response. For the information levels greater than 0x100,
5416 * the transaction response has 1 parameter word which should be
5417 * ignored by the client.
5419 * However Windows only follows this rule for the IS_NAME_VALID call.
5421 switch (info_level
) {
5422 case SMB_INFO_IS_NAME_VALID
:
5427 if ((info_level
& 0xFF00) == 0xFF00) {
5429 * We use levels that start with 0xFF00
5430 * internally to represent SMB2 specific levels
5432 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
5436 status
= smbd_do_qfilepathinfo(conn
, req
, info_level
,
5438 delete_pending
, write_time_ts
,
5440 lock_data_count
, lock_data
,
5441 req
->flags2
, max_data_bytes
,
5442 ppdata
, &data_size
);
5443 if (!NT_STATUS_IS_OK(status
)) {
5444 reply_nterror(req
, status
);
5448 send_trans2_replies(conn
, req
, params
, param_size
, *ppdata
, data_size
,
5454 /****************************************************************************
5455 Set a hard link (called by UNIX extensions and by NT rename with HARD link
5457 ****************************************************************************/
5459 NTSTATUS
hardlink_internals(TALLOC_CTX
*ctx
,
5460 connection_struct
*conn
,
5461 struct smb_request
*req
,
5462 bool overwrite_if_exists
,
5463 const struct smb_filename
*smb_fname_old
,
5464 struct smb_filename
*smb_fname_new
)
5466 NTSTATUS status
= NT_STATUS_OK
;
5468 /* source must already exist. */
5469 if (!VALID_STAT(smb_fname_old
->st
)) {
5470 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5473 if (VALID_STAT(smb_fname_new
->st
)) {
5474 if (overwrite_if_exists
) {
5475 if (S_ISDIR(smb_fname_new
->st
.st_ex_mode
)) {
5476 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5478 status
= unlink_internals(conn
,
5480 FILE_ATTRIBUTE_NORMAL
,
5483 if (!NT_STATUS_IS_OK(status
)) {
5487 /* Disallow if newname already exists. */
5488 return NT_STATUS_OBJECT_NAME_COLLISION
;
5492 /* No links from a directory. */
5493 if (S_ISDIR(smb_fname_old
->st
.st_ex_mode
)) {
5494 return NT_STATUS_FILE_IS_A_DIRECTORY
;
5497 /* Setting a hardlink to/from a stream isn't currently supported. */
5498 if (is_ntfs_stream_smb_fname(smb_fname_old
) ||
5499 is_ntfs_stream_smb_fname(smb_fname_new
)) {
5500 return NT_STATUS_INVALID_PARAMETER
;
5503 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5504 smb_fname_old
->base_name
, smb_fname_new
->base_name
));
5506 if (SMB_VFS_LINK(conn
, smb_fname_old
->base_name
,
5507 smb_fname_new
->base_name
) != 0) {
5508 status
= map_nt_error_from_unix(errno
);
5509 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5510 nt_errstr(status
), smb_fname_old
->base_name
,
5511 smb_fname_new
->base_name
));
5516 /****************************************************************************
5517 Deal with setting the time from any of the setfilepathinfo functions.
5518 ****************************************************************************/
5520 NTSTATUS
smb_set_file_time(connection_struct
*conn
,
5522 const struct smb_filename
*smb_fname
,
5523 struct smb_file_time
*ft
,
5524 bool setting_write_time
)
5526 struct smb_filename smb_fname_base
;
5528 FILE_NOTIFY_CHANGE_LAST_ACCESS
5529 |FILE_NOTIFY_CHANGE_LAST_WRITE
5530 |FILE_NOTIFY_CHANGE_CREATION
;
5532 if (!VALID_STAT(smb_fname
->st
)) {
5533 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5536 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
5537 return NT_STATUS_ACCESS_DENIED
;
5540 /* get some defaults (no modifications) if any info is zero or -1. */
5541 if (null_timespec(ft
->create_time
)) {
5542 action
&= ~FILE_NOTIFY_CHANGE_CREATION
;
5545 if (null_timespec(ft
->atime
)) {
5546 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
5549 if (null_timespec(ft
->mtime
)) {
5550 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5553 if (!setting_write_time
) {
5554 /* ft->mtime comes from change time, not write time. */
5555 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
5558 /* Ensure the resolution is the correct for
5559 * what we can store on this filesystem. */
5561 round_timespec(conn
->ts_res
, &ft
->create_time
);
5562 round_timespec(conn
->ts_res
, &ft
->ctime
);
5563 round_timespec(conn
->ts_res
, &ft
->atime
);
5564 round_timespec(conn
->ts_res
, &ft
->mtime
);
5566 DEBUG(5,("smb_set_filetime: actime: %s\n ",
5567 time_to_asc(convert_timespec_to_time_t(ft
->atime
))));
5568 DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5569 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5570 DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5571 time_to_asc(convert_timespec_to_time_t(ft
->ctime
))));
5572 DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5573 time_to_asc(convert_timespec_to_time_t(ft
->create_time
))));
5575 if (setting_write_time
) {
5577 * This was a Windows setfileinfo on an open file.
5578 * NT does this a lot. We also need to
5579 * set the time here, as it can be read by
5580 * FindFirst/FindNext and with the patch for bug #2045
5581 * in smbd/fileio.c it ensures that this timestamp is
5582 * kept sticky even after a write. We save the request
5583 * away and will set it on file close and after a write. JRA.
5586 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5587 time_to_asc(convert_timespec_to_time_t(ft
->mtime
))));
5590 if (fsp
->base_fsp
) {
5591 set_sticky_write_time_fsp(fsp
->base_fsp
,
5594 set_sticky_write_time_fsp(fsp
, ft
->mtime
);
5597 set_sticky_write_time_path(
5598 vfs_file_id_from_sbuf(conn
, &smb_fname
->st
),
5603 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5605 /* Always call ntimes on the base, even if a stream was passed in. */
5606 smb_fname_base
= *smb_fname
;
5607 smb_fname_base
.stream_name
= NULL
;
5609 if(file_ntimes(conn
, &smb_fname_base
, ft
)!=0) {
5610 return map_nt_error_from_unix(errno
);
5613 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
,
5614 smb_fname
->base_name
);
5615 return NT_STATUS_OK
;
5618 /****************************************************************************
5619 Deal with setting the dosmode from any of the setfilepathinfo functions.
5620 ****************************************************************************/
5622 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
5623 const struct smb_filename
*smb_fname
,
5626 struct smb_filename
*smb_fname_base
= NULL
;
5629 if (!VALID_STAT(smb_fname
->st
)) {
5630 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5633 /* Always operate on the base_name, even if a stream was passed in. */
5634 status
= create_synthetic_smb_fname(talloc_tos(), smb_fname
->base_name
,
5635 NULL
, &smb_fname
->st
,
5637 if (!NT_STATUS_IS_OK(status
)) {
5642 if (S_ISDIR(smb_fname_base
->st
.st_ex_mode
)) {
5643 dosmode
|= FILE_ATTRIBUTE_DIRECTORY
;
5645 dosmode
&= ~FILE_ATTRIBUTE_DIRECTORY
;
5649 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode
));
5651 /* check the mode isn't different, before changing it */
5652 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, smb_fname_base
))) {
5653 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5654 "0x%x\n", smb_fname_str_dbg(smb_fname_base
),
5655 (unsigned int)dosmode
));
5657 if(file_set_dosmode(conn
, smb_fname_base
, dosmode
, NULL
,
5659 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5661 smb_fname_str_dbg(smb_fname_base
),
5663 status
= map_nt_error_from_unix(errno
);
5667 status
= NT_STATUS_OK
;
5669 TALLOC_FREE(smb_fname_base
);
5673 /****************************************************************************
5674 Deal with setting the size from any of the setfilepathinfo functions.
5675 ****************************************************************************/
5677 static NTSTATUS
smb_set_file_size(connection_struct
*conn
,
5678 struct smb_request
*req
,
5680 const struct smb_filename
*smb_fname
,
5681 const SMB_STRUCT_STAT
*psbuf
,
5683 bool fail_after_createfile
)
5685 NTSTATUS status
= NT_STATUS_OK
;
5686 struct smb_filename
*smb_fname_tmp
= NULL
;
5687 files_struct
*new_fsp
= NULL
;
5689 if (!VALID_STAT(*psbuf
)) {
5690 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5693 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
5694 return NT_STATUS_ACCESS_DENIED
;
5697 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size
));
5699 if (size
== get_file_size_stat(psbuf
)) {
5700 return NT_STATUS_OK
;
5703 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5704 smb_fname_str_dbg(smb_fname
), (double)size
));
5706 if (fsp
&& fsp
->fh
->fd
!= -1) {
5707 /* Handle based call. */
5708 if (vfs_set_filelen(fsp
, size
) == -1) {
5709 return map_nt_error_from_unix(errno
);
5711 trigger_write_time_update_immediate(fsp
);
5712 return NT_STATUS_OK
;
5715 status
= copy_smb_filename(talloc_tos(), smb_fname
, &smb_fname_tmp
);
5716 if (!NT_STATUS_IS_OK(status
)) {
5720 smb_fname_tmp
->st
= *psbuf
;
5722 status
= SMB_VFS_CREATE_FILE(
5725 0, /* root_dir_fid */
5726 smb_fname_tmp
, /* fname */
5727 FILE_WRITE_DATA
, /* access_mask */
5728 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
5730 FILE_OPEN
, /* create_disposition*/
5731 0, /* create_options */
5732 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5733 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
5734 0, /* allocation_size */
5735 0, /* private_flags */
5738 &new_fsp
, /* result */
5741 TALLOC_FREE(smb_fname_tmp
);
5743 if (!NT_STATUS_IS_OK(status
)) {
5744 /* NB. We check for open_was_deferred in the caller. */
5748 /* See RAW-SFILEINFO-END-OF-FILE */
5749 if (fail_after_createfile
) {
5750 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5751 return NT_STATUS_INVALID_LEVEL
;
5754 if (vfs_set_filelen(new_fsp
, size
) == -1) {
5755 status
= map_nt_error_from_unix(errno
);
5756 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5760 trigger_write_time_update_immediate(new_fsp
);
5761 close_file(req
, new_fsp
,NORMAL_CLOSE
);
5762 return NT_STATUS_OK
;
5765 /****************************************************************************
5766 Deal with SMB_INFO_SET_EA.
5767 ****************************************************************************/
5769 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
5773 const struct smb_filename
*smb_fname
)
5775 struct ea_list
*ea_list
= NULL
;
5776 TALLOC_CTX
*ctx
= NULL
;
5777 NTSTATUS status
= NT_STATUS_OK
;
5779 if (total_data
< 10) {
5781 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5782 length. They seem to have no effect. Bug #3212. JRA */
5784 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
5785 /* We're done. We only get EA info in this call. */
5786 return NT_STATUS_OK
;
5789 return NT_STATUS_INVALID_PARAMETER
;
5792 if (IVAL(pdata
,0) > total_data
) {
5793 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5794 IVAL(pdata
,0), (unsigned int)total_data
));
5795 return NT_STATUS_INVALID_PARAMETER
;
5799 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
5801 return NT_STATUS_INVALID_PARAMETER
;
5804 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_EA
)) {
5805 return NT_STATUS_ACCESS_DENIED
;
5808 status
= set_ea(conn
, fsp
, smb_fname
, ea_list
);
5813 /****************************************************************************
5814 Deal with SMB_FILE_FULL_EA_INFORMATION set.
5815 ****************************************************************************/
5817 static NTSTATUS
smb_set_file_full_ea_info(connection_struct
*conn
,
5822 struct ea_list
*ea_list
= NULL
;
5826 return NT_STATUS_INVALID_HANDLE
;
5829 if (!lp_ea_support(SNUM(conn
))) {
5830 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5831 "EA's not supported.\n",
5832 (unsigned int)total_data
));
5833 return NT_STATUS_EAS_NOT_SUPPORTED
;
5836 if (total_data
< 10) {
5837 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5839 (unsigned int)total_data
));
5840 return NT_STATUS_INVALID_PARAMETER
;
5843 ea_list
= read_nttrans_ea_list(talloc_tos(),
5848 return NT_STATUS_INVALID_PARAMETER
;
5851 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_EA
)) {
5852 return NT_STATUS_ACCESS_DENIED
;
5855 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
5857 DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5858 smb_fname_str_dbg(fsp
->fsp_name
),
5859 nt_errstr(status
) ));
5865 /****************************************************************************
5866 Deal with SMB_SET_FILE_DISPOSITION_INFO.
5867 ****************************************************************************/
5869 static NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
5873 struct smb_filename
*smb_fname
)
5875 NTSTATUS status
= NT_STATUS_OK
;
5876 bool delete_on_close
;
5879 if (total_data
< 1) {
5880 return NT_STATUS_INVALID_PARAMETER
;
5884 return NT_STATUS_INVALID_HANDLE
;
5887 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
5888 dosmode
= dos_mode(conn
, smb_fname
);
5890 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5891 "delete_on_close = %u\n",
5892 smb_fname_str_dbg(smb_fname
),
5893 (unsigned int)dosmode
,
5894 (unsigned int)delete_on_close
));
5896 if (delete_on_close
) {
5897 status
= can_set_delete_on_close(fsp
, dosmode
);
5898 if (!NT_STATUS_IS_OK(status
)) {
5903 /* The set is across all open files on this dev/inode pair. */
5904 if (!set_delete_on_close(fsp
, delete_on_close
,
5905 conn
->session_info
->security_token
,
5906 &conn
->session_info
->utok
)) {
5907 return NT_STATUS_ACCESS_DENIED
;
5909 return NT_STATUS_OK
;
5912 /****************************************************************************
5913 Deal with SMB_FILE_POSITION_INFORMATION.
5914 ****************************************************************************/
5916 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
5921 uint64_t position_information
;
5923 if (total_data
< 8) {
5924 return NT_STATUS_INVALID_PARAMETER
;
5928 /* Ignore on pathname based set. */
5929 return NT_STATUS_OK
;
5932 position_information
= (uint64_t)IVAL(pdata
,0);
5933 #ifdef LARGE_SMB_OFF_T
5934 position_information
|= (((uint64_t)IVAL(pdata
,4)) << 32);
5935 #else /* LARGE_SMB_OFF_T */
5936 if (IVAL(pdata
,4) != 0) {
5937 /* more than 32 bits? */
5938 return NT_STATUS_INVALID_PARAMETER
;
5940 #endif /* LARGE_SMB_OFF_T */
5942 DEBUG(10,("smb_file_position_information: Set file position "
5943 "information for file %s to %.0f\n", fsp_str_dbg(fsp
),
5944 (double)position_information
));
5945 fsp
->fh
->position_information
= position_information
;
5946 return NT_STATUS_OK
;
5949 /****************************************************************************
5950 Deal with SMB_FILE_MODE_INFORMATION.
5951 ****************************************************************************/
5953 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
5959 if (total_data
< 4) {
5960 return NT_STATUS_INVALID_PARAMETER
;
5962 mode
= IVAL(pdata
,0);
5963 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
5964 return NT_STATUS_INVALID_PARAMETER
;
5966 return NT_STATUS_OK
;
5969 /****************************************************************************
5970 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
5971 ****************************************************************************/
5973 static NTSTATUS
smb_set_file_unix_link(connection_struct
*conn
,
5974 struct smb_request
*req
,
5977 const struct smb_filename
*smb_fname
)
5979 char *link_target
= NULL
;
5980 const char *newname
= smb_fname
->base_name
;
5981 TALLOC_CTX
*ctx
= talloc_tos();
5983 /* Set a symbolic link. */
5984 /* Don't allow this if follow links is false. */
5986 if (total_data
== 0) {
5987 return NT_STATUS_INVALID_PARAMETER
;
5990 if (!lp_symlinks(SNUM(conn
))) {
5991 return NT_STATUS_ACCESS_DENIED
;
5994 srvstr_pull_talloc(ctx
, pdata
, req
->flags2
, &link_target
, pdata
,
5995 total_data
, STR_TERMINATE
);
5998 return NT_STATUS_INVALID_PARAMETER
;
6001 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
6002 newname
, link_target
));
6004 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0) {
6005 return map_nt_error_from_unix(errno
);
6008 return NT_STATUS_OK
;
6011 /****************************************************************************
6012 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
6013 ****************************************************************************/
6015 static NTSTATUS
smb_set_file_unix_hlink(connection_struct
*conn
,
6016 struct smb_request
*req
,
6017 const char *pdata
, int total_data
,
6018 struct smb_filename
*smb_fname_new
)
6020 char *oldname
= NULL
;
6021 struct smb_filename
*smb_fname_old
= NULL
;
6022 TALLOC_CTX
*ctx
= talloc_tos();
6023 NTSTATUS status
= NT_STATUS_OK
;
6025 /* Set a hard link. */
6026 if (total_data
== 0) {
6027 return NT_STATUS_INVALID_PARAMETER
;
6030 srvstr_get_path(ctx
, pdata
, req
->flags2
, &oldname
, pdata
,
6031 total_data
, STR_TERMINATE
, &status
);
6032 if (!NT_STATUS_IS_OK(status
)) {
6036 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6037 smb_fname_str_dbg(smb_fname_new
), oldname
));
6039 status
= filename_convert(ctx
,
6041 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6046 if (!NT_STATUS_IS_OK(status
)) {
6050 return hardlink_internals(ctx
, conn
, req
, false,
6051 smb_fname_old
, smb_fname_new
);
6054 /****************************************************************************
6055 Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6056 ****************************************************************************/
6058 static NTSTATUS
smb2_file_rename_information(connection_struct
*conn
,
6059 struct smb_request
*req
,
6063 struct smb_filename
*smb_fname_src
)
6067 char *newname
= NULL
;
6068 struct smb_filename
*smb_fname_dst
= NULL
;
6069 NTSTATUS status
= NT_STATUS_OK
;
6070 TALLOC_CTX
*ctx
= talloc_tos();
6073 return NT_STATUS_INVALID_HANDLE
;
6076 if (total_data
< 20) {
6077 return NT_STATUS_INVALID_PARAMETER
;
6080 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6081 len
= IVAL(pdata
,16);
6083 if (len
> (total_data
- 20) || (len
== 0)) {
6084 return NT_STATUS_INVALID_PARAMETER
;
6087 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6088 &pdata
[20], len
, STR_TERMINATE
,
6090 if (!NT_STATUS_IS_OK(status
)) {
6094 DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
6097 status
= filename_convert(ctx
,
6099 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6104 if (!NT_STATUS_IS_OK(status
)) {
6108 if (fsp
->base_fsp
) {
6109 /* newname must be a stream name. */
6110 if (newname
[0] != ':') {
6111 return NT_STATUS_NOT_SUPPORTED
;
6114 /* Create an smb_fname to call rename_internals_fsp() with. */
6115 status
= create_synthetic_smb_fname(talloc_tos(),
6116 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6118 if (!NT_STATUS_IS_OK(status
)) {
6123 * Set the original last component, since
6124 * rename_internals_fsp() requires it.
6126 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6128 if (smb_fname_dst
->original_lcomp
== NULL
) {
6129 status
= NT_STATUS_NO_MEMORY
;
6135 DEBUG(10,("smb2_file_rename_information: "
6136 "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6137 fsp
->fnum
, fsp_str_dbg(fsp
),
6138 smb_fname_str_dbg(smb_fname_dst
)));
6139 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
,
6140 (FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
),
6144 TALLOC_FREE(smb_fname_dst
);
6148 static NTSTATUS
smb_file_link_information(connection_struct
*conn
,
6149 struct smb_request
*req
,
6153 struct smb_filename
*smb_fname_src
)
6157 char *newname
= NULL
;
6158 struct smb_filename
*smb_fname_dst
= NULL
;
6159 NTSTATUS status
= NT_STATUS_OK
;
6160 TALLOC_CTX
*ctx
= talloc_tos();
6163 return NT_STATUS_INVALID_HANDLE
;
6166 if (total_data
< 20) {
6167 return NT_STATUS_INVALID_PARAMETER
;
6170 overwrite
= (CVAL(pdata
,0) ? true : false);
6171 len
= IVAL(pdata
,16);
6173 if (len
> (total_data
- 20) || (len
== 0)) {
6174 return NT_STATUS_INVALID_PARAMETER
;
6177 srvstr_get_path(ctx
, pdata
, req
->flags2
, &newname
,
6178 &pdata
[20], len
, STR_TERMINATE
,
6180 if (!NT_STATUS_IS_OK(status
)) {
6184 DEBUG(10,("smb_file_link_information: got name |%s|\n",
6187 status
= filename_convert(ctx
,
6189 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6194 if (!NT_STATUS_IS_OK(status
)) {
6198 if (fsp
->base_fsp
) {
6199 /* No stream names. */
6200 return NT_STATUS_NOT_SUPPORTED
;
6203 DEBUG(10,("smb_file_link_information: "
6204 "SMB_FILE_LINK_INFORMATION (fnum %d) %s -> %s\n",
6205 fsp
->fnum
, fsp_str_dbg(fsp
),
6206 smb_fname_str_dbg(smb_fname_dst
)));
6207 status
= hardlink_internals(ctx
,
6214 TALLOC_FREE(smb_fname_dst
);
6218 /****************************************************************************
6219 Deal with SMB_FILE_RENAME_INFORMATION.
6220 ****************************************************************************/
6222 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
6223 struct smb_request
*req
,
6227 struct smb_filename
*smb_fname_src
)
6232 char *newname
= NULL
;
6233 struct smb_filename
*smb_fname_dst
= NULL
;
6234 bool dest_has_wcard
= False
;
6235 NTSTATUS status
= NT_STATUS_OK
;
6237 TALLOC_CTX
*ctx
= talloc_tos();
6239 if (total_data
< 13) {
6240 return NT_STATUS_INVALID_PARAMETER
;
6243 overwrite
= (CVAL(pdata
,0) ? True
: False
);
6244 root_fid
= IVAL(pdata
,4);
6245 len
= IVAL(pdata
,8);
6247 if (len
> (total_data
- 12) || (len
== 0) || (root_fid
!= 0)) {
6248 return NT_STATUS_INVALID_PARAMETER
;
6251 srvstr_get_path_wcard(ctx
, pdata
, req
->flags2
, &newname
, &pdata
[12],
6254 if (!NT_STATUS_IS_OK(status
)) {
6258 DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6261 status
= resolve_dfspath_wcard(ctx
, conn
,
6262 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
6267 if (!NT_STATUS_IS_OK(status
)) {
6271 /* Check the new name has no '/' characters. */
6272 if (strchr_m(newname
, '/')) {
6273 return NT_STATUS_NOT_SUPPORTED
;
6276 if (fsp
&& fsp
->base_fsp
) {
6277 /* newname must be a stream name. */
6278 if (newname
[0] != ':') {
6279 return NT_STATUS_NOT_SUPPORTED
;
6282 /* Create an smb_fname to call rename_internals_fsp() with. */
6283 status
= create_synthetic_smb_fname(talloc_tos(),
6284 fsp
->base_fsp
->fsp_name
->base_name
, newname
, NULL
,
6286 if (!NT_STATUS_IS_OK(status
)) {
6291 * Set the original last component, since
6292 * rename_internals_fsp() requires it.
6294 smb_fname_dst
->original_lcomp
= talloc_strdup(smb_fname_dst
,
6296 if (smb_fname_dst
->original_lcomp
== NULL
) {
6297 status
= NT_STATUS_NO_MEMORY
;
6303 * Build up an smb_fname_dst based on the filename passed in.
6304 * We basically just strip off the last component, and put on
6305 * the newname instead.
6307 char *base_name
= NULL
;
6309 /* newname must *not* be a stream name. */
6310 if (newname
[0] == ':') {
6311 return NT_STATUS_NOT_SUPPORTED
;
6315 * Strip off the last component (filename) of the path passed
6318 base_name
= talloc_strdup(ctx
, smb_fname_src
->base_name
);
6320 return NT_STATUS_NO_MEMORY
;
6322 p
= strrchr_m(base_name
, '/');
6326 base_name
= talloc_strdup(ctx
, "");
6328 return NT_STATUS_NO_MEMORY
;
6331 /* Append the new name. */
6332 base_name
= talloc_asprintf_append(base_name
,
6336 return NT_STATUS_NO_MEMORY
;
6339 status
= unix_convert(ctx
, conn
, base_name
, &smb_fname_dst
,
6342 UCF_ALWAYS_ALLOW_WCARD_LCOMP
:
6345 /* If an error we expect this to be
6346 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6348 if (!NT_STATUS_IS_OK(status
)) {
6349 if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND
,
6353 /* Create an smb_fname to call rename_internals_fsp() */
6354 status
= create_synthetic_smb_fname(ctx
,
6358 if (!NT_STATUS_IS_OK(status
)) {
6365 DEBUG(10,("smb_file_rename_information: "
6366 "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6367 fsp
->fnum
, fsp_str_dbg(fsp
),
6368 smb_fname_str_dbg(smb_fname_dst
)));
6369 status
= rename_internals_fsp(conn
, fsp
, smb_fname_dst
, 0,
6372 DEBUG(10,("smb_file_rename_information: "
6373 "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6374 smb_fname_str_dbg(smb_fname_src
),
6375 smb_fname_str_dbg(smb_fname_dst
)));
6376 status
= rename_internals(ctx
, conn
, req
, smb_fname_src
,
6377 smb_fname_dst
, 0, overwrite
, false,
6379 FILE_WRITE_ATTRIBUTES
);
6382 TALLOC_FREE(smb_fname_dst
);
6386 /****************************************************************************
6387 Deal with SMB_SET_POSIX_ACL.
6388 ****************************************************************************/
6390 #if defined(HAVE_POSIX_ACLS)
6391 static NTSTATUS
smb_set_posix_acl(connection_struct
*conn
,
6395 const struct smb_filename
*smb_fname
)
6397 uint16 posix_acl_version
;
6398 uint16 num_file_acls
;
6399 uint16 num_def_acls
;
6400 bool valid_file_acls
= True
;
6401 bool valid_def_acls
= True
;
6403 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
6404 return NT_STATUS_INVALID_PARAMETER
;
6406 posix_acl_version
= SVAL(pdata
,0);
6407 num_file_acls
= SVAL(pdata
,2);
6408 num_def_acls
= SVAL(pdata
,4);
6410 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6411 valid_file_acls
= False
;
6415 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
6416 valid_def_acls
= False
;
6420 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
6421 return NT_STATUS_INVALID_PARAMETER
;
6424 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
6425 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
6426 return NT_STATUS_INVALID_PARAMETER
;
6429 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6430 smb_fname
? smb_fname_str_dbg(smb_fname
) : fsp_str_dbg(fsp
),
6431 (unsigned int)num_file_acls
,
6432 (unsigned int)num_def_acls
));
6434 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
,
6435 smb_fname
->base_name
, num_file_acls
,
6436 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
6437 return map_nt_error_from_unix(errno
);
6440 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
,
6441 smb_fname
->base_name
, &smb_fname
->st
, num_def_acls
,
6442 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
6443 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
6444 return map_nt_error_from_unix(errno
);
6446 return NT_STATUS_OK
;
6450 /****************************************************************************
6451 Deal with SMB_SET_POSIX_LOCK.
6452 ****************************************************************************/
6454 static NTSTATUS
smb_set_posix_lock(connection_struct
*conn
,
6455 struct smb_request
*req
,
6463 bool blocking_lock
= False
;
6464 enum brl_type lock_type
;
6466 NTSTATUS status
= NT_STATUS_OK
;
6468 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
6469 return NT_STATUS_INVALID_HANDLE
;
6472 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
6473 return NT_STATUS_INVALID_PARAMETER
;
6476 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
6477 case POSIX_LOCK_TYPE_READ
:
6478 lock_type
= READ_LOCK
;
6480 case POSIX_LOCK_TYPE_WRITE
:
6481 /* Return the right POSIX-mappable error code for files opened read-only. */
6482 if (!fsp
->can_write
) {
6483 return NT_STATUS_INVALID_HANDLE
;
6485 lock_type
= WRITE_LOCK
;
6487 case POSIX_LOCK_TYPE_UNLOCK
:
6488 lock_type
= UNLOCK_LOCK
;
6491 return NT_STATUS_INVALID_PARAMETER
;
6494 if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_NOWAIT
) {
6495 blocking_lock
= False
;
6496 } else if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_WAIT
) {
6497 blocking_lock
= True
;
6499 return NT_STATUS_INVALID_PARAMETER
;
6502 if (!lp_blocking_locks(SNUM(conn
))) {
6503 blocking_lock
= False
;
6506 smblctx
= (uint64_t)IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
6507 #if defined(HAVE_LONGLONG)
6508 offset
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
6509 ((uint64_t) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
6510 count
= (((uint64_t) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
6511 ((uint64_t) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
6512 #else /* HAVE_LONGLONG */
6513 offset
= (uint64_t)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
6514 count
= (uint64_t)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
6515 #endif /* HAVE_LONGLONG */
6517 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6518 "smblctx = %llu, count = %.0f, offset = %.0f\n",
6520 (unsigned int)lock_type
,
6521 (unsigned long long)smblctx
,
6525 if (lock_type
== UNLOCK_LOCK
) {
6526 status
= do_unlock(req
->sconn
->msg_ctx
,
6533 uint64_t block_smblctx
;
6535 struct byte_range_lock
*br_lck
= do_lock(req
->sconn
->msg_ctx
,
6547 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
6549 * A blocking lock was requested. Package up
6550 * this smb into a queued request and push it
6551 * onto the blocking lock queue.
6553 if(push_blocking_lock_request(br_lck
,
6556 -1, /* infinite timeout. */
6564 TALLOC_FREE(br_lck
);
6568 TALLOC_FREE(br_lck
);
6574 /****************************************************************************
6575 Deal with SMB_SET_FILE_BASIC_INFO.
6576 ****************************************************************************/
6578 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
6582 const struct smb_filename
*smb_fname
)
6584 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6585 struct smb_file_time ft
;
6587 NTSTATUS status
= NT_STATUS_OK
;
6591 if (total_data
< 36) {
6592 return NT_STATUS_INVALID_PARAMETER
;
6595 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
6596 return NT_STATUS_ACCESS_DENIED
;
6599 /* Set the attributes */
6600 dosmode
= IVAL(pdata
,32);
6601 status
= smb_set_file_dosmode(conn
, smb_fname
, dosmode
);
6602 if (!NT_STATUS_IS_OK(status
)) {
6607 ft
.create_time
= interpret_long_date(pdata
);
6610 ft
.atime
= interpret_long_date(pdata
+8);
6613 ft
.mtime
= interpret_long_date(pdata
+16);
6616 ft
.ctime
= interpret_long_date(pdata
+24);
6618 DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6619 smb_fname_str_dbg(smb_fname
)));
6621 return smb_set_file_time(conn
, fsp
, smb_fname
, &ft
,
6625 /****************************************************************************
6626 Deal with SMB_INFO_STANDARD.
6627 ****************************************************************************/
6629 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
6633 const struct smb_filename
*smb_fname
)
6635 struct smb_file_time ft
;
6639 if (total_data
< 12) {
6640 return NT_STATUS_INVALID_PARAMETER
;
6643 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_ATTRIBUTES
)) {
6644 return NT_STATUS_ACCESS_DENIED
;
6648 ft
.create_time
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
));
6650 ft
.atime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+4));
6652 ft
.mtime
= convert_time_t_to_timespec(srv_make_unix_date2(pdata
+8));
6654 DEBUG(10,("smb_set_info_standard: file %s\n",
6655 smb_fname_str_dbg(smb_fname
)));
6657 return smb_set_file_time(conn
,
6664 /****************************************************************************
6665 Deal with SMB_SET_FILE_ALLOCATION_INFO.
6666 ****************************************************************************/
6668 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
6669 struct smb_request
*req
,
6673 struct smb_filename
*smb_fname
)
6675 uint64_t allocation_size
= 0;
6676 NTSTATUS status
= NT_STATUS_OK
;
6677 files_struct
*new_fsp
= NULL
;
6679 if (!VALID_STAT(smb_fname
->st
)) {
6680 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6683 if (total_data
< 8) {
6684 return NT_STATUS_INVALID_PARAMETER
;
6687 allocation_size
= (uint64_t)IVAL(pdata
,0);
6688 #ifdef LARGE_SMB_OFF_T
6689 allocation_size
|= (((uint64_t)IVAL(pdata
,4)) << 32);
6690 #else /* LARGE_SMB_OFF_T */
6691 if (IVAL(pdata
,4) != 0) {
6692 /* more than 32 bits? */
6693 return NT_STATUS_INVALID_PARAMETER
;
6695 #endif /* LARGE_SMB_OFF_T */
6697 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6698 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6699 (double)allocation_size
));
6701 if (allocation_size
) {
6702 allocation_size
= smb_roundup(conn
, allocation_size
);
6705 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6706 return NT_STATUS_ACCESS_DENIED
;
6709 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6710 "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname
),
6711 (double)allocation_size
));
6713 if (fsp
&& fsp
->fh
->fd
!= -1) {
6714 /* Open file handle. */
6715 /* Only change if needed. */
6716 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6717 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
6718 return map_nt_error_from_unix(errno
);
6721 /* But always update the time. */
6723 * This is equivalent to a write. Ensure it's seen immediately
6724 * if there are no pending writes.
6726 trigger_write_time_update_immediate(fsp
);
6727 return NT_STATUS_OK
;
6730 /* Pathname or stat or directory file. */
6731 status
= SMB_VFS_CREATE_FILE(
6734 0, /* root_dir_fid */
6735 smb_fname
, /* fname */
6736 FILE_WRITE_DATA
, /* access_mask */
6737 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
6739 FILE_OPEN
, /* create_disposition*/
6740 0, /* create_options */
6741 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
6742 FORCE_OPLOCK_BREAK_TO_NONE
, /* oplock_request */
6743 0, /* allocation_size */
6744 0, /* private_flags */
6747 &new_fsp
, /* result */
6750 if (!NT_STATUS_IS_OK(status
)) {
6751 /* NB. We check for open_was_deferred in the caller. */
6755 /* Only change if needed. */
6756 if (allocation_size
!= get_file_size_stat(&smb_fname
->st
)) {
6757 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
6758 status
= map_nt_error_from_unix(errno
);
6759 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6764 /* Changing the allocation size should set the last mod time. */
6766 * This is equivalent to a write. Ensure it's seen immediately
6767 * if there are no pending writes.
6769 trigger_write_time_update_immediate(new_fsp
);
6771 close_file(req
, new_fsp
, NORMAL_CLOSE
);
6772 return NT_STATUS_OK
;
6775 /****************************************************************************
6776 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6777 ****************************************************************************/
6779 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
6780 struct smb_request
*req
,
6784 const struct smb_filename
*smb_fname
,
6785 bool fail_after_createfile
)
6789 if (total_data
< 8) {
6790 return NT_STATUS_INVALID_PARAMETER
;
6793 size
= IVAL(pdata
,0);
6794 #ifdef LARGE_SMB_OFF_T
6795 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
6796 #else /* LARGE_SMB_OFF_T */
6797 if (IVAL(pdata
,4) != 0) {
6798 /* more than 32 bits? */
6799 return NT_STATUS_INVALID_PARAMETER
;
6801 #endif /* LARGE_SMB_OFF_T */
6802 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6803 "file %s to %.0f\n", smb_fname_str_dbg(smb_fname
),
6806 if (fsp
&& !(fsp
->access_mask
& FILE_WRITE_DATA
)) {
6807 return NT_STATUS_ACCESS_DENIED
;
6810 return smb_set_file_size(conn
, req
,
6815 fail_after_createfile
);
6818 /****************************************************************************
6819 Allow a UNIX info mknod.
6820 ****************************************************************************/
6822 static NTSTATUS
smb_unix_mknod(connection_struct
*conn
,
6825 const struct smb_filename
*smb_fname
)
6827 uint32 file_type
= IVAL(pdata
,56);
6828 #if defined(HAVE_MAKEDEV)
6829 uint32 dev_major
= IVAL(pdata
,60);
6830 uint32 dev_minor
= IVAL(pdata
,68);
6832 SMB_DEV_T dev
= (SMB_DEV_T
)0;
6833 uint32 raw_unixmode
= IVAL(pdata
,84);
6837 if (total_data
< 100) {
6838 return NT_STATUS_INVALID_PARAMETER
;
6841 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6842 PERM_NEW_FILE
, &unixmode
);
6843 if (!NT_STATUS_IS_OK(status
)) {
6847 #if defined(HAVE_MAKEDEV)
6848 dev
= makedev(dev_major
, dev_minor
);
6851 switch (file_type
) {
6852 #if defined(S_IFIFO)
6853 case UNIX_TYPE_FIFO
:
6854 unixmode
|= S_IFIFO
;
6857 #if defined(S_IFSOCK)
6858 case UNIX_TYPE_SOCKET
:
6859 unixmode
|= S_IFSOCK
;
6862 #if defined(S_IFCHR)
6863 case UNIX_TYPE_CHARDEV
:
6864 unixmode
|= S_IFCHR
;
6867 #if defined(S_IFBLK)
6868 case UNIX_TYPE_BLKDEV
:
6869 unixmode
|= S_IFBLK
;
6873 return NT_STATUS_INVALID_PARAMETER
;
6876 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6877 "%.0f mode 0%o for file %s\n", (double)dev
,
6878 (unsigned int)unixmode
, smb_fname_str_dbg(smb_fname
)));
6880 /* Ok - do the mknod. */
6881 if (SMB_VFS_MKNOD(conn
, smb_fname
->base_name
, unixmode
, dev
) != 0) {
6882 return map_nt_error_from_unix(errno
);
6885 /* If any of the other "set" calls fail we
6886 * don't want to end up with a half-constructed mknod.
6889 if (lp_inherit_perms(SNUM(conn
))) {
6891 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
,
6893 return NT_STATUS_NO_MEMORY
;
6895 inherit_access_posix_acl(conn
, parent
, smb_fname
->base_name
,
6897 TALLOC_FREE(parent
);
6900 return NT_STATUS_OK
;
6903 /****************************************************************************
6904 Deal with SMB_SET_FILE_UNIX_BASIC.
6905 ****************************************************************************/
6907 static NTSTATUS
smb_set_file_unix_basic(connection_struct
*conn
,
6908 struct smb_request
*req
,
6912 const struct smb_filename
*smb_fname
)
6914 struct smb_file_time ft
;
6915 uint32 raw_unixmode
;
6918 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
6919 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
6920 NTSTATUS status
= NT_STATUS_OK
;
6921 bool delete_on_fail
= False
;
6922 enum perm_type ptype
;
6923 files_struct
*all_fsps
= NULL
;
6924 bool modify_mtime
= true;
6926 struct smb_filename
*smb_fname_tmp
= NULL
;
6927 SMB_STRUCT_STAT sbuf
;
6931 if (total_data
< 100) {
6932 return NT_STATUS_INVALID_PARAMETER
;
6935 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
6936 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
6937 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
6938 #ifdef LARGE_SMB_OFF_T
6939 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
6940 #else /* LARGE_SMB_OFF_T */
6941 if (IVAL(pdata
,4) != 0) {
6942 /* more than 32 bits? */
6943 return NT_STATUS_INVALID_PARAMETER
;
6945 #endif /* LARGE_SMB_OFF_T */
6948 ft
.atime
= interpret_long_date(pdata
+24); /* access_time */
6949 ft
.mtime
= interpret_long_date(pdata
+32); /* modification_time */
6950 set_owner
= (uid_t
)IVAL(pdata
,40);
6951 set_grp
= (gid_t
)IVAL(pdata
,48);
6952 raw_unixmode
= IVAL(pdata
,84);
6954 if (VALID_STAT(smb_fname
->st
)) {
6955 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
6956 ptype
= PERM_EXISTING_DIR
;
6958 ptype
= PERM_EXISTING_FILE
;
6961 ptype
= PERM_NEW_FILE
;
6964 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
6966 if (!NT_STATUS_IS_OK(status
)) {
6970 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
6971 "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
6972 smb_fname_str_dbg(smb_fname
), (double)size
,
6973 (unsigned int)set_owner
, (unsigned int)set_grp
,
6974 (int)raw_unixmode
));
6976 sbuf
= smb_fname
->st
;
6978 if (!VALID_STAT(sbuf
)) {
6980 * The only valid use of this is to create character and block
6981 * devices, and named pipes. This is deprecated (IMHO) and
6982 * a new info level should be used for mknod. JRA.
6985 status
= smb_unix_mknod(conn
,
6989 if (!NT_STATUS_IS_OK(status
)) {
6993 status
= copy_smb_filename(talloc_tos(), smb_fname
,
6995 if (!NT_STATUS_IS_OK(status
)) {
6999 if (SMB_VFS_STAT(conn
, smb_fname_tmp
) != 0) {
7000 status
= map_nt_error_from_unix(errno
);
7001 TALLOC_FREE(smb_fname_tmp
);
7002 SMB_VFS_UNLINK(conn
, smb_fname
);
7006 sbuf
= smb_fname_tmp
->st
;
7007 smb_fname
= smb_fname_tmp
;
7009 /* Ensure we don't try and change anything else. */
7010 raw_unixmode
= SMB_MODE_NO_CHANGE
;
7011 size
= get_file_size_stat(&sbuf
);
7012 ft
.atime
= sbuf
.st_ex_atime
;
7013 ft
.mtime
= sbuf
.st_ex_mtime
;
7015 * We continue here as we might want to change the
7018 delete_on_fail
= True
;
7022 /* Horrible backwards compatibility hack as an old server bug
7023 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
7027 size
= get_file_size_stat(&sbuf
);
7032 * Deal with the UNIX specific mode set.
7035 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
7036 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7037 "setting mode 0%o for file %s\n",
7038 (unsigned int)unixmode
,
7039 smb_fname_str_dbg(smb_fname
)));
7040 if (SMB_VFS_CHMOD(conn
, smb_fname
->base_name
, unixmode
) != 0) {
7041 return map_nt_error_from_unix(errno
);
7046 * Deal with the UNIX specific uid set.
7049 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) &&
7050 (sbuf
.st_ex_uid
!= set_owner
)) {
7053 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7054 "changing owner %u for path %s\n",
7055 (unsigned int)set_owner
,
7056 smb_fname_str_dbg(smb_fname
)));
7058 if (S_ISLNK(sbuf
.st_ex_mode
)) {
7059 ret
= SMB_VFS_LCHOWN(conn
, smb_fname
->base_name
,
7060 set_owner
, (gid_t
)-1);
7062 ret
= SMB_VFS_CHOWN(conn
, smb_fname
->base_name
,
7063 set_owner
, (gid_t
)-1);
7067 status
= map_nt_error_from_unix(errno
);
7068 if (delete_on_fail
) {
7069 SMB_VFS_UNLINK(conn
, smb_fname
);
7076 * Deal with the UNIX specific gid set.
7079 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) &&
7080 (sbuf
.st_ex_gid
!= set_grp
)) {
7081 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7082 "changing group %u for file %s\n",
7083 (unsigned int)set_owner
,
7084 smb_fname_str_dbg(smb_fname
)));
7085 if (SMB_VFS_CHOWN(conn
, smb_fname
->base_name
, (uid_t
)-1,
7087 status
= map_nt_error_from_unix(errno
);
7088 if (delete_on_fail
) {
7089 SMB_VFS_UNLINK(conn
, smb_fname
);
7095 /* Deal with any size changes. */
7097 status
= smb_set_file_size(conn
, req
,
7103 if (!NT_STATUS_IS_OK(status
)) {
7107 /* Deal with any time changes. */
7108 if (null_timespec(ft
.mtime
) && null_timespec(ft
.atime
)) {
7109 /* No change, don't cancel anything. */
7113 id
= vfs_file_id_from_sbuf(conn
, &sbuf
);
7114 for(all_fsps
= file_find_di_first(conn
->sconn
, id
); all_fsps
;
7115 all_fsps
= file_find_di_next(all_fsps
)) {
7117 * We're setting the time explicitly for UNIX.
7118 * Cancel any pending changes over all handles.
7120 all_fsps
->update_write_time_on_close
= false;
7121 TALLOC_FREE(all_fsps
->update_write_time_event
);
7125 * Override the "setting_write_time"
7126 * parameter here as it almost does what
7127 * we need. Just remember if we modified
7128 * mtime and send the notify ourselves.
7130 if (null_timespec(ft
.mtime
)) {
7131 modify_mtime
= false;
7134 status
= smb_set_file_time(conn
,
7140 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
,
7141 FILE_NOTIFY_CHANGE_LAST_WRITE
, smb_fname
->base_name
);
7146 /****************************************************************************
7147 Deal with SMB_SET_FILE_UNIX_INFO2.
7148 ****************************************************************************/
7150 static NTSTATUS
smb_set_file_unix_info2(connection_struct
*conn
,
7151 struct smb_request
*req
,
7155 const struct smb_filename
*smb_fname
)
7161 if (total_data
< 116) {
7162 return NT_STATUS_INVALID_PARAMETER
;
7165 /* Start by setting all the fields that are common between UNIX_BASIC
7168 status
= smb_set_file_unix_basic(conn
, req
, pdata
, total_data
,
7170 if (!NT_STATUS_IS_OK(status
)) {
7174 smb_fflags
= IVAL(pdata
, 108);
7175 smb_fmask
= IVAL(pdata
, 112);
7177 /* NB: We should only attempt to alter the file flags if the client
7178 * sends a non-zero mask.
7180 if (smb_fmask
!= 0) {
7181 int stat_fflags
= 0;
7183 if (!map_info2_flags_to_sbuf(&smb_fname
->st
, smb_fflags
,
7184 smb_fmask
, &stat_fflags
)) {
7185 /* Client asked to alter a flag we don't understand. */
7186 return NT_STATUS_INVALID_PARAMETER
;
7189 if (fsp
&& fsp
->fh
->fd
!= -1) {
7190 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
7191 return NT_STATUS_NOT_SUPPORTED
;
7193 if (SMB_VFS_CHFLAGS(conn
, smb_fname
->base_name
,
7194 stat_fflags
) != 0) {
7195 return map_nt_error_from_unix(errno
);
7200 /* XXX: need to add support for changing the create_time here. You
7201 * can do this for paths on Darwin with setattrlist(2). The right way
7202 * to hook this up is probably by extending the VFS utimes interface.
7205 return NT_STATUS_OK
;
7208 /****************************************************************************
7209 Create a directory with POSIX semantics.
7210 ****************************************************************************/
7212 static NTSTATUS
smb_posix_mkdir(connection_struct
*conn
,
7213 struct smb_request
*req
,
7216 struct smb_filename
*smb_fname
,
7217 int *pdata_return_size
)
7219 NTSTATUS status
= NT_STATUS_OK
;
7220 uint32 raw_unixmode
= 0;
7221 uint32 mod_unixmode
= 0;
7222 mode_t unixmode
= (mode_t
)0;
7223 files_struct
*fsp
= NULL
;
7224 uint16 info_level_return
= 0;
7226 char *pdata
= *ppdata
;
7228 if (total_data
< 18) {
7229 return NT_STATUS_INVALID_PARAMETER
;
7232 raw_unixmode
= IVAL(pdata
,8);
7233 /* Next 4 bytes are not yet defined. */
7235 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7236 PERM_NEW_DIR
, &unixmode
);
7237 if (!NT_STATUS_IS_OK(status
)) {
7241 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7243 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7244 smb_fname_str_dbg(smb_fname
), (unsigned int)unixmode
));
7246 status
= SMB_VFS_CREATE_FILE(
7249 0, /* root_dir_fid */
7250 smb_fname
, /* fname */
7251 FILE_READ_ATTRIBUTES
, /* access_mask */
7252 FILE_SHARE_NONE
, /* share_access */
7253 FILE_CREATE
, /* create_disposition*/
7254 FILE_DIRECTORY_FILE
, /* create_options */
7255 mod_unixmode
, /* file_attributes */
7256 0, /* oplock_request */
7257 0, /* allocation_size */
7258 0, /* private_flags */
7264 if (NT_STATUS_IS_OK(status
)) {
7265 close_file(req
, fsp
, NORMAL_CLOSE
);
7268 info_level_return
= SVAL(pdata
,16);
7270 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7271 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7272 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7273 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7275 *pdata_return_size
= 12;
7278 /* Realloc the data size */
7279 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7280 if (*ppdata
== NULL
) {
7281 *pdata_return_size
= 0;
7282 return NT_STATUS_NO_MEMORY
;
7286 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7287 SSVAL(pdata
,2,0); /* No fnum. */
7288 SIVAL(pdata
,4,info
); /* Was directory created. */
7290 switch (info_level_return
) {
7291 case SMB_QUERY_FILE_UNIX_BASIC
:
7292 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7293 SSVAL(pdata
,10,0); /* Padding. */
7294 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7297 case SMB_QUERY_FILE_UNIX_INFO2
:
7298 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7299 SSVAL(pdata
,10,0); /* Padding. */
7300 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7304 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7305 SSVAL(pdata
,10,0); /* Padding. */
7312 /****************************************************************************
7313 Open/Create a file with POSIX semantics.
7314 ****************************************************************************/
7316 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7317 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7319 static NTSTATUS
smb_posix_open(connection_struct
*conn
,
7320 struct smb_request
*req
,
7323 struct smb_filename
*smb_fname
,
7324 int *pdata_return_size
)
7326 bool extended_oplock_granted
= False
;
7327 char *pdata
= *ppdata
;
7329 uint32 wire_open_mode
= 0;
7330 uint32 raw_unixmode
= 0;
7331 uint32 mod_unixmode
= 0;
7332 uint32 create_disp
= 0;
7333 uint32 access_mask
= 0;
7334 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
7335 NTSTATUS status
= NT_STATUS_OK
;
7336 mode_t unixmode
= (mode_t
)0;
7337 files_struct
*fsp
= NULL
;
7338 int oplock_request
= 0;
7340 uint16 info_level_return
= 0;
7342 if (total_data
< 18) {
7343 return NT_STATUS_INVALID_PARAMETER
;
7346 flags
= IVAL(pdata
,0);
7347 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
7348 if (oplock_request
) {
7349 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
7352 wire_open_mode
= IVAL(pdata
,4);
7354 if (wire_open_mode
== (SMB_O_CREAT
|SMB_O_DIRECTORY
)) {
7355 return smb_posix_mkdir(conn
, req
,
7362 switch (wire_open_mode
& SMB_ACCMODE
) {
7364 access_mask
= SMB_O_RDONLY_MAPPING
;
7367 access_mask
= SMB_O_WRONLY_MAPPING
;
7370 access_mask
= (SMB_O_RDONLY_MAPPING
|
7371 SMB_O_WRONLY_MAPPING
);
7374 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7375 (unsigned int)wire_open_mode
));
7376 return NT_STATUS_INVALID_PARAMETER
;
7379 wire_open_mode
&= ~SMB_ACCMODE
;
7381 /* First take care of O_CREAT|O_EXCL interactions. */
7382 switch (wire_open_mode
& (SMB_O_CREAT
| SMB_O_EXCL
)) {
7383 case (SMB_O_CREAT
| SMB_O_EXCL
):
7384 /* File exists fail. File not exist create. */
7385 create_disp
= FILE_CREATE
;
7388 /* File exists open. File not exist create. */
7389 create_disp
= FILE_OPEN_IF
;
7392 /* O_EXCL on its own without O_CREAT is undefined.
7393 We deliberately ignore it as some versions of
7394 Linux CIFSFS can send a bare O_EXCL on the
7395 wire which other filesystems in the kernel
7396 ignore. See bug 9519 for details. */
7401 /* File exists open. File not exist fail. */
7402 create_disp
= FILE_OPEN
;
7405 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7406 (unsigned int)wire_open_mode
));
7407 return NT_STATUS_INVALID_PARAMETER
;
7410 /* Next factor in the effects of O_TRUNC. */
7411 wire_open_mode
&= ~(SMB_O_CREAT
| SMB_O_EXCL
);
7413 if (wire_open_mode
& SMB_O_TRUNC
) {
7414 switch (create_disp
) {
7416 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7417 /* Leave create_disp alone as
7418 (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7420 /* File exists fail. File not exist create. */
7423 /* SMB_O_CREAT | SMB_O_TRUNC */
7424 /* File exists overwrite. File not exist create. */
7425 create_disp
= FILE_OVERWRITE_IF
;
7429 /* File exists overwrite. File not exist fail. */
7430 create_disp
= FILE_OVERWRITE
;
7433 /* Cannot get here. */
7434 smb_panic("smb_posix_open: logic error");
7435 return NT_STATUS_INVALID_PARAMETER
;
7439 raw_unixmode
= IVAL(pdata
,8);
7440 /* Next 4 bytes are not yet defined. */
7442 status
= unix_perms_from_wire(conn
, &smb_fname
->st
, raw_unixmode
,
7443 (VALID_STAT(smb_fname
->st
) ?
7444 PERM_EXISTING_FILE
: PERM_NEW_FILE
),
7447 if (!NT_STATUS_IS_OK(status
)) {
7451 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
7453 if (wire_open_mode
& SMB_O_SYNC
) {
7454 create_options
|= FILE_WRITE_THROUGH
;
7456 if (wire_open_mode
& SMB_O_APPEND
) {
7457 access_mask
|= FILE_APPEND_DATA
;
7459 if (wire_open_mode
& SMB_O_DIRECT
) {
7460 mod_unixmode
|= FILE_FLAG_NO_BUFFERING
;
7463 if ((wire_open_mode
& SMB_O_DIRECTORY
) ||
7464 VALID_STAT_OF_DIR(smb_fname
->st
)) {
7465 if (access_mask
!= SMB_O_RDONLY_MAPPING
) {
7466 return NT_STATUS_FILE_IS_A_DIRECTORY
;
7468 create_options
&= ~FILE_NON_DIRECTORY_FILE
;
7469 create_options
|= FILE_DIRECTORY_FILE
;
7472 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7473 smb_fname_str_dbg(smb_fname
),
7474 (unsigned int)wire_open_mode
,
7475 (unsigned int)unixmode
));
7477 status
= SMB_VFS_CREATE_FILE(
7480 0, /* root_dir_fid */
7481 smb_fname
, /* fname */
7482 access_mask
, /* access_mask */
7483 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7485 create_disp
, /* create_disposition*/
7486 create_options
, /* create_options */
7487 mod_unixmode
, /* file_attributes */
7488 oplock_request
, /* oplock_request */
7489 0, /* allocation_size */
7490 0, /* private_flags */
7496 if (!NT_STATUS_IS_OK(status
)) {
7500 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
7501 extended_oplock_granted
= True
;
7504 if(oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
7505 extended_oplock_granted
= True
;
7508 info_level_return
= SVAL(pdata
,16);
7510 /* Allocate the correct return size. */
7512 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
7513 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
7514 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
7515 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
7517 *pdata_return_size
= 12;
7520 /* Realloc the data size */
7521 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
7522 if (*ppdata
== NULL
) {
7523 close_file(req
, fsp
, ERROR_CLOSE
);
7524 *pdata_return_size
= 0;
7525 return NT_STATUS_NO_MEMORY
;
7529 if (extended_oplock_granted
) {
7530 if (flags
& REQUEST_BATCH_OPLOCK
) {
7531 SSVAL(pdata
,0, BATCH_OPLOCK_RETURN
);
7533 SSVAL(pdata
,0, EXCLUSIVE_OPLOCK_RETURN
);
7535 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
7536 SSVAL(pdata
,0, LEVEL_II_OPLOCK_RETURN
);
7538 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
7541 SSVAL(pdata
,2,fsp
->fnum
);
7542 SIVAL(pdata
,4,info
); /* Was file created etc. */
7544 switch (info_level_return
) {
7545 case SMB_QUERY_FILE_UNIX_BASIC
:
7546 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
7547 SSVAL(pdata
,10,0); /* padding. */
7548 store_file_unix_basic(conn
, pdata
+ 12, fsp
,
7551 case SMB_QUERY_FILE_UNIX_INFO2
:
7552 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
7553 SSVAL(pdata
,10,0); /* padding. */
7554 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
,
7558 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
7559 SSVAL(pdata
,10,0); /* padding. */
7562 return NT_STATUS_OK
;
7565 /****************************************************************************
7566 Delete a file with POSIX semantics.
7567 ****************************************************************************/
7569 static NTSTATUS
smb_posix_unlink(connection_struct
*conn
,
7570 struct smb_request
*req
,
7573 struct smb_filename
*smb_fname
)
7575 NTSTATUS status
= NT_STATUS_OK
;
7576 files_struct
*fsp
= NULL
;
7580 int create_options
= 0;
7582 struct share_mode_lock
*lck
= NULL
;
7584 if (total_data
< 2) {
7585 return NT_STATUS_INVALID_PARAMETER
;
7588 flags
= SVAL(pdata
,0);
7590 if (!VALID_STAT(smb_fname
->st
)) {
7591 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
7594 if ((flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) &&
7595 !VALID_STAT_OF_DIR(smb_fname
->st
)) {
7596 return NT_STATUS_NOT_A_DIRECTORY
;
7599 DEBUG(10,("smb_posix_unlink: %s %s\n",
7600 (flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) ? "directory" : "file",
7601 smb_fname_str_dbg(smb_fname
)));
7603 if (VALID_STAT_OF_DIR(smb_fname
->st
)) {
7604 create_options
|= FILE_DIRECTORY_FILE
;
7607 status
= SMB_VFS_CREATE_FILE(
7610 0, /* root_dir_fid */
7611 smb_fname
, /* fname */
7612 DELETE_ACCESS
, /* access_mask */
7613 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
7615 FILE_OPEN
, /* create_disposition*/
7616 create_options
, /* create_options */
7617 FILE_FLAG_POSIX_SEMANTICS
|0777, /* file_attributes */
7618 0, /* oplock_request */
7619 0, /* allocation_size */
7620 0, /* private_flags */
7626 if (!NT_STATUS_IS_OK(status
)) {
7631 * Don't lie to client. If we can't really delete due to
7632 * non-POSIX opens return SHARING_VIOLATION.
7635 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
, NULL
, NULL
,
7638 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7639 "lock for file %s\n", fsp_str_dbg(fsp
)));
7640 close_file(req
, fsp
, NORMAL_CLOSE
);
7641 return NT_STATUS_INVALID_PARAMETER
;
7645 * See if others still have the file open. If this is the case, then
7646 * don't delete. If all opens are POSIX delete we can set the delete
7647 * on close disposition.
7649 for (i
=0; i
<lck
->num_share_modes
; i
++) {
7650 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
7651 if (is_valid_share_mode_entry(e
)) {
7652 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
7655 /* Fail with sharing violation. */
7657 close_file(req
, fsp
, NORMAL_CLOSE
);
7658 return NT_STATUS_SHARING_VIOLATION
;
7663 * Set the delete on close.
7665 status
= smb_set_file_disposition_info(conn
,
7673 if (!NT_STATUS_IS_OK(status
)) {
7674 close_file(req
, fsp
, NORMAL_CLOSE
);
7677 return close_file(req
, fsp
, NORMAL_CLOSE
);
7680 NTSTATUS
smbd_do_setfilepathinfo(connection_struct
*conn
,
7681 struct smb_request
*req
,
7682 TALLOC_CTX
*mem_ctx
,
7683 uint16_t info_level
,
7685 struct smb_filename
*smb_fname
,
7686 char **ppdata
, int total_data
,
7689 char *pdata
= *ppdata
;
7690 NTSTATUS status
= NT_STATUS_OK
;
7691 int data_return_size
= 0;
7695 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
7696 return NT_STATUS_INVALID_LEVEL
;
7699 if (!CAN_WRITE(conn
)) {
7700 /* Allow POSIX opens. The open path will deny
7701 * any non-readonly opens. */
7702 if (info_level
!= SMB_POSIX_PATH_OPEN
) {
7703 return NT_STATUS_DOS(ERRSRV
, ERRaccess
);
7707 DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
7708 "totdata=%d\n", smb_fname_str_dbg(smb_fname
),
7709 fsp
? fsp
->fnum
: -1, info_level
, total_data
));
7711 switch (info_level
) {
7713 case SMB_INFO_STANDARD
:
7715 status
= smb_set_info_standard(conn
,
7723 case SMB_INFO_SET_EA
:
7725 status
= smb_info_set_ea(conn
,
7733 case SMB_SET_FILE_BASIC_INFO
:
7734 case SMB_FILE_BASIC_INFORMATION
:
7736 status
= smb_set_file_basic_info(conn
,
7744 case SMB_FILE_ALLOCATION_INFORMATION
:
7745 case SMB_SET_FILE_ALLOCATION_INFO
:
7747 status
= smb_set_file_allocation_info(conn
, req
,
7755 case SMB_FILE_END_OF_FILE_INFORMATION
:
7756 case SMB_SET_FILE_END_OF_FILE_INFO
:
7759 * XP/Win7 both fail after the createfile with
7760 * SMB_SET_FILE_END_OF_FILE_INFO but not
7761 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7762 * The level is known here, so pass it down
7766 (info_level
== SMB_SET_FILE_END_OF_FILE_INFO
);
7768 status
= smb_set_file_end_of_file_info(conn
, req
,
7777 case SMB_FILE_DISPOSITION_INFORMATION
:
7778 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
7781 /* JRA - We used to just ignore this on a path ?
7782 * Shouldn't this be invalid level on a pathname
7785 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
7786 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
7789 status
= smb_set_file_disposition_info(conn
,
7797 case SMB_FILE_POSITION_INFORMATION
:
7799 status
= smb_file_position_information(conn
,
7806 case SMB_FILE_FULL_EA_INFORMATION
:
7808 status
= smb_set_file_full_ea_info(conn
,
7815 /* From tridge Samba4 :
7816 * MODE_INFORMATION in setfileinfo (I have no
7817 * idea what "mode information" on a file is - it takes a value of 0,
7818 * 2, 4 or 6. What could it be?).
7821 case SMB_FILE_MODE_INFORMATION
:
7823 status
= smb_file_mode_information(conn
,
7830 * CIFS UNIX extensions.
7833 case SMB_SET_FILE_UNIX_BASIC
:
7835 status
= smb_set_file_unix_basic(conn
, req
,
7843 case SMB_SET_FILE_UNIX_INFO2
:
7845 status
= smb_set_file_unix_info2(conn
, req
,
7853 case SMB_SET_FILE_UNIX_LINK
:
7856 /* We must have a pathname for this. */
7857 return NT_STATUS_INVALID_LEVEL
;
7859 status
= smb_set_file_unix_link(conn
, req
, pdata
,
7860 total_data
, smb_fname
);
7864 case SMB_SET_FILE_UNIX_HLINK
:
7867 /* We must have a pathname for this. */
7868 return NT_STATUS_INVALID_LEVEL
;
7870 status
= smb_set_file_unix_hlink(conn
, req
,
7876 case SMB_FILE_RENAME_INFORMATION
:
7878 status
= smb_file_rename_information(conn
, req
,
7884 case SMB2_FILE_RENAME_INFORMATION_INTERNAL
:
7886 /* SMB2 rename information. */
7887 status
= smb2_file_rename_information(conn
, req
,
7893 case SMB_FILE_LINK_INFORMATION
:
7895 status
= smb_file_link_information(conn
, req
,
7901 #if defined(HAVE_POSIX_ACLS)
7902 case SMB_SET_POSIX_ACL
:
7904 status
= smb_set_posix_acl(conn
,
7913 case SMB_SET_POSIX_LOCK
:
7916 return NT_STATUS_INVALID_LEVEL
;
7918 status
= smb_set_posix_lock(conn
, req
,
7919 pdata
, total_data
, fsp
);
7923 case SMB_POSIX_PATH_OPEN
:
7926 /* We must have a pathname for this. */
7927 return NT_STATUS_INVALID_LEVEL
;
7930 status
= smb_posix_open(conn
, req
,
7938 case SMB_POSIX_PATH_UNLINK
:
7941 /* We must have a pathname for this. */
7942 return NT_STATUS_INVALID_LEVEL
;
7945 status
= smb_posix_unlink(conn
, req
,
7953 return NT_STATUS_INVALID_LEVEL
;
7956 if (!NT_STATUS_IS_OK(status
)) {
7960 *ret_data_size
= data_return_size
;
7961 return NT_STATUS_OK
;
7964 /****************************************************************************
7965 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
7966 ****************************************************************************/
7968 static void call_trans2setfilepathinfo(connection_struct
*conn
,
7969 struct smb_request
*req
,
7970 unsigned int tran_call
,
7971 char **pparams
, int total_params
,
7972 char **ppdata
, int total_data
,
7973 unsigned int max_data_bytes
)
7975 char *params
= *pparams
;
7976 char *pdata
= *ppdata
;
7978 struct smb_filename
*smb_fname
= NULL
;
7979 files_struct
*fsp
= NULL
;
7980 NTSTATUS status
= NT_STATUS_OK
;
7981 int data_return_size
= 0;
7984 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7988 if (tran_call
== TRANSACT2_SETFILEINFO
) {
7989 if (total_params
< 4) {
7990 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
7994 fsp
= file_fsp(req
, SVAL(params
,0));
7995 /* Basic check for non-null fsp. */
7996 if (!check_fsp_open(conn
, req
, fsp
)) {
7999 info_level
= SVAL(params
,2);
8001 status
= copy_smb_filename(talloc_tos(), fsp
->fsp_name
,
8003 if (!NT_STATUS_IS_OK(status
)) {
8004 reply_nterror(req
, status
);
8008 if(fsp
->fh
->fd
== -1) {
8010 * This is actually a SETFILEINFO on a directory
8011 * handle (returned from an NT SMB). NT5.0 seems
8012 * to do this call. JRA.
8014 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8015 /* Always do lstat for UNIX calls. */
8016 if (SMB_VFS_LSTAT(conn
, smb_fname
)) {
8017 DEBUG(3,("call_trans2setfilepathinfo: "
8018 "SMB_VFS_LSTAT of %s failed "
8020 smb_fname_str_dbg(smb_fname
),
8022 reply_nterror(req
, map_nt_error_from_unix(errno
));
8026 if (SMB_VFS_STAT(conn
, smb_fname
) != 0) {
8027 DEBUG(3,("call_trans2setfilepathinfo: "
8028 "fileinfo of %s failed (%s)\n",
8029 smb_fname_str_dbg(smb_fname
),
8031 reply_nterror(req
, map_nt_error_from_unix(errno
));
8035 } else if (fsp
->print_file
) {
8037 * Doing a DELETE_ON_CLOSE should cancel a print job.
8039 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
8040 fsp
->fh
->private_options
|= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE
;
8042 DEBUG(3,("call_trans2setfilepathinfo: "
8043 "Cancelling print job (%s)\n",
8047 send_trans2_replies(conn
, req
, params
, 2,
8053 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
8058 * Original code - this is an open file.
8060 if (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
) != 0) {
8061 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8062 "of fnum %d failed (%s)\n", fsp
->fnum
,
8064 reply_nterror(req
, map_nt_error_from_unix(errno
));
8070 uint32_t ucf_flags
= 0;
8073 if (total_params
< 7) {
8074 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8078 info_level
= SVAL(params
,0);
8079 srvstr_get_path(req
, params
, req
->flags2
, &fname
, ¶ms
[6],
8080 total_params
- 6, STR_TERMINATE
,
8082 if (!NT_STATUS_IS_OK(status
)) {
8083 reply_nterror(req
, status
);
8087 if (info_level
== SMB_SET_FILE_UNIX_BASIC
||
8088 info_level
== SMB_SET_FILE_UNIX_INFO2
||
8089 info_level
== SMB_FILE_RENAME_INFORMATION
||
8090 info_level
== SMB_POSIX_PATH_UNLINK
) {
8091 ucf_flags
|= UCF_UNIX_NAME_LOOKUP
;
8094 status
= filename_convert(req
, conn
,
8095 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8100 if (!NT_STATUS_IS_OK(status
)) {
8101 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8102 reply_botherror(req
,
8103 NT_STATUS_PATH_NOT_COVERED
,
8104 ERRSRV
, ERRbadpath
);
8107 reply_nterror(req
, status
);
8111 if (INFO_LEVEL_IS_UNIX(info_level
)) {
8113 * For CIFS UNIX extensions the target name may not exist.
8116 /* Always do lstat for UNIX calls. */
8117 SMB_VFS_LSTAT(conn
, smb_fname
);
8119 } else if (!VALID_STAT(smb_fname
->st
) &&
8120 SMB_VFS_STAT(conn
, smb_fname
)) {
8121 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8123 smb_fname_str_dbg(smb_fname
),
8125 reply_nterror(req
, map_nt_error_from_unix(errno
));
8130 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
8131 "totdata=%d\n", tran_call
, smb_fname_str_dbg(smb_fname
),
8132 fsp
? fsp
->fnum
: -1, info_level
,total_data
));
8134 /* Realloc the parameter size */
8135 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8136 if (*pparams
== NULL
) {
8137 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8144 status
= smbd_do_setfilepathinfo(conn
, req
, req
,
8150 if (!NT_STATUS_IS_OK(status
)) {
8151 if (open_was_deferred(req
->mid
)) {
8152 /* We have re-scheduled this call. */
8155 if (blocking_lock_was_deferred_smb1(req
->sconn
, req
->mid
)) {
8156 /* We have re-scheduled this call. */
8159 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8160 reply_botherror(req
, NT_STATUS_PATH_NOT_COVERED
,
8161 ERRSRV
, ERRbadpath
);
8164 if (info_level
== SMB_POSIX_PATH_OPEN
) {
8165 reply_openerror(req
, status
);
8169 reply_nterror(req
, status
);
8173 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, data_return_size
,
8179 /****************************************************************************
8180 Reply to a TRANS2_MKDIR (make directory with extended attributes).
8181 ****************************************************************************/
8183 static void call_trans2mkdir(connection_struct
*conn
, struct smb_request
*req
,
8184 char **pparams
, int total_params
,
8185 char **ppdata
, int total_data
,
8186 unsigned int max_data_bytes
)
8188 struct smb_filename
*smb_dname
= NULL
;
8189 char *params
= *pparams
;
8190 char *pdata
= *ppdata
;
8191 char *directory
= NULL
;
8192 NTSTATUS status
= NT_STATUS_OK
;
8193 struct ea_list
*ea_list
= NULL
;
8194 TALLOC_CTX
*ctx
= talloc_tos();
8196 if (!CAN_WRITE(conn
)) {
8197 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8201 if (total_params
< 5) {
8202 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8206 srvstr_get_path(ctx
, params
, req
->flags2
, &directory
, ¶ms
[4],
8207 total_params
- 4, STR_TERMINATE
,
8209 if (!NT_STATUS_IS_OK(status
)) {
8210 reply_nterror(req
, status
);
8214 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
8216 status
= filename_convert(ctx
,
8218 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
8224 if (!NT_STATUS_IS_OK(status
)) {
8225 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
8226 reply_botherror(req
,
8227 NT_STATUS_PATH_NOT_COVERED
,
8228 ERRSRV
, ERRbadpath
);
8231 reply_nterror(req
, status
);
8236 * OS/2 workplace shell seems to send SET_EA requests of "null"
8237 * length (4 bytes containing IVAL 4).
8238 * They seem to have no effect. Bug #3212. JRA.
8241 if (total_data
&& (total_data
!= 4)) {
8242 /* Any data in this call is an EA list. */
8243 if (total_data
< 10) {
8244 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8248 if (IVAL(pdata
,0) > total_data
) {
8249 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8250 IVAL(pdata
,0), (unsigned int)total_data
));
8251 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8255 ea_list
= read_ea_list(talloc_tos(), pdata
+ 4,
8258 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8262 if (!lp_ea_support(SNUM(conn
))) {
8263 reply_nterror(req
, NT_STATUS_EAS_NOT_SUPPORTED
);
8267 /* If total_data == 4 Windows doesn't care what values
8268 * are placed in that field, it just ignores them.
8269 * The System i QNTC IBM SMB client puts bad values here,
8270 * so ignore them. */
8272 status
= create_directory(conn
, req
, smb_dname
);
8274 if (!NT_STATUS_IS_OK(status
)) {
8275 reply_nterror(req
, status
);
8279 /* Try and set any given EA. */
8281 status
= set_ea(conn
, NULL
, smb_dname
, ea_list
);
8282 if (!NT_STATUS_IS_OK(status
)) {
8283 reply_nterror(req
, status
);
8288 /* Realloc the parameter and data sizes */
8289 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
8290 if(*pparams
== NULL
) {
8291 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8298 send_trans2_replies(conn
, req
, params
, 2, *ppdata
, 0, max_data_bytes
);
8301 TALLOC_FREE(smb_dname
);
8305 /****************************************************************************
8306 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8307 We don't actually do this - we just send a null response.
8308 ****************************************************************************/
8310 static void call_trans2findnotifyfirst(connection_struct
*conn
,
8311 struct smb_request
*req
,
8312 char **pparams
, int total_params
,
8313 char **ppdata
, int total_data
,
8314 unsigned int max_data_bytes
)
8316 char *params
= *pparams
;
8319 if (total_params
< 6) {
8320 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8324 info_level
= SVAL(params
,4);
8325 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
8327 switch (info_level
) {
8332 reply_nterror(req
, NT_STATUS_INVALID_LEVEL
);
8336 /* Realloc the parameter and data sizes */
8337 *pparams
= (char *)SMB_REALLOC(*pparams
,6);
8338 if (*pparams
== NULL
) {
8339 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8344 SSVAL(params
,0,fnf_handle
);
8345 SSVAL(params
,2,0); /* No changes */
8346 SSVAL(params
,4,0); /* No EA errors */
8353 send_trans2_replies(conn
, req
, params
, 6, *ppdata
, 0, max_data_bytes
);
8358 /****************************************************************************
8359 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
8360 changes). Currently this does nothing.
8361 ****************************************************************************/
8363 static void call_trans2findnotifynext(connection_struct
*conn
,
8364 struct smb_request
*req
,
8365 char **pparams
, int total_params
,
8366 char **ppdata
, int total_data
,
8367 unsigned int max_data_bytes
)
8369 char *params
= *pparams
;
8371 DEBUG(3,("call_trans2findnotifynext\n"));
8373 /* Realloc the parameter and data sizes */
8374 *pparams
= (char *)SMB_REALLOC(*pparams
,4);
8375 if (*pparams
== NULL
) {
8376 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8381 SSVAL(params
,0,0); /* No changes */
8382 SSVAL(params
,2,0); /* No EA errors */
8384 send_trans2_replies(conn
, req
, params
, 4, *ppdata
, 0, max_data_bytes
);
8389 /****************************************************************************
8390 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8391 ****************************************************************************/
8393 static void call_trans2getdfsreferral(connection_struct
*conn
,
8394 struct smb_request
*req
,
8395 char **pparams
, int total_params
,
8396 char **ppdata
, int total_data
,
8397 unsigned int max_data_bytes
)
8399 char *params
= *pparams
;
8400 char *pathname
= NULL
;
8402 int max_referral_level
;
8403 NTSTATUS status
= NT_STATUS_OK
;
8404 TALLOC_CTX
*ctx
= talloc_tos();
8406 DEBUG(10,("call_trans2getdfsreferral\n"));
8408 if (total_params
< 3) {
8409 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8413 max_referral_level
= SVAL(params
,0);
8415 if(!lp_host_msdfs()) {
8416 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8420 srvstr_pull_talloc(ctx
, params
, req
->flags2
, &pathname
, ¶ms
[2],
8421 total_params
- 2, STR_TERMINATE
);
8423 reply_nterror(req
, NT_STATUS_NOT_FOUND
);
8426 if((reply_size
= setup_dfs_referral(conn
, pathname
, max_referral_level
,
8427 ppdata
,&status
)) < 0) {
8428 reply_nterror(req
, status
);
8432 SSVAL(req
->inbuf
, smb_flg2
,
8433 SVAL(req
->inbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
8434 send_trans2_replies(conn
, req
,0,0,*ppdata
,reply_size
, max_data_bytes
);
8439 #define LMCAT_SPL 0x53
8440 #define LMFUNC_GETJOBID 0x60
8442 /****************************************************************************
8443 Reply to a TRANS2_IOCTL - used for OS/2 printing.
8444 ****************************************************************************/
8446 static void call_trans2ioctl(connection_struct
*conn
,
8447 struct smb_request
*req
,
8448 char **pparams
, int total_params
,
8449 char **ppdata
, int total_data
,
8450 unsigned int max_data_bytes
)
8452 char *pdata
= *ppdata
;
8453 files_struct
*fsp
= file_fsp(req
, SVAL(req
->vwv
+15, 0));
8455 /* check for an invalid fid before proceeding */
8458 reply_nterror(req
, NT_STATUS_INVALID_HANDLE
);
8462 if ((SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8463 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8464 *ppdata
= (char *)SMB_REALLOC(*ppdata
, 32);
8465 if (*ppdata
== NULL
) {
8466 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8471 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8472 CAN ACCEPT THIS IN UNICODE. JRA. */
8475 if (fsp
->print_file
) {
8476 SSVAL(pdata
, 0, fsp
->print_file
->rap_jobid
);
8480 srvstr_push(pdata
, req
->flags2
, pdata
+ 2,
8481 global_myname(), 15,
8482 STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
8483 srvstr_push(pdata
, req
->flags2
, pdata
+18,
8484 lp_servicename(SNUM(conn
)), 13,
8485 STR_ASCII
|STR_TERMINATE
); /* Service name */
8486 send_trans2_replies(conn
, req
, *pparams
, 0, *ppdata
, 32,
8491 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8492 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8495 /****************************************************************************
8496 Reply to a SMBfindclose (stop trans2 directory search).
8497 ****************************************************************************/
8499 void reply_findclose(struct smb_request
*req
)
8502 struct smbd_server_connection
*sconn
= req
->sconn
;
8504 START_PROFILE(SMBfindclose
);
8507 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8508 END_PROFILE(SMBfindclose
);
8512 dptr_num
= SVALS(req
->vwv
+0, 0);
8514 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
8516 dptr_close(sconn
, &dptr_num
);
8518 reply_outbuf(req
, 0, 0);
8520 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
8522 END_PROFILE(SMBfindclose
);
8526 /****************************************************************************
8527 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8528 ****************************************************************************/
8530 void reply_findnclose(struct smb_request
*req
)
8534 START_PROFILE(SMBfindnclose
);
8537 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8538 END_PROFILE(SMBfindnclose
);
8542 dptr_num
= SVAL(req
->vwv
+0, 0);
8544 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
8546 /* We never give out valid handles for a
8547 findnotifyfirst - so any dptr_num is ok here.
8550 reply_outbuf(req
, 0, 0);
8552 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
8554 END_PROFILE(SMBfindnclose
);
8558 static void handle_trans2(connection_struct
*conn
, struct smb_request
*req
,
8559 struct trans_state
*state
)
8561 if (get_Protocol() >= PROTOCOL_NT1
) {
8562 req
->flags2
|= 0x40; /* IS_LONG_NAME */
8563 SSVAL(req
->inbuf
,smb_flg2
,req
->flags2
);
8566 if (conn
->encrypt_level
== Required
&& !req
->encrypted
) {
8567 if (state
->call
!= TRANSACT2_QFSINFO
&&
8568 state
->call
!= TRANSACT2_SETFSINFO
) {
8569 DEBUG(0,("handle_trans2: encryption required "
8571 (unsigned int)state
->call
));
8572 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8577 SMB_PERFCOUNT_SET_SUBOP(&req
->pcd
, state
->call
);
8579 /* Now we must call the relevant TRANS2 function */
8580 switch(state
->call
) {
8581 case TRANSACT2_OPEN
:
8583 START_PROFILE(Trans2_open
);
8584 call_trans2open(conn
, req
,
8585 &state
->param
, state
->total_param
,
8586 &state
->data
, state
->total_data
,
8587 state
->max_data_return
);
8588 END_PROFILE(Trans2_open
);
8592 case TRANSACT2_FINDFIRST
:
8594 START_PROFILE(Trans2_findfirst
);
8595 call_trans2findfirst(conn
, req
,
8596 &state
->param
, state
->total_param
,
8597 &state
->data
, state
->total_data
,
8598 state
->max_data_return
);
8599 END_PROFILE(Trans2_findfirst
);
8603 case TRANSACT2_FINDNEXT
:
8605 START_PROFILE(Trans2_findnext
);
8606 call_trans2findnext(conn
, req
,
8607 &state
->param
, state
->total_param
,
8608 &state
->data
, state
->total_data
,
8609 state
->max_data_return
);
8610 END_PROFILE(Trans2_findnext
);
8614 case TRANSACT2_QFSINFO
:
8616 START_PROFILE(Trans2_qfsinfo
);
8617 call_trans2qfsinfo(conn
, req
,
8618 &state
->param
, state
->total_param
,
8619 &state
->data
, state
->total_data
,
8620 state
->max_data_return
);
8621 END_PROFILE(Trans2_qfsinfo
);
8625 case TRANSACT2_SETFSINFO
:
8627 START_PROFILE(Trans2_setfsinfo
);
8628 call_trans2setfsinfo(conn
, req
,
8629 &state
->param
, state
->total_param
,
8630 &state
->data
, state
->total_data
,
8631 state
->max_data_return
);
8632 END_PROFILE(Trans2_setfsinfo
);
8636 case TRANSACT2_QPATHINFO
:
8637 case TRANSACT2_QFILEINFO
:
8639 START_PROFILE(Trans2_qpathinfo
);
8640 call_trans2qfilepathinfo(conn
, req
, state
->call
,
8641 &state
->param
, state
->total_param
,
8642 &state
->data
, state
->total_data
,
8643 state
->max_data_return
);
8644 END_PROFILE(Trans2_qpathinfo
);
8648 case TRANSACT2_SETPATHINFO
:
8649 case TRANSACT2_SETFILEINFO
:
8651 START_PROFILE(Trans2_setpathinfo
);
8652 call_trans2setfilepathinfo(conn
, req
, state
->call
,
8653 &state
->param
, state
->total_param
,
8654 &state
->data
, state
->total_data
,
8655 state
->max_data_return
);
8656 END_PROFILE(Trans2_setpathinfo
);
8660 case TRANSACT2_FINDNOTIFYFIRST
:
8662 START_PROFILE(Trans2_findnotifyfirst
);
8663 call_trans2findnotifyfirst(conn
, req
,
8664 &state
->param
, state
->total_param
,
8665 &state
->data
, state
->total_data
,
8666 state
->max_data_return
);
8667 END_PROFILE(Trans2_findnotifyfirst
);
8671 case TRANSACT2_FINDNOTIFYNEXT
:
8673 START_PROFILE(Trans2_findnotifynext
);
8674 call_trans2findnotifynext(conn
, req
,
8675 &state
->param
, state
->total_param
,
8676 &state
->data
, state
->total_data
,
8677 state
->max_data_return
);
8678 END_PROFILE(Trans2_findnotifynext
);
8682 case TRANSACT2_MKDIR
:
8684 START_PROFILE(Trans2_mkdir
);
8685 call_trans2mkdir(conn
, req
,
8686 &state
->param
, state
->total_param
,
8687 &state
->data
, state
->total_data
,
8688 state
->max_data_return
);
8689 END_PROFILE(Trans2_mkdir
);
8693 case TRANSACT2_GET_DFS_REFERRAL
:
8695 START_PROFILE(Trans2_get_dfs_referral
);
8696 call_trans2getdfsreferral(conn
, req
,
8697 &state
->param
, state
->total_param
,
8698 &state
->data
, state
->total_data
,
8699 state
->max_data_return
);
8700 END_PROFILE(Trans2_get_dfs_referral
);
8704 case TRANSACT2_IOCTL
:
8706 START_PROFILE(Trans2_ioctl
);
8707 call_trans2ioctl(conn
, req
,
8708 &state
->param
, state
->total_param
,
8709 &state
->data
, state
->total_data
,
8710 state
->max_data_return
);
8711 END_PROFILE(Trans2_ioctl
);
8716 /* Error in request */
8717 DEBUG(2,("Unknown request %d in trans2 call\n", state
->call
));
8718 reply_nterror(req
, NT_STATUS_NOT_IMPLEMENTED
);
8722 /****************************************************************************
8723 Reply to a SMBtrans2.
8724 ****************************************************************************/
8726 void reply_trans2(struct smb_request
*req
)
8728 connection_struct
*conn
= req
->conn
;
8733 unsigned int tran_call
;
8734 struct trans_state
*state
;
8737 START_PROFILE(SMBtrans2
);
8739 if (req
->wct
< 14) {
8740 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8741 END_PROFILE(SMBtrans2
);
8745 dsoff
= SVAL(req
->vwv
+12, 0);
8746 dscnt
= SVAL(req
->vwv
+11, 0);
8747 psoff
= SVAL(req
->vwv
+10, 0);
8748 pscnt
= SVAL(req
->vwv
+9, 0);
8749 tran_call
= SVAL(req
->vwv
+14, 0);
8751 result
= allow_new_trans(conn
->pending_trans
, req
->mid
);
8752 if (!NT_STATUS_IS_OK(result
)) {
8753 DEBUG(2, ("Got invalid trans2 request: %s\n",
8754 nt_errstr(result
)));
8755 reply_nterror(req
, result
);
8756 END_PROFILE(SMBtrans2
);
8761 switch (tran_call
) {
8762 /* List the allowed trans2 calls on IPC$ */
8763 case TRANSACT2_OPEN
:
8764 case TRANSACT2_GET_DFS_REFERRAL
:
8765 case TRANSACT2_QFILEINFO
:
8766 case TRANSACT2_QFSINFO
:
8767 case TRANSACT2_SETFSINFO
:
8770 reply_nterror(req
, NT_STATUS_ACCESS_DENIED
);
8771 END_PROFILE(SMBtrans2
);
8776 if ((state
= TALLOC_P(conn
, struct trans_state
)) == NULL
) {
8777 DEBUG(0, ("talloc failed\n"));
8778 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8779 END_PROFILE(SMBtrans2
);
8783 state
->cmd
= SMBtrans2
;
8785 state
->mid
= req
->mid
;
8786 state
->vuid
= req
->vuid
;
8787 state
->setup_count
= SVAL(req
->vwv
+13, 0);
8788 state
->setup
= NULL
;
8789 state
->total_param
= SVAL(req
->vwv
+0, 0);
8790 state
->param
= NULL
;
8791 state
->total_data
= SVAL(req
->vwv
+1, 0);
8793 state
->max_param_return
= SVAL(req
->vwv
+2, 0);
8794 state
->max_data_return
= SVAL(req
->vwv
+3, 0);
8795 state
->max_setup_return
= SVAL(req
->vwv
+4, 0);
8796 state
->close_on_completion
= BITSETW(req
->vwv
+5, 0);
8797 state
->one_way
= BITSETW(req
->vwv
+5, 1);
8799 state
->call
= tran_call
;
8801 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8802 is so as a sanity check */
8803 if (state
->setup_count
!= 1) {
8805 * Need to have rc=0 for ioctl to get job id for OS/2.
8806 * Network printing will fail if function is not successful.
8807 * Similar function in reply.c will be used if protocol
8808 * is LANMAN1.0 instead of LM1.2X002.
8809 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
8810 * outbuf doesn't have to be set(only job id is used).
8812 if ( (state
->setup_count
== 4)
8813 && (tran_call
== TRANSACT2_IOCTL
)
8814 && (SVAL(req
->vwv
+16, 0) == LMCAT_SPL
)
8815 && (SVAL(req
->vwv
+17, 0) == LMFUNC_GETJOBID
)) {
8816 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8818 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state
->setup_count
));
8819 DEBUG(2,("Transaction is %d\n",tran_call
));
8821 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8822 END_PROFILE(SMBtrans2
);
8827 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
8830 if (state
->total_data
) {
8832 if (trans_oob(state
->total_data
, 0, dscnt
)
8833 || trans_oob(smb_len(req
->inbuf
), dsoff
, dscnt
)) {
8837 /* Can't use talloc here, the core routines do realloc on the
8838 * params and data. */
8839 state
->data
= (char *)SMB_MALLOC(state
->total_data
);
8840 if (state
->data
== NULL
) {
8841 DEBUG(0,("reply_trans2: data malloc fail for %u "
8842 "bytes !\n", (unsigned int)state
->total_data
));
8844 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8845 END_PROFILE(SMBtrans2
);
8849 memcpy(state
->data
,smb_base(req
->inbuf
)+dsoff
,dscnt
);
8852 if (state
->total_param
) {
8854 if (trans_oob(state
->total_param
, 0, pscnt
)
8855 || trans_oob(smb_len(req
->inbuf
), psoff
, pscnt
)) {
8859 /* Can't use talloc here, the core routines do realloc on the
8860 * params and data. */
8861 state
->param
= (char *)SMB_MALLOC(state
->total_param
);
8862 if (state
->param
== NULL
) {
8863 DEBUG(0,("reply_trans: param malloc fail for %u "
8864 "bytes !\n", (unsigned int)state
->total_param
));
8865 SAFE_FREE(state
->data
);
8867 reply_nterror(req
, NT_STATUS_NO_MEMORY
);
8868 END_PROFILE(SMBtrans2
);
8872 memcpy(state
->param
,smb_base(req
->inbuf
)+psoff
,pscnt
);
8875 state
->received_data
= dscnt
;
8876 state
->received_param
= pscnt
;
8878 if ((state
->received_param
== state
->total_param
) &&
8879 (state
->received_data
== state
->total_data
)) {
8881 handle_trans2(conn
, req
, state
);
8883 SAFE_FREE(state
->data
);
8884 SAFE_FREE(state
->param
);
8886 END_PROFILE(SMBtrans2
);
8890 DLIST_ADD(conn
->pending_trans
, state
);
8892 /* We need to send an interim response then receive the rest
8893 of the parameter/data bytes */
8894 reply_outbuf(req
, 0, 0);
8895 show_msg((char *)req
->outbuf
);
8896 END_PROFILE(SMBtrans2
);
8901 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8902 SAFE_FREE(state
->data
);
8903 SAFE_FREE(state
->param
);
8905 END_PROFILE(SMBtrans2
);
8906 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8910 /****************************************************************************
8911 Reply to a SMBtranss2
8912 ****************************************************************************/
8914 void reply_transs2(struct smb_request
*req
)
8916 connection_struct
*conn
= req
->conn
;
8917 unsigned int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
8918 struct trans_state
*state
;
8920 START_PROFILE(SMBtranss2
);
8922 show_msg((char *)req
->inbuf
);
8924 /* Windows clients expect all replies to
8925 a transact secondary (SMBtranss2 0x33)
8926 to have a command code of transact
8927 (SMBtrans2 0x32). See bug #8989
8928 and also [MS-CIFS] section 2.2.4.47.2
8931 req
->cmd
= SMBtrans2
;
8934 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8935 END_PROFILE(SMBtranss2
);
8939 for (state
= conn
->pending_trans
; state
!= NULL
;
8940 state
= state
->next
) {
8941 if (state
->mid
== req
->mid
) {
8946 if ((state
== NULL
) || (state
->cmd
!= SMBtrans2
)) {
8947 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
8948 END_PROFILE(SMBtranss2
);
8952 /* Revise state->total_param and state->total_data in case they have
8953 changed downwards */
8955 if (SVAL(req
->vwv
+0, 0) < state
->total_param
)
8956 state
->total_param
= SVAL(req
->vwv
+0, 0);
8957 if (SVAL(req
->vwv
+1, 0) < state
->total_data
)
8958 state
->total_data
= SVAL(req
->vwv
+1, 0);
8960 pcnt
= SVAL(req
->vwv
+2, 0);
8961 poff
= SVAL(req
->vwv
+3, 0);
8962 pdisp
= SVAL(req
->vwv
+4, 0);
8964 dcnt
= SVAL(req
->vwv
+5, 0);
8965 doff
= SVAL(req
->vwv
+6, 0);
8966 ddisp
= SVAL(req
->vwv
+7, 0);
8968 state
->received_param
+= pcnt
;
8969 state
->received_data
+= dcnt
;
8971 if ((state
->received_data
> state
->total_data
) ||
8972 (state
->received_param
> state
->total_param
))
8976 if (trans_oob(state
->total_param
, pdisp
, pcnt
)
8977 || trans_oob(smb_len(req
->inbuf
), poff
, pcnt
)) {
8980 memcpy(state
->param
+pdisp
,smb_base(req
->inbuf
)+poff
,pcnt
);
8984 if (trans_oob(state
->total_data
, ddisp
, dcnt
)
8985 || trans_oob(smb_len(req
->inbuf
), doff
, dcnt
)) {
8988 memcpy(state
->data
+ddisp
, smb_base(req
->inbuf
)+doff
,dcnt
);
8991 if ((state
->received_param
< state
->total_param
) ||
8992 (state
->received_data
< state
->total_data
)) {
8993 END_PROFILE(SMBtranss2
);
8997 handle_trans2(conn
, req
, state
);
8999 DLIST_REMOVE(conn
->pending_trans
, state
);
9000 SAFE_FREE(state
->data
);
9001 SAFE_FREE(state
->param
);
9004 END_PROFILE(SMBtranss2
);
9009 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
9010 DLIST_REMOVE(conn
->pending_trans
, state
);
9011 SAFE_FREE(state
->data
);
9012 SAFE_FREE(state
->param
);
9014 reply_nterror(req
, NT_STATUS_INVALID_PARAMETER
);
9015 END_PROFILE(SMBtranss2
);