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
7 Copyright (C) Steve French 2005
8 Copyright (C) James Peach 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 2 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, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 extern enum protocol_types Protocol
;
31 extern int smb_read_error
;
32 extern uint32 global_client_caps
;
33 extern struct current_user current_user
;
35 #define get_file_size(sbuf) ((sbuf).st_size)
36 #define DIR_ENTRY_SAFETY_MARGIN 4096
38 static char *store_file_unix_basic(connection_struct
*conn
,
41 const SMB_STRUCT_STAT
*psbuf
);
43 static char *store_file_unix_basic_info2(connection_struct
*conn
,
46 const SMB_STRUCT_STAT
*psbuf
);
48 /********************************************************************
49 Roundup a value to the nearest allocation roundup size boundary.
50 Only do this for Windows clients.
51 ********************************************************************/
53 SMB_BIG_UINT
smb_roundup(connection_struct
*conn
, SMB_BIG_UINT val
)
55 SMB_BIG_UINT rval
= lp_allocation_roundup_size(SNUM(conn
));
57 /* Only roundup for Windows clients. */
58 enum remote_arch_types ra_type
= get_remote_arch();
59 if (rval
&& (ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
60 val
= SMB_ROUNDUP(val
,rval
);
65 /********************************************************************
66 Given a stat buffer return the allocated size on disk, taking into
68 ********************************************************************/
70 SMB_BIG_UINT
get_allocation_size(connection_struct
*conn
, files_struct
*fsp
, const SMB_STRUCT_STAT
*sbuf
)
74 if(S_ISDIR(sbuf
->st_mode
)) {
78 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
79 ret
= (SMB_BIG_UINT
)STAT_ST_BLOCKSIZE
* (SMB_BIG_UINT
)sbuf
->st_blocks
;
81 ret
= (SMB_BIG_UINT
)get_file_size(*sbuf
);
84 if (fsp
&& fsp
->initial_allocation_size
)
85 ret
= MAX(ret
,fsp
->initial_allocation_size
);
87 return smb_roundup(conn
, ret
);
90 /****************************************************************************
91 Utility functions for dealing with extended attributes.
92 ****************************************************************************/
94 static const char *prohibited_ea_names
[] = {
95 SAMBA_POSIX_INHERITANCE_EA_NAME
,
96 SAMBA_XATTR_DOS_ATTRIB
,
100 /****************************************************************************
101 Refuse to allow clients to overwrite our private xattrs.
102 ****************************************************************************/
104 static BOOL
samba_private_attr_name(const char *unix_ea_name
)
108 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
109 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
115 /****************************************************************************
116 Get one EA value. Fill in a struct ea_struct.
117 ****************************************************************************/
119 static BOOL
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
120 const char *fname
, char *ea_name
, struct ea_struct
*pea
)
122 /* Get the value of this xattr. Max size is 64k. */
123 size_t attr_size
= 256;
129 val
= TALLOC_REALLOC_ARRAY(mem_ctx
, val
, char, attr_size
);
134 if (fsp
&& fsp
->fh
->fd
!= -1) {
135 sizeret
= SMB_VFS_FGETXATTR(fsp
, fsp
->fh
->fd
, ea_name
, val
, attr_size
);
137 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
140 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
149 DEBUG(10,("get_ea_value: EA %s is of length %u: ", ea_name
, (unsigned int)sizeret
));
150 dump_data(10, val
, sizeret
);
153 if (strnequal(ea_name
, "user.", 5)) {
154 pea
->name
= &ea_name
[5];
158 pea
->value
.data
= (unsigned char *)val
;
159 pea
->value
.length
= (size_t)sizeret
;
163 /****************************************************************************
164 Return a linked list of the total EA's. Plus the total size
165 ****************************************************************************/
167 static struct ea_list
*get_ea_list_from_file(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
168 const char *fname
, size_t *pea_total_len
)
170 /* Get a list of all xattrs. Max namesize is 64k. */
171 size_t ea_namelist_size
= 1024;
176 struct ea_list
*ea_list_head
= NULL
;
180 if (!lp_ea_support(SNUM(conn
))) {
184 for (i
= 0, ea_namelist
= TALLOC_ARRAY(mem_ctx
, char, ea_namelist_size
); i
< 6;
185 ea_namelist
= TALLOC_REALLOC_ARRAY(mem_ctx
, ea_namelist
, char, ea_namelist_size
), i
++) {
191 if (fsp
&& fsp
->fh
->fd
!= -1) {
192 sizeret
= SMB_VFS_FLISTXATTR(fsp
, fsp
->fh
->fd
, ea_namelist
, ea_namelist_size
);
194 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
, ea_namelist_size
);
197 if (sizeret
== -1 && errno
== ERANGE
) {
198 ea_namelist_size
*= 2;
207 DEBUG(10,("get_ea_list_from_file: ea_namelist size = %u\n", (unsigned int)sizeret
));
210 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
) + 1) {
211 struct ea_list
*listp
;
213 if (strnequal(p
, "system.", 7) || samba_private_attr_name(p
))
216 listp
= TALLOC_P(mem_ctx
, struct ea_list
);
220 if (!get_ea_value(mem_ctx
, conn
, fsp
, fname
, p
, &listp
->ea
)) {
226 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
227 *pea_total_len
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
228 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n",
229 (unsigned int)*pea_total_len
, dos_ea_name
,
230 (unsigned int)listp
->ea
.value
.length
));
232 DLIST_ADD_END(ea_list_head
, listp
, struct ea_list
*);
234 /* Add on 4 for total length. */
235 if (*pea_total_len
) {
240 DEBUG(10,("get_ea_list_from_file: total_len = %u\n", (unsigned int)*pea_total_len
));
244 /****************************************************************************
245 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
247 ****************************************************************************/
249 static unsigned int fill_ea_buffer(TALLOC_CTX
*mem_ctx
, char *pdata
, unsigned int total_data_size
,
250 connection_struct
*conn
, struct ea_list
*ea_list
)
252 unsigned int ret_data_size
= 4;
255 SMB_ASSERT(total_data_size
>= 4);
257 if (!lp_ea_support(SNUM(conn
))) {
262 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
265 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
266 dos_namelen
= strlen(dos_ea_name
);
267 if (dos_namelen
> 255 || dos_namelen
== 0) {
270 if (ea_list
->ea
.value
.length
> 65535) {
273 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
277 /* We know we have room. */
278 SCVAL(p
,0,ea_list
->ea
.flags
);
279 SCVAL(p
,1,dos_namelen
);
280 SSVAL(p
,2,ea_list
->ea
.value
.length
);
281 fstrcpy(p
+4, dos_ea_name
);
282 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
284 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
285 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
288 ret_data_size
= PTR_DIFF(p
, pdata
);
289 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size
));
290 SIVAL(pdata
,0,ret_data_size
);
291 return ret_data_size
;
294 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
296 size_t total_ea_len
= 0;
297 TALLOC_CTX
*mem_ctx
= NULL
;
299 if (!lp_ea_support(SNUM(conn
))) {
302 mem_ctx
= talloc_init("estimate_ea_size");
303 (void)get_ea_list_from_file(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
304 talloc_destroy(mem_ctx
);
308 /****************************************************************************
309 Ensure the EA name is case insensitive by matching any existing EA name.
310 ****************************************************************************/
312 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
315 TALLOC_CTX
*mem_ctx
= talloc_init("canonicalize_ea_name");
316 struct ea_list
*ea_list
= get_ea_list_from_file(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
318 for (; ea_list
; ea_list
= ea_list
->next
) {
319 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
320 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
321 &unix_ea_name
[5], ea_list
->ea
.name
));
322 safe_strcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-6);
326 talloc_destroy(mem_ctx
);
329 /****************************************************************************
330 Set or delete an extended attribute.
331 ****************************************************************************/
333 NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, struct ea_list
*ea_list
)
335 if (!lp_ea_support(SNUM(conn
))) {
336 return NT_STATUS_EAS_NOT_SUPPORTED
;
339 for (;ea_list
; ea_list
= ea_list
->next
) {
341 fstring unix_ea_name
;
343 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
344 fstrcat(unix_ea_name
, ea_list
->ea
.name
);
346 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
348 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, (unsigned int)ea_list
->ea
.value
.length
));
350 if (samba_private_attr_name(unix_ea_name
)) {
351 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
352 return NT_STATUS_ACCESS_DENIED
;
355 if (ea_list
->ea
.value
.length
== 0) {
356 /* Remove the attribute. */
357 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
358 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
359 unix_ea_name
, fsp
->fsp_name
));
360 ret
= SMB_VFS_FREMOVEXATTR(fsp
, fsp
->fh
->fd
, unix_ea_name
);
362 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
363 unix_ea_name
, fname
));
364 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
367 /* Removing a non existent attribute always succeeds. */
368 if (ret
== -1 && errno
== ENOATTR
) {
369 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
375 if (fsp
&& (fsp
->fh
->fd
!= -1)) {
376 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
377 unix_ea_name
, fsp
->fsp_name
));
378 ret
= SMB_VFS_FSETXATTR(fsp
, fsp
->fh
->fd
, unix_ea_name
,
379 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
381 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
382 unix_ea_name
, fname
));
383 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
,
384 ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
, 0);
390 if (errno
== ENOTSUP
) {
391 return NT_STATUS_EAS_NOT_SUPPORTED
;
394 return map_nt_error_from_unix(errno
);
400 /****************************************************************************
401 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
402 ****************************************************************************/
404 static struct ea_list
*read_ea_name_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
406 struct ea_list
*ea_list_head
= NULL
;
409 while (offset
+ 2 < data_size
) {
410 struct ea_list
*eal
= TALLOC_ZERO_P(ctx
, struct ea_list
);
411 unsigned int namelen
= CVAL(pdata
,offset
);
413 offset
++; /* Go past the namelen byte. */
415 /* integer wrap paranioa. */
416 if ((offset
+ namelen
< offset
) || (offset
+ namelen
< namelen
) ||
417 (offset
> data_size
) || (namelen
> data_size
) ||
418 (offset
+ namelen
>= data_size
)) {
421 /* Ensure the name is null terminated. */
422 if (pdata
[offset
+ namelen
] != '\0') {
425 pull_ascii_talloc(ctx
, &eal
->ea
.name
, &pdata
[offset
]);
430 offset
+= (namelen
+ 1); /* Go past the name + terminating zero. */
431 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
432 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal
->ea
.name
));
438 /****************************************************************************
439 Read one EA list entry from the buffer.
440 ****************************************************************************/
442 struct ea_list
*read_ea_list_entry(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
, size_t *pbytes_used
)
444 struct ea_list
*eal
= TALLOC_ZERO_P(ctx
, struct ea_list
);
446 unsigned int namelen
;
456 eal
->ea
.flags
= CVAL(pdata
,0);
457 namelen
= CVAL(pdata
,1);
458 val_len
= SVAL(pdata
,2);
460 if (4 + namelen
+ 1 + val_len
> data_size
) {
464 /* Ensure the name is null terminated. */
465 if (pdata
[namelen
+ 4] != '\0') {
468 pull_ascii_talloc(ctx
, &eal
->ea
.name
, pdata
+ 4);
473 eal
->ea
.value
= data_blob_talloc(eal
, NULL
, (size_t)val_len
+ 1);
474 if (!eal
->ea
.value
.data
) {
478 memcpy(eal
->ea
.value
.data
, pdata
+ 4 + namelen
+ 1, val_len
);
480 /* Ensure we're null terminated just in case we print the value. */
481 eal
->ea
.value
.data
[val_len
] = '\0';
482 /* But don't count the null. */
483 eal
->ea
.value
.length
--;
486 *pbytes_used
= 4 + namelen
+ 1 + val_len
;
489 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal
->ea
.name
));
490 dump_data(10, (const char *)eal
->ea
.value
.data
, eal
->ea
.value
.length
);
495 /****************************************************************************
496 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
497 ****************************************************************************/
499 static struct ea_list
*read_ea_list(TALLOC_CTX
*ctx
, const char *pdata
, size_t data_size
)
501 struct ea_list
*ea_list_head
= NULL
;
503 size_t bytes_used
= 0;
505 while (offset
< data_size
) {
506 struct ea_list
*eal
= read_ea_list_entry(ctx
, pdata
+ offset
, data_size
- offset
, &bytes_used
);
512 DLIST_ADD_END(ea_list_head
, eal
, struct ea_list
*);
513 offset
+= bytes_used
;
519 /****************************************************************************
520 Count the total EA size needed.
521 ****************************************************************************/
523 static size_t ea_list_size(struct ea_list
*ealist
)
526 struct ea_list
*listp
;
529 for (listp
= ealist
; listp
; listp
= listp
->next
) {
530 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
531 ret
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
533 /* Add on 4 for total length. */
541 /****************************************************************************
542 Return a union of EA's from a file list and a list of names.
543 The TALLOC context for the two lists *MUST* be identical as we steal
544 memory from one list to add to another. JRA.
545 ****************************************************************************/
547 static struct ea_list
*ea_list_union(struct ea_list
*name_list
, struct ea_list
*file_list
, size_t *total_ea_len
)
549 struct ea_list
*nlistp
, *flistp
;
551 for (nlistp
= name_list
; nlistp
; nlistp
= nlistp
->next
) {
552 for (flistp
= file_list
; flistp
; flistp
= flistp
->next
) {
553 if (strequal(nlistp
->ea
.name
, flistp
->ea
.name
)) {
559 /* Copy the data from this entry. */
560 nlistp
->ea
.flags
= flistp
->ea
.flags
;
561 nlistp
->ea
.value
= flistp
->ea
.value
;
564 nlistp
->ea
.flags
= 0;
565 ZERO_STRUCT(nlistp
->ea
.value
);
569 *total_ea_len
= ea_list_size(name_list
);
573 /****************************************************************************
574 Send the required number of replies back.
575 We assume all fields other than the data fields are
576 set correctly for the type of call.
577 HACK ! Always assumes smb_setup field is zero.
578 ****************************************************************************/
580 int send_trans2_replies(char *outbuf
,
588 /* As we are using a protocol > LANMAN1 then the max_send
589 variable must have been set in the sessetupX call.
590 This takes precedence over the max_xmit field in the
591 global struct. These different max_xmit variables should
592 be merged as this is now too confusing */
594 int data_to_send
= datasize
;
595 int params_to_send
= paramsize
;
597 const char *pp
= params
;
598 const char *pd
= pdata
;
599 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
600 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
601 int data_alignment_offset
= 0;
603 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
605 set_message(outbuf
,10,0,True
);
607 /* Modify the data_to_send and datasize and set the error if
608 we're trying to send more than max_data_bytes. We still send
609 the part of the packet(s) that fit. Strange, but needed
612 if (max_data_bytes
> 0 && datasize
> max_data_bytes
) {
613 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
614 max_data_bytes
, datasize
));
615 datasize
= data_to_send
= max_data_bytes
;
616 error_packet_set(outbuf
,ERRDOS
,ERRbufferoverflow
,STATUS_BUFFER_OVERFLOW
,__LINE__
,__FILE__
);
619 /* If there genuinely are no parameters or data to send just send the empty packet */
621 if(params_to_send
== 0 && data_to_send
== 0) {
623 if (!send_smb(smbd_server_fd(),outbuf
))
624 exit_server_cleanly("send_trans2_replies: send_smb failed.");
628 /* When sending params and data ensure that both are nicely aligned */
629 /* Only do this alignment when there is also data to send - else
630 can cause NT redirector problems. */
632 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
633 data_alignment_offset
= 4 - (params_to_send
% 4);
635 /* Space is bufsize minus Netbios over TCP header minus SMB header */
636 /* The alignment_offset is to align the param bytes on an even byte
637 boundary. NT 4.0 Beta needs this to work correctly. */
639 useable_space
= bufsize
- ((smb_buf(outbuf
)+ alignment_offset
+data_alignment_offset
) - outbuf
);
641 /* useable_space can never be more than max_send minus the alignment offset. */
643 useable_space
= MIN(useable_space
, max_send
- (alignment_offset
+data_alignment_offset
));
645 while (params_to_send
|| data_to_send
) {
646 /* Calculate whether we will totally or partially fill this packet */
648 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
+ data_alignment_offset
;
650 /* We can never send more than useable_space */
652 * Note that 'useable_space' does not include the alignment offsets,
653 * but we must include the alignment offsets in the calculation of
654 * the length of the data we send over the wire, as the alignment offsets
655 * are sent here. Fix from Marc_Jacobsen@hp.com.
658 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
+ alignment_offset
+ data_alignment_offset
);
660 set_message(outbuf
, 10, total_sent_thistime
, True
);
662 /* Set total params and data to be sent */
663 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
664 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
666 /* Calculate how many parameters and data we can fit into
667 * this packet. Parameters get precedence
670 params_sent_thistime
= MIN(params_to_send
,useable_space
);
671 data_sent_thistime
= useable_space
- params_sent_thistime
;
672 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
674 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
676 /* smb_proff is the offset from the start of the SMB header to the
677 parameter bytes, however the first 4 bytes of outbuf are
678 the Netbios over TCP header. Thus use smb_base() to subtract
679 them from the calculation */
681 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
683 if(params_sent_thistime
== 0)
684 SSVAL(outbuf
,smb_prdisp
,0);
686 /* Absolute displacement of param bytes sent in this packet */
687 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
689 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
690 if(data_sent_thistime
== 0) {
691 SSVAL(outbuf
,smb_droff
,0);
692 SSVAL(outbuf
,smb_drdisp
, 0);
694 /* The offset of the data bytes is the offset of the
695 parameter bytes plus the number of parameters being sent this time */
696 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
697 smb_base(outbuf
)) + params_sent_thistime
+ data_alignment_offset
);
698 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
701 /* Copy the param bytes into the packet */
703 if(params_sent_thistime
)
704 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
706 /* Copy in the data bytes */
707 if(data_sent_thistime
)
708 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
+
709 data_alignment_offset
,pd
,data_sent_thistime
);
711 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
712 params_sent_thistime
, data_sent_thistime
, useable_space
));
713 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
714 params_to_send
, data_to_send
, paramsize
, datasize
));
716 /* Send the packet */
718 if (!send_smb(smbd_server_fd(),outbuf
))
719 exit_server_cleanly("send_trans2_replies: send_smb failed.");
721 pp
+= params_sent_thistime
;
722 pd
+= data_sent_thistime
;
724 params_to_send
-= params_sent_thistime
;
725 data_to_send
-= data_sent_thistime
;
728 if(params_to_send
< 0 || data_to_send
< 0) {
729 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
730 params_to_send
, data_to_send
));
738 /****************************************************************************
739 Reply to a TRANSACT2_OPEN.
740 ****************************************************************************/
742 static int call_trans2open(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
743 char **pparams
, int total_params
, char **ppdata
, int total_data
,
744 unsigned int max_data_bytes
)
746 char *params
= *pparams
;
747 char *pdata
= *ppdata
;
752 BOOL return_additional_info
;
763 SMB_STRUCT_STAT sbuf
;
766 struct ea_list
*ea_list
= NULL
;
771 uint32 create_disposition
;
772 uint32 create_options
= 0;
775 * Ensure we have enough parameters to perform the operation.
778 if (total_params
< 29) {
779 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
782 flags
= SVAL(params
, 0);
783 deny_mode
= SVAL(params
, 2);
784 open_attr
= SVAL(params
,6);
785 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
786 if (oplock_request
) {
787 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
791 return_additional_info
= BITSETW(params
,0);
792 open_sattr
= SVAL(params
, 4);
793 open_time
= make_unix_date3(params
+8);
795 open_ofun
= SVAL(params
,12);
796 open_size
= IVAL(params
,14);
800 return(ERROR_DOS(ERRSRV
,ERRaccess
));
803 srvstr_get_path(inbuf
, fname
, pname
, sizeof(fname
), total_params
- 28, STR_TERMINATE
, &status
);
804 if (!NT_STATUS_IS_OK(status
)) {
805 return ERROR_NT(status
);
808 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
809 fname
, (unsigned int)deny_mode
, (unsigned int)open_attr
,
810 (unsigned int)open_ofun
, open_size
));
812 /* XXXX we need to handle passed times, sattr and flags */
814 status
= unix_convert(conn
, fname
, False
, NULL
, &sbuf
);
815 if (!NT_STATUS_IS_OK(status
)) {
816 return ERROR_NT(status
);
819 status
= check_name(conn
, fname
);
820 if (!NT_STATUS_IS_OK(status
)) {
821 return ERROR_NT(status
);
824 if (open_ofun
== 0) {
825 return ERROR_NT(NT_STATUS_OBJECT_NAME_COLLISION
);
828 if (!map_open_params_to_ntcreate(fname
, deny_mode
, open_ofun
,
833 return ERROR_DOS(ERRDOS
, ERRbadaccess
);
836 /* Any data in this call is an EA list. */
837 if (total_data
&& (total_data
!= 4) && !lp_ea_support(SNUM(conn
))) {
838 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED
);
841 if (total_data
!= 4) {
842 if (total_data
< 10) {
843 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
846 if (IVAL(pdata
,0) > total_data
) {
847 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
848 IVAL(pdata
,0), (unsigned int)total_data
));
849 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
852 ea_list
= read_ea_list(tmp_talloc_ctx(), pdata
+ 4,
855 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
857 } else if (IVAL(pdata
,0) != 4) {
858 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
861 status
= open_file_ntcreate(conn
,fname
,&sbuf
,
870 if (!NT_STATUS_IS_OK(status
)) {
871 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
872 /* We have re-scheduled this call. */
875 return ERROR_OPEN(status
);
878 size
= get_file_size(sbuf
);
879 fattr
= dos_mode(conn
,fname
,&sbuf
);
880 mtime
= sbuf
.st_mtime
;
883 close_file(fsp
,ERROR_CLOSE
);
884 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
887 /* Save the requested allocation size. */
888 /* Allocate space for the file if a size hint is supplied */
889 if ((smb_action
== FILE_WAS_CREATED
) || (smb_action
== FILE_WAS_OVERWRITTEN
)) {
890 SMB_BIG_UINT allocation_size
= (SMB_BIG_UINT
)open_size
;
891 if (allocation_size
&& (allocation_size
> (SMB_BIG_UINT
)size
)) {
892 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
, allocation_size
);
893 if (fsp
->is_directory
) {
894 close_file(fsp
,ERROR_CLOSE
);
895 /* Can't set allocation size on a directory. */
896 return ERROR_NT(NT_STATUS_ACCESS_DENIED
);
898 if (vfs_allocate_file_space(fsp
, fsp
->initial_allocation_size
) == -1) {
899 close_file(fsp
,ERROR_CLOSE
);
900 return ERROR_NT(NT_STATUS_DISK_FULL
);
903 /* Adjust size here to return the right size in the reply.
904 Windows does it this way. */
905 size
= fsp
->initial_allocation_size
;
907 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
,(SMB_BIG_UINT
)size
);
911 if (ea_list
&& smb_action
== FILE_WAS_CREATED
) {
912 status
= set_ea(conn
, fsp
, fname
, ea_list
);
913 if (!NT_STATUS_IS_OK(status
)) {
914 close_file(fsp
,ERROR_CLOSE
);
915 return ERROR_NT(status
);
919 /* Realloc the size of parameters and data we will return */
920 *pparams
= (char *)SMB_REALLOC(*pparams
, 30);
921 if(*pparams
== NULL
) {
922 return ERROR_NT(NT_STATUS_NO_MEMORY
);
926 SSVAL(params
,0,fsp
->fnum
);
927 SSVAL(params
,2,fattr
);
928 srv_put_dos_date2(params
,4, mtime
);
929 SIVAL(params
,8, (uint32
)size
);
930 SSVAL(params
,12,deny_mode
);
931 SSVAL(params
,14,0); /* open_type - file or directory. */
932 SSVAL(params
,16,0); /* open_state - only valid for IPC device. */
934 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
935 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
938 SSVAL(params
,18,smb_action
);
941 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
943 SIVAL(params
,20,inode
);
944 SSVAL(params
,24,0); /* Padding. */
946 uint32 ea_size
= estimate_ea_size(conn
, fsp
, fname
);
947 SIVAL(params
, 26, ea_size
);
949 SIVAL(params
, 26, 0);
952 /* Send the required number of replies */
953 send_trans2_replies(outbuf
, bufsize
, params
, 30, *ppdata
, 0, max_data_bytes
);
958 /*********************************************************
959 Routine to check if a given string matches exactly.
960 as a special case a mask of "." does NOT match. That
961 is required for correct wildcard semantics
962 Case can be significant or not.
963 **********************************************************/
965 static BOOL
exact_match(connection_struct
*conn
, char *str
, char *mask
)
967 if (mask
[0] == '.' && mask
[1] == 0)
969 if (conn
->case_sensitive
)
970 return strcmp(str
,mask
)==0;
971 if (StrCaseCmp(str
,mask
) != 0) {
974 if (dptr_has_wild(conn
->dirptr
)) {
980 /****************************************************************************
981 Return the filetype for UNIX extensions.
982 ****************************************************************************/
984 static uint32
unix_filetype(mode_t mode
)
987 return UNIX_TYPE_FILE
;
988 else if(S_ISDIR(mode
))
989 return UNIX_TYPE_DIR
;
991 else if(S_ISLNK(mode
))
992 return UNIX_TYPE_SYMLINK
;
995 else if(S_ISCHR(mode
))
996 return UNIX_TYPE_CHARDEV
;
999 else if(S_ISBLK(mode
))
1000 return UNIX_TYPE_BLKDEV
;
1003 else if(S_ISFIFO(mode
))
1004 return UNIX_TYPE_FIFO
;
1007 else if(S_ISSOCK(mode
))
1008 return UNIX_TYPE_SOCKET
;
1011 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode
));
1012 return UNIX_TYPE_UNKNOWN
;
1015 /****************************************************************************
1016 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1017 ****************************************************************************/
1019 enum perm_type
{ PERM_NEW_FILE
, PERM_NEW_DIR
, PERM_EXISTING_FILE
, PERM_EXISTING_DIR
};
1021 static NTSTATUS
unix_perms_from_wire( connection_struct
*conn
,
1022 SMB_STRUCT_STAT
*psbuf
,
1024 enum perm_type ptype
,
1029 if (perms
== SMB_MODE_NO_CHANGE
) {
1030 if (!VALID_STAT(*psbuf
)) {
1031 return NT_STATUS_INVALID_PARAMETER
;
1033 *ret_perms
= psbuf
->st_mode
;
1034 return NT_STATUS_OK
;
1038 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
1039 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
1040 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
1041 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
1042 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
1043 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
1044 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
1045 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
1046 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
1048 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
1051 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
1054 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
1059 /* Apply mode mask */
1060 ret
&= lp_create_mask(SNUM(conn
));
1061 /* Add in force bits */
1062 ret
|= lp_force_create_mode(SNUM(conn
));
1065 ret
&= lp_dir_mask(SNUM(conn
));
1066 /* Add in force bits */
1067 ret
|= lp_force_dir_mode(SNUM(conn
));
1069 case PERM_EXISTING_FILE
:
1070 /* Apply mode mask */
1071 ret
&= lp_security_mask(SNUM(conn
));
1072 /* Add in force bits */
1073 ret
|= lp_force_security_mode(SNUM(conn
));
1075 case PERM_EXISTING_DIR
:
1076 /* Apply mode mask */
1077 ret
&= lp_dir_security_mask(SNUM(conn
));
1078 /* Add in force bits */
1079 ret
|= lp_force_dir_security_mode(SNUM(conn
));
1084 return NT_STATUS_OK
;
1087 /****************************************************************************
1088 Get a level dependent lanman2 dir entry.
1089 ****************************************************************************/
1091 static BOOL
get_lanman2_dir_entry(connection_struct
*conn
,
1092 void *inbuf
, char *outbuf
,
1093 char *path_mask
,uint32 dirtype
,int info_level
,
1094 int requires_resume_key
,
1095 BOOL dont_descend
,char **ppdata
,
1096 char *base_data
, char *end_data
, int space_remaining
,
1097 BOOL
*out_of_space
, BOOL
*got_exact_match
,
1098 int *last_entry_off
, struct ea_list
*name_list
, TALLOC_CTX
*ea_ctx
)
1102 SMB_STRUCT_STAT sbuf
;
1106 char *p
, *q
, *pdata
= *ppdata
;
1110 SMB_OFF_T file_size
= 0;
1111 SMB_BIG_UINT allocation_size
= 0;
1113 struct timespec mdate_ts
, adate_ts
, create_date_ts
;
1114 time_t mdate
= (time_t)0, adate
= (time_t)0, create_date
= (time_t)0;
1116 char *last_entry_ptr
;
1118 uint32 nt_extmode
; /* Used for NT connections instead of mode */
1119 BOOL needslash
= ( conn
->dirpath
[strlen(conn
->dirpath
) -1] != '/');
1120 BOOL check_mangled_names
= lp_manglednames(conn
->params
);
1123 *out_of_space
= False
;
1124 *got_exact_match
= False
;
1126 ZERO_STRUCT(mdate_ts
);
1127 ZERO_STRUCT(adate_ts
);
1128 ZERO_STRUCT(create_date_ts
);
1133 p
= strrchr_m(path_mask
,'/');
1136 pstrcpy(mask
,"*.*");
1140 pstrcpy(mask
, path_mask
);
1145 BOOL ms_dfs_link
= False
;
1147 /* Needed if we run out of space */
1148 long curr_dirpos
= prev_dirpos
= dptr_TellDir(conn
->dirptr
);
1149 dname
= dptr_ReadDirName(conn
->dirptr
,&curr_dirpos
,&sbuf
);
1152 * Due to bugs in NT client redirectors we are not using
1153 * resume keys any more - set them to zero.
1154 * Check out the related comments in findfirst/findnext.
1160 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1161 (long)conn
->dirptr
,curr_dirpos
));
1166 pstrcpy(fname
,dname
);
1168 if(!(got_match
= *got_exact_match
= exact_match(conn
, fname
, mask
)))
1169 got_match
= mask_match(fname
, mask
, conn
->case_sensitive
);
1171 if(!got_match
&& check_mangled_names
&&
1172 !mangle_is_8_3(fname
, False
, conn
->params
)) {
1175 * It turns out that NT matches wildcards against
1176 * both long *and* short names. This may explain some
1177 * of the wildcard wierdness from old DOS clients
1178 * that some people have been seeing.... JRA.
1182 pstrcpy( newname
, fname
);
1183 mangle_map( newname
, True
, False
, conn
->params
);
1184 if(!(got_match
= *got_exact_match
= exact_match(conn
, newname
, mask
)))
1185 got_match
= mask_match(newname
, mask
, conn
->case_sensitive
);
1189 BOOL isdots
= (strequal(fname
,"..") || strequal(fname
,"."));
1190 if (dont_descend
&& !isdots
)
1193 pstrcpy(pathreal
,conn
->dirpath
);
1195 pstrcat(pathreal
,"/");
1196 pstrcat(pathreal
,dname
);
1198 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1199 if (SMB_VFS_LSTAT(conn
,pathreal
,&sbuf
) != 0) {
1200 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1201 pathreal
,strerror(errno
)));
1204 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,pathreal
,&sbuf
) != 0) {
1205 pstring link_target
;
1207 /* Needed to show the msdfs symlinks as
1210 if(lp_host_msdfs() &&
1211 lp_msdfs_root(SNUM(conn
)) &&
1212 ((ms_dfs_link
= is_msdfs_link(conn
, pathreal
, link_target
, &sbuf
)) == True
)) {
1213 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s "
1216 sbuf
.st_mode
= (sbuf
.st_mode
& 0xFFF) | S_IFDIR
;
1220 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1221 pathreal
,strerror(errno
)));
1227 mode
= dos_mode_msdfs(conn
,pathreal
,&sbuf
);
1229 mode
= dos_mode(conn
,pathreal
,&sbuf
);
1232 if (!dir_check_ftype(conn
,mode
,dirtype
)) {
1233 DEBUG(5,("[%s] attribs didn't match %x\n",fname
,dirtype
));
1238 file_size
= get_file_size(sbuf
);
1239 allocation_size
= get_allocation_size(conn
,NULL
,&sbuf
);
1241 mdate_ts
= get_mtimespec(&sbuf
);
1242 adate_ts
= get_atimespec(&sbuf
);
1243 create_date_ts
= get_create_timespec(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
1245 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1246 dos_filetime_timespec(&create_date_ts
);
1247 dos_filetime_timespec(&mdate_ts
);
1248 dos_filetime_timespec(&adate_ts
);
1251 create_date
= convert_timespec_to_time_t(create_date_ts
);
1252 mdate
= convert_timespec_to_time_t(mdate_ts
);
1253 adate
= convert_timespec_to_time_t(adate_ts
);
1255 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal
,fname
));
1259 dptr_DirCacheAdd(conn
->dirptr
, dname
, curr_dirpos
);
1263 mangle_map(fname
,False
,True
,conn
->params
);
1268 nt_extmode
= mode
? mode
: FILE_ATTRIBUTE_NORMAL
;
1270 switch (info_level
) {
1271 case SMB_FIND_INFO_STANDARD
:
1272 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1273 if(requires_resume_key
) {
1277 srv_put_dos_date2(p
,0,create_date
);
1278 srv_put_dos_date2(p
,4,adate
);
1279 srv_put_dos_date2(p
,8,mdate
);
1280 SIVAL(p
,12,(uint32
)file_size
);
1281 SIVAL(p
,16,(uint32
)allocation_size
);
1285 p
+= align_string(outbuf
, p
, 0);
1286 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), STR_TERMINATE
);
1287 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
) {
1289 SCVAL(nameptr
, -1, len
- 2);
1291 SCVAL(nameptr
, -1, 0);
1295 SCVAL(nameptr
, -1, len
- 1);
1297 SCVAL(nameptr
, -1, 0);
1303 case SMB_FIND_EA_SIZE
:
1304 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1305 if(requires_resume_key
) {
1309 srv_put_dos_date2(p
,0,create_date
);
1310 srv_put_dos_date2(p
,4,adate
);
1311 srv_put_dos_date2(p
,8,mdate
);
1312 SIVAL(p
,12,(uint32
)file_size
);
1313 SIVAL(p
,16,(uint32
)allocation_size
);
1316 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1317 SIVAL(p
,22,ea_size
); /* Extended attributes */
1321 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), STR_TERMINATE
| STR_NOALIGN
);
1322 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
) {
1335 SCVAL(nameptr
,0,len
);
1337 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1340 case SMB_FIND_EA_LIST
:
1342 struct ea_list
*file_list
= NULL
;
1345 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1349 if(requires_resume_key
) {
1353 srv_put_dos_date2(p
,0,create_date
);
1354 srv_put_dos_date2(p
,4,adate
);
1355 srv_put_dos_date2(p
,8,mdate
);
1356 SIVAL(p
,12,(uint32
)file_size
);
1357 SIVAL(p
,16,(uint32
)allocation_size
);
1359 p
+= 22; /* p now points to the EA area. */
1361 file_list
= get_ea_list_from_file(ea_ctx
, conn
, NULL
, pathreal
, &ea_len
);
1362 name_list
= ea_list_union(name_list
, file_list
, &ea_len
);
1364 /* We need to determine if this entry will fit in the space available. */
1365 /* Max string size is 255 bytes. */
1366 if (PTR_DIFF(p
+ 255 + ea_len
,pdata
) > space_remaining
) {
1367 /* Move the dirptr back to prev_dirpos */
1368 dptr_SeekDir(conn
->dirptr
, prev_dirpos
);
1369 *out_of_space
= True
;
1370 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1371 return False
; /* Not finished - just out of space */
1374 /* Push the ea_data followed by the name. */
1375 p
+= fill_ea_buffer(ea_ctx
, p
, space_remaining
- (p
- pdata
), conn
, name_list
);
1377 len
= srvstr_push(outbuf
, p
+ 1, fname
, PTR_DIFF(end_data
, p
+1), STR_TERMINATE
| STR_NOALIGN
);
1378 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
) {
1391 SCVAL(nameptr
,0,len
);
1393 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1397 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1398 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1399 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1401 SIVAL(p
,0,reskey
); p
+= 4;
1402 put_long_date_timespec(p
,create_date_ts
); p
+= 8;
1403 put_long_date_timespec(p
,adate_ts
); p
+= 8;
1404 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1405 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1406 SOFF_T(p
,0,file_size
); p
+= 8;
1407 SOFF_T(p
,0,allocation_size
); p
+= 8;
1408 SIVAL(p
,0,nt_extmode
); p
+= 4;
1409 q
= p
; p
+= 4; /* q is placeholder for name length. */
1411 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1412 SIVAL(p
,0,ea_size
); /* Extended attributes */
1415 /* Clear the short name buffer. This is
1416 * IMPORTANT as not doing so will trigger
1417 * a Win2k client bug. JRA.
1419 if (!was_8_3
&& check_mangled_names
) {
1420 pstring mangled_name
;
1421 pstrcpy(mangled_name
, fname
);
1422 mangle_map(mangled_name
,True
,True
,
1424 mangled_name
[12] = 0;
1425 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
|STR_UNICODE
);
1427 memset(p
+ 2 + len
,'\0',24 - len
);
1434 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), STR_TERMINATE_ASCII
);
1437 SIVAL(p
,0,0); /* Ensure any padding is null. */
1438 len
= PTR_DIFF(p
, pdata
);
1439 len
= (len
+ 3) & ~3;
1444 case SMB_FIND_FILE_DIRECTORY_INFO
:
1445 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1447 SIVAL(p
,0,reskey
); p
+= 4;
1448 put_long_date_timespec(p
,create_date_ts
); p
+= 8;
1449 put_long_date_timespec(p
,adate_ts
); p
+= 8;
1450 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1451 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1452 SOFF_T(p
,0,file_size
); p
+= 8;
1453 SOFF_T(p
,0,allocation_size
); p
+= 8;
1454 SIVAL(p
,0,nt_extmode
); p
+= 4;
1455 len
= srvstr_push(outbuf
, p
+ 4, fname
, PTR_DIFF(end_data
, p
+4), STR_TERMINATE_ASCII
);
1458 SIVAL(p
,0,0); /* Ensure any padding is null. */
1459 len
= PTR_DIFF(p
, pdata
);
1460 len
= (len
+ 3) & ~3;
1465 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1466 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1468 SIVAL(p
,0,reskey
); p
+= 4;
1469 put_long_date_timespec(p
,create_date_ts
); p
+= 8;
1470 put_long_date_timespec(p
,adate_ts
); p
+= 8;
1471 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1472 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1473 SOFF_T(p
,0,file_size
); p
+= 8;
1474 SOFF_T(p
,0,allocation_size
); p
+= 8;
1475 SIVAL(p
,0,nt_extmode
); p
+= 4;
1476 q
= p
; p
+= 4; /* q is placeholder for name length. */
1478 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1479 SIVAL(p
,0,ea_size
); /* Extended attributes */
1482 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), STR_TERMINATE_ASCII
);
1486 SIVAL(p
,0,0); /* Ensure any padding is null. */
1487 len
= PTR_DIFF(p
, pdata
);
1488 len
= (len
+ 3) & ~3;
1493 case SMB_FIND_FILE_NAMES_INFO
:
1494 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1496 SIVAL(p
,0,reskey
); p
+= 4;
1498 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1499 acl on a dir (tridge) */
1500 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), STR_TERMINATE_ASCII
);
1503 SIVAL(p
,0,0); /* Ensure any padding is null. */
1504 len
= PTR_DIFF(p
, pdata
);
1505 len
= (len
+ 3) & ~3;
1510 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1511 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1513 SIVAL(p
,0,reskey
); p
+= 4;
1514 put_long_date_timespec(p
,create_date_ts
); p
+= 8;
1515 put_long_date_timespec(p
,adate_ts
); p
+= 8;
1516 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1517 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1518 SOFF_T(p
,0,file_size
); p
+= 8;
1519 SOFF_T(p
,0,allocation_size
); p
+= 8;
1520 SIVAL(p
,0,nt_extmode
); p
+= 4;
1521 q
= p
; p
+= 4; /* q is placeholder for name length. */
1523 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1524 SIVAL(p
,0,ea_size
); /* Extended attributes */
1527 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
1528 SIVAL(p
,0,sbuf
.st_ino
); p
+= 4; /* FileIndexLow */
1529 SIVAL(p
,0,sbuf
.st_dev
); p
+= 4; /* FileIndexHigh */
1530 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), STR_TERMINATE_ASCII
);
1533 SIVAL(p
,0,0); /* Ensure any padding is null. */
1534 len
= PTR_DIFF(p
, pdata
);
1535 len
= (len
+ 3) & ~3;
1540 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1541 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1542 was_8_3
= mangle_is_8_3(fname
, True
, conn
->params
);
1544 SIVAL(p
,0,reskey
); p
+= 4;
1545 put_long_date_timespec(p
,create_date_ts
); p
+= 8;
1546 put_long_date_timespec(p
,adate_ts
); p
+= 8;
1547 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1548 put_long_date_timespec(p
,mdate_ts
); p
+= 8;
1549 SOFF_T(p
,0,file_size
); p
+= 8;
1550 SOFF_T(p
,0,allocation_size
); p
+= 8;
1551 SIVAL(p
,0,nt_extmode
); p
+= 4;
1552 q
= p
; p
+= 4; /* q is placeholder for name length */
1554 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1555 SIVAL(p
,0,ea_size
); /* Extended attributes */
1558 /* Clear the short name buffer. This is
1559 * IMPORTANT as not doing so will trigger
1560 * a Win2k client bug. JRA.
1562 if (!was_8_3
&& check_mangled_names
) {
1563 pstring mangled_name
;
1564 pstrcpy(mangled_name
, fname
);
1565 mangle_map(mangled_name
,True
,True
,
1567 mangled_name
[12] = 0;
1568 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
|STR_UNICODE
);
1571 memset(p
+ 2 + len
,'\0',24 - len
);
1578 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
1579 SIVAL(p
,0,sbuf
.st_ino
); p
+= 4; /* FileIndexLow */
1580 SIVAL(p
,0,sbuf
.st_dev
); p
+= 4; /* FileIndexHigh */
1581 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), STR_TERMINATE_ASCII
);
1584 SIVAL(p
,0,0); /* Ensure any padding is null. */
1585 len
= PTR_DIFF(p
, pdata
);
1586 len
= (len
+ 3) & ~3;
1591 /* CIFS UNIX Extension. */
1593 case SMB_FIND_FILE_UNIX
:
1594 case SMB_FIND_FILE_UNIX_INFO2
:
1596 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
1598 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1600 if (info_level
== SMB_FIND_FILE_UNIX
) {
1601 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1602 p
= store_file_unix_basic(conn
, p
,
1604 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), STR_TERMINATE
);
1606 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1607 p
= store_file_unix_basic_info2(conn
, p
,
1611 len
= srvstr_push(outbuf
, p
, fname
, PTR_DIFF(end_data
, p
), 0);
1612 SIVAL(nameptr
, 0, len
);
1616 SIVAL(p
,0,0); /* Ensure any padding is null. */
1618 len
= PTR_DIFF(p
, pdata
);
1619 len
= (len
+ 3) & ~3;
1620 SIVAL(pdata
,0,len
); /* Offset from this structure to the beginning of the next one */
1622 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1631 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
1632 /* Move the dirptr back to prev_dirpos */
1633 dptr_SeekDir(conn
->dirptr
, prev_dirpos
);
1634 *out_of_space
= True
;
1635 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1636 return False
; /* Not finished - just out of space */
1639 /* Setup the last entry pointer, as an offset from base_data */
1640 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
1641 /* Advance the data pointer to the next slot */
1647 /****************************************************************************
1648 Reply to a TRANS2_FINDFIRST.
1649 ****************************************************************************/
1651 static int call_trans2findfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
1652 char **pparams
, int total_params
, char **ppdata
, int total_data
,
1653 unsigned int max_data_bytes
)
1655 /* We must be careful here that we don't return more than the
1656 allowed number of data bytes. If this means returning fewer than
1657 maxentries then so be it. We assume that the redirector has
1658 enough room for the fixed number of parameter bytes it has
1660 char *params
= *pparams
;
1661 char *pdata
= *ppdata
;
1665 uint16 findfirst_flags
;
1666 BOOL close_after_first
;
1668 BOOL requires_resume_key
;
1673 int last_entry_off
=0;
1677 BOOL finished
= False
;
1678 BOOL dont_descend
= False
;
1679 BOOL out_of_space
= False
;
1680 int space_remaining
;
1681 BOOL mask_contains_wcard
= False
;
1682 SMB_STRUCT_STAT sbuf
;
1683 TALLOC_CTX
*ea_ctx
= NULL
;
1684 struct ea_list
*ea_list
= NULL
;
1685 NTSTATUS ntstatus
= NT_STATUS_OK
;
1687 if (total_params
< 13) {
1688 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1691 dirtype
= SVAL(params
,0);
1692 maxentries
= SVAL(params
,2);
1693 findfirst_flags
= SVAL(params
,4);
1694 close_after_first
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE
);
1695 close_if_end
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
1696 requires_resume_key
= (findfirst_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
1697 info_level
= SVAL(params
,6);
1699 *directory
= *mask
= 0;
1701 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
1702 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1703 (unsigned int)dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
1704 info_level
, max_data_bytes
));
1707 /* W2K3 seems to treat zero as 1. */
1711 switch (info_level
) {
1712 case SMB_FIND_INFO_STANDARD
:
1713 case SMB_FIND_EA_SIZE
:
1714 case SMB_FIND_EA_LIST
:
1715 case SMB_FIND_FILE_DIRECTORY_INFO
:
1716 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1717 case SMB_FIND_FILE_NAMES_INFO
:
1718 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1719 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1720 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1722 case SMB_FIND_FILE_UNIX
:
1723 case SMB_FIND_FILE_UNIX_INFO2
:
1724 if (!lp_unix_extensions()) {
1725 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
1729 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
1732 srvstr_get_path_wcard(inbuf
, directory
, params
+12, sizeof(directory
), total_params
- 12, STR_TERMINATE
, &ntstatus
, &mask_contains_wcard
);
1733 if (!NT_STATUS_IS_OK(ntstatus
)) {
1734 return ERROR_NT(ntstatus
);
1737 ntstatus
= resolve_dfspath_wcard(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, directory
, &mask_contains_wcard
);
1738 if (!NT_STATUS_IS_OK(ntstatus
)) {
1739 if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_PATH_NOT_COVERED
)) {
1740 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
1742 return ERROR_NT(ntstatus
);
1745 ntstatus
= unix_convert(conn
, directory
, True
, NULL
, &sbuf
);
1746 if (!NT_STATUS_IS_OK(ntstatus
)) {
1747 return ERROR_NT(ntstatus
);
1749 ntstatus
= check_name(conn
, directory
);
1750 if (!NT_STATUS_IS_OK(ntstatus
)) {
1751 return ERROR_NT(ntstatus
);
1754 p
= strrchr_m(directory
,'/');
1756 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1757 if((directory
[0] == '.') && (directory
[1] == '\0')) {
1759 mask_contains_wcard
= True
;
1761 pstrcpy(mask
,directory
);
1763 pstrcpy(directory
,"./");
1769 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
1771 if (info_level
== SMB_FIND_EA_LIST
) {
1774 if (total_data
< 4) {
1775 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1778 ea_size
= IVAL(pdata
,0);
1779 if (ea_size
!= total_data
) {
1780 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
1781 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
1782 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1785 if (!lp_ea_support(SNUM(conn
))) {
1786 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
1789 if ((ea_ctx
= talloc_init("findnext_ea_list")) == NULL
) {
1790 return ERROR_NT(NT_STATUS_NO_MEMORY
);
1793 /* Pull out the list of names. */
1794 ea_list
= read_ea_name_list(ea_ctx
, pdata
+ 4, ea_size
- 4);
1796 talloc_destroy(ea_ctx
);
1797 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1801 *ppdata
= (char *)SMB_REALLOC(
1802 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1803 if(*ppdata
== NULL
) {
1804 talloc_destroy(ea_ctx
);
1805 return ERROR_NT(NT_STATUS_NO_MEMORY
);
1808 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
1810 /* Realloc the params space */
1811 *pparams
= (char *)SMB_REALLOC(*pparams
, 10);
1812 if (*pparams
== NULL
) {
1813 talloc_destroy(ea_ctx
);
1814 return ERROR_NT(NT_STATUS_NO_MEMORY
);
1818 /* Save the wildcard match and attribs we are using on this directory -
1819 needed as lanman2 assumes these are being saved between calls */
1821 ntstatus
= dptr_create(conn
,
1825 SVAL(inbuf
,smb_pid
),
1827 mask_contains_wcard
,
1831 if (!NT_STATUS_IS_OK(ntstatus
)) {
1832 talloc_destroy(ea_ctx
);
1833 return ERROR_NT(ntstatus
);
1836 dptr_num
= dptr_dnum(conn
->dirptr
);
1837 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num
, mask
, dirtype
));
1839 /* We don't need to check for VOL here as this is returned by
1840 a different TRANS2 call. */
1842 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1843 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
1844 dont_descend
= True
;
1847 space_remaining
= max_data_bytes
;
1848 out_of_space
= False
;
1850 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
1851 BOOL got_exact_match
= False
;
1853 /* this is a heuristic to avoid seeking the dirptr except when
1854 absolutely necessary. It allows for a filename of about 40 chars */
1855 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1856 out_of_space
= True
;
1859 finished
= !get_lanman2_dir_entry(conn
,
1861 mask
,dirtype
,info_level
,
1862 requires_resume_key
,dont_descend
,
1863 &p
,pdata
,data_end
,space_remaining
, &out_of_space
, &got_exact_match
,
1864 &last_entry_off
, ea_list
, ea_ctx
);
1867 if (finished
&& out_of_space
)
1870 if (!finished
&& !out_of_space
)
1874 * As an optimisation if we know we aren't looking
1875 * for a wildcard name (ie. the name matches the wildcard exactly)
1876 * then we can finish on any (first) match.
1877 * This speeds up large directory searches. JRA.
1883 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1886 talloc_destroy(ea_ctx
);
1888 /* Check if we can close the dirptr */
1889 if(close_after_first
|| (finished
&& close_if_end
)) {
1890 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
1891 dptr_close(&dptr_num
);
1895 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1896 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
1897 * the protocol level is less than NT1. Tested with smbclient. JRA.
1898 * This should fix the OS/2 client bug #2335.
1901 if(numentries
== 0) {
1902 dptr_close(&dptr_num
);
1903 if (Protocol
< PROTOCOL_NT1
) {
1904 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1906 return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE
,ERRDOS
,ERRbadfile
);
1910 /* At this point pdata points to numentries directory entries. */
1912 /* Set up the return parameter block */
1913 SSVAL(params
,0,dptr_num
);
1914 SSVAL(params
,2,numentries
);
1915 SSVAL(params
,4,finished
);
1916 SSVAL(params
,6,0); /* Never an EA error */
1917 SSVAL(params
,8,last_entry_off
);
1919 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
), max_data_bytes
);
1921 if ((! *directory
) && dptr_path(dptr_num
))
1922 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1924 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1925 smb_fn_name(CVAL(inbuf
,smb_com
)),
1926 mask
, directory
, dirtype
, numentries
) );
1929 * Force a name mangle here to ensure that the
1930 * mask as an 8.3 name is top of the mangled cache.
1931 * The reasons for this are subtle. Don't remove
1932 * this code unless you know what you are doing
1933 * (see PR#13758). JRA.
1936 if(!mangle_is_8_3_wildcards( mask
, False
, conn
->params
))
1937 mangle_map(mask
, True
, True
, conn
->params
);
1942 /****************************************************************************
1943 Reply to a TRANS2_FINDNEXT.
1944 ****************************************************************************/
1946 static int call_trans2findnext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1947 char **pparams
, int total_params
, char **ppdata
, int total_data
,
1948 unsigned int max_data_bytes
)
1950 /* We must be careful here that we don't return more than the
1951 allowed number of data bytes. If this means returning fewer than
1952 maxentries then so be it. We assume that the redirector has
1953 enough room for the fixed number of parameter bytes it has
1955 char *params
= *pparams
;
1956 char *pdata
= *ppdata
;
1962 uint16 findnext_flags
;
1963 BOOL close_after_request
;
1965 BOOL requires_resume_key
;
1967 BOOL mask_contains_wcard
= False
;
1968 pstring resume_name
;
1974 int i
, last_entry_off
=0;
1975 BOOL finished
= False
;
1976 BOOL dont_descend
= False
;
1977 BOOL out_of_space
= False
;
1978 int space_remaining
;
1979 TALLOC_CTX
*ea_ctx
= NULL
;
1980 struct ea_list
*ea_list
= NULL
;
1981 NTSTATUS ntstatus
= NT_STATUS_OK
;
1983 if (total_params
< 13) {
1984 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1987 dptr_num
= SVAL(params
,0);
1988 maxentries
= SVAL(params
,2);
1989 info_level
= SVAL(params
,4);
1990 resume_key
= IVAL(params
,6);
1991 findnext_flags
= SVAL(params
,10);
1992 close_after_request
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE
);
1993 close_if_end
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
1994 requires_resume_key
= (findnext_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
1995 continue_bit
= (findnext_flags
& FLAG_TRANS2_FIND_CONTINUE
);
1997 *mask
= *directory
= *resume_name
= 0;
1999 srvstr_get_path_wcard(inbuf
, resume_name
, params
+12, sizeof(resume_name
), total_params
- 12, STR_TERMINATE
, &ntstatus
, &mask_contains_wcard
);
2000 if (!NT_STATUS_IS_OK(ntstatus
)) {
2001 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2002 complain (it thinks we're asking for the directory above the shared
2003 path or an invalid name). Catch this as the resume name is only compared, never used in
2004 a file access. JRA. */
2005 srvstr_pull(inbuf
, resume_name
, params
+12,
2006 sizeof(resume_name
), total_params
- 12,
2009 if (!(ISDOT(resume_name
) || ISDOTDOT(resume_name
))) {
2010 return ERROR_NT(ntstatus
);
2014 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2015 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2016 resume_key = %d resume name = %s continue=%d level = %d\n",
2017 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
2018 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
2021 /* W2K3 seems to treat zero as 1. */
2025 switch (info_level
) {
2026 case SMB_FIND_INFO_STANDARD
:
2027 case SMB_FIND_EA_SIZE
:
2028 case SMB_FIND_EA_LIST
:
2029 case SMB_FIND_FILE_DIRECTORY_INFO
:
2030 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
2031 case SMB_FIND_FILE_NAMES_INFO
:
2032 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
2033 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
2034 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
2036 case SMB_FIND_FILE_UNIX
:
2037 case SMB_FIND_FILE_UNIX_INFO2
:
2038 if (!lp_unix_extensions()) {
2039 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2043 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2046 if (info_level
== SMB_FIND_EA_LIST
) {
2049 if (total_data
< 4) {
2050 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2053 ea_size
= IVAL(pdata
,0);
2054 if (ea_size
!= total_data
) {
2055 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2056 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
2057 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2060 if (!lp_ea_support(SNUM(conn
))) {
2061 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
2064 if ((ea_ctx
= talloc_init("findnext_ea_list")) == NULL
) {
2065 return ERROR_NT(NT_STATUS_NO_MEMORY
);
2068 /* Pull out the list of names. */
2069 ea_list
= read_ea_name_list(ea_ctx
, pdata
+ 4, ea_size
- 4);
2071 talloc_destroy(ea_ctx
);
2072 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2076 *ppdata
= (char *)SMB_REALLOC(
2077 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2078 if(*ppdata
== NULL
) {
2079 talloc_destroy(ea_ctx
);
2080 return ERROR_NT(NT_STATUS_NO_MEMORY
);
2084 data_end
= pdata
+ max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
- 1;
2086 /* Realloc the params space */
2087 *pparams
= (char *)SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
2088 if(*pparams
== NULL
) {
2089 talloc_destroy(ea_ctx
);
2090 return ERROR_NT(NT_STATUS_NO_MEMORY
);
2095 /* Check that the dptr is valid */
2096 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
))) {
2097 talloc_destroy(ea_ctx
);
2098 return ERROR_DOS(ERRDOS
,ERRnofiles
);
2101 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
2103 /* Get the wildcard mask from the dptr */
2104 if((p
= dptr_wcard(dptr_num
))== NULL
) {
2105 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
2106 talloc_destroy(ea_ctx
);
2107 return ERROR_DOS(ERRDOS
,ERRnofiles
);
2111 pstrcpy(directory
,conn
->dirpath
);
2113 /* Get the attr mask from the dptr */
2114 dirtype
= dptr_attr(dptr_num
);
2116 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2117 dptr_num
, mask
, dirtype
,
2119 dptr_TellDir(conn
->dirptr
)));
2121 /* We don't need to check for VOL here as this is returned by
2122 a different TRANS2 call. */
2124 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
2125 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
2126 dont_descend
= True
;
2129 space_remaining
= max_data_bytes
;
2130 out_of_space
= False
;
2133 * Seek to the correct position. We no longer use the resume key but
2134 * depend on the last file name instead.
2137 if(*resume_name
&& !continue_bit
) {
2140 long current_pos
= 0;
2142 * Remember, mangle_map is called by
2143 * get_lanman2_dir_entry(), so the resume name
2144 * could be mangled. Ensure we check the unmangled name.
2147 if (mangle_is_mangled(resume_name
, conn
->params
)) {
2148 mangle_check_cache(resume_name
, sizeof(resume_name
)-1,
2153 * Fix for NT redirector problem triggered by resume key indexes
2154 * changing between directory scans. We now return a resume key of 0
2155 * and instead look for the filename to continue from (also given
2156 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2157 * findfirst/findnext (as is usual) then the directory pointer
2158 * should already be at the correct place.
2161 finished
= !dptr_SearchDir(conn
->dirptr
, resume_name
, ¤t_pos
, &st
);
2162 } /* end if resume_name && !continue_bit */
2164 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
2165 BOOL got_exact_match
= False
;
2167 /* this is a heuristic to avoid seeking the dirptr except when
2168 absolutely necessary. It allows for a filename of about 40 chars */
2169 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
2170 out_of_space
= True
;
2173 finished
= !get_lanman2_dir_entry(conn
,
2175 mask
,dirtype
,info_level
,
2176 requires_resume_key
,dont_descend
,
2177 &p
,pdata
,data_end
,space_remaining
, &out_of_space
, &got_exact_match
,
2178 &last_entry_off
, ea_list
, ea_ctx
);
2181 if (finished
&& out_of_space
)
2184 if (!finished
&& !out_of_space
)
2188 * As an optimisation if we know we aren't looking
2189 * for a wildcard name (ie. the name matches the wildcard exactly)
2190 * then we can finish on any (first) match.
2191 * This speeds up large directory searches. JRA.
2197 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
2200 talloc_destroy(ea_ctx
);
2202 /* Check if we can close the dirptr */
2203 if(close_after_request
|| (finished
&& close_if_end
)) {
2204 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
2205 dptr_close(&dptr_num
); /* This frees up the saved mask */
2208 /* Set up the return parameter block */
2209 SSVAL(params
,0,numentries
);
2210 SSVAL(params
,2,finished
);
2211 SSVAL(params
,4,0); /* Never an EA error */
2212 SSVAL(params
,6,last_entry_off
);
2214 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
), max_data_bytes
);
2216 if ((! *directory
) && dptr_path(dptr_num
))
2217 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
2219 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2220 smb_fn_name(CVAL(inbuf
,smb_com
)),
2221 mask
, directory
, dirtype
, numentries
) );
2226 static void samba_extended_info_version(struct smb_extended_info
*extended_info
)
2228 SMB_ASSERT(extended_info
!= NULL
);
2230 extended_info
->samba_magic
= SAMBA_EXTENDED_INFO_MAGIC
;
2231 extended_info
->samba_version
= ((SAMBA_VERSION_MAJOR
& 0xff) << 24)
2232 | ((SAMBA_VERSION_MINOR
& 0xff) << 16)
2233 | ((SAMBA_VERSION_RELEASE
& 0xff) << 8);
2234 #ifdef SAMBA_VERSION_REVISION
2235 extended_info
->samba_version
|= (tolower(*SAMBA_VERSION_REVISION
) - 'a' + 1) & 0xff;
2237 extended_info
->samba_subversion
= 0;
2238 #ifdef SAMBA_VERSION_RC_RELEASE
2239 extended_info
->samba_subversion
|= (SAMBA_VERSION_RC_RELEASE
& 0xff) << 24;
2241 #ifdef SAMBA_VERSION_PRE_RELEASE
2242 extended_info
->samba_subversion
|= (SAMBA_VERSION_PRE_RELEASE
& 0xff) << 16;
2245 #ifdef SAMBA_VERSION_VENDOR_PATCH
2246 extended_info
->samba_subversion
|= (SAMBA_VERSION_VENDOR_PATCH
& 0xffff);
2248 extended_info
->samba_subversion
= 0;
2249 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2250 unix_to_nt_time(&extended_info
->samba_gitcommitdate
, SAMBA_VERSION_GIT_COMMIT_TIME
);
2253 memset(extended_info
->samba_version_string
, 0,
2254 sizeof(extended_info
->samba_version_string
));
2256 snprintf (extended_info
->samba_version_string
,
2257 sizeof(extended_info
->samba_version_string
),
2258 "%s", samba_version_string());
2261 /****************************************************************************
2262 Reply to a TRANS2_QFSINFO (query filesystem info).
2263 ****************************************************************************/
2265 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2266 char **pparams
, int total_params
, char **ppdata
, int total_data
,
2267 unsigned int max_data_bytes
)
2270 char *params
= *pparams
;
2274 const char *vname
= volume_label(SNUM(conn
));
2275 int snum
= SNUM(conn
);
2276 char *fstype
= lp_fstype(SNUM(conn
));
2279 if (total_params
< 2) {
2280 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2283 info_level
= SVAL(params
,0);
2285 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
2287 if(SMB_VFS_STAT(conn
,".",&st
)!=0) {
2288 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
2289 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
2292 *ppdata
= (char *)SMB_REALLOC(
2293 *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2294 if (*ppdata
== NULL
) {
2295 return ERROR_NT(NT_STATUS_NO_MEMORY
);
2299 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
2301 switch (info_level
) {
2302 case SMB_INFO_ALLOCATION
:
2304 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
2306 if (get_dfree_info(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (SMB_BIG_UINT
)-1) {
2307 return(UNIXERROR(ERRHRD
,ERRgeneral
));
2310 block_size
= lp_block_size(snum
);
2311 if (bsize
< block_size
) {
2312 SMB_BIG_UINT factor
= block_size
/bsize
;
2317 if (bsize
> block_size
) {
2318 SMB_BIG_UINT factor
= bsize
/block_size
;
2323 bytes_per_sector
= 512;
2324 sectors_per_unit
= bsize
/bytes_per_sector
;
2326 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2327 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
2328 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
2330 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
2331 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
2332 SIVAL(pdata
,l1_cUnit
,dsize
);
2333 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
2334 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
2338 case SMB_INFO_VOLUME
:
2339 /* Return volume name */
2341 * Add volume serial number - hash of a combination of
2342 * the called hostname and the service name.
2344 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
2346 * Win2k3 and previous mess this up by sending a name length
2347 * one byte short. I believe only older clients (OS/2 Win9x) use
2348 * this call so try fixing this by adding a terminating null to
2349 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2351 len
= srvstr_push(outbuf
, pdata
+l2_vol_szVolLabel
, vname
, max_data_bytes
- l2_vol_szVolLabel
, STR_NOALIGN
|STR_TERMINATE
);
2352 SCVAL(pdata
,l2_vol_cch
,len
);
2353 data_len
= l2_vol_szVolLabel
+ len
;
2354 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2355 (unsigned)st
.st_ctime
, len
, vname
));
2358 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
2359 case SMB_FS_ATTRIBUTE_INFORMATION
:
2362 #if defined(HAVE_SYS_QUOTAS)
2363 quota_flag
= FILE_VOLUME_QUOTAS
;
2366 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
2367 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)|
2368 FILE_UNICODE_ON_DISK
|
2369 quota_flag
); /* FS ATTRIBUTES */
2371 SIVAL(pdata
,4,255); /* Max filename component length */
2372 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2373 and will think we can't do long filenames */
2374 len
= srvstr_push(outbuf
, pdata
+12, fstype
, max_data_bytes
- 12, STR_UNICODE
);
2376 data_len
= 12 + len
;
2379 case SMB_QUERY_FS_LABEL_INFO
:
2380 case SMB_FS_LABEL_INFORMATION
:
2381 len
= srvstr_push(outbuf
, pdata
+4, vname
, max_data_bytes
- 4, 0);
2386 case SMB_QUERY_FS_VOLUME_INFO
:
2387 case SMB_FS_VOLUME_INFORMATION
:
2390 * Add volume serial number - hash of a combination of
2391 * the called hostname and the service name.
2393 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
2394 (str_checksum(get_local_machine_name())<<16));
2396 /* Max label len is 32 characters. */
2397 len
= srvstr_push(outbuf
, pdata
+18, vname
, max_data_bytes
- 18, STR_UNICODE
);
2398 SIVAL(pdata
,12,len
);
2401 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2402 (int)strlen(vname
),vname
, lp_servicename(snum
)));
2405 case SMB_QUERY_FS_SIZE_INFO
:
2406 case SMB_FS_SIZE_INFORMATION
:
2408 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
2410 if (get_dfree_info(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (SMB_BIG_UINT
)-1) {
2411 return(UNIXERROR(ERRHRD
,ERRgeneral
));
2413 block_size
= lp_block_size(snum
);
2414 if (bsize
< block_size
) {
2415 SMB_BIG_UINT factor
= block_size
/bsize
;
2420 if (bsize
> block_size
) {
2421 SMB_BIG_UINT factor
= bsize
/block_size
;
2426 bytes_per_sector
= 512;
2427 sectors_per_unit
= bsize
/bytes_per_sector
;
2428 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2429 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
2430 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
2431 SBIG_UINT(pdata
,0,dsize
);
2432 SBIG_UINT(pdata
,8,dfree
);
2433 SIVAL(pdata
,16,sectors_per_unit
);
2434 SIVAL(pdata
,20,bytes_per_sector
);
2438 case SMB_FS_FULL_SIZE_INFORMATION
:
2440 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
2442 if (get_dfree_info(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (SMB_BIG_UINT
)-1) {
2443 return(UNIXERROR(ERRHRD
,ERRgeneral
));
2445 block_size
= lp_block_size(snum
);
2446 if (bsize
< block_size
) {
2447 SMB_BIG_UINT factor
= block_size
/bsize
;
2452 if (bsize
> block_size
) {
2453 SMB_BIG_UINT factor
= bsize
/block_size
;
2458 bytes_per_sector
= 512;
2459 sectors_per_unit
= bsize
/bytes_per_sector
;
2460 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2461 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
2462 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
2463 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
2464 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
2465 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
2466 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
2467 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
2471 case SMB_QUERY_FS_DEVICE_INFO
:
2472 case SMB_FS_DEVICE_INFORMATION
:
2474 SIVAL(pdata
,0,0); /* dev type */
2475 SIVAL(pdata
,4,0); /* characteristics */
2478 #ifdef HAVE_SYS_QUOTAS
2479 case SMB_FS_QUOTA_INFORMATION
:
2481 * what we have to send --metze:
2483 * Unknown1: 24 NULL bytes
2484 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2485 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2486 * Quota Flags: 2 byte :
2487 * Unknown3: 6 NULL bytes
2491 * details for Quota Flags:
2493 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2494 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2495 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2496 * 0x0001 Enable Quotas: enable quota for this fs
2500 /* we need to fake up a fsp here,
2501 * because its not send in this call
2504 SMB_NTQUOTA_STRUCT quotas
;
2507 ZERO_STRUCT(quotas
);
2513 if (current_user
.ut
.uid
!= 0) {
2514 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2515 lp_servicename(SNUM(conn
)),conn
->user
));
2516 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
2519 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
2520 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
2521 return ERROR_DOS(ERRSRV
,ERRerror
);
2526 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn
))));
2528 /* Unknown1 24 NULL bytes*/
2529 SBIG_UINT(pdata
,0,(SMB_BIG_UINT
)0);
2530 SBIG_UINT(pdata
,8,(SMB_BIG_UINT
)0);
2531 SBIG_UINT(pdata
,16,(SMB_BIG_UINT
)0);
2533 /* Default Soft Quota 8 bytes */
2534 SBIG_UINT(pdata
,24,quotas
.softlim
);
2536 /* Default Hard Quota 8 bytes */
2537 SBIG_UINT(pdata
,32,quotas
.hardlim
);
2539 /* Quota flag 2 bytes */
2540 SSVAL(pdata
,40,quotas
.qflags
);
2542 /* Unknown3 6 NULL bytes */
2548 #endif /* HAVE_SYS_QUOTAS */
2549 case SMB_FS_OBJECTID_INFORMATION
:
2552 * No object id, but we transmit version information.
2554 struct smb_extended_info extended_info
;
2555 samba_extended_info_version (&extended_info
);
2556 SIVAL(pdata
,16,extended_info
.samba_magic
);
2557 SIVAL(pdata
,20,extended_info
.samba_version
);
2558 SIVAL(pdata
,24,extended_info
.samba_subversion
);
2559 SBIG_UINT(pdata
,28,extended_info
.samba_gitcommitdate
);
2560 memcpy(pdata
+36,extended_info
.samba_version_string
,28);
2566 * Query the version and capabilities of the CIFS UNIX extensions
2570 case SMB_QUERY_CIFS_UNIX_INFO
:
2571 if (!lp_unix_extensions()) {
2572 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2575 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
2576 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
2577 /* We have POSIX ACLs, pathname and locking capability. */
2578 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)(
2579 CIFS_UNIX_POSIX_ACLS_CAP
|
2580 CIFS_UNIX_POSIX_PATHNAMES_CAP
|
2581 CIFS_UNIX_FCNTL_LOCKS_CAP
|
2582 CIFS_UNIX_EXTATTR_CAP
|
2583 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)));
2586 case SMB_QUERY_POSIX_FS_INFO
:
2589 vfs_statvfs_struct svfs
;
2591 if (!lp_unix_extensions()) {
2592 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2595 rc
= SMB_VFS_STATVFS(conn
, ".", &svfs
);
2599 SIVAL(pdata
,0,svfs
.OptimalTransferSize
);
2600 SIVAL(pdata
,4,svfs
.BlockSize
);
2601 SBIG_UINT(pdata
,8,svfs
.TotalBlocks
);
2602 SBIG_UINT(pdata
,16,svfs
.BlocksAvail
);
2603 SBIG_UINT(pdata
,24,svfs
.UserBlocksAvail
);
2604 SBIG_UINT(pdata
,32,svfs
.TotalFileNodes
);
2605 SBIG_UINT(pdata
,40,svfs
.FreeFileNodes
);
2606 SBIG_UINT(pdata
,48,svfs
.FsIdentifier
);
2607 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2609 } else if (rc
== EOPNOTSUPP
) {
2610 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2611 #endif /* EOPNOTSUPP */
2613 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
2614 return ERROR_DOS(ERRSRV
,ERRerror
);
2619 case SMB_QUERY_POSIX_WHOAMI
:
2625 if (!lp_unix_extensions()) {
2626 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2629 if (max_data_bytes
< 40) {
2630 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL
);
2633 /* We ARE guest if global_sid_Builtin_Guests is
2634 * in our list of SIDs.
2636 if (nt_token_check_sid(&global_sid_Builtin_Guests
,
2637 current_user
.nt_user_token
)) {
2638 flags
|= SMB_WHOAMI_GUEST
;
2641 /* We are NOT guest if global_sid_Authenticated_Users
2642 * is in our list of SIDs.
2644 if (nt_token_check_sid(&global_sid_Authenticated_Users
,
2645 current_user
.nt_user_token
)) {
2646 flags
&= ~SMB_WHOAMI_GUEST
;
2649 /* NOTE: 8 bytes for UID/GID, irrespective of native
2650 * platform size. This matches
2651 * SMB_QUERY_FILE_UNIX_BASIC and friends.
2653 data_len
= 4 /* flags */
2660 + 4 /* pad/reserved */
2661 + (current_user
.ut
.ngroups
* 8)
2663 + (current_user
.nt_user_token
->num_sids
*
2667 SIVAL(pdata
, 0, flags
);
2668 SIVAL(pdata
, 4, SMB_WHOAMI_MASK
);
2669 SBIG_UINT(pdata
, 8, (SMB_BIG_UINT
)current_user
.ut
.uid
);
2670 SBIG_UINT(pdata
, 16, (SMB_BIG_UINT
)current_user
.ut
.gid
);
2673 if (data_len
>= max_data_bytes
) {
2674 /* Potential overflow, skip the GIDs and SIDs. */
2676 SIVAL(pdata
, 24, 0); /* num_groups */
2677 SIVAL(pdata
, 28, 0); /* num_sids */
2678 SIVAL(pdata
, 32, 0); /* num_sid_bytes */
2679 SIVAL(pdata
, 36, 0); /* reserved */
2685 SIVAL(pdata
, 24, current_user
.ut
.ngroups
);
2687 current_user
.nt_user_token
->num_sids
);
2689 /* We walk the SID list twice, but this call is fairly
2690 * infrequent, and I don't expect that it's performance
2691 * sensitive -- jpeach
2693 for (i
= 0, sid_bytes
= 0;
2694 i
< current_user
.nt_user_token
->num_sids
; ++i
) {
2696 sid_size(¤t_user
.nt_user_token
->user_sids
[i
]);
2699 /* SID list byte count */
2700 SIVAL(pdata
, 32, sid_bytes
);
2702 /* 4 bytes pad/reserved - must be zero */
2703 SIVAL(pdata
, 36, 0);
2707 for (i
= 0; i
< current_user
.ut
.ngroups
; ++i
) {
2708 SBIG_UINT(pdata
, data_len
,
2709 (SMB_BIG_UINT
)current_user
.ut
.groups
[i
]);
2715 i
< current_user
.nt_user_token
->num_sids
; ++i
) {
2717 sid_size(¤t_user
.nt_user_token
->user_sids
[i
]);
2719 sid_linearize(pdata
+ data_len
, sid_len
,
2720 ¤t_user
.nt_user_token
->user_sids
[i
]);
2721 data_len
+= sid_len
;
2727 case SMB_MAC_QUERY_FS_INFO
:
2729 * Thursby MAC extension... ONLY on NTFS filesystems
2730 * once we do streams then we don't need this
2732 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
2734 SIVAL(pdata
,84,0x100); /* Don't support mac... */
2739 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2743 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
, max_data_bytes
);
2745 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
2750 /****************************************************************************
2751 Reply to a TRANS2_SETFSINFO (set filesystem info).
2752 ****************************************************************************/
2754 static int call_trans2setfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2755 char **pparams
, int total_params
, char **ppdata
, int total_data
,
2756 unsigned int max_data_bytes
)
2758 char *pdata
= *ppdata
;
2759 char *params
= *pparams
;
2763 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn
))));
2766 if (total_params
< 4) {
2767 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2769 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2772 info_level
= SVAL(params
,2);
2774 switch(info_level
) {
2775 case SMB_SET_CIFS_UNIX_INFO
:
2777 uint16 client_unix_major
;
2778 uint16 client_unix_minor
;
2779 uint32 client_unix_cap_low
;
2780 uint32 client_unix_cap_high
;
2782 if (!lp_unix_extensions()) {
2783 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2786 /* There should be 12 bytes of capabilities set. */
2787 if (total_data
< 8) {
2788 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2790 client_unix_major
= SVAL(pdata
,0);
2791 client_unix_minor
= SVAL(pdata
,2);
2792 client_unix_cap_low
= IVAL(pdata
,4);
2793 client_unix_cap_high
= IVAL(pdata
,8);
2794 /* Just print these values for now. */
2795 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
2796 cap_low = 0x%x, cap_high = 0x%x\n",
2797 (unsigned int)client_unix_major
,
2798 (unsigned int)client_unix_minor
,
2799 (unsigned int)client_unix_cap_low
,
2800 (unsigned int)client_unix_cap_high
));
2802 /* Here is where we must switch to posix pathname processing... */
2803 if (client_unix_cap_low
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
2804 lp_set_posix_pathnames();
2805 mangle_change_to_posix();
2808 if ((client_unix_cap_low
& CIFS_UNIX_FCNTL_LOCKS_CAP
) &&
2809 !(client_unix_cap_low
& CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP
)) {
2810 /* Client that knows how to do posix locks,
2811 * but not posix open/mkdir operations. Set a
2812 * default type for read/write checks. */
2814 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK
);
2819 case SMB_FS_QUOTA_INFORMATION
:
2821 files_struct
*fsp
= NULL
;
2822 SMB_NTQUOTA_STRUCT quotas
;
2824 ZERO_STRUCT(quotas
);
2827 if ((current_user
.ut
.uid
!= 0)||!CAN_WRITE(conn
)) {
2828 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2829 lp_servicename(SNUM(conn
)),conn
->user
));
2830 return ERROR_DOS(ERRSRV
,ERRaccess
);
2833 /* note: normaly there're 48 bytes,
2834 * but we didn't use the last 6 bytes for now
2837 fsp
= file_fsp(params
,0);
2838 if (!CHECK_NTQUOTA_HANDLE_OK(fsp
,conn
)) {
2839 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2840 return ERROR_NT(NT_STATUS_INVALID_HANDLE
);
2843 if (total_data
< 42) {
2844 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2846 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2849 /* unknown_1 24 NULL bytes in pdata*/
2851 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2852 quotas
.softlim
= (SMB_BIG_UINT
)IVAL(pdata
,24);
2853 #ifdef LARGE_SMB_OFF_T
2854 quotas
.softlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,28)) << 32);
2855 #else /* LARGE_SMB_OFF_T */
2856 if ((IVAL(pdata
,28) != 0)&&
2857 ((quotas
.softlim
!= 0xFFFFFFFF)||
2858 (IVAL(pdata
,28)!=0xFFFFFFFF))) {
2859 /* more than 32 bits? */
2860 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2862 #endif /* LARGE_SMB_OFF_T */
2864 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2865 quotas
.hardlim
= (SMB_BIG_UINT
)IVAL(pdata
,32);
2866 #ifdef LARGE_SMB_OFF_T
2867 quotas
.hardlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,36)) << 32);
2868 #else /* LARGE_SMB_OFF_T */
2869 if ((IVAL(pdata
,36) != 0)&&
2870 ((quotas
.hardlim
!= 0xFFFFFFFF)||
2871 (IVAL(pdata
,36)!=0xFFFFFFFF))) {
2872 /* more than 32 bits? */
2873 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2875 #endif /* LARGE_SMB_OFF_T */
2877 /* quota_flags 2 bytes **/
2878 quotas
.qflags
= SVAL(pdata
,40);
2880 /* unknown_2 6 NULL bytes follow*/
2882 /* now set the quotas */
2883 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
2884 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
2885 return ERROR_DOS(ERRSRV
,ERRerror
);
2891 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2893 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
2898 * sending this reply works fine,
2899 * but I'm not sure it's the same
2900 * like windows do...
2903 outsize
= set_message(outbuf
,10,0,True
);
2908 #if defined(HAVE_POSIX_ACLS)
2909 /****************************************************************************
2910 Utility function to count the number of entries in a POSIX acl.
2911 ****************************************************************************/
2913 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
2915 unsigned int ace_count
= 0;
2916 int entry_id
= SMB_ACL_FIRST_ENTRY
;
2917 SMB_ACL_ENTRY_T entry
;
2919 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
2921 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
2922 entry_id
= SMB_ACL_NEXT_ENTRY
;
2929 /****************************************************************************
2930 Utility function to marshall a POSIX acl into wire format.
2931 ****************************************************************************/
2933 static BOOL
marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
2935 int entry_id
= SMB_ACL_FIRST_ENTRY
;
2936 SMB_ACL_ENTRY_T entry
;
2938 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
2939 SMB_ACL_TAG_T tagtype
;
2940 SMB_ACL_PERMSET_T permset
;
2941 unsigned char perms
= 0;
2942 unsigned int own_grp
;
2945 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
2946 entry_id
= SMB_ACL_NEXT_ENTRY
;
2949 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn
, entry
, &tagtype
) == -1) {
2950 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2954 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn
, entry
, &permset
) == -1) {
2955 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2959 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
2960 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
2961 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
2963 SCVAL(pdata
,1,perms
);
2966 case SMB_ACL_USER_OBJ
:
2967 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
2968 own_grp
= (unsigned int)pst
->st_uid
;
2969 SIVAL(pdata
,2,own_grp
);
2974 uid_t
*puid
= (uid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
2976 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2978 own_grp
= (unsigned int)*puid
;
2979 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)puid
,tagtype
);
2980 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
2981 SIVAL(pdata
,2,own_grp
);
2985 case SMB_ACL_GROUP_OBJ
:
2986 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
2987 own_grp
= (unsigned int)pst
->st_gid
;
2988 SIVAL(pdata
,2,own_grp
);
2993 gid_t
*pgid
= (gid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
2995 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2997 own_grp
= (unsigned int)*pgid
;
2998 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)pgid
,tagtype
);
2999 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
3000 SIVAL(pdata
,2,own_grp
);
3005 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
3006 SIVAL(pdata
,2,0xFFFFFFFF);
3007 SIVAL(pdata
,6,0xFFFFFFFF);
3010 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
3011 SIVAL(pdata
,2,0xFFFFFFFF);
3012 SIVAL(pdata
,6,0xFFFFFFFF);
3015 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
3018 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
3025 /****************************************************************************
3026 Store the FILE_UNIX_BASIC info.
3027 ****************************************************************************/
3029 static char *store_file_unix_basic(connection_struct
*conn
,
3032 const SMB_STRUCT_STAT
*psbuf
)
3034 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
3035 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf
->st_mode
));
3037 SOFF_T(pdata
,0,get_file_size(*psbuf
)); /* File size 64 Bit */
3040 SOFF_T(pdata
,0,get_allocation_size(conn
,fsp
,psbuf
)); /* Number of bytes used on disk - 64 Bit */
3043 put_long_date_timespec(pdata
,get_ctimespec(psbuf
)); /* Change Time 64 Bit */
3044 put_long_date_timespec(pdata
+8,get_atimespec(psbuf
)); /* Last access time 64 Bit */
3045 put_long_date_timespec(pdata
+16,get_mtimespec(psbuf
)); /* Last modification time 64 Bit */
3048 SIVAL(pdata
,0,psbuf
->st_uid
); /* user id for the owner */
3052 SIVAL(pdata
,0,psbuf
->st_gid
); /* group id of owner */
3056 SIVAL(pdata
,0,unix_filetype(psbuf
->st_mode
));
3059 SIVAL(pdata
,0,unix_dev_major(psbuf
->st_rdev
)); /* Major device number if type is device */
3063 SIVAL(pdata
,0,unix_dev_minor(psbuf
->st_rdev
)); /* Minor device number if type is device */
3067 SINO_T_VAL(pdata
,0,(SMB_INO_T
)psbuf
->st_ino
); /* inode number */
3070 SIVAL(pdata
,0, unix_perms_to_wire(psbuf
->st_mode
)); /* Standard UNIX file permissions */
3074 SIVAL(pdata
,0,psbuf
->st_nlink
); /* number of hard links */
3081 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
3082 * the chflags(2) (or equivalent) flags.
3084 * XXX: this really should be behind the VFS interface. To do this, we would
3085 * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
3086 * Each VFS module could then implement it's own mapping as appropriate for the
3087 * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
3089 static const struct {unsigned stat_fflag
; unsigned smb_fflag
;}
3093 { UF_NODUMP
, EXT_DO_NOT_BACKUP
},
3097 { UF_IMMUTABLE
, EXT_IMMUTABLE
},
3101 { UF_APPEND
, EXT_OPEN_APPEND_ONLY
},
3105 { UF_HIDDEN
, EXT_HIDDEN
},
3108 /* Do not remove. We need to guarantee that this array has at least one
3109 * entry to build on HP-UX.
3115 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT
*psbuf
,
3116 uint32
*smb_fflags
, uint32
*smb_fmask
)
3118 #ifdef HAVE_STAT_ST_FLAGS
3121 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
3122 *smb_fmask
|= info2_flags_map
[i
].smb_fflag
;
3123 if (psbuf
->st_flags
& info2_flags_map
[i
].stat_fflag
) {
3124 *smb_fflags
|= info2_flags_map
[i
].smb_fflag
;
3127 #endif /* HAVE_STAT_ST_FLAGS */
3130 static BOOL
map_info2_flags_to_sbuf(const SMB_STRUCT_STAT
*psbuf
,
3131 const uint32 smb_fflags
,
3132 const uint32 smb_fmask
,
3135 #ifdef HAVE_STAT_ST_FLAGS
3136 uint32 max_fmask
= 0;
3139 *stat_fflags
= psbuf
->st_flags
;
3141 /* For each flags requested in smb_fmask, check the state of the
3142 * corresponding flag in smb_fflags and set or clear the matching
3146 for (i
= 0; i
< ARRAY_SIZE(info2_flags_map
); ++i
) {
3147 max_fmask
|= info2_flags_map
[i
].smb_fflag
;
3148 if (smb_fmask
& info2_flags_map
[i
].smb_fflag
) {
3149 if (smb_fflags
& info2_flags_map
[i
].smb_fflag
) {
3150 *stat_fflags
|= info2_flags_map
[i
].stat_fflag
;
3152 *stat_fflags
&= ~info2_flags_map
[i
].stat_fflag
;
3157 /* If smb_fmask is asking to set any bits that are not supported by
3158 * our flag mappings, we should fail.
3160 if ((smb_fmask
& max_fmask
) != smb_fmask
) {
3167 #endif /* HAVE_STAT_ST_FLAGS */
3171 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
3172 * of file flags and birth (create) time.
3174 static char *store_file_unix_basic_info2(connection_struct
*conn
,
3177 const SMB_STRUCT_STAT
*psbuf
)
3179 uint32 file_flags
= 0;
3180 uint32 flags_mask
= 0;
3182 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, psbuf
);
3184 /* Create (birth) time 64 bit */
3185 put_long_date_timespec(pdata
, get_create_timespec(psbuf
, False
));
3188 map_info2_flags_from_sbuf(psbuf
, &file_flags
, &flags_mask
);
3189 SIVAL(pdata
, 0, file_flags
); /* flags */
3190 SIVAL(pdata
, 4, flags_mask
); /* mask */
3196 /****************************************************************************
3197 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
3198 file name or file id).
3199 ****************************************************************************/
3201 static int call_trans2qfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
3202 unsigned int tran_call
,
3203 char **pparams
, int total_params
, char **ppdata
, int total_data
,
3204 unsigned int max_data_bytes
)
3206 char *params
= *pparams
;
3207 char *pdata
= *ppdata
;
3211 SMB_OFF_T file_size
=0;
3212 SMB_BIG_UINT allocation_size
=0;
3213 unsigned int data_size
= 0;
3214 unsigned int param_size
= 2;
3215 SMB_STRUCT_STAT sbuf
;
3216 pstring fname
, dos_fname
;
3221 BOOL delete_pending
= False
;
3223 time_t create_time
, mtime
, atime
;
3224 struct timespec create_time_ts
, mtime_ts
, atime_ts
;
3225 files_struct
*fsp
= NULL
;
3226 TALLOC_CTX
*data_ctx
= NULL
;
3227 struct ea_list
*ea_list
= NULL
;
3228 uint32 access_mask
= 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
3229 char *lock_data
= NULL
;
3232 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3236 if (tran_call
== TRANSACT2_QFILEINFO
) {
3237 if (total_params
< 4) {
3238 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3241 fsp
= file_fsp(params
,0);
3242 info_level
= SVAL(params
,2);
3244 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
3246 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
3247 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
3250 if(fsp
&& (fsp
->fake_file_handle
)) {
3252 * This is actually for the QUOTA_FAKE_FILE --metze
3255 pstrcpy(fname
, fsp
->fsp_name
);
3256 /* We know this name is ok, it's already passed the checks. */
3258 } else if(fsp
&& (fsp
->is_directory
|| fsp
->fh
->fd
== -1)) {
3260 * This is actually a QFILEINFO on a directory
3261 * handle (returned from an NT SMB). NT5.0 seems
3262 * to do this call. JRA.
3264 /* We know this name is ok, it's already passed the checks. */
3265 pstrcpy(fname
, fsp
->fsp_name
);
3267 if (INFO_LEVEL_IS_UNIX(info_level
)) {
3268 /* Always do lstat for UNIX calls. */
3269 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
3270 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
3271 return UNIXERROR(ERRDOS
,ERRbadpath
);
3273 } else if (SMB_VFS_STAT(conn
,fname
,&sbuf
)) {
3274 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
3275 return UNIXERROR(ERRDOS
,ERRbadpath
);
3278 delete_pending
= get_delete_on_close_flag(sbuf
.st_dev
, sbuf
.st_ino
);
3281 * Original code - this is an open file.
3283 CHECK_FSP(fsp
,conn
);
3285 pstrcpy(fname
, fsp
->fsp_name
);
3286 if (SMB_VFS_FSTAT(fsp
,fsp
->fh
->fd
,&sbuf
) != 0) {
3287 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp
->fnum
, strerror(errno
)));
3288 return(UNIXERROR(ERRDOS
,ERRbadfid
));
3290 pos
= fsp
->fh
->position_information
;
3291 delete_pending
= get_delete_on_close_flag(sbuf
.st_dev
, sbuf
.st_ino
);
3292 access_mask
= fsp
->access_mask
;
3295 NTSTATUS status
= NT_STATUS_OK
;
3298 if (total_params
< 7) {
3299 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3302 info_level
= SVAL(params
,0);
3304 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
3306 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
3307 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
3310 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), total_params
- 6, STR_TERMINATE
, &status
);
3311 if (!NT_STATUS_IS_OK(status
)) {
3312 return ERROR_NT(status
);
3315 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, fname
);
3316 if (!NT_STATUS_IS_OK(status
)) {
3317 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
3318 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
3320 return ERROR_NT(status
);
3323 status
= unix_convert(conn
, fname
, False
, NULL
, &sbuf
);
3324 if (!NT_STATUS_IS_OK(status
)) {
3325 return ERROR_NT(status
);
3327 status
= check_name(conn
, fname
);
3328 if (!NT_STATUS_IS_OK(status
)) {
3329 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,nt_errstr(status
)));
3330 return ERROR_NT(status
);
3333 if (INFO_LEVEL_IS_UNIX(info_level
)) {
3334 /* Always do lstat for UNIX calls. */
3335 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
3336 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
3337 return UNIXERROR(ERRDOS
,ERRbadpath
);
3339 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,fname
,&sbuf
) && (info_level
!= SMB_INFO_IS_NAME_VALID
)) {
3340 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
3341 return UNIXERROR(ERRDOS
,ERRbadpath
);
3344 delete_pending
= get_delete_on_close_flag(sbuf
.st_dev
, sbuf
.st_ino
);
3345 if (delete_pending
) {
3346 return ERROR_NT(NT_STATUS_DELETE_PENDING
);
3350 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
3351 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
3354 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
3355 fname
,fsp
? fsp
->fnum
: -1, info_level
,tran_call
,total_data
));
3357 p
= strrchr_m(fname
,'/');
3363 mode
= dos_mode(conn
,fname
,&sbuf
);
3365 mode
= FILE_ATTRIBUTE_NORMAL
;
3367 nlink
= sbuf
.st_nlink
;
3369 if (nlink
&& (mode
&aDIR
)) {
3373 if ((nlink
> 0) && delete_pending
) {
3377 fullpathname
= fname
;
3379 file_size
= get_file_size(sbuf
);
3381 /* Pull out any data sent here before we realloc. */
3382 switch (info_level
) {
3383 case SMB_INFO_QUERY_EAS_FROM_LIST
:
3385 /* Pull any EA list from the data portion. */
3388 if (total_data
< 4) {
3389 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3391 ea_size
= IVAL(pdata
,0);
3393 if (total_data
> 0 && ea_size
!= total_data
) {
3394 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
3395 total_data=%u (should be %u)\n", (unsigned int)total_data
, (unsigned int)IVAL(pdata
,0) ));
3396 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3399 if (!lp_ea_support(SNUM(conn
))) {
3400 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
3403 if ((data_ctx
= talloc_init("ea_list")) == NULL
) {
3404 return ERROR_NT(NT_STATUS_NO_MEMORY
);
3407 /* Pull out the list of names. */
3408 ea_list
= read_ea_name_list(data_ctx
, pdata
+ 4, ea_size
- 4);
3410 talloc_destroy(data_ctx
);
3411 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3416 case SMB_QUERY_POSIX_LOCK
:
3418 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
3419 return ERROR_NT(NT_STATUS_INVALID_HANDLE
);
3422 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
3423 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3426 if ((data_ctx
= talloc_init("lock_request")) == NULL
) {
3427 return ERROR_NT(NT_STATUS_NO_MEMORY
);
3430 /* Copy the lock range data. */
3431 lock_data
= (char *)TALLOC_MEMDUP(
3432 data_ctx
, pdata
, total_data
);
3434 talloc_destroy(data_ctx
);
3435 return ERROR_NT(NT_STATUS_NO_MEMORY
);
3442 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
3443 if (*pparams
== NULL
) {
3444 talloc_destroy(data_ctx
);
3445 return ERROR_NT(NT_STATUS_NO_MEMORY
);
3449 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
3450 *ppdata
= (char *)SMB_REALLOC(*ppdata
, data_size
);
3451 if (*ppdata
== NULL
) {
3452 talloc_destroy(data_ctx
);
3453 return ERROR_NT(NT_STATUS_NO_MEMORY
);
3457 create_time_ts
= get_create_timespec(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
3458 mtime_ts
= get_mtimespec(&sbuf
);
3459 atime_ts
= get_atimespec(&sbuf
);
3461 allocation_size
= get_allocation_size(conn
,fsp
,&sbuf
);
3464 if (!null_timespec(fsp
->pending_modtime
)) {
3465 /* the pending modtime overrides the current modtime */
3466 mtime_ts
= fsp
->pending_modtime
;
3469 /* Do we have this path open ? */
3470 files_struct
*fsp1
= file_find_di_first(sbuf
.st_dev
, sbuf
.st_ino
);
3471 if (fsp1
&& !null_timespec(fsp1
->pending_modtime
)) {
3472 /* the pending modtime overrides the current modtime */
3473 mtime_ts
= fsp1
->pending_modtime
;
3475 if (fsp1
&& fsp1
->initial_allocation_size
) {
3476 allocation_size
= get_allocation_size(conn
, fsp1
, &sbuf
);
3480 if (lp_dos_filetime_resolution(SNUM(conn
))) {
3481 dos_filetime_timespec(&create_time_ts
);
3482 dos_filetime_timespec(&mtime_ts
);
3483 dos_filetime_timespec(&atime_ts
);
3486 create_time
= convert_timespec_to_time_t(create_time_ts
);
3487 mtime
= convert_timespec_to_time_t(mtime_ts
);
3488 atime
= convert_timespec_to_time_t(atime_ts
);
3490 /* NT expects the name to be in an exact form of the *full*
3491 filename. See the trans2 torture test */
3492 if (strequal(base_name
,".")) {
3493 pstrcpy(dos_fname
, "\\");
3495 pstr_sprintf(dos_fname
, "\\%s", fname
);
3496 string_replace(dos_fname
, '/', '\\');
3499 switch (info_level
) {
3500 case SMB_INFO_STANDARD
:
3501 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
3503 srv_put_dos_date2(pdata
,l1_fdateCreation
,create_time
);
3504 srv_put_dos_date2(pdata
,l1_fdateLastAccess
,atime
);
3505 srv_put_dos_date2(pdata
,l1_fdateLastWrite
,mtime
); /* write time */
3506 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
3507 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
3508 SSVAL(pdata
,l1_attrFile
,mode
);
3511 case SMB_INFO_QUERY_EA_SIZE
:
3513 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
3514 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
3516 srv_put_dos_date2(pdata
,0,create_time
);
3517 srv_put_dos_date2(pdata
,4,atime
);
3518 srv_put_dos_date2(pdata
,8,mtime
); /* write time */
3519 SIVAL(pdata
,12,(uint32
)file_size
);
3520 SIVAL(pdata
,16,(uint32
)allocation_size
);
3521 SSVAL(pdata
,20,mode
);
3522 SIVAL(pdata
,22,ea_size
);
3526 case SMB_INFO_IS_NAME_VALID
:
3527 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
3528 if (tran_call
== TRANSACT2_QFILEINFO
) {
3529 /* os/2 needs this ? really ?*/
3530 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
3536 case SMB_INFO_QUERY_EAS_FROM_LIST
:
3538 size_t total_ea_len
= 0;
3539 struct ea_list
*ea_file_list
= NULL
;
3541 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
3543 ea_file_list
= get_ea_list_from_file(data_ctx
, conn
, fsp
, fname
, &total_ea_len
);
3544 ea_list
= ea_list_union(ea_list
, ea_file_list
, &total_ea_len
);
3546 if (!ea_list
|| (total_ea_len
> data_size
)) {
3547 talloc_destroy(data_ctx
);
3549 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
3553 data_size
= fill_ea_buffer(data_ctx
, pdata
, data_size
, conn
, ea_list
);
3554 talloc_destroy(data_ctx
);
3558 case SMB_INFO_QUERY_ALL_EAS
:
3560 /* We have data_size bytes to put EA's into. */
3561 size_t total_ea_len
= 0;
3563 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
3565 data_ctx
= talloc_init("ea_ctx");
3567 return ERROR_NT(NT_STATUS_NO_MEMORY
);
3570 ea_list
= get_ea_list_from_file(data_ctx
, conn
, fsp
, fname
, &total_ea_len
);
3571 if (!ea_list
|| (total_ea_len
> data_size
)) {
3572 talloc_destroy(data_ctx
);
3574 SIVAL(pdata
,0,4); /* EA List Length must be set to 4 if no EA's. */
3578 data_size
= fill_ea_buffer(data_ctx
, pdata
, data_size
, conn
, ea_list
);
3579 talloc_destroy(data_ctx
);
3583 case SMB_FILE_BASIC_INFORMATION
:
3584 case SMB_QUERY_FILE_BASIC_INFO
:
3586 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
3587 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
3588 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
3590 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
3594 put_long_date_timespec(pdata
,create_time_ts
);
3595 put_long_date_timespec(pdata
+8,atime_ts
);
3596 put_long_date_timespec(pdata
+16,mtime_ts
); /* write time */
3597 put_long_date_timespec(pdata
+24,mtime_ts
); /* change time */
3598 SIVAL(pdata
,32,mode
);
3600 DEBUG(5,("SMB_QFBI - "));
3601 DEBUG(5,("create: %s ", ctime(&create_time
)));
3602 DEBUG(5,("access: %s ", ctime(&atime
)));
3603 DEBUG(5,("write: %s ", ctime(&mtime
)));
3604 DEBUG(5,("change: %s ", ctime(&mtime
)));
3605 DEBUG(5,("mode: %x\n", mode
));
3608 case SMB_FILE_STANDARD_INFORMATION
:
3609 case SMB_QUERY_FILE_STANDARD_INFO
:
3611 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
3613 SOFF_T(pdata
,0,allocation_size
);
3614 SOFF_T(pdata
,8,file_size
);
3615 SIVAL(pdata
,16,nlink
);
3616 SCVAL(pdata
,20,delete_pending
?1:0);
3617 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
3618 SSVAL(pdata
,22,0); /* Padding. */
3621 case SMB_FILE_EA_INFORMATION
:
3622 case SMB_QUERY_FILE_EA_INFO
:
3624 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
3625 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
3627 SIVAL(pdata
,0,ea_size
);
3631 /* Get the 8.3 name - used if NT SMB was negotiated. */
3632 case SMB_QUERY_FILE_ALT_NAME_INFO
:
3633 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
3637 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
3638 pstrcpy(short_name
,base_name
);
3639 /* Mangle if not already 8.3 */
3640 if(!mangle_is_8_3(short_name
, True
, conn
->params
)) {
3641 mangle_map(short_name
,True
,True
,conn
->params
);
3643 len
= srvstr_push(outbuf
, pdata
+4, short_name
, max_data_bytes
- 4, STR_UNICODE
);
3644 data_size
= 4 + len
;
3649 case SMB_QUERY_FILE_NAME_INFO
:
3651 this must be *exactly* right for ACLs on mapped drives to work
3653 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, max_data_bytes
- 4, STR_UNICODE
);
3654 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
3655 data_size
= 4 + len
;
3659 case SMB_FILE_ALLOCATION_INFORMATION
:
3660 case SMB_QUERY_FILE_ALLOCATION_INFO
:
3661 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
3663 SOFF_T(pdata
,0,allocation_size
);
3666 case SMB_FILE_END_OF_FILE_INFORMATION
:
3667 case SMB_QUERY_FILE_END_OF_FILEINFO
:
3668 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
3670 SOFF_T(pdata
,0,file_size
);
3673 case SMB_QUERY_FILE_ALL_INFO
:
3674 case SMB_FILE_ALL_INFORMATION
:
3676 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
3677 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
3678 put_long_date_timespec(pdata
,create_time_ts
);
3679 put_long_date_timespec(pdata
+8,atime_ts
);
3680 put_long_date_timespec(pdata
+16,mtime_ts
); /* write time */
3681 put_long_date_timespec(pdata
+24,mtime_ts
); /* change time */
3682 SIVAL(pdata
,32,mode
);
3683 SIVAL(pdata
,36,0); /* padding. */
3685 SOFF_T(pdata
,0,allocation_size
);
3686 SOFF_T(pdata
,8,file_size
);
3687 SIVAL(pdata
,16,nlink
);
3688 SCVAL(pdata
,20,delete_pending
);
3689 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
3692 SIVAL(pdata
,0,ea_size
);
3693 pdata
+= 4; /* EA info */
3694 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, max_data_bytes
- (pdata
+4 - *ppdata
), STR_UNICODE
);
3697 data_size
= PTR_DIFF(pdata
,(*ppdata
));
3700 case SMB_FILE_INTERNAL_INFORMATION
:
3701 /* This should be an index number - looks like
3704 I think this causes us to fail the IFSKIT
3705 BasicFileInformationTest. -tpot */
3707 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3708 SIVAL(pdata
,0,sbuf
.st_ino
); /* FileIndexLow */
3709 SIVAL(pdata
,4,sbuf
.st_dev
); /* FileIndexHigh */
3713 case SMB_FILE_ACCESS_INFORMATION
:
3714 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3715 SIVAL(pdata
,0,access_mask
);
3719 case SMB_FILE_NAME_INFORMATION
:
3720 /* Pathname with leading '\'. */
3723 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,(size_t)max_data_bytes
,False
);
3724 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3725 SIVAL(pdata
,0,byte_len
);
3726 data_size
= 4 + byte_len
;
3730 case SMB_FILE_DISPOSITION_INFORMATION
:
3731 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3733 SCVAL(pdata
,0,delete_pending
);
3736 case SMB_FILE_POSITION_INFORMATION
:
3737 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3739 SOFF_T(pdata
,0,pos
);
3742 case SMB_FILE_MODE_INFORMATION
:
3743 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3744 SIVAL(pdata
,0,mode
);
3748 case SMB_FILE_ALIGNMENT_INFORMATION
:
3749 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3750 SIVAL(pdata
,0,0); /* No alignment needed. */
3756 * NT4 server just returns "invalid query" to this - if we try to answer
3757 * it then NTws gets a BSOD! (tridge).
3758 * W2K seems to want this. JRA.
3760 case SMB_QUERY_FILE_STREAM_INFO
:
3762 case SMB_FILE_STREAM_INFORMATION
:
3763 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
3767 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", (size_t)0xE, False
);
3768 SIVAL(pdata
,0,0); /* ??? */
3769 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
3770 SOFF_T(pdata
,8,file_size
);
3771 SOFF_T(pdata
,16,allocation_size
);
3772 data_size
= 24 + byte_len
;
3776 case SMB_QUERY_COMPRESSION_INFO
:
3777 case SMB_FILE_COMPRESSION_INFORMATION
:
3778 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3779 SOFF_T(pdata
,0,file_size
);
3780 SIVAL(pdata
,8,0); /* ??? */
3781 SIVAL(pdata
,12,0); /* ??? */
3785 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
3786 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3787 put_long_date_timespec(pdata
,create_time_ts
);
3788 put_long_date_timespec(pdata
+8,atime_ts
);
3789 put_long_date_timespec(pdata
+16,mtime_ts
); /* write time */
3790 put_long_date_timespec(pdata
+24,mtime_ts
); /* change time */
3791 SOFF_T(pdata
,32,allocation_size
);
3792 SOFF_T(pdata
,40,file_size
);
3793 SIVAL(pdata
,48,mode
);
3794 SIVAL(pdata
,52,0); /* ??? */
3798 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
3799 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3800 SIVAL(pdata
,0,mode
);
3806 * CIFS UNIX Extensions.
3809 case SMB_QUERY_FILE_UNIX_BASIC
:
3811 pdata
= store_file_unix_basic(conn
, pdata
, fsp
, &sbuf
);
3812 data_size
= PTR_DIFF(pdata
,(*ppdata
));
3816 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
3818 for (i
=0; i
<100; i
++)
3819 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
3825 case SMB_QUERY_FILE_UNIX_INFO2
:
3827 pdata
= store_file_unix_basic_info2(conn
, pdata
, fsp
, &sbuf
);
3828 data_size
= PTR_DIFF(pdata
,(*ppdata
));
3832 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
3834 for (i
=0; i
<100; i
++)
3835 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
3841 case SMB_QUERY_FILE_UNIX_LINK
:
3845 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
3847 if(!S_ISLNK(sbuf
.st_mode
))
3848 return(UNIXERROR(ERRSRV
,ERRbadlink
));
3850 return(UNIXERROR(ERRDOS
,ERRbadlink
));
3852 len
= SMB_VFS_READLINK(conn
,fullpathname
, buffer
, sizeof(pstring
)-1); /* read link */
3854 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3856 len
= srvstr_push(outbuf
, pdata
, buffer
, max_data_bytes
, STR_TERMINATE
);
3858 data_size
= PTR_DIFF(pdata
,(*ppdata
));
3863 #if defined(HAVE_POSIX_ACLS)
3864 case SMB_QUERY_POSIX_ACL
:
3866 SMB_ACL_T file_acl
= NULL
;
3867 SMB_ACL_T def_acl
= NULL
;
3868 uint16 num_file_acls
= 0;
3869 uint16 num_def_acls
= 0;
3871 if (fsp
&& !fsp
->is_directory
&& (fsp
->fh
->fd
!= -1)) {
3872 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
, fsp
->fh
->fd
);
3874 file_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fname
, SMB_ACL_TYPE_ACCESS
);
3877 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
3878 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
3880 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED
);
3883 if (S_ISDIR(sbuf
.st_mode
)) {
3884 if (fsp
&& fsp
->is_directory
) {
3885 def_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fsp
->fsp_name
, SMB_ACL_TYPE_DEFAULT
);
3887 def_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fname
, SMB_ACL_TYPE_DEFAULT
);
3889 def_acl
= free_empty_sys_acl(conn
, def_acl
);
3892 num_file_acls
= count_acl_entries(conn
, file_acl
);
3893 num_def_acls
= count_acl_entries(conn
, def_acl
);
3895 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
3896 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
3898 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
3899 SMB_POSIX_ACL_HEADER_SIZE
) ));
3901 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
3904 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
3906 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL
);
3909 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
3910 SSVAL(pdata
,2,num_file_acls
);
3911 SSVAL(pdata
,4,num_def_acls
);
3912 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, &sbuf
, file_acl
)) {
3914 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
3917 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
3919 return ERROR_NT(NT_STATUS_INTERNAL_ERROR
);
3921 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), &sbuf
, def_acl
)) {
3923 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
3926 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
3928 return ERROR_NT(NT_STATUS_INTERNAL_ERROR
);
3932 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
3935 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
3937 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
3943 case SMB_QUERY_POSIX_LOCK
:
3945 NTSTATUS status
= NT_STATUS_INVALID_LEVEL
;
3947 SMB_BIG_UINT offset
;
3949 enum brl_type lock_type
;
3951 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
3952 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3955 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
3956 case POSIX_LOCK_TYPE_READ
:
3957 lock_type
= READ_LOCK
;
3959 case POSIX_LOCK_TYPE_WRITE
:
3960 lock_type
= WRITE_LOCK
;
3962 case POSIX_LOCK_TYPE_UNLOCK
:
3964 /* There's no point in asking for an unlock... */
3965 talloc_destroy(data_ctx
);
3966 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3969 lock_pid
= IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
3970 #if defined(HAVE_LONGLONG)
3971 offset
= (((SMB_BIG_UINT
) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
3972 ((SMB_BIG_UINT
) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
3973 count
= (((SMB_BIG_UINT
) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
3974 ((SMB_BIG_UINT
) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
3975 #else /* HAVE_LONGLONG */
3976 offset
= (SMB_BIG_UINT
)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
3977 count
= (SMB_BIG_UINT
)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
3978 #endif /* HAVE_LONGLONG */
3980 status
= query_lock(fsp
,
3987 if (ERROR_WAS_LOCK_DENIED(status
)) {
3988 /* Here we need to report who has it locked... */
3989 data_size
= POSIX_LOCK_DATA_SIZE
;
3991 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, lock_type
);
3992 SSVAL(pdata
, POSIX_LOCK_FLAGS_OFFSET
, 0);
3993 SIVAL(pdata
, POSIX_LOCK_PID_OFFSET
, lock_pid
);
3994 #if defined(HAVE_LONGLONG)
3995 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, (uint32
)(offset
& 0xFFFFFFFF));
3996 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
+ 4, (uint32
)((offset
>> 32) & 0xFFFFFFFF));
3997 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, (uint32
)(count
& 0xFFFFFFFF));
3998 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
+ 4, (uint32
)((count
>> 32) & 0xFFFFFFFF));
3999 #else /* HAVE_LONGLONG */
4000 SIVAL(pdata
, POSIX_LOCK_START_OFFSET
, offset
);
4001 SIVAL(pdata
, POSIX_LOCK_LEN_OFFSET
, count
);
4002 #endif /* HAVE_LONGLONG */
4004 } else if (NT_STATUS_IS_OK(status
)) {
4005 /* For success we just return a copy of what we sent
4006 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
4007 data_size
= POSIX_LOCK_DATA_SIZE
;
4008 memcpy(pdata
, lock_data
, POSIX_LOCK_DATA_SIZE
);
4009 SSVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
, POSIX_LOCK_TYPE_UNLOCK
);
4011 return ERROR_NT(status
);
4017 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
4020 send_trans2_replies(outbuf
, bufsize
, params
, param_size
, *ppdata
, data_size
, max_data_bytes
);
4025 /****************************************************************************
4026 Set a hard link (called by UNIX extensions and by NT rename with HARD link
4028 ****************************************************************************/
4030 NTSTATUS
hardlink_internals(connection_struct
*conn
, pstring oldname
, pstring newname
)
4032 SMB_STRUCT_STAT sbuf1
, sbuf2
;
4033 pstring last_component_oldname
;
4034 pstring last_component_newname
;
4035 NTSTATUS status
= NT_STATUS_OK
;
4040 status
= unix_convert(conn
, oldname
, False
, last_component_oldname
, &sbuf1
);
4041 if (!NT_STATUS_IS_OK(status
)) {
4045 status
= check_name(conn
, oldname
);
4046 if (!NT_STATUS_IS_OK(status
)) {
4050 /* source must already exist. */
4051 if (!VALID_STAT(sbuf1
)) {
4052 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4055 status
= unix_convert(conn
, newname
, False
, last_component_newname
, &sbuf2
);
4056 if (!NT_STATUS_IS_OK(status
)) {
4060 status
= check_name(conn
, newname
);
4061 if (!NT_STATUS_IS_OK(status
)) {
4065 /* Disallow if newname already exists. */
4066 if (VALID_STAT(sbuf2
)) {
4067 return NT_STATUS_OBJECT_NAME_COLLISION
;
4070 /* No links from a directory. */
4071 if (S_ISDIR(sbuf1
.st_mode
)) {
4072 return NT_STATUS_FILE_IS_A_DIRECTORY
;
4075 /* Ensure this is within the share. */
4076 status
= reduce_name(conn
, oldname
);
4077 if (!NT_STATUS_IS_OK(status
)) {
4081 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname
, oldname
));
4083 if (SMB_VFS_LINK(conn
,oldname
,newname
) != 0) {
4084 status
= map_nt_error_from_unix(errno
);
4085 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
4086 nt_errstr(status
), newname
, oldname
));
4092 /****************************************************************************
4093 Deal with setting the time from any of the setfilepathinfo functions.
4094 ****************************************************************************/
4096 static NTSTATUS
smb_set_file_time(connection_struct
*conn
,
4099 const SMB_STRUCT_STAT
*psbuf
,
4100 struct timespec ts
[2])
4103 FILE_NOTIFY_CHANGE_LAST_ACCESS
4104 |FILE_NOTIFY_CHANGE_LAST_WRITE
;
4107 if (!VALID_STAT(*psbuf
)) {
4108 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4111 /* get some defaults (no modifications) if any info is zero or -1. */
4112 if (null_timespec(ts
[0])) {
4113 ts
[0] = get_atimespec(psbuf
);
4114 action
&= ~FILE_NOTIFY_CHANGE_LAST_ACCESS
;
4117 if (null_timespec(ts
[1])) {
4118 ts
[1] = get_mtimespec(psbuf
);
4119 action
&= ~FILE_NOTIFY_CHANGE_LAST_WRITE
;
4122 DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts
[0])) ));
4123 DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts
[1])) ));
4126 * Try and set the times of this file if
4127 * they are different from the current values.
4131 struct timespec mts
= get_mtimespec(psbuf
);
4132 struct timespec ats
= get_atimespec(psbuf
);
4133 if ((timespec_compare(&ts
[0], &ats
) == 0) && (timespec_compare(&ts
[1], &mts
) == 0)) {
4134 return NT_STATUS_OK
;
4140 * This was a setfileinfo on an open file.
4141 * NT does this a lot. We also need to
4142 * set the time here, as it can be read by
4143 * FindFirst/FindNext and with the patch for bug #2045
4144 * in smbd/fileio.c it ensures that this timestamp is
4145 * kept sticky even after a write. We save the request
4146 * away and will set it on file close and after a write. JRA.
4149 if (!null_timespec(ts
[1])) {
4150 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
4151 time_to_asc(convert_timespec_to_time_t(ts
[1])) ));
4152 fsp_set_pending_modtime(fsp
, ts
[1]);
4156 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
4158 if(file_ntimes(conn
, fname
, ts
)!=0) {
4159 return map_nt_error_from_unix(errno
);
4162 notify_fname(conn
, NOTIFY_ACTION_MODIFIED
, action
, fname
);
4164 return NT_STATUS_OK
;
4167 /****************************************************************************
4168 Deal with setting the dosmode from any of the setfilepathinfo functions.
4169 ****************************************************************************/
4171 static NTSTATUS
smb_set_file_dosmode(connection_struct
*conn
,
4173 SMB_STRUCT_STAT
*psbuf
,
4176 if (!VALID_STAT(*psbuf
)) {
4177 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4181 if (S_ISDIR(psbuf
->st_mode
)) {
4188 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode
));
4190 /* check the mode isn't different, before changing it */
4191 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, fname
, psbuf
))) {
4193 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode 0x%x\n",
4194 fname
, (unsigned int)dosmode
));
4196 if(file_set_dosmode(conn
, fname
, dosmode
, psbuf
, False
)) {
4197 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of %s failed (%s)\n",
4198 fname
, strerror(errno
)));
4199 return map_nt_error_from_unix(errno
);
4202 return NT_STATUS_OK
;
4205 /****************************************************************************
4206 Deal with setting the size from any of the setfilepathinfo functions.
4207 ****************************************************************************/
4209 static NTSTATUS
smb_set_file_size(connection_struct
*conn
,
4212 SMB_STRUCT_STAT
*psbuf
,
4215 NTSTATUS status
= NT_STATUS_OK
;
4216 files_struct
*new_fsp
= NULL
;
4218 if (!VALID_STAT(*psbuf
)) {
4219 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4222 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size
));
4224 if (size
== get_file_size(*psbuf
)) {
4225 return NT_STATUS_OK
;
4228 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
4229 fname
, (double)size
));
4231 if (fsp
&& fsp
->fh
->fd
!= -1) {
4232 /* Handle based call. */
4233 if (vfs_set_filelen(fsp
, size
) == -1) {
4234 return map_nt_error_from_unix(errno
);
4236 return NT_STATUS_OK
;
4239 status
= open_file_ntcreate(conn
, fname
, psbuf
,
4241 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4244 FILE_ATTRIBUTE_NORMAL
,
4245 FORCE_OPLOCK_BREAK_TO_NONE
,
4248 if (!NT_STATUS_IS_OK(status
)) {
4249 /* NB. We check for open_was_deferred in the caller. */
4253 if (vfs_set_filelen(new_fsp
, size
) == -1) {
4254 status
= map_nt_error_from_unix(errno
);
4255 close_file(new_fsp
,NORMAL_CLOSE
);
4259 close_file(new_fsp
,NORMAL_CLOSE
);
4260 return NT_STATUS_OK
;
4263 /****************************************************************************
4264 Deal with SMB_INFO_SET_EA.
4265 ****************************************************************************/
4267 static NTSTATUS
smb_info_set_ea(connection_struct
*conn
,
4273 struct ea_list
*ea_list
= NULL
;
4274 TALLOC_CTX
*ctx
= NULL
;
4275 NTSTATUS status
= NT_STATUS_OK
;
4277 if (total_data
< 10) {
4279 /* OS/2 workplace shell seems to send SET_EA requests of "null"
4280 length. They seem to have no effect. Bug #3212. JRA */
4282 if ((total_data
== 4) && (IVAL(pdata
,0) == 4)) {
4283 /* We're done. We only get EA info in this call. */
4284 return NT_STATUS_OK
;
4287 return NT_STATUS_INVALID_PARAMETER
;
4290 if (IVAL(pdata
,0) > total_data
) {
4291 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
4292 IVAL(pdata
,0), (unsigned int)total_data
));
4293 return NT_STATUS_INVALID_PARAMETER
;
4296 ctx
= talloc_init("SMB_INFO_SET_EA");
4298 return NT_STATUS_NO_MEMORY
;
4300 ea_list
= read_ea_list(ctx
, pdata
+ 4, total_data
- 4);
4302 talloc_destroy(ctx
);
4303 return NT_STATUS_INVALID_PARAMETER
;
4305 status
= set_ea(conn
, fsp
, fname
, ea_list
);
4306 talloc_destroy(ctx
);
4311 /****************************************************************************
4312 Deal with SMB_SET_FILE_DISPOSITION_INFO.
4313 ****************************************************************************/
4315 static NTSTATUS
smb_set_file_disposition_info(connection_struct
*conn
,
4320 SMB_STRUCT_STAT
*psbuf
)
4322 NTSTATUS status
= NT_STATUS_OK
;
4323 BOOL delete_on_close
;
4326 if (total_data
< 1) {
4327 return NT_STATUS_INVALID_PARAMETER
;
4331 return NT_STATUS_INVALID_HANDLE
;
4334 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
4335 dosmode
= dos_mode(conn
, fname
, psbuf
);
4337 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
4338 "delete_on_close = %u\n",
4340 (unsigned int)dosmode
,
4341 (unsigned int)delete_on_close
));
4343 status
= can_set_delete_on_close(fsp
, delete_on_close
, dosmode
);
4345 if (!NT_STATUS_IS_OK(status
)) {
4349 /* The set is across all open files on this dev/inode pair. */
4350 if (!set_delete_on_close(fsp
, delete_on_close
, ¤t_user
.ut
)) {
4351 return NT_STATUS_ACCESS_DENIED
;
4353 return NT_STATUS_OK
;
4356 /****************************************************************************
4357 Deal with SMB_FILE_POSITION_INFORMATION.
4358 ****************************************************************************/
4360 static NTSTATUS
smb_file_position_information(connection_struct
*conn
,
4365 SMB_BIG_UINT position_information
;
4367 if (total_data
< 8) {
4368 return NT_STATUS_INVALID_PARAMETER
;
4372 /* Ignore on pathname based set. */
4373 return NT_STATUS_OK
;
4376 position_information
= (SMB_BIG_UINT
)IVAL(pdata
,0);
4377 #ifdef LARGE_SMB_OFF_T
4378 position_information
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
4379 #else /* LARGE_SMB_OFF_T */
4380 if (IVAL(pdata
,4) != 0) {
4381 /* more than 32 bits? */
4382 return NT_STATUS_INVALID_PARAMETER
;
4384 #endif /* LARGE_SMB_OFF_T */
4386 DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n",
4387 fsp
->fsp_name
, (double)position_information
));
4388 fsp
->fh
->position_information
= position_information
;
4389 return NT_STATUS_OK
;
4392 /****************************************************************************
4393 Deal with SMB_FILE_MODE_INFORMATION.
4394 ****************************************************************************/
4396 static NTSTATUS
smb_file_mode_information(connection_struct
*conn
,
4402 if (total_data
< 4) {
4403 return NT_STATUS_INVALID_PARAMETER
;
4405 mode
= IVAL(pdata
,0);
4406 if (mode
!= 0 && mode
!= 2 && mode
!= 4 && mode
!= 6) {
4407 return NT_STATUS_INVALID_PARAMETER
;
4409 return NT_STATUS_OK
;
4412 /****************************************************************************
4413 Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
4414 ****************************************************************************/
4416 static NTSTATUS
smb_set_file_unix_link(connection_struct
*conn
,
4422 pstring link_target
;
4423 const char *newname
= fname
;
4424 NTSTATUS status
= NT_STATUS_OK
;
4426 /* Set a symbolic link. */
4427 /* Don't allow this if follow links is false. */
4429 if (total_data
== 0) {
4430 return NT_STATUS_INVALID_PARAMETER
;
4433 if (!lp_symlinks(SNUM(conn
))) {
4434 return NT_STATUS_ACCESS_DENIED
;
4437 srvstr_pull(inbuf
, link_target
, pdata
, sizeof(link_target
), total_data
, STR_TERMINATE
);
4439 /* !widelinks forces the target path to be within the share. */
4440 /* This means we can interpret the target as a pathname. */
4441 if (!lp_widelinks(SNUM(conn
))) {
4443 char *last_dirp
= NULL
;
4445 if (*link_target
== '/') {
4446 /* No absolute paths allowed. */
4447 return NT_STATUS_ACCESS_DENIED
;
4449 pstrcpy(rel_name
, newname
);
4450 last_dirp
= strrchr_m(rel_name
, '/');
4452 last_dirp
[1] = '\0';
4454 pstrcpy(rel_name
, "./");
4456 pstrcat(rel_name
, link_target
);
4458 status
= check_name(conn
, rel_name
);
4459 if (!NT_STATUS_IS_OK(status
)) {
4464 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
4465 newname
, link_target
));
4467 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0) {
4468 return map_nt_error_from_unix(errno
);
4471 return NT_STATUS_OK
;
4474 /****************************************************************************
4475 Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
4476 ****************************************************************************/
4478 static NTSTATUS
smb_set_file_unix_hlink(connection_struct
*conn
,
4486 NTSTATUS status
= NT_STATUS_OK
;
4488 /* Set a hard link. */
4489 if (total_data
== 0) {
4490 return NT_STATUS_INVALID_PARAMETER
;
4493 srvstr_get_path(inbuf
, oldname
, pdata
, sizeof(oldname
), total_data
, STR_TERMINATE
, &status
);
4494 if (!NT_STATUS_IS_OK(status
)) {
4498 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, oldname
);
4499 if (!NT_STATUS_IS_OK(status
)) {
4503 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
4506 return hardlink_internals(conn
, oldname
, fname
);
4509 /****************************************************************************
4510 Deal with SMB_FILE_RENAME_INFORMATION.
4511 ****************************************************************************/
4513 static NTSTATUS
smb_file_rename_information(connection_struct
*conn
,
4522 /* uint32 root_fid; */ /* Not used */
4526 BOOL dest_has_wcard
= False
;
4527 NTSTATUS status
= NT_STATUS_OK
;
4530 if (total_data
< 13) {
4531 return NT_STATUS_INVALID_PARAMETER
;
4534 overwrite
= (CVAL(pdata
,0) ? True
: False
);
4535 /* root_fid = IVAL(pdata,4); */
4536 len
= IVAL(pdata
,8);
4538 if (len
> (total_data
- 12) || (len
== 0)) {
4539 return NT_STATUS_INVALID_PARAMETER
;
4542 srvstr_get_path_wcard(inbuf
, newname
, &pdata
[12], sizeof(newname
), len
, 0, &status
, &dest_has_wcard
);
4543 if (!NT_STATUS_IS_OK(status
)) {
4547 status
= resolve_dfspath_wcard(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, newname
, &dest_has_wcard
);
4548 if (!NT_STATUS_IS_OK(status
)) {
4552 /* Check the new name has no '/' characters. */
4553 if (strchr_m(newname
, '/')) {
4554 return NT_STATUS_NOT_SUPPORTED
;
4557 /* Create the base directory. */
4558 pstrcpy(base_name
, fname
);
4559 p
= strrchr_m(base_name
, '/');
4563 pstrcpy(base_name
, "./");
4565 /* Append the new name. */
4566 pstrcat(base_name
, newname
);
4569 DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
4570 fsp
->fnum
, fsp
->fsp_name
, base_name
));
4571 status
= rename_internals_fsp(conn
, fsp
, base_name
, 0, overwrite
);
4573 DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4575 status
= rename_internals(conn
, fname
, base_name
, 0, overwrite
, False
, dest_has_wcard
);
4581 /****************************************************************************
4582 Deal with SMB_SET_POSIX_ACL.
4583 ****************************************************************************/
4585 #if defined(HAVE_POSIX_ACLS)
4586 static NTSTATUS
smb_set_posix_acl(connection_struct
*conn
,
4591 SMB_STRUCT_STAT
*psbuf
)
4593 uint16 posix_acl_version
;
4594 uint16 num_file_acls
;
4595 uint16 num_def_acls
;
4596 BOOL valid_file_acls
= True
;
4597 BOOL valid_def_acls
= True
;
4599 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
4600 return NT_STATUS_INVALID_PARAMETER
;
4602 posix_acl_version
= SVAL(pdata
,0);
4603 num_file_acls
= SVAL(pdata
,2);
4604 num_def_acls
= SVAL(pdata
,4);
4606 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
4607 valid_file_acls
= False
;
4611 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
4612 valid_def_acls
= False
;
4616 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
4617 return NT_STATUS_INVALID_PARAMETER
;
4620 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
4621 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
4622 return NT_STATUS_INVALID_PARAMETER
;
4625 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
4626 fname
? fname
: fsp
->fsp_name
,
4627 (unsigned int)num_file_acls
,
4628 (unsigned int)num_def_acls
));
4630 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
, fname
, num_file_acls
,
4631 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
4632 return map_nt_error_from_unix(errno
);
4635 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
, fname
, psbuf
, num_def_acls
,
4636 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
4637 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
4638 return map_nt_error_from_unix(errno
);
4640 return NT_STATUS_OK
;
4644 /****************************************************************************
4645 Deal with SMB_SET_POSIX_LOCK.
4646 ****************************************************************************/
4648 static NTSTATUS
smb_set_posix_lock(connection_struct
*conn
,
4656 SMB_BIG_UINT offset
;
4658 BOOL blocking_lock
= False
;
4659 enum brl_type lock_type
;
4660 NTSTATUS status
= NT_STATUS_OK
;
4662 if (fsp
== NULL
|| fsp
->fh
->fd
== -1) {
4663 return NT_STATUS_INVALID_HANDLE
;
4666 if (total_data
!= POSIX_LOCK_DATA_SIZE
) {
4667 return NT_STATUS_INVALID_PARAMETER
;
4670 switch (SVAL(pdata
, POSIX_LOCK_TYPE_OFFSET
)) {
4671 case POSIX_LOCK_TYPE_READ
:
4672 lock_type
= READ_LOCK
;
4674 case POSIX_LOCK_TYPE_WRITE
:
4675 /* Return the right POSIX-mappable error code for files opened read-only. */
4676 if (!fsp
->can_write
) {
4677 return NT_STATUS_INVALID_HANDLE
;
4679 lock_type
= WRITE_LOCK
;
4681 case POSIX_LOCK_TYPE_UNLOCK
:
4682 lock_type
= UNLOCK_LOCK
;
4685 return NT_STATUS_INVALID_PARAMETER
;
4688 if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_NOWAIT
) {
4689 blocking_lock
= False
;
4690 } else if (SVAL(pdata
,POSIX_LOCK_FLAGS_OFFSET
) == POSIX_LOCK_FLAG_WAIT
) {
4691 blocking_lock
= True
;
4693 return NT_STATUS_INVALID_PARAMETER
;
4696 if (!lp_blocking_locks(SNUM(conn
))) {
4697 blocking_lock
= False
;
4700 lock_pid
= IVAL(pdata
, POSIX_LOCK_PID_OFFSET
);
4701 #if defined(HAVE_LONGLONG)
4702 offset
= (((SMB_BIG_UINT
) IVAL(pdata
,(POSIX_LOCK_START_OFFSET
+4))) << 32) |
4703 ((SMB_BIG_UINT
) IVAL(pdata
,POSIX_LOCK_START_OFFSET
));
4704 count
= (((SMB_BIG_UINT
) IVAL(pdata
,(POSIX_LOCK_LEN_OFFSET
+4))) << 32) |
4705 ((SMB_BIG_UINT
) IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
));
4706 #else /* HAVE_LONGLONG */
4707 offset
= (SMB_BIG_UINT
)IVAL(pdata
,POSIX_LOCK_START_OFFSET
);
4708 count
= (SMB_BIG_UINT
)IVAL(pdata
,POSIX_LOCK_LEN_OFFSET
);
4709 #endif /* HAVE_LONGLONG */
4711 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
4712 "lock_pid = %u, count = %.0f, offset = %.0f\n",
4714 (unsigned int)lock_type
,
4715 (unsigned int)lock_pid
,
4719 if (lock_type
== UNLOCK_LOCK
) {
4720 status
= do_unlock(fsp
,
4726 uint32 block_smbpid
;
4728 struct byte_range_lock
*br_lck
= do_lock(fsp
,
4738 if (br_lck
&& blocking_lock
&& ERROR_WAS_LOCK_DENIED(status
)) {
4740 * A blocking lock was requested. Package up
4741 * this smb into a queued request and push it
4742 * onto the blocking lock queue.
4744 if(push_blocking_lock_request(br_lck
,
4747 -1, /* infinite timeout. */
4755 TALLOC_FREE(br_lck
);
4759 TALLOC_FREE(br_lck
);
4765 /****************************************************************************
4766 Deal with SMB_INFO_STANDARD.
4767 ****************************************************************************/
4769 static NTSTATUS
smb_set_info_standard(connection_struct
*conn
,
4774 const SMB_STRUCT_STAT
*psbuf
)
4776 struct timespec ts
[2];
4778 if (total_data
< 12) {
4779 return NT_STATUS_INVALID_PARAMETER
;
4783 ts
[0] = convert_time_t_to_timespec(srv_make_unix_date2(pdata
+l1_fdateLastAccess
));
4785 ts
[1] = convert_time_t_to_timespec(srv_make_unix_date2(pdata
+l1_fdateLastWrite
));
4787 DEBUG(10,("smb_set_info_standard: file %s\n",
4788 fname
? fname
: fsp
->fsp_name
));
4790 return smb_set_file_time(conn
,
4797 /****************************************************************************
4798 Deal with SMB_SET_FILE_BASIC_INFO.
4799 ****************************************************************************/
4801 static NTSTATUS
smb_set_file_basic_info(connection_struct
*conn
,
4806 SMB_STRUCT_STAT
*psbuf
)
4808 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
4809 struct timespec write_time
;
4810 struct timespec changed_time
;
4812 struct timespec ts
[2];
4813 NTSTATUS status
= NT_STATUS_OK
;
4815 if (total_data
< 36) {
4816 return NT_STATUS_INVALID_PARAMETER
;
4819 /* Set the attributes */
4820 dosmode
= IVAL(pdata
,32);
4821 status
= smb_set_file_dosmode(conn
,
4825 if (!NT_STATUS_IS_OK(status
)) {
4829 /* Ignore create time at offset pdata. */
4832 ts
[0] = interpret_long_date(pdata
+8);
4834 write_time
= interpret_long_date(pdata
+16);
4835 changed_time
= interpret_long_date(pdata
+24);
4838 ts
[1] = timespec_min(&write_time
, &changed_time
);
4840 if ((timespec_compare(&write_time
, &ts
[1]) == 1) && !null_timespec(write_time
)) {
4844 /* Prefer a defined time to an undefined one. */
4845 if (null_timespec(ts
[1])) {
4846 ts
[1] = null_timespec(write_time
) ? changed_time
: write_time
;
4849 DEBUG(10,("smb_set_file_basic_info: file %s\n",
4850 fname
? fname
: fsp
->fsp_name
));
4852 return smb_set_file_time(conn
,
4859 /****************************************************************************
4860 Deal with SMB_SET_FILE_ALLOCATION_INFO.
4861 ****************************************************************************/
4863 static NTSTATUS
smb_set_file_allocation_info(connection_struct
*conn
,
4868 SMB_STRUCT_STAT
*psbuf
)
4870 SMB_BIG_UINT allocation_size
= 0;
4871 NTSTATUS status
= NT_STATUS_OK
;
4872 files_struct
*new_fsp
= NULL
;
4874 if (!VALID_STAT(*psbuf
)) {
4875 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4878 if (total_data
< 8) {
4879 return NT_STATUS_INVALID_PARAMETER
;
4882 allocation_size
= (SMB_BIG_UINT
)IVAL(pdata
,0);
4883 #ifdef LARGE_SMB_OFF_T
4884 allocation_size
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
4885 #else /* LARGE_SMB_OFF_T */
4886 if (IVAL(pdata
,4) != 0) {
4887 /* more than 32 bits? */
4888 return NT_STATUS_INVALID_PARAMETER
;
4890 #endif /* LARGE_SMB_OFF_T */
4892 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for file %s to %.0f\n",
4893 fname
, (double)allocation_size
));
4895 if (allocation_size
) {
4896 allocation_size
= smb_roundup(conn
, allocation_size
);
4899 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new allocation size to %.0f\n",
4900 fname
, (double)allocation_size
));
4902 if (fsp
&& fsp
->fh
->fd
!= -1) {
4903 /* Open file handle. */
4904 /* Only change if needed. */
4905 if (allocation_size
!= get_file_size(*psbuf
)) {
4906 if (vfs_allocate_file_space(fsp
, allocation_size
) == -1) {
4907 return map_nt_error_from_unix(errno
);
4910 /* But always update the time. */
4911 if (null_timespec(fsp
->pending_modtime
)) {
4913 * This is equivalent to a write. Ensure it's seen immediately
4914 * if there are no pending writes.
4916 set_filetime(fsp
->conn
, fsp
->fsp_name
, timespec_current());
4918 return NT_STATUS_OK
;
4921 /* Pathname or stat or directory file. */
4923 status
= open_file_ntcreate(conn
, fname
, psbuf
,
4925 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4928 FILE_ATTRIBUTE_NORMAL
,
4929 FORCE_OPLOCK_BREAK_TO_NONE
,
4932 if (!NT_STATUS_IS_OK(status
)) {
4933 /* NB. We check for open_was_deferred in the caller. */
4937 /* Only change if needed. */
4938 if (allocation_size
!= get_file_size(*psbuf
)) {
4939 if (vfs_allocate_file_space(new_fsp
, allocation_size
) == -1) {
4940 status
= map_nt_error_from_unix(errno
);
4941 close_file(new_fsp
,NORMAL_CLOSE
);
4946 /* Changing the allocation size should set the last mod time. */
4947 /* Don't need to call set_filetime as this will be flushed on
4950 fsp_set_pending_modtime(new_fsp
, timespec_current());
4952 close_file(new_fsp
,NORMAL_CLOSE
);
4953 return NT_STATUS_OK
;
4956 /****************************************************************************
4957 Deal with SMB_SET_FILE_END_OF_FILE_INFO.
4958 ****************************************************************************/
4960 static NTSTATUS
smb_set_file_end_of_file_info(connection_struct
*conn
,
4965 SMB_STRUCT_STAT
*psbuf
)
4969 if (total_data
< 8) {
4970 return NT_STATUS_INVALID_PARAMETER
;
4973 size
= IVAL(pdata
,0);
4974 #ifdef LARGE_SMB_OFF_T
4975 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
4976 #else /* LARGE_SMB_OFF_T */
4977 if (IVAL(pdata
,4) != 0) {
4978 /* more than 32 bits? */
4979 return NT_STATUS_INVALID_PARAMETER
;
4981 #endif /* LARGE_SMB_OFF_T */
4982 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
4983 "file %s to %.0f\n", fname
, (double)size
));
4985 return smb_set_file_size(conn
,
4992 /****************************************************************************
4993 Allow a UNIX info mknod.
4994 ****************************************************************************/
4996 static NTSTATUS
smb_unix_mknod(connection_struct
*conn
,
5000 SMB_STRUCT_STAT
*psbuf
)
5002 uint32 file_type
= IVAL(pdata
,56);
5003 #if defined(HAVE_MAKEDEV)
5004 uint32 dev_major
= IVAL(pdata
,60);
5005 uint32 dev_minor
= IVAL(pdata
,68);
5007 SMB_DEV_T dev
= (SMB_DEV_T
)0;
5008 uint32 raw_unixmode
= IVAL(pdata
,84);
5012 if (total_data
< 100) {
5013 return NT_STATUS_INVALID_PARAMETER
;
5016 status
= unix_perms_from_wire(conn
, psbuf
, raw_unixmode
, PERM_NEW_FILE
, &unixmode
);
5017 if (!NT_STATUS_IS_OK(status
)) {
5021 #if defined(HAVE_MAKEDEV)
5022 dev
= makedev(dev_major
, dev_minor
);
5025 switch (file_type
) {
5026 #if defined(S_IFIFO)
5027 case UNIX_TYPE_FIFO
:
5028 unixmode
|= S_IFIFO
;
5031 #if defined(S_IFSOCK)
5032 case UNIX_TYPE_SOCKET
:
5033 unixmode
|= S_IFSOCK
;
5036 #if defined(S_IFCHR)
5037 case UNIX_TYPE_CHARDEV
:
5038 unixmode
|= S_IFCHR
;
5041 #if defined(S_IFBLK)
5042 case UNIX_TYPE_BLKDEV
:
5043 unixmode
|= S_IFBLK
;
5047 return NT_STATUS_INVALID_PARAMETER
;
5050 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
5051 0%o for file %s\n", (double)dev
, (unsigned int)unixmode
, fname
));
5053 /* Ok - do the mknod. */
5054 if (SMB_VFS_MKNOD(conn
, fname
, unixmode
, dev
) != 0) {
5055 return map_nt_error_from_unix(errno
);
5058 /* If any of the other "set" calls fail we
5059 * don't want to end up with a half-constructed mknod.
5062 if (lp_inherit_perms(SNUM(conn
))) {
5064 conn
, parent_dirname(fname
),
5068 if (SMB_VFS_STAT(conn
, fname
, psbuf
) != 0) {
5069 status
= map_nt_error_from_unix(errno
);
5070 SMB_VFS_UNLINK(conn
,fname
);
5073 return NT_STATUS_OK
;
5076 /****************************************************************************
5077 Deal with SMB_SET_FILE_UNIX_BASIC.
5078 ****************************************************************************/
5080 static NTSTATUS
smb_set_file_unix_basic(connection_struct
*conn
,
5085 SMB_STRUCT_STAT
*psbuf
)
5087 struct timespec ts
[2];
5088 uint32 raw_unixmode
;
5091 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
5092 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
5093 NTSTATUS status
= NT_STATUS_OK
;
5094 BOOL delete_on_fail
= False
;
5095 enum perm_type ptype
;
5097 if (total_data
< 100) {
5098 return NT_STATUS_INVALID_PARAMETER
;
5101 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
5102 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
5103 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
5104 #ifdef LARGE_SMB_OFF_T
5105 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
5106 #else /* LARGE_SMB_OFF_T */
5107 if (IVAL(pdata
,4) != 0) {
5108 /* more than 32 bits? */
5109 return NT_STATUS_INVALID_PARAMETER
;
5111 #endif /* LARGE_SMB_OFF_T */
5114 ts
[0] = interpret_long_date(pdata
+24); /* access_time */
5115 ts
[1] = interpret_long_date(pdata
+32); /* modification_time */
5116 set_owner
= (uid_t
)IVAL(pdata
,40);
5117 set_grp
= (gid_t
)IVAL(pdata
,48);
5118 raw_unixmode
= IVAL(pdata
,84);
5120 if (VALID_STAT(*psbuf
)) {
5121 if (S_ISDIR(psbuf
->st_mode
)) {
5122 ptype
= PERM_EXISTING_DIR
;
5124 ptype
= PERM_EXISTING_FILE
;
5127 ptype
= PERM_NEW_FILE
;
5130 status
= unix_perms_from_wire(conn
, psbuf
, raw_unixmode
, ptype
, &unixmode
);
5131 if (!NT_STATUS_IS_OK(status
)) {
5135 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = %s \
5136 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
5137 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
5139 if (!VALID_STAT(*psbuf
)) {
5141 * The only valid use of this is to create character and block
5142 * devices, and named pipes. This is deprecated (IMHO) and
5143 * a new info level should be used for mknod. JRA.
5146 status
= smb_unix_mknod(conn
,
5151 if (!NT_STATUS_IS_OK(status
)) {
5155 /* Ensure we don't try and change anything else. */
5156 raw_unixmode
= SMB_MODE_NO_CHANGE
;
5157 size
= get_file_size(*psbuf
);
5158 ts
[0] = get_atimespec(psbuf
);
5159 ts
[1] = get_mtimespec(psbuf
);
5161 * We continue here as we might want to change the
5164 delete_on_fail
= True
;
5168 /* Horrible backwards compatibility hack as an old server bug
5169 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
5173 size
= get_file_size(*psbuf
);
5178 * Deal with the UNIX specific mode set.
5181 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
5182 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
5183 (unsigned int)unixmode
, fname
));
5184 if (SMB_VFS_CHMOD(conn
, fname
, unixmode
) != 0) {
5185 return map_nt_error_from_unix(errno
);
5190 * Deal with the UNIX specific uid set.
5193 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) && (psbuf
->st_uid
!= set_owner
)) {
5194 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
5195 (unsigned int)set_owner
, fname
));
5196 if (SMB_VFS_CHOWN(conn
, fname
, set_owner
, (gid_t
)-1) != 0) {
5197 status
= map_nt_error_from_unix(errno
);
5198 if (delete_on_fail
) {
5199 SMB_VFS_UNLINK(conn
,fname
);
5206 * Deal with the UNIX specific gid set.
5209 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) && (psbuf
->st_gid
!= set_grp
)) {
5210 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
5211 (unsigned int)set_owner
, fname
));
5212 if (SMB_VFS_CHOWN(conn
, fname
, (uid_t
)-1, set_grp
) != 0) {
5213 status
= map_nt_error_from_unix(errno
);
5214 if (delete_on_fail
) {
5215 SMB_VFS_UNLINK(conn
,fname
);
5221 /* Deal with any size changes. */
5223 status
= smb_set_file_size(conn
,
5228 if (!NT_STATUS_IS_OK(status
)) {
5232 /* Deal with any time changes. */
5234 return smb_set_file_time(conn
,
5241 /****************************************************************************
5242 Deal with SMB_SET_FILE_UNIX_INFO2.
5243 ****************************************************************************/
5245 static NTSTATUS
smb_set_file_unix_info2(connection_struct
*conn
,
5250 SMB_STRUCT_STAT
*psbuf
)
5256 if (total_data
< 116) {
5257 return NT_STATUS_INVALID_PARAMETER
;
5260 /* Start by setting all the fields that are common between UNIX_BASIC
5263 status
= smb_set_file_unix_basic(conn
, pdata
, total_data
,
5265 if (!NT_STATUS_IS_OK(status
)) {
5269 smb_fflags
= IVAL(pdata
, 108);
5270 smb_fmask
= IVAL(pdata
, 112);
5272 /* NB: We should only attempt to alter the file flags if the client
5273 * sends a non-zero mask.
5275 if (smb_fmask
!= 0) {
5276 int stat_fflags
= 0;
5278 if (!map_info2_flags_to_sbuf(psbuf
, smb_fflags
, smb_fmask
,
5280 /* Client asked to alter a flag we don't understand. */
5281 return NT_STATUS_INVALID_PARAMETER
;
5284 if (fsp
&& fsp
->fh
->fd
!= -1) {
5285 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */
5286 return NT_STATUS_NOT_SUPPORTED
;
5288 if (SMB_VFS_CHFLAGS(conn
, fname
, stat_fflags
) != 0) {
5289 return map_nt_error_from_unix(errno
);
5294 /* XXX: need to add support for changing the create_time here. You
5295 * can do this for paths on Darwin with setattrlist(2). The right way
5296 * to hook this up is probably by extending the VFS utimes interface.
5299 return NT_STATUS_OK
;
5302 /****************************************************************************
5303 Create a directory with POSIX semantics.
5304 ****************************************************************************/
5306 static NTSTATUS
smb_posix_mkdir(connection_struct
*conn
,
5310 SMB_STRUCT_STAT
*psbuf
,
5311 int *pdata_return_size
)
5313 NTSTATUS status
= NT_STATUS_OK
;
5314 uint32 raw_unixmode
= 0;
5315 uint32 mod_unixmode
= 0;
5316 mode_t unixmode
= (mode_t
)0;
5317 files_struct
*fsp
= NULL
;
5318 uint16 info_level_return
= 0;
5320 char *pdata
= *ppdata
;
5322 if (total_data
< 18) {
5323 return NT_STATUS_INVALID_PARAMETER
;
5326 raw_unixmode
= IVAL(pdata
,8);
5327 /* Next 4 bytes are not yet defined. */
5329 status
= unix_perms_from_wire(conn
, psbuf
, raw_unixmode
, PERM_NEW_DIR
, &unixmode
);
5330 if (!NT_STATUS_IS_OK(status
)) {
5334 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
5336 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
5337 fname
, (unsigned int)unixmode
));
5339 status
= open_directory(conn
,
5342 FILE_READ_ATTRIBUTES
, /* Just a stat open */
5343 FILE_SHARE_NONE
, /* Ignored for stat opens */
5350 if (NT_STATUS_IS_OK(status
)) {
5351 close_file(fsp
, NORMAL_CLOSE
);
5354 info_level_return
= SVAL(pdata
,16);
5356 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
5357 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
5358 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
5359 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
5361 *pdata_return_size
= 12;
5364 /* Realloc the data size */
5365 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
5366 if (*ppdata
== NULL
) {
5367 *pdata_return_size
= 0;
5368 return NT_STATUS_NO_MEMORY
;
5372 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
5373 SSVAL(pdata
,2,0); /* No fnum. */
5374 SIVAL(pdata
,4,info
); /* Was directory created. */
5376 switch (info_level_return
) {
5377 case SMB_QUERY_FILE_UNIX_BASIC
:
5378 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
5379 SSVAL(pdata
,10,0); /* Padding. */
5380 store_file_unix_basic(conn
, pdata
+ 12, fsp
, psbuf
);
5382 case SMB_QUERY_FILE_UNIX_INFO2
:
5383 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
5384 SSVAL(pdata
,10,0); /* Padding. */
5385 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
, psbuf
);
5388 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
5389 SSVAL(pdata
,10,0); /* Padding. */
5396 /****************************************************************************
5397 Open/Create a file with POSIX semantics.
5398 ****************************************************************************/
5400 static NTSTATUS
smb_posix_open(connection_struct
*conn
,
5404 SMB_STRUCT_STAT
*psbuf
,
5405 int *pdata_return_size
)
5407 BOOL extended_oplock_granted
= False
;
5408 char *pdata
= *ppdata
;
5410 uint32 wire_open_mode
= 0;
5411 uint32 raw_unixmode
= 0;
5412 uint32 mod_unixmode
= 0;
5413 uint32 create_disp
= 0;
5414 uint32 access_mask
= 0;
5415 uint32 create_options
= 0;
5416 NTSTATUS status
= NT_STATUS_OK
;
5417 mode_t unixmode
= (mode_t
)0;
5418 files_struct
*fsp
= NULL
;
5419 int oplock_request
= 0;
5421 uint16 info_level_return
= 0;
5423 if (total_data
< 18) {
5424 return NT_STATUS_INVALID_PARAMETER
;
5427 flags
= IVAL(pdata
,0);
5428 oplock_request
= (flags
& REQUEST_OPLOCK
) ? EXCLUSIVE_OPLOCK
: 0;
5429 if (oplock_request
) {
5430 oplock_request
|= (flags
& REQUEST_BATCH_OPLOCK
) ? BATCH_OPLOCK
: 0;
5433 wire_open_mode
= IVAL(pdata
,4);
5435 if (wire_open_mode
== (SMB_O_CREAT
|SMB_O_DIRECTORY
)) {
5436 return smb_posix_mkdir(conn
,
5444 switch (wire_open_mode
& SMB_ACCMODE
) {
5446 access_mask
= FILE_READ_DATA
;
5449 access_mask
= FILE_WRITE_DATA
;
5452 access_mask
= FILE_READ_DATA
|FILE_WRITE_DATA
;
5455 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
5456 (unsigned int)wire_open_mode
));
5457 return NT_STATUS_INVALID_PARAMETER
;
5460 wire_open_mode
&= ~SMB_ACCMODE
;
5462 if((wire_open_mode
& (SMB_O_CREAT
| SMB_O_EXCL
)) == (SMB_O_CREAT
| SMB_O_EXCL
)) {
5463 create_disp
= FILE_CREATE
;
5464 } else if((wire_open_mode
& (SMB_O_CREAT
| SMB_O_TRUNC
)) == (SMB_O_CREAT
| SMB_O_TRUNC
)) {
5465 create_disp
= FILE_OVERWRITE_IF
;
5466 } else if((wire_open_mode
& SMB_O_CREAT
) == SMB_O_CREAT
) {
5467 create_disp
= FILE_OPEN_IF
;
5469 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
5470 (unsigned int)wire_open_mode
));
5471 return NT_STATUS_INVALID_PARAMETER
;
5474 raw_unixmode
= IVAL(pdata
,8);
5475 /* Next 4 bytes are not yet defined. */
5477 status
= unix_perms_from_wire(conn
,
5480 VALID_STAT(*psbuf
) ? PERM_EXISTING_FILE
: PERM_NEW_FILE
,
5483 if (!NT_STATUS_IS_OK(status
)) {
5487 mod_unixmode
= (uint32
)unixmode
| FILE_FLAG_POSIX_SEMANTICS
;
5489 if (wire_open_mode
& SMB_O_SYNC
) {
5490 create_options
|= FILE_WRITE_THROUGH
;
5492 if (wire_open_mode
& SMB_O_APPEND
) {
5493 access_mask
|= FILE_APPEND_DATA
;
5495 if (wire_open_mode
& SMB_O_DIRECT
) {
5496 mod_unixmode
|= FILE_FLAG_NO_BUFFERING
;
5499 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
5501 (unsigned int)wire_open_mode
,
5502 (unsigned int)unixmode
));
5504 status
= open_file_ntcreate(conn
,
5508 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5510 0, /* no create options yet. */
5516 if (!NT_STATUS_IS_OK(status
)) {
5520 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
))) {
5521 extended_oplock_granted
= True
;
5524 if(oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
5525 extended_oplock_granted
= True
;
5528 info_level_return
= SVAL(pdata
,16);
5530 /* Allocate the correct return size. */
5532 if (info_level_return
== SMB_QUERY_FILE_UNIX_BASIC
) {
5533 *pdata_return_size
= 12 + SMB_FILE_UNIX_BASIC_SIZE
;
5534 } else if (info_level_return
== SMB_QUERY_FILE_UNIX_INFO2
) {
5535 *pdata_return_size
= 12 + SMB_FILE_UNIX_INFO2_SIZE
;
5537 *pdata_return_size
= 12;
5540 /* Realloc the data size */
5541 *ppdata
= (char *)SMB_REALLOC(*ppdata
,*pdata_return_size
);
5542 if (*ppdata
== NULL
) {
5543 close_file(fsp
,ERROR_CLOSE
);
5544 *pdata_return_size
= 0;
5545 return NT_STATUS_NO_MEMORY
;
5549 if (extended_oplock_granted
) {
5550 if (flags
& REQUEST_BATCH_OPLOCK
) {
5551 SSVAL(pdata
,0, BATCH_OPLOCK_RETURN
);
5553 SSVAL(pdata
,0, EXCLUSIVE_OPLOCK_RETURN
);
5555 } else if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
5556 SSVAL(pdata
,0, LEVEL_II_OPLOCK_RETURN
);
5558 SSVAL(pdata
,0,NO_OPLOCK_RETURN
);
5561 SSVAL(pdata
,2,fsp
->fnum
);
5562 SIVAL(pdata
,4,info
); /* Was file created etc. */
5564 switch (info_level_return
) {
5565 case SMB_QUERY_FILE_UNIX_BASIC
:
5566 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_BASIC
);
5567 SSVAL(pdata
,10,0); /* padding. */
5568 store_file_unix_basic(conn
, pdata
+ 12, fsp
, psbuf
);
5570 case SMB_QUERY_FILE_UNIX_INFO2
:
5571 SSVAL(pdata
,8,SMB_QUERY_FILE_UNIX_INFO2
);
5572 SSVAL(pdata
,10,0); /* padding. */
5573 store_file_unix_basic_info2(conn
, pdata
+ 12, fsp
, psbuf
);
5576 SSVAL(pdata
,8,SMB_NO_INFO_LEVEL_RETURNED
);
5577 SSVAL(pdata
,10,0); /* padding. */
5580 return NT_STATUS_OK
;
5583 /****************************************************************************
5584 Delete a file with POSIX semantics.
5585 ****************************************************************************/
5587 static NTSTATUS
smb_posix_unlink(connection_struct
*conn
,
5591 SMB_STRUCT_STAT
*psbuf
)
5593 NTSTATUS status
= NT_STATUS_OK
;
5594 files_struct
*fsp
= NULL
;
5599 struct share_mode_lock
*lck
= NULL
;
5601 if (total_data
< 2) {
5602 return NT_STATUS_INVALID_PARAMETER
;
5605 flags
= SVAL(pdata
,0);
5607 if (!VALID_STAT(*psbuf
)) {
5608 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5611 if ((flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) &&
5612 !VALID_STAT_OF_DIR(*psbuf
)) {
5613 return NT_STATUS_NOT_A_DIRECTORY
;
5616 DEBUG(10,("smb_posix_unlink: %s %s\n",
5617 (flags
== SMB_POSIX_UNLINK_DIRECTORY_TARGET
) ? "directory" : "file",
5620 if (VALID_STAT_OF_DIR(*psbuf
)) {
5621 status
= open_directory(conn
,
5625 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5628 FILE_FLAG_POSIX_SEMANTICS
|0777,
5633 status
= open_file_ntcreate(conn
,
5637 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5640 FILE_FLAG_POSIX_SEMANTICS
|0777,
5641 0, /* No oplock, but break existing ones. */
5646 if (!NT_STATUS_IS_OK(status
)) {
5651 * Don't lie to client. If we can't really delete due to
5652 * non-POSIX opens return SHARING_VIOLATION.
5655 lck
= get_share_mode_lock(NULL
, fsp
->dev
, fsp
->inode
, NULL
, NULL
);
5657 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
5658 "lock for file %s\n", fsp
->fsp_name
));
5659 close_file(fsp
, NORMAL_CLOSE
);
5660 return NT_STATUS_INVALID_PARAMETER
;
5664 * See if others still have the file open. If this is the case, then
5665 * don't delete. If all opens are POSIX delete we can set the delete
5666 * on close disposition.
5668 for (i
=0; i
<lck
->num_share_modes
; i
++) {
5669 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
5670 if (is_valid_share_mode_entry(e
)) {
5671 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
5674 /* Fail with sharing violation. */
5675 close_file(fsp
, NORMAL_CLOSE
);
5677 return NT_STATUS_SHARING_VIOLATION
;
5682 * Set the delete on close.
5684 status
= smb_set_file_disposition_info(conn
,
5691 if (!NT_STATUS_IS_OK(status
)) {
5692 close_file(fsp
, NORMAL_CLOSE
);
5697 return close_file(fsp
, NORMAL_CLOSE
);
5700 /****************************************************************************
5701 Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
5702 ****************************************************************************/
5704 static int call_trans2setfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
5705 unsigned int tran_call
,
5706 char **pparams
, int total_params
, char **ppdata
, int total_data
,
5707 unsigned int max_data_bytes
)
5709 char *params
= *pparams
;
5710 char *pdata
= *ppdata
;
5712 SMB_STRUCT_STAT sbuf
;
5714 files_struct
*fsp
= NULL
;
5715 NTSTATUS status
= NT_STATUS_OK
;
5716 int data_return_size
= 0;
5719 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
5724 if (tran_call
== TRANSACT2_SETFILEINFO
) {
5725 if (total_params
< 4) {
5726 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
5729 fsp
= file_fsp(params
,0);
5730 info_level
= SVAL(params
,2);
5732 if(fsp
&& (fsp
->is_directory
|| fsp
->fh
->fd
== -1)) {
5734 * This is actually a SETFILEINFO on a directory
5735 * handle (returned from an NT SMB). NT5.0 seems
5736 * to do this call. JRA.
5738 pstrcpy(fname
, fsp
->fsp_name
);
5739 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5740 /* Always do lstat for UNIX calls. */
5741 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
5742 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
5743 return UNIXERROR(ERRDOS
,ERRbadpath
);
5746 if (SMB_VFS_STAT(conn
,fname
,&sbuf
) != 0) {
5747 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
5748 return UNIXERROR(ERRDOS
,ERRbadpath
);
5751 } else if (fsp
&& fsp
->print_file
) {
5753 * Doing a DELETE_ON_CLOSE should cancel a print job.
5755 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
5756 fsp
->fh
->private_options
|= FILE_DELETE_ON_CLOSE
;
5758 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp
->fsp_name
));
5761 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0, max_data_bytes
);
5764 return (UNIXERROR(ERRDOS
,ERRbadpath
));
5767 * Original code - this is an open file.
5769 CHECK_FSP(fsp
,conn
);
5771 pstrcpy(fname
, fsp
->fsp_name
);
5773 if (SMB_VFS_FSTAT(fsp
, fsp
->fh
->fd
, &sbuf
) != 0) {
5774 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
5775 return(UNIXERROR(ERRDOS
,ERRbadfid
));
5780 if (total_params
< 7) {
5781 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
5784 info_level
= SVAL(params
,0);
5785 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), total_params
- 6, STR_TERMINATE
, &status
);
5786 if (!NT_STATUS_IS_OK(status
)) {
5787 return ERROR_NT(status
);
5790 status
= resolve_dfspath(conn
, SVAL(inbuf
,smb_flg2
) & FLAGS2_DFS_PATHNAMES
, fname
);
5791 if (!NT_STATUS_IS_OK(status
)) {
5792 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
5793 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
5795 return ERROR_NT(status
);
5798 status
= unix_convert(conn
, fname
, False
, NULL
, &sbuf
);
5799 if (!NT_STATUS_IS_OK(status
)) {
5800 return ERROR_NT(status
);
5803 status
= check_name(conn
, fname
);
5804 if (!NT_STATUS_IS_OK(status
)) {
5805 return ERROR_NT(status
);
5808 if (INFO_LEVEL_IS_UNIX(info_level
)) {
5810 * For CIFS UNIX extensions the target name may not exist.
5813 /* Always do lstat for UNIX calls. */
5814 SMB_VFS_LSTAT(conn
,fname
,&sbuf
);
5816 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,fname
,&sbuf
)) {
5817 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
5818 return UNIXERROR(ERRDOS
,ERRbadpath
);
5822 if (!CAN_WRITE(conn
)) {
5823 return ERROR_DOS(ERRSRV
,ERRaccess
);
5826 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions()) {
5827 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
5830 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
5831 tran_call
,fname
, fsp
? fsp
->fnum
: -1, info_level
,total_data
));
5833 /* Realloc the parameter size */
5834 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
5835 if (*pparams
== NULL
) {
5836 return ERROR_NT(NT_STATUS_NO_MEMORY
);
5842 if (fsp
&& !null_timespec(fsp
->pending_modtime
)) {
5843 /* the pending modtime overrides the current modtime */
5844 set_mtimespec(&sbuf
, fsp
->pending_modtime
);
5847 switch (info_level
) {
5849 case SMB_INFO_STANDARD
:
5851 status
= smb_set_info_standard(conn
,
5860 case SMB_INFO_SET_EA
:
5862 status
= smb_info_set_ea(conn
,
5870 case SMB_SET_FILE_BASIC_INFO
:
5871 case SMB_FILE_BASIC_INFORMATION
:
5873 status
= smb_set_file_basic_info(conn
,
5882 case SMB_FILE_ALLOCATION_INFORMATION
:
5883 case SMB_SET_FILE_ALLOCATION_INFO
:
5885 status
= smb_set_file_allocation_info(conn
,
5894 case SMB_FILE_END_OF_FILE_INFORMATION
:
5895 case SMB_SET_FILE_END_OF_FILE_INFO
:
5897 status
= smb_set_file_end_of_file_info(conn
,
5906 case SMB_FILE_DISPOSITION_INFORMATION
:
5907 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
5910 /* JRA - We used to just ignore this on a path ?
5911 * Shouldn't this be invalid level on a pathname
5914 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
5915 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
5918 status
= smb_set_file_disposition_info(conn
,
5927 case SMB_FILE_POSITION_INFORMATION
:
5929 status
= smb_file_position_information(conn
,
5936 /* From tridge Samba4 :
5937 * MODE_INFORMATION in setfileinfo (I have no
5938 * idea what "mode information" on a file is - it takes a value of 0,
5939 * 2, 4 or 6. What could it be?).
5942 case SMB_FILE_MODE_INFORMATION
:
5944 status
= smb_file_mode_information(conn
,
5951 * CIFS UNIX extensions.
5954 case SMB_SET_FILE_UNIX_BASIC
:
5956 status
= smb_set_file_unix_basic(conn
,
5965 case SMB_SET_FILE_UNIX_INFO2
:
5967 status
= smb_set_file_unix_info2(conn
,
5976 case SMB_SET_FILE_UNIX_LINK
:
5978 if (tran_call
!= TRANSACT2_SETPATHINFO
) {
5979 /* We must have a pathname for this. */
5980 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
5982 status
= smb_set_file_unix_link(conn
,
5990 case SMB_SET_FILE_UNIX_HLINK
:
5992 if (tran_call
!= TRANSACT2_SETPATHINFO
) {
5993 /* We must have a pathname for this. */
5994 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
5996 status
= smb_set_file_unix_hlink(conn
,
6005 case SMB_FILE_RENAME_INFORMATION
:
6007 status
= smb_file_rename_information(conn
,
6017 #if defined(HAVE_POSIX_ACLS)
6018 case SMB_SET_POSIX_ACL
:
6020 status
= smb_set_posix_acl(conn
,
6030 case SMB_SET_POSIX_LOCK
:
6032 if (tran_call
!= TRANSACT2_SETFILEINFO
) {
6033 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
6035 status
= smb_set_posix_lock(conn
,
6044 case SMB_POSIX_PATH_OPEN
:
6046 if (tran_call
!= TRANSACT2_SETPATHINFO
) {
6047 /* We must have a pathname for this. */
6048 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
6051 status
= smb_posix_open(conn
,
6060 case SMB_POSIX_PATH_UNLINK
:
6062 if (tran_call
!= TRANSACT2_SETPATHINFO
) {
6063 /* We must have a pathname for this. */
6064 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
6067 status
= smb_posix_unlink(conn
,
6076 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
6080 if (!NT_STATUS_IS_OK(status
)) {
6081 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
6082 /* We have re-scheduled this call. */
6085 if (blocking_lock_was_deferred(SVAL(inbuf
,smb_mid
))) {
6086 /* We have re-scheduled this call. */
6089 if (NT_STATUS_EQUAL(status
,NT_STATUS_PATH_NOT_COVERED
)) {
6090 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED
, ERRSRV
, ERRbadpath
);
6092 if (info_level
== SMB_POSIX_PATH_OPEN
) {
6093 return ERROR_OPEN(status
);
6095 return ERROR_NT(status
);
6099 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, data_return_size
, max_data_bytes
);
6104 /****************************************************************************
6105 Reply to a TRANS2_MKDIR (make directory with extended attributes).
6106 ****************************************************************************/
6108 static int call_trans2mkdir(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
6109 char **pparams
, int total_params
, char **ppdata
, int total_data
,
6110 unsigned int max_data_bytes
)
6112 char *params
= *pparams
;
6113 char *pdata
= *ppdata
;
6115 SMB_STRUCT_STAT sbuf
;
6116 NTSTATUS status
= NT_STATUS_OK
;
6117 struct ea_list
*ea_list
= NULL
;
6119 if (!CAN_WRITE(conn
))
6120 return ERROR_DOS(ERRSRV
,ERRaccess
);
6122 if (total_params
< 5) {
6123 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6126 srvstr_get_path(inbuf
, directory
, ¶ms
[4], sizeof(directory
), total_params
- 4, STR_TERMINATE
, &status
);
6127 if (!NT_STATUS_IS_OK(status
)) {
6128 return ERROR_NT(status
);
6131 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
6133 status
= unix_convert(conn
, directory
, False
, NULL
, &sbuf
);
6134 if (!NT_STATUS_IS_OK(status
)) {
6135 return ERROR_NT(status
);
6138 status
= check_name(conn
, directory
);
6139 if (!NT_STATUS_IS_OK(status
)) {
6140 DEBUG(5,("call_trans2mkdir error (%s)\n", nt_errstr(status
)));
6141 return ERROR_NT(status
);
6144 /* Any data in this call is an EA list. */
6145 if (total_data
&& (total_data
!= 4) && !lp_ea_support(SNUM(conn
))) {
6146 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED
);
6150 * OS/2 workplace shell seems to send SET_EA requests of "null"
6151 * length (4 bytes containing IVAL 4).
6152 * They seem to have no effect. Bug #3212. JRA.
6155 if (total_data
!= 4) {
6156 if (total_data
< 10) {
6157 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6160 if (IVAL(pdata
,0) > total_data
) {
6161 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
6162 IVAL(pdata
,0), (unsigned int)total_data
));
6163 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6166 ea_list
= read_ea_list(tmp_talloc_ctx(), pdata
+ 4,
6169 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6171 } else if (IVAL(pdata
,0) != 4) {
6172 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6175 status
= create_directory(conn
, directory
);
6177 if (!NT_STATUS_IS_OK(status
)) {
6178 return ERROR_NT(status
);
6181 /* Try and set any given EA. */
6183 status
= set_ea(conn
, NULL
, directory
, ea_list
);
6184 if (!NT_STATUS_IS_OK(status
)) {
6185 return ERROR_NT(status
);
6189 /* Realloc the parameter and data sizes */
6190 *pparams
= (char *)SMB_REALLOC(*pparams
,2);
6191 if(*pparams
== NULL
) {
6192 return ERROR_NT(NT_STATUS_NO_MEMORY
);
6198 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0, max_data_bytes
);
6203 /****************************************************************************
6204 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
6205 We don't actually do this - we just send a null response.
6206 ****************************************************************************/
6208 static int call_trans2findnotifyfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
6209 char **pparams
, int total_params
, char **ppdata
, int total_data
,
6210 unsigned int max_data_bytes
)
6212 static uint16 fnf_handle
= 257;
6213 char *params
= *pparams
;
6216 if (total_params
< 6) {
6217 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6220 info_level
= SVAL(params
,4);
6221 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
6223 switch (info_level
) {
6228 return ERROR_NT(NT_STATUS_INVALID_LEVEL
);
6231 /* Realloc the parameter and data sizes */
6232 *pparams
= (char *)SMB_REALLOC(*pparams
,6);
6233 if (*pparams
== NULL
) {
6234 return ERROR_NT(NT_STATUS_NO_MEMORY
);
6238 SSVAL(params
,0,fnf_handle
);
6239 SSVAL(params
,2,0); /* No changes */
6240 SSVAL(params
,4,0); /* No EA errors */
6247 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0, max_data_bytes
);
6252 /****************************************************************************
6253 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
6254 changes). Currently this does nothing.
6255 ****************************************************************************/
6257 static int call_trans2findnotifynext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
6258 char **pparams
, int total_params
, char **ppdata
, int total_data
,
6259 unsigned int max_data_bytes
)
6261 char *params
= *pparams
;
6263 DEBUG(3,("call_trans2findnotifynext\n"));
6265 /* Realloc the parameter and data sizes */
6266 *pparams
= (char *)SMB_REALLOC(*pparams
,4);
6267 if (*pparams
== NULL
) {
6268 return ERROR_NT(NT_STATUS_NO_MEMORY
);
6272 SSVAL(params
,0,0); /* No changes */
6273 SSVAL(params
,2,0); /* No EA errors */
6275 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0, max_data_bytes
);
6280 /****************************************************************************
6281 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
6282 ****************************************************************************/
6284 static int call_trans2getdfsreferral(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
6285 char **pparams
, int total_params
, char **ppdata
, int total_data
,
6286 unsigned int max_data_bytes
)
6288 char *params
= *pparams
;
6291 int max_referral_level
;
6292 NTSTATUS status
= NT_STATUS_OK
;
6294 DEBUG(10,("call_trans2getdfsreferral\n"));
6296 if (total_params
< 3) {
6297 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6300 max_referral_level
= SVAL(params
,0);
6302 if(!lp_host_msdfs())
6303 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
6305 srvstr_pull(inbuf
, pathname
, ¶ms
[2], sizeof(pathname
), total_params
- 2, STR_TERMINATE
);
6306 if((reply_size
= setup_dfs_referral(conn
, pathname
,max_referral_level
,ppdata
,&status
)) < 0)
6307 return ERROR_NT(status
);
6309 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
6310 send_trans2_replies(outbuf
,bufsize
,0,0,*ppdata
,reply_size
, max_data_bytes
);
6315 #define LMCAT_SPL 0x53
6316 #define LMFUNC_GETJOBID 0x60
6318 /****************************************************************************
6319 Reply to a TRANS2_IOCTL - used for OS/2 printing.
6320 ****************************************************************************/
6322 static int call_trans2ioctl(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
6323 char **pparams
, int total_params
, char **ppdata
, int total_data
,
6324 unsigned int max_data_bytes
)
6326 char *pdata
= *ppdata
;
6327 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv15
);
6329 /* check for an invalid fid before proceeding */
6332 return(ERROR_DOS(ERRDOS
,ERRbadfid
));
6334 if ((SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
6335 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
6336 *ppdata
= (char *)SMB_REALLOC(*ppdata
, 32);
6337 if (*ppdata
== NULL
) {
6338 return ERROR_NT(NT_STATUS_NO_MEMORY
);
6342 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
6343 CAN ACCEPT THIS IN UNICODE. JRA. */
6345 SSVAL(pdata
,0,fsp
->rap_print_jobid
); /* Job number */
6346 srvstr_push( outbuf
, pdata
+ 2, global_myname(), 15, STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
6347 srvstr_push( outbuf
, pdata
+18, lp_servicename(SNUM(conn
)), 13, STR_ASCII
|STR_TERMINATE
); /* Service name */
6348 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32, max_data_bytes
);
6351 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
6352 return ERROR_DOS(ERRSRV
,ERRerror
);
6356 /****************************************************************************
6357 Reply to a SMBfindclose (stop trans2 directory search).
6358 ****************************************************************************/
6360 int reply_findclose(connection_struct
*conn
,
6361 char *inbuf
,char *outbuf
,int length
,int bufsize
)
6364 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
6365 START_PROFILE(SMBfindclose
);
6367 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
6369 dptr_close(&dptr_num
);
6371 outsize
= set_message(outbuf
,0,0,False
);
6373 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
6375 END_PROFILE(SMBfindclose
);
6379 /****************************************************************************
6380 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
6381 ****************************************************************************/
6383 int reply_findnclose(connection_struct
*conn
,
6384 char *inbuf
,char *outbuf
,int length
,int bufsize
)
6388 START_PROFILE(SMBfindnclose
);
6390 dptr_num
= SVAL(inbuf
,smb_vwv0
);
6392 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
6394 /* We never give out valid handles for a
6395 findnotifyfirst - so any dptr_num is ok here.
6398 outsize
= set_message(outbuf
,0,0,False
);
6400 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
6402 END_PROFILE(SMBfindnclose
);
6406 int handle_trans2(connection_struct
*conn
,
6407 struct trans_state
*state
,
6408 char *inbuf
, char *outbuf
, int size
, int bufsize
)
6412 if (Protocol
>= PROTOCOL_NT1
) {
6413 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | 0x40); /* IS_LONG_NAME */
6416 /* Now we must call the relevant TRANS2 function */
6417 switch(state
->call
) {
6418 case TRANSACT2_OPEN
:
6420 START_PROFILE(Trans2_open
);
6421 outsize
= call_trans2open(
6422 conn
, inbuf
, outbuf
, bufsize
,
6423 &state
->param
, state
->total_param
,
6424 &state
->data
, state
->total_data
,
6425 state
->max_data_return
);
6426 END_PROFILE(Trans2_open
);
6430 case TRANSACT2_FINDFIRST
:
6432 START_PROFILE(Trans2_findfirst
);
6433 outsize
= call_trans2findfirst(
6434 conn
, inbuf
, outbuf
, bufsize
,
6435 &state
->param
, state
->total_param
,
6436 &state
->data
, state
->total_data
,
6437 state
->max_data_return
);
6438 END_PROFILE(Trans2_findfirst
);
6442 case TRANSACT2_FINDNEXT
:
6444 START_PROFILE(Trans2_findnext
);
6445 outsize
= call_trans2findnext(
6446 conn
, inbuf
, outbuf
, size
, bufsize
,
6447 &state
->param
, state
->total_param
,
6448 &state
->data
, state
->total_data
,
6449 state
->max_data_return
);
6450 END_PROFILE(Trans2_findnext
);
6454 case TRANSACT2_QFSINFO
:
6456 START_PROFILE(Trans2_qfsinfo
);
6457 outsize
= call_trans2qfsinfo(
6458 conn
, inbuf
, outbuf
, size
, bufsize
,
6459 &state
->param
, state
->total_param
,
6460 &state
->data
, state
->total_data
,
6461 state
->max_data_return
);
6462 END_PROFILE(Trans2_qfsinfo
);
6466 case TRANSACT2_SETFSINFO
:
6468 START_PROFILE(Trans2_setfsinfo
);
6469 outsize
= call_trans2setfsinfo(
6470 conn
, inbuf
, outbuf
, size
, bufsize
,
6471 &state
->param
, state
->total_param
,
6472 &state
->data
, state
->total_data
,
6473 state
->max_data_return
);
6474 END_PROFILE(Trans2_setfsinfo
);
6478 case TRANSACT2_QPATHINFO
:
6479 case TRANSACT2_QFILEINFO
:
6481 START_PROFILE(Trans2_qpathinfo
);
6482 outsize
= call_trans2qfilepathinfo(
6483 conn
, inbuf
, outbuf
, size
, bufsize
, state
->call
,
6484 &state
->param
, state
->total_param
,
6485 &state
->data
, state
->total_data
,
6486 state
->max_data_return
);
6487 END_PROFILE(Trans2_qpathinfo
);
6491 case TRANSACT2_SETPATHINFO
:
6492 case TRANSACT2_SETFILEINFO
:
6494 START_PROFILE(Trans2_setpathinfo
);
6495 outsize
= call_trans2setfilepathinfo(
6496 conn
, inbuf
, outbuf
, size
, bufsize
, state
->call
,
6497 &state
->param
, state
->total_param
,
6498 &state
->data
, state
->total_data
,
6499 state
->max_data_return
);
6500 END_PROFILE(Trans2_setpathinfo
);
6504 case TRANSACT2_FINDNOTIFYFIRST
:
6506 START_PROFILE(Trans2_findnotifyfirst
);
6507 outsize
= call_trans2findnotifyfirst(
6508 conn
, inbuf
, outbuf
, size
, bufsize
,
6509 &state
->param
, state
->total_param
,
6510 &state
->data
, state
->total_data
,
6511 state
->max_data_return
);
6512 END_PROFILE(Trans2_findnotifyfirst
);
6516 case TRANSACT2_FINDNOTIFYNEXT
:
6518 START_PROFILE(Trans2_findnotifynext
);
6519 outsize
= call_trans2findnotifynext(
6520 conn
, inbuf
, outbuf
, size
, bufsize
,
6521 &state
->param
, state
->total_param
,
6522 &state
->data
, state
->total_data
,
6523 state
->max_data_return
);
6524 END_PROFILE(Trans2_findnotifynext
);
6528 case TRANSACT2_MKDIR
:
6530 START_PROFILE(Trans2_mkdir
);
6531 outsize
= call_trans2mkdir(
6532 conn
, inbuf
, outbuf
, size
, bufsize
,
6533 &state
->param
, state
->total_param
,
6534 &state
->data
, state
->total_data
,
6535 state
->max_data_return
);
6536 END_PROFILE(Trans2_mkdir
);
6540 case TRANSACT2_GET_DFS_REFERRAL
:
6542 START_PROFILE(Trans2_get_dfs_referral
);
6543 outsize
= call_trans2getdfsreferral(
6544 conn
, inbuf
, outbuf
, size
, bufsize
,
6545 &state
->param
, state
->total_param
,
6546 &state
->data
, state
->total_data
,
6547 state
->max_data_return
);
6548 END_PROFILE(Trans2_get_dfs_referral
);
6552 case TRANSACT2_IOCTL
:
6554 START_PROFILE(Trans2_ioctl
);
6555 outsize
= call_trans2ioctl(
6556 conn
, inbuf
, outbuf
, size
, bufsize
,
6557 &state
->param
, state
->total_param
,
6558 &state
->data
, state
->total_data
,
6559 state
->max_data_return
);
6560 END_PROFILE(Trans2_ioctl
);
6565 /* Error in request */
6566 DEBUG(2,("Unknown request %d in trans2 call\n", state
->call
));
6567 outsize
= ERROR_DOS(ERRSRV
,ERRerror
);
6573 /****************************************************************************
6574 Reply to a SMBtrans2.
6575 ****************************************************************************/
6577 int reply_trans2(connection_struct
*conn
, char *inbuf
,char *outbuf
,
6578 int size
, int bufsize
)
6581 unsigned int dsoff
= SVAL(inbuf
, smb_dsoff
);
6582 unsigned int dscnt
= SVAL(inbuf
, smb_dscnt
);
6583 unsigned int psoff
= SVAL(inbuf
, smb_psoff
);
6584 unsigned int pscnt
= SVAL(inbuf
, smb_pscnt
);
6585 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
6586 unsigned int av_size
= size
-4;
6587 struct trans_state
*state
;
6590 START_PROFILE(SMBtrans2
);
6592 result
= allow_new_trans(conn
->pending_trans
, SVAL(inbuf
, smb_mid
));
6593 if (!NT_STATUS_IS_OK(result
)) {
6594 DEBUG(2, ("Got invalid trans2 request: %s\n",
6595 nt_errstr(result
)));
6596 END_PROFILE(SMBtrans2
);
6597 return ERROR_NT(result
);
6600 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
6601 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
6602 END_PROFILE(SMBtrans2
);
6603 return ERROR_DOS(ERRSRV
,ERRaccess
);
6606 if ((state
= TALLOC_P(conn
->mem_ctx
, struct trans_state
)) == NULL
) {
6607 DEBUG(0, ("talloc failed\n"));
6608 END_PROFILE(SMBtrans2
);
6609 return ERROR_NT(NT_STATUS_NO_MEMORY
);
6612 state
->cmd
= SMBtrans2
;
6614 state
->mid
= SVAL(inbuf
, smb_mid
);
6615 state
->vuid
= SVAL(inbuf
, smb_uid
);
6616 state
->setup_count
= SVAL(inbuf
, smb_suwcnt
);
6617 state
->setup
= NULL
;
6618 state
->total_param
= SVAL(inbuf
, smb_tpscnt
);
6619 state
->param
= NULL
;
6620 state
->total_data
= SVAL(inbuf
, smb_tdscnt
);
6622 state
->max_param_return
= SVAL(inbuf
, smb_mprcnt
);
6623 state
->max_data_return
= SVAL(inbuf
, smb_mdrcnt
);
6624 state
->max_setup_return
= SVAL(inbuf
, smb_msrcnt
);
6625 state
->close_on_completion
= BITSETW(inbuf
+smb_vwv5
,0);
6626 state
->one_way
= BITSETW(inbuf
+smb_vwv5
,1);
6628 state
->call
= tran_call
;
6630 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
6631 is so as a sanity check */
6632 if (state
->setup_count
!= 1) {
6634 * Need to have rc=0 for ioctl to get job id for OS/2.
6635 * Network printing will fail if function is not successful.
6636 * Similar function in reply.c will be used if protocol
6637 * is LANMAN1.0 instead of LM1.2X002.
6638 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
6639 * outbuf doesn't have to be set(only job id is used).
6641 if ( (state
->setup_count
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
6642 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
6643 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
6644 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
6646 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state
->setup_count
));
6647 DEBUG(2,("Transaction is %d\n",tran_call
));
6649 END_PROFILE(SMBtrans2
);
6650 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6654 if ((dscnt
> state
->total_data
) || (pscnt
> state
->total_param
))
6657 if (state
->total_data
) {
6658 /* Can't use talloc here, the core routines do realloc on the
6659 * params and data. */
6660 state
->data
= (char *)SMB_MALLOC(state
->total_data
);
6661 if (state
->data
== NULL
) {
6662 DEBUG(0,("reply_trans2: data malloc fail for %u "
6663 "bytes !\n", (unsigned int)state
->total_data
));
6665 END_PROFILE(SMBtrans2
);
6666 return(ERROR_DOS(ERRDOS
,ERRnomem
));
6669 if (dscnt
> state
->total_data
||
6670 dsoff
+dscnt
< dsoff
) {
6674 if (dsoff
> av_size
||
6676 dsoff
+dscnt
> av_size
) {
6680 memcpy(state
->data
,smb_base(inbuf
)+dsoff
,dscnt
);
6683 if (state
->total_param
) {
6684 /* Can't use talloc here, the core routines do realloc on the
6685 * params and data. */
6686 state
->param
= (char *)SMB_MALLOC(state
->total_param
);
6687 if (state
->param
== NULL
) {
6688 DEBUG(0,("reply_trans: param malloc fail for %u "
6689 "bytes !\n", (unsigned int)state
->total_param
));
6690 SAFE_FREE(state
->data
);
6692 END_PROFILE(SMBtrans2
);
6693 return(ERROR_DOS(ERRDOS
,ERRnomem
));
6696 if (pscnt
> state
->total_param
||
6697 psoff
+pscnt
< psoff
) {
6701 if (psoff
> av_size
||
6703 psoff
+pscnt
> av_size
) {
6707 memcpy(state
->param
,smb_base(inbuf
)+psoff
,pscnt
);
6710 state
->received_data
= dscnt
;
6711 state
->received_param
= pscnt
;
6713 if ((state
->received_param
== state
->total_param
) &&
6714 (state
->received_data
== state
->total_data
)) {
6716 outsize
= handle_trans2(conn
, state
, inbuf
, outbuf
,
6718 SAFE_FREE(state
->data
);
6719 SAFE_FREE(state
->param
);
6721 END_PROFILE(SMBtrans2
);
6725 DLIST_ADD(conn
->pending_trans
, state
);
6727 /* We need to send an interim response then receive the rest
6728 of the parameter/data bytes */
6729 outsize
= set_message(outbuf
,0,0,False
);
6731 END_PROFILE(SMBtrans2
);
6736 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
6737 SAFE_FREE(state
->data
);
6738 SAFE_FREE(state
->param
);
6740 END_PROFILE(SMBtrans2
);
6741 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6745 /****************************************************************************
6746 Reply to a SMBtranss2
6747 ****************************************************************************/
6749 int reply_transs2(connection_struct
*conn
,
6750 char *inbuf
,char *outbuf
,int size
,int bufsize
)
6753 unsigned int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
6754 unsigned int av_size
= size
-4;
6755 struct trans_state
*state
;
6757 START_PROFILE(SMBtranss2
);
6761 for (state
= conn
->pending_trans
; state
!= NULL
;
6762 state
= state
->next
) {
6763 if (state
->mid
== SVAL(inbuf
,smb_mid
)) {
6768 if ((state
== NULL
) || (state
->cmd
!= SMBtrans2
)) {
6769 END_PROFILE(SMBtranss2
);
6770 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
6773 /* Revise state->total_param and state->total_data in case they have
6774 changed downwards */
6776 if (SVAL(inbuf
, smb_tpscnt
) < state
->total_param
)
6777 state
->total_param
= SVAL(inbuf
, smb_tpscnt
);
6778 if (SVAL(inbuf
, smb_tdscnt
) < state
->total_data
)
6779 state
->total_data
= SVAL(inbuf
, smb_tdscnt
);
6781 pcnt
= SVAL(inbuf
, smb_spscnt
);
6782 poff
= SVAL(inbuf
, smb_spsoff
);
6783 pdisp
= SVAL(inbuf
, smb_spsdisp
);
6785 dcnt
= SVAL(inbuf
, smb_sdscnt
);
6786 doff
= SVAL(inbuf
, smb_sdsoff
);
6787 ddisp
= SVAL(inbuf
, smb_sdsdisp
);
6789 state
->received_param
+= pcnt
;
6790 state
->received_data
+= dcnt
;
6792 if ((state
->received_data
> state
->total_data
) ||
6793 (state
->received_param
> state
->total_param
))
6797 if (pdisp
> state
->total_param
||
6798 pcnt
> state
->total_param
||
6799 pdisp
+pcnt
> state
->total_param
||
6800 pdisp
+pcnt
< pdisp
) {
6804 if (poff
> av_size
||
6806 poff
+pcnt
> av_size
||
6811 memcpy(state
->param
+pdisp
,smb_base(inbuf
)+poff
,
6816 if (ddisp
> state
->total_data
||
6817 dcnt
> state
->total_data
||
6818 ddisp
+dcnt
> state
->total_data
||
6819 ddisp
+dcnt
< ddisp
) {
6823 if (ddisp
> av_size
||
6825 ddisp
+dcnt
> av_size
||
6826 ddisp
+dcnt
< ddisp
) {
6830 memcpy(state
->data
+ddisp
, smb_base(inbuf
)+doff
,
6834 if ((state
->received_param
< state
->total_param
) ||
6835 (state
->received_data
< state
->total_data
)) {
6836 END_PROFILE(SMBtranss2
);
6840 /* construct_reply_common has done us the favor to pre-fill the
6841 * command field with SMBtranss2 which is wrong :-)
6843 SCVAL(outbuf
,smb_com
,SMBtrans2
);
6845 outsize
= handle_trans2(conn
, state
, inbuf
, outbuf
, size
, bufsize
);
6847 DLIST_REMOVE(conn
->pending_trans
, state
);
6848 SAFE_FREE(state
->data
);
6849 SAFE_FREE(state
->param
);
6853 END_PROFILE(SMBtranss2
);
6854 return(ERROR_DOS(ERRSRV
,ERRnosupport
));
6857 END_PROFILE(SMBtranss2
);
6862 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
6863 DLIST_REMOVE(conn
->pending_trans
, state
);
6864 SAFE_FREE(state
->data
);
6865 SAFE_FREE(state
->param
);
6867 END_PROFILE(SMBtranss2
);
6868 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);