2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
5 Copyright (C) Stefan (metze) Metzmacher 2003
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern enum protocol_types Protocol
;
27 extern int smb_read_error
;
28 extern int global_oplock_break
;
29 extern uint32 global_client_caps
;
30 extern struct current_user current_user
;
32 #define get_file_size(sbuf) ((sbuf).st_size)
33 #define DIR_ENTRY_SAFETY_MARGIN 4096
35 /********************************************************************
36 Roundup a value to the nearest allocation roundup size boundary.
37 Only do this for Windows clients.
38 ********************************************************************/
40 SMB_BIG_UINT
smb_roundup(connection_struct
*conn
, SMB_BIG_UINT val
)
42 SMB_BIG_UINT rval
= lp_allocation_roundup_size(SNUM(conn
));
44 /* Only roundup for Windows clients. */
45 enum remote_arch_types ra_type
= get_remote_arch();
46 if (rval
&& (ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
47 val
= SMB_ROUNDUP(val
,rval
);
52 /********************************************************************
53 Given a stat buffer return the allocated size on disk, taking into
55 ********************************************************************/
57 SMB_BIG_UINT
get_allocation_size(connection_struct
*conn
, files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
61 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
62 ret
= (SMB_BIG_UINT
)STAT_ST_BLOCKSIZE
* (SMB_BIG_UINT
)sbuf
->st_blocks
;
64 ret
= (SMB_BIG_UINT
)get_file_size(*sbuf
);
67 if (!ret
&& fsp
&& fsp
->initial_allocation_size
)
68 ret
= fsp
->initial_allocation_size
;
70 return smb_roundup(conn
, ret
);
73 /****************************************************************************
74 Utility functions for dealing with extended attributes.
75 ****************************************************************************/
77 static const char *prohibited_ea_names
[] = {
78 SAMBA_POSIX_INHERITANCE_EA_NAME
,
79 SAMBA_XATTR_DOS_ATTRIB
,
83 /****************************************************************************
84 Refuse to allow clients to overwrite our private xattrs.
85 ****************************************************************************/
87 static BOOL
samba_private_attr_name(const char *unix_ea_name
)
91 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
92 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
99 struct ea_list
*next
, *prev
;
103 /****************************************************************************
104 Get one EA value. Fill in a struct ea_struct.
105 ****************************************************************************/
107 static BOOL
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
108 const char *fname
, char *ea_name
, struct ea_struct
*pea
)
110 /* Get the value of this xattr. Max size is 64k. */
111 size_t attr_size
= 256;
117 val
= TALLOC_REALLOC_ARRAY(mem_ctx
, val
, char, attr_size
);
122 if (fsp
&& fsp
->fd
!= -1) {
123 sizeret
= SMB_VFS_FGETXATTR(fsp
, fsp
->fd
, ea_name
, val
, attr_size
);
125 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
128 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
137 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name
, sizeret
));
138 dump_data(10, val
, sizeret
);
141 if (strnequal(ea_name
, "user.", 5)) {
142 pea
->name
= &ea_name
[5];
146 pea
->value
.data
= val
;
147 pea
->value
.length
= (size_t)sizeret
;
151 /****************************************************************************
152 Return a linked list of the total EA's. Plus the total size
153 ****************************************************************************/
155 static struct ea_list
*get_ea_list(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
, const char *fname
, size_t *pea_total_len
)
157 /* Get a list of all xattrs. Max namesize is 64k. */
158 size_t ea_namelist_size
= 1024;
163 struct ea_list
*ea_list_head
= NULL
;
167 if (!lp_ea_support(SNUM(conn
))) {
171 for (i
= 0, ea_namelist
= TALLOC(mem_ctx
, ea_namelist_size
); i
< 6;
172 ea_namelist
= TALLOC_REALLOC_ARRAY(mem_ctx
, ea_namelist
, char, ea_namelist_size
), i
++) {
173 if (fsp
&& fsp
->fd
!= -1) {
174 sizeret
= SMB_VFS_FLISTXATTR(fsp
, fsp
->fd
, ea_namelist
, ea_namelist_size
);
176 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
, ea_namelist_size
);
179 if (sizeret
== -1 && errno
== ERANGE
) {
180 ea_namelist_size
*= 2;
189 DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret
));
192 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
) + 1) {
193 struct ea_list
*listp
, *tmp
;
195 if (strnequal(p
, "system.", 7) || samba_private_attr_name(p
))
198 listp
= TALLOC_P(mem_ctx
, struct ea_list
);
202 if (!get_ea_value(mem_ctx
, conn
, fsp
, fname
, p
, &listp
->ea
)) {
208 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
209 *pea_total_len
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
210 DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
211 *pea_total_len
, dos_ea_name
,
212 (unsigned int)listp
->ea
.value
.length
));
214 DLIST_ADD_END(ea_list_head
, listp
, tmp
);
216 /* Add on 4 for total length. */
217 if (*pea_total_len
) {
222 DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len
));
226 /****************************************************************************
227 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
229 ****************************************************************************/
231 static unsigned int fill_ea_buffer(char *pdata
, unsigned int total_data_size
,
232 connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
234 unsigned int ret_data_size
= 4;
238 struct ea_list
*ea_list
;
240 SMB_ASSERT(total_data_size
>= 4);
243 if (!lp_ea_support(SNUM(conn
))) {
246 mem_ctx
= talloc_init("fill_ea_buffer");
251 ea_list
= get_ea_list(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
253 talloc_destroy(mem_ctx
);
257 if (total_ea_len
> total_data_size
) {
258 talloc_destroy(mem_ctx
);
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, total_ea_len = %u\n",
290 ret_data_size
, total_ea_len
));
291 talloc_destroy(mem_ctx
);
292 SIVAL(pdata
,0,ret_data_size
);
293 return ret_data_size
;
296 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
298 size_t total_ea_len
= 0;
299 TALLOC_CTX
*mem_ctx
= NULL
;
301 if (!lp_ea_support(SNUM(conn
))) {
304 mem_ctx
= talloc_init("estimate_ea_size");
305 (void)get_ea_list(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
306 talloc_destroy(mem_ctx
);
310 /****************************************************************************
311 Ensure the EA name is case insensitive by matching any existing EA name.
312 ****************************************************************************/
314 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
317 TALLOC_CTX
*mem_ctx
= talloc_init("canonicalize_ea_name");
318 struct ea_list
*ea_list
= get_ea_list(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
320 for (; ea_list
; ea_list
= ea_list
->next
) {
321 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
322 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
323 &unix_ea_name
[5], ea_list
->ea
.name
));
324 safe_strcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-6);
328 talloc_destroy(mem_ctx
);
331 /****************************************************************************
332 Set or delete an extended attribute.
333 ****************************************************************************/
335 static NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
, const char *fname
,
336 char *pdata
, int total_data
)
338 unsigned int namelen
;
341 fstring unix_ea_name
;
343 if (!lp_ea_support(SNUM(conn
))) {
344 return NT_STATUS_EAS_NOT_SUPPORTED
;
347 if (total_data
< 8) {
348 return NT_STATUS_INVALID_PARAMETER
;
351 if (IVAL(pdata
,0) > total_data
) {
352 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata
,0), (unsigned int)total_data
));
353 return NT_STATUS_INVALID_PARAMETER
;
357 namelen
= CVAL(pdata
,1);
358 ealen
= SVAL(pdata
,2);
360 if (total_data
< 8 + namelen
+ 1 + ealen
) {
361 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
362 (unsigned int)total_data
, namelen
, ealen
));
363 return NT_STATUS_INVALID_PARAMETER
;
366 if (pdata
[namelen
] != '\0') {
367 DEBUG(10,("set_ea: ea name not null terminated\n"));
368 return NT_STATUS_INVALID_PARAMETER
;
371 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
372 pull_ascii(&unix_ea_name
[5], pdata
, sizeof(fstring
) - 5, -1, STR_TERMINATE
);
373 pdata
+= (namelen
+ 1);
375 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
377 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, ealen
));
379 DEBUG(10,("set_ea: data :\n"));
380 dump_data(10, pdata
, ealen
);
383 if (samba_private_attr_name(unix_ea_name
)) {
384 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
385 return NT_STATUS_ACCESS_DENIED
;
389 /* Remove the attribute. */
390 if (fsp
&& (fsp
->fd
!= -1)) {
391 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
392 unix_ea_name
, fsp
->fsp_name
));
393 ret
= SMB_VFS_FREMOVEXATTR(fsp
, fsp
->fd
, unix_ea_name
);
395 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
396 unix_ea_name
, fname
));
397 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
400 /* Removing a non existent attribute always succeeds. */
401 if (ret
== -1 && errno
== ENOATTR
) {
402 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name
));
407 if (fsp
&& (fsp
->fd
!= -1)) {
408 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
409 unix_ea_name
, fsp
->fsp_name
));
410 ret
= SMB_VFS_FSETXATTR(fsp
, fsp
->fd
, unix_ea_name
, pdata
, ealen
, 0);
412 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
413 unix_ea_name
, fname
));
414 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
, pdata
, ealen
, 0);
420 if (errno
== ENOTSUP
) {
421 return NT_STATUS_EAS_NOT_SUPPORTED
;
424 return map_nt_error_from_unix(errno
);
430 /****************************************************************************
431 Send the required number of replies back.
432 We assume all fields other than the data fields are
433 set correctly for the type of call.
434 HACK ! Always assumes smb_setup field is zero.
435 ****************************************************************************/
437 static int send_trans2_replies(char *outbuf
,
444 /* As we are using a protocol > LANMAN1 then the max_send
445 variable must have been set in the sessetupX call.
446 This takes precedence over the max_xmit field in the
447 global struct. These different max_xmit variables should
448 be merged as this is now too confusing */
451 int data_to_send
= datasize
;
452 int params_to_send
= paramsize
;
456 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
457 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
458 int data_alignment_offset
= 0;
460 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
462 set_message(outbuf
,10,0,True
);
464 /* If there genuinely are no parameters or data to send just send the empty packet */
466 if(params_to_send
== 0 && data_to_send
== 0) {
467 if (!send_smb(smbd_server_fd(),outbuf
))
468 exit_server("send_trans2_replies: send_smb failed.");
472 /* When sending params and data ensure that both are nicely aligned */
473 /* Only do this alignment when there is also data to send - else
474 can cause NT redirector problems. */
476 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
477 data_alignment_offset
= 4 - (params_to_send
% 4);
479 /* Space is bufsize minus Netbios over TCP header minus SMB header */
480 /* The alignment_offset is to align the param bytes on an even byte
481 boundary. NT 4.0 Beta needs this to work correctly. */
483 useable_space
= bufsize
- ((smb_buf(outbuf
)+ alignment_offset
+data_alignment_offset
) - outbuf
);
485 /* useable_space can never be more than max_send minus the alignment offset. */
487 useable_space
= MIN(useable_space
, max_send
- (alignment_offset
+data_alignment_offset
));
489 while (params_to_send
|| data_to_send
) {
490 /* Calculate whether we will totally or partially fill this packet */
492 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
+ data_alignment_offset
;
494 /* We can never send more than useable_space */
496 * Note that 'useable_space' does not include the alignment offsets,
497 * but we must include the alignment offsets in the calculation of
498 * the length of the data we send over the wire, as the alignment offsets
499 * are sent here. Fix from Marc_Jacobsen@hp.com.
502 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
+ alignment_offset
+ data_alignment_offset
);
504 set_message(outbuf
, 10, total_sent_thistime
, True
);
506 /* Set total params and data to be sent */
507 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
508 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
510 /* Calculate how many parameters and data we can fit into
511 * this packet. Parameters get precedence
514 params_sent_thistime
= MIN(params_to_send
,useable_space
);
515 data_sent_thistime
= useable_space
- params_sent_thistime
;
516 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
518 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
520 /* smb_proff is the offset from the start of the SMB header to the
521 parameter bytes, however the first 4 bytes of outbuf are
522 the Netbios over TCP header. Thus use smb_base() to subtract
523 them from the calculation */
525 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
527 if(params_sent_thistime
== 0)
528 SSVAL(outbuf
,smb_prdisp
,0);
530 /* Absolute displacement of param bytes sent in this packet */
531 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
533 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
534 if(data_sent_thistime
== 0) {
535 SSVAL(outbuf
,smb_droff
,0);
536 SSVAL(outbuf
,smb_drdisp
, 0);
538 /* The offset of the data bytes is the offset of the
539 parameter bytes plus the number of parameters being sent this time */
540 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
541 smb_base(outbuf
)) + params_sent_thistime
+ data_alignment_offset
);
542 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
545 /* Copy the param bytes into the packet */
547 if(params_sent_thistime
)
548 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
550 /* Copy in the data bytes */
551 if(data_sent_thistime
)
552 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
+
553 data_alignment_offset
,pd
,data_sent_thistime
);
555 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
556 params_sent_thistime
, data_sent_thistime
, useable_space
));
557 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
558 params_to_send
, data_to_send
, paramsize
, datasize
));
560 /* Send the packet */
561 if (!send_smb(smbd_server_fd(),outbuf
))
562 exit_server("send_trans2_replies: send_smb failed.");
564 pp
+= params_sent_thistime
;
565 pd
+= data_sent_thistime
;
567 params_to_send
-= params_sent_thistime
;
568 data_to_send
-= data_sent_thistime
;
571 if(params_to_send
< 0 || data_to_send
< 0) {
572 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
573 params_to_send
, data_to_send
));
581 /****************************************************************************
582 Reply to a TRANSACT2_OPEN.
583 ****************************************************************************/
585 static int call_trans2open(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
586 char **pparams
, int total_params
, char **ppdata
, int total_data
,
587 unsigned int max_data_bytes
)
589 char *params
= *pparams
;
594 BOOL return_additional_info
;
603 int fmode
=0,mtime
=0,rmode
;
605 SMB_STRUCT_STAT sbuf
;
607 BOOL bad_path
= False
;
612 * Ensure we have enough parameters to perform the operation.
615 if (total_params
< 29)
616 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
618 open_mode
= SVAL(params
, 2);
619 open_attr
= SVAL(params
,6);
620 oplock_request
= (((SVAL(params
,0)|(1<<1))>>1) | ((SVAL(params
,0)|(1<<2))>>1));
622 return_additional_info
= BITSETW(params
,0);
623 open_sattr
= SVAL(params
, 4);
624 open_time
= make_unix_date3(params
+8);
626 open_ofun
= SVAL(params
,12);
627 open_size
= IVAL(params
,14);
631 return(ERROR_DOS(ERRSRV
,ERRaccess
));
633 srvstr_get_path(inbuf
, fname
, pname
, sizeof(fname
), -1, STR_TERMINATE
, &status
, False
);
634 if (!NT_STATUS_IS_OK(status
)) {
635 return ERROR_NT(status
);
638 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
639 fname
,open_mode
, open_attr
, open_ofun
, open_size
));
641 /* XXXX we need to handle passed times, sattr and flags */
643 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
645 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
648 if (!check_name(fname
,conn
)) {
649 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRnoaccess
);
652 fsp
= open_file_shared(conn
,fname
,&sbuf
,open_mode
,open_ofun
,(uint32
)open_attr
,
653 oplock_request
, &rmode
,&smb_action
);
656 if (open_was_deferred(SVAL(inbuf
,smb_mid
))) {
657 /* We have re-scheduled this call. */
658 clear_cached_errors();
661 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRnoaccess
);
664 size
= get_file_size(sbuf
);
665 fmode
= dos_mode(conn
,fname
,&sbuf
);
666 mtime
= sbuf
.st_mtime
;
669 close_file(fsp
,False
);
670 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
673 /* Realloc the size of parameters and data we will return */
674 params
= SMB_REALLOC(*pparams
, 28);
676 return(ERROR_DOS(ERRDOS
,ERRnomem
));
679 memset((char *)params
,'\0',28);
680 SSVAL(params
,0,fsp
->fnum
);
681 SSVAL(params
,2,fmode
);
682 put_dos_date2(params
,4, mtime
);
683 SIVAL(params
,8, (uint32
)size
);
684 SSVAL(params
,12,rmode
);
686 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
687 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
689 SSVAL(params
,18,smb_action
);
692 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
694 SIVAL(params
,20,inode
);
696 /* Send the required number of replies */
697 send_trans2_replies(outbuf
, bufsize
, params
, 28, *ppdata
, 0);
702 /*********************************************************
703 Routine to check if a given string matches exactly.
704 as a special case a mask of "." does NOT match. That
705 is required for correct wildcard semantics
706 Case can be significant or not.
707 **********************************************************/
709 static BOOL
exact_match(char *str
,char *mask
, BOOL case_sig
)
711 if (mask
[0] == '.' && mask
[1] == 0)
714 return strcmp(str
,mask
)==0;
715 if (StrCaseCmp(str
,mask
) != 0) {
718 if (ms_has_wild(str
)) {
724 /****************************************************************************
725 Return the filetype for UNIX extensions.
726 ****************************************************************************/
728 static uint32
unix_filetype(mode_t mode
)
731 return UNIX_TYPE_FILE
;
732 else if(S_ISDIR(mode
))
733 return UNIX_TYPE_DIR
;
735 else if(S_ISLNK(mode
))
736 return UNIX_TYPE_SYMLINK
;
739 else if(S_ISCHR(mode
))
740 return UNIX_TYPE_CHARDEV
;
743 else if(S_ISBLK(mode
))
744 return UNIX_TYPE_BLKDEV
;
747 else if(S_ISFIFO(mode
))
748 return UNIX_TYPE_FIFO
;
751 else if(S_ISSOCK(mode
))
752 return UNIX_TYPE_SOCKET
;
755 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode
));
756 return UNIX_TYPE_UNKNOWN
;
759 /****************************************************************************
760 Map wire perms onto standard UNIX permissions. Obey share restrictions.
761 ****************************************************************************/
763 static mode_t
unix_perms_from_wire( connection_struct
*conn
, SMB_STRUCT_STAT
*pst
, uint32 perms
)
767 if (perms
== SMB_MODE_NO_CHANGE
)
770 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
771 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
772 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
773 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
774 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
775 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
776 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
777 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
778 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
780 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
783 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
786 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
789 if (VALID_STAT(*pst
) && S_ISDIR(pst
->st_mode
)) {
790 ret
&= lp_dir_mask(SNUM(conn
));
791 /* Add in force bits */
792 ret
|= lp_force_dir_mode(SNUM(conn
));
794 /* Apply mode mask */
795 ret
&= lp_create_mask(SNUM(conn
));
796 /* Add in force bits */
797 ret
|= lp_force_create_mode(SNUM(conn
));
803 /****************************************************************************
804 Get a level dependent lanman2 dir entry.
805 ****************************************************************************/
807 static BOOL
get_lanman2_dir_entry(connection_struct
*conn
,
808 void *inbuf
, void *outbuf
,
809 char *path_mask
,int dirtype
,int info_level
,
810 int requires_resume_key
,
811 BOOL dont_descend
,char **ppdata
,
812 char *base_data
, int space_remaining
,
813 BOOL
*out_of_space
, BOOL
*got_exact_match
,
818 SMB_STRUCT_STAT sbuf
;
822 char *p
, *q
, *pdata
= *ppdata
;
826 SMB_OFF_T file_size
= 0;
827 SMB_BIG_UINT allocation_size
= 0;
829 time_t mdate
=0, adate
=0, cdate
=0;
831 char *last_entry_ptr
;
833 int nt_extmode
; /* Used for NT connections instead of mode */
834 BOOL needslash
= ( conn
->dirpath
[strlen(conn
->dirpath
) -1] != '/');
837 *out_of_space
= False
;
838 *got_exact_match
= False
;
843 p
= strrchr_m(path_mask
,'/');
850 pstrcpy(mask
, path_mask
);
855 /* Needed if we run out of space */
856 long curr_dirpos
= prev_dirpos
= dptr_TellDir(conn
->dirptr
);
857 dname
= dptr_ReadDirName(conn
->dirptr
,&curr_dirpos
,&sbuf
);
860 * Due to bugs in NT client redirectors we are not using
861 * resume keys any more - set them to zero.
862 * Check out the related comments in findfirst/findnext.
868 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
869 (long)conn
->dirptr
,curr_dirpos
));
874 pstrcpy(fname
,dname
);
876 if(!(got_match
= *got_exact_match
= exact_match(fname
, mask
, conn
->case_sensitive
)))
877 got_match
= mask_match(fname
, mask
, conn
->case_sensitive
);
879 if(!got_match
&& !mangle_is_8_3(fname
, False
)) {
882 * It turns out that NT matches wildcards against
883 * both long *and* short names. This may explain some
884 * of the wildcard wierdness from old DOS clients
885 * that some people have been seeing.... JRA.
889 pstrcpy( newname
, fname
);
890 mangle_map( newname
, True
, False
, SNUM(conn
));
891 if(!(got_match
= *got_exact_match
= exact_match(newname
, mask
, conn
->case_sensitive
)))
892 got_match
= mask_match(newname
, mask
, conn
->case_sensitive
);
896 BOOL isdots
= (strequal(fname
,"..") || strequal(fname
,"."));
897 if (dont_descend
&& !isdots
)
900 pstrcpy(pathreal
,conn
->dirpath
);
902 pstrcat(pathreal
,"/");
903 pstrcat(pathreal
,dname
);
905 if (INFO_LEVEL_IS_UNIX(info_level
)) {
906 if (SMB_VFS_LSTAT(conn
,pathreal
,&sbuf
) != 0) {
907 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
908 pathreal
,strerror(errno
)));
911 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,pathreal
,&sbuf
) != 0) {
913 /* Needed to show the msdfs symlinks as
916 if(lp_host_msdfs() &&
917 lp_msdfs_root(SNUM(conn
)) &&
918 is_msdfs_link(conn
, pathreal
, NULL
, NULL
,
921 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal
));
922 sbuf
.st_mode
= (sbuf
.st_mode
& 0xFFF) | S_IFDIR
;
926 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
927 pathreal
,strerror(errno
)));
932 mode
= dos_mode(conn
,pathreal
,&sbuf
);
934 if (!dir_check_ftype(conn
,mode
,dirtype
)) {
935 DEBUG(5,("[%s] attribs didn't match %x\n",fname
,dirtype
));
939 file_size
= get_file_size(sbuf
);
940 allocation_size
= get_allocation_size(conn
,NULL
,&sbuf
);
941 mdate
= sbuf
.st_mtime
;
942 adate
= sbuf
.st_atime
;
943 cdate
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
945 if (lp_dos_filetime_resolution(SNUM(conn
))) {
952 /* This is necessary, as otherwise the
953 * desktop.ini file in this folder is
955 mode
|= (lp_profile_acls(SNUM(conn
)) ? aRONLY
: 0);
959 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal
,fname
));
965 mangle_map(fname
,False
,True
,SNUM(conn
));
970 nt_extmode
= mode
? mode
: FILE_ATTRIBUTE_NORMAL
;
972 switch (info_level
) {
973 case SMB_INFO_STANDARD
:
974 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
975 if(requires_resume_key
) {
979 put_dos_date2(p
,l1_fdateCreation
,cdate
);
980 put_dos_date2(p
,l1_fdateLastAccess
,adate
);
981 put_dos_date2(p
,l1_fdateLastWrite
,mdate
);
982 SIVAL(p
,l1_cbFile
,(uint32
)file_size
);
983 SIVAL(p
,l1_cbFileAlloc
,(uint32
)allocation_size
);
984 SSVAL(p
,l1_attrFile
,mode
);
987 p
+= align_string(outbuf
, p
, 0);
988 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
989 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
) {
991 SCVAL(nameptr
, -1, len
- 2);
993 SCVAL(nameptr
, -1, 0);
997 SCVAL(nameptr
, -1, len
- 1);
999 SCVAL(nameptr
, -1, 0);
1005 case SMB_INFO_QUERY_EA_SIZE
:
1006 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
1007 if(requires_resume_key
) {
1011 put_dos_date2(p
,l2_fdateCreation
,cdate
);
1012 put_dos_date2(p
,l2_fdateLastAccess
,adate
);
1013 put_dos_date2(p
,l2_fdateLastWrite
,mdate
);
1014 SIVAL(p
,l2_cbFile
,(uint32
)file_size
);
1015 SIVAL(p
,l2_cbFileAlloc
,(uint32
)allocation_size
);
1016 SSVAL(p
,l2_attrFile
,mode
);
1018 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1019 SIVAL(p
,l2_cbList
,ea_size
); /* Extended attributes */
1023 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
| STR_NOALIGN
);
1024 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
) {
1037 SCVAL(nameptr
,0,len
);
1039 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1042 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1043 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1044 was_8_3
= mangle_is_8_3(fname
, True
);
1046 SIVAL(p
,0,reskey
); p
+= 4;
1047 put_long_date(p
,cdate
); p
+= 8;
1048 put_long_date(p
,adate
); p
+= 8;
1049 put_long_date(p
,mdate
); p
+= 8;
1050 put_long_date(p
,mdate
); p
+= 8;
1051 SOFF_T(p
,0,file_size
); p
+= 8;
1052 SOFF_T(p
,0,allocation_size
); p
+= 8;
1053 SIVAL(p
,0,nt_extmode
); p
+= 4;
1054 q
= p
; p
+= 4; /* q is placeholder for name length. */
1056 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1057 SIVAL(p
,0,ea_size
); /* Extended attributes */
1060 /* Clear the short name buffer. This is
1061 * IMPORTANT as not doing so will trigger
1062 * a Win2k client bug. JRA.
1065 if (!was_8_3
&& lp_manglednames(SNUM(conn
))) {
1066 pstring mangled_name
;
1067 pstrcpy(mangled_name
, fname
);
1068 mangle_map(mangled_name
,True
,True
,SNUM(conn
));
1069 mangled_name
[12] = 0;
1070 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
|STR_UNICODE
);
1077 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1080 len
= PTR_DIFF(p
, pdata
);
1081 len
= (len
+ 3) & ~3;
1086 case SMB_FIND_FILE_DIRECTORY_INFO
:
1087 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1089 SIVAL(p
,0,reskey
); p
+= 4;
1090 put_long_date(p
,cdate
); p
+= 8;
1091 put_long_date(p
,adate
); p
+= 8;
1092 put_long_date(p
,mdate
); p
+= 8;
1093 put_long_date(p
,mdate
); p
+= 8;
1094 SOFF_T(p
,0,file_size
); p
+= 8;
1095 SOFF_T(p
,0,allocation_size
); p
+= 8;
1096 SIVAL(p
,0,nt_extmode
); p
+= 4;
1097 len
= srvstr_push(outbuf
, p
+ 4, fname
, -1, STR_TERMINATE_ASCII
);
1100 len
= PTR_DIFF(p
, pdata
);
1101 len
= (len
+ 3) & ~3;
1106 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1107 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1109 SIVAL(p
,0,reskey
); p
+= 4;
1110 put_long_date(p
,cdate
); p
+= 8;
1111 put_long_date(p
,adate
); p
+= 8;
1112 put_long_date(p
,mdate
); p
+= 8;
1113 put_long_date(p
,mdate
); p
+= 8;
1114 SOFF_T(p
,0,file_size
); p
+= 8;
1115 SOFF_T(p
,0,allocation_size
); p
+= 8;
1116 SIVAL(p
,0,nt_extmode
); p
+= 4;
1117 q
= p
; p
+= 4; /* q is placeholder for name length. */
1119 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1120 SIVAL(p
,0,ea_size
); /* Extended attributes */
1123 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1127 len
= PTR_DIFF(p
, pdata
);
1128 len
= (len
+ 3) & ~3;
1133 case SMB_FIND_FILE_NAMES_INFO
:
1134 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1136 SIVAL(p
,0,reskey
); p
+= 4;
1138 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1139 acl on a dir (tridge) */
1140 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1143 len
= PTR_DIFF(p
, pdata
);
1144 len
= (len
+ 3) & ~3;
1149 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1150 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1152 SIVAL(p
,0,reskey
); p
+= 4;
1153 put_long_date(p
,cdate
); p
+= 8;
1154 put_long_date(p
,adate
); p
+= 8;
1155 put_long_date(p
,mdate
); p
+= 8;
1156 put_long_date(p
,mdate
); p
+= 8;
1157 SOFF_T(p
,0,file_size
); p
+= 8;
1158 SOFF_T(p
,0,allocation_size
); p
+= 8;
1159 SIVAL(p
,0,nt_extmode
); p
+= 4;
1160 q
= p
; p
+= 4; /* q is placeholder for name length. */
1162 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1163 SIVAL(p
,0,ea_size
); /* Extended attributes */
1166 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
1167 SIVAL(p
,0,sbuf
.st_dev
); p
+= 4;
1168 SIVAL(p
,0,sbuf
.st_ino
); p
+= 4;
1169 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1172 len
= PTR_DIFF(p
, pdata
);
1173 len
= (len
+ 3) & ~3;
1178 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1179 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1180 was_8_3
= mangle_is_8_3(fname
, True
);
1182 SIVAL(p
,0,reskey
); p
+= 4;
1183 put_long_date(p
,cdate
); p
+= 8;
1184 put_long_date(p
,adate
); p
+= 8;
1185 put_long_date(p
,mdate
); p
+= 8;
1186 put_long_date(p
,mdate
); p
+= 8;
1187 SOFF_T(p
,0,file_size
); p
+= 8;
1188 SOFF_T(p
,0,allocation_size
); p
+= 8;
1189 SIVAL(p
,0,nt_extmode
); p
+= 4;
1190 q
= p
; p
+= 4; /* q is placeholder for name length */
1192 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1193 SIVAL(p
,0,ea_size
); /* Extended attributes */
1196 /* Clear the short name buffer. This is
1197 * IMPORTANT as not doing so will trigger
1198 * a Win2k client bug. JRA.
1201 if (!was_8_3
&& lp_manglednames(SNUM(conn
))) {
1202 pstring mangled_name
;
1203 pstrcpy(mangled_name
, fname
);
1204 mangle_map(mangled_name
,True
,True
,SNUM(conn
));
1205 mangled_name
[12] = 0;
1206 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
|STR_UNICODE
);
1213 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
1214 SIVAL(p
,0,sbuf
.st_dev
); p
+= 4;
1215 SIVAL(p
,0,sbuf
.st_ino
); p
+= 4;
1216 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1219 len
= PTR_DIFF(p
, pdata
);
1220 len
= (len
+ 3) & ~3;
1225 /* CIFS UNIX Extension. */
1227 case SMB_FIND_FILE_UNIX
:
1228 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1230 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
1232 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1233 SOFF_T(p
,0,get_file_size(sbuf
)); /* File size 64 Bit */
1236 SOFF_T(p
,0,get_allocation_size(conn
,NULL
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
1239 put_long_date(p
,sbuf
.st_ctime
); /* Inode change Time 64 Bit */
1240 put_long_date(p
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
1241 put_long_date(p
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
1244 SIVAL(p
,0,sbuf
.st_uid
); /* user id for the owner */
1248 SIVAL(p
,0,sbuf
.st_gid
); /* group id of owner */
1252 SIVAL(p
,0,unix_filetype(sbuf
.st_mode
));
1255 SIVAL(p
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
1259 SIVAL(p
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
1263 SINO_T(p
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
1266 SIVAL(p
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
1270 SIVAL(p
,0,sbuf
.st_nlink
); /* number of hard links */
1274 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
1277 len
= PTR_DIFF(p
, pdata
);
1278 len
= (len
+ 3) & ~3;
1279 SIVAL(pdata
,0,len
); /* Offset from this structure to the beginning of the next one */
1281 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1290 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
1291 /* Move the dirptr back to prev_dirpos */
1292 dptr_SeekDir(conn
->dirptr
, prev_dirpos
);
1293 *out_of_space
= True
;
1294 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1295 return False
; /* Not finished - just out of space */
1298 /* Setup the last entry pointer, as an offset from base_data */
1299 *last_entry_off
= PTR_DIFF(last_entry_ptr
,base_data
);
1300 /* Advance the data pointer to the next slot */
1306 /****************************************************************************
1307 Reply to a TRANS2_FINDFIRST.
1308 ****************************************************************************/
1310 static int call_trans2findfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
1311 char **pparams
, int total_params
, char **ppdata
, int total_data
,
1312 unsigned int max_data_bytes
)
1314 /* We must be careful here that we don't return more than the
1315 allowed number of data bytes. If this means returning fewer than
1316 maxentries then so be it. We assume that the redirector has
1317 enough room for the fixed number of parameter bytes it has
1319 char *params
= *pparams
;
1320 char *pdata
= *ppdata
;
1321 int dirtype
= SVAL(params
,0);
1322 int maxentries
= SVAL(params
,2);
1323 uint16 findfirst_flags
= SVAL(params
,4);
1324 BOOL close_after_first
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE
);
1325 BOOL close_if_end
= (findfirst_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
1326 BOOL requires_resume_key
= (findfirst_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
1327 int info_level
= SVAL(params
,6);
1331 int last_entry_off
=0;
1335 BOOL finished
= False
;
1336 BOOL dont_descend
= False
;
1337 BOOL out_of_space
= False
;
1338 int space_remaining
;
1339 BOOL bad_path
= False
;
1340 SMB_STRUCT_STAT sbuf
;
1341 NTSTATUS ntstatus
= NT_STATUS_OK
;
1343 if (total_params
< 12)
1344 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1346 *directory
= *mask
= 0;
1348 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1349 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1350 dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
1351 info_level
, max_data_bytes
));
1354 /* W2K3 seems to treat zero as 1. */
1358 switch (info_level
) {
1359 case SMB_INFO_STANDARD
:
1360 case SMB_INFO_QUERY_EA_SIZE
:
1361 case SMB_FIND_FILE_DIRECTORY_INFO
:
1362 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1363 case SMB_FIND_FILE_NAMES_INFO
:
1364 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1365 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1366 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1368 case SMB_FIND_FILE_UNIX
:
1369 if (!lp_unix_extensions())
1370 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1373 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1376 srvstr_get_path(inbuf
, directory
, params
+12, sizeof(directory
), -1, STR_TERMINATE
, &ntstatus
, True
);
1377 if (!NT_STATUS_IS_OK(ntstatus
)) {
1378 return ERROR_NT(ntstatus
);
1381 RESOLVE_DFSPATH(directory
, conn
, inbuf
, outbuf
);
1383 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
1385 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1387 if(!check_name(directory
,conn
)) {
1388 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
1391 p
= strrchr_m(directory
,'/');
1393 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1394 if((directory
[0] == '.') && (directory
[1] == '\0'))
1397 pstrcpy(mask
,directory
);
1398 pstrcpy(directory
,"./");
1404 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
1406 pdata
= SMB_REALLOC(*ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1408 return(ERROR_DOS(ERRDOS
,ERRnomem
));
1411 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1413 /* Realloc the params space */
1414 params
= SMB_REALLOC(*pparams
, 10);
1416 return ERROR_DOS(ERRDOS
,ERRnomem
);
1419 dptr_num
= dptr_create(conn
,directory
, False
, True
,SVAL(inbuf
,smb_pid
));
1421 return(UNIXERROR(ERRDOS
,ERRbadfile
));
1423 /* Save the wildcard match and attribs we are using on this directory -
1424 needed as lanman2 assumes these are being saved between calls */
1426 if (!dptr_set_wcard_and_attributes(dptr_num
, mask
, dirtype
)) {
1427 dptr_close(&dptr_num
);
1428 return ERROR_DOS(ERRDOS
,ERRnomem
);
1431 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num
, mask
, dirtype
));
1433 /* We don't need to check for VOL here as this is returned by
1434 a different TRANS2 call. */
1436 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1437 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
1438 dont_descend
= True
;
1441 space_remaining
= max_data_bytes
;
1442 out_of_space
= False
;
1444 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
1445 BOOL got_exact_match
= False
;
1447 /* this is a heuristic to avoid seeking the dirptr except when
1448 absolutely necessary. It allows for a filename of about 40 chars */
1449 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1450 out_of_space
= True
;
1453 finished
= !get_lanman2_dir_entry(conn
,
1455 mask
,dirtype
,info_level
,
1456 requires_resume_key
,dont_descend
,
1457 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1461 if (finished
&& out_of_space
)
1464 if (!finished
&& !out_of_space
)
1468 * As an optimisation if we know we aren't looking
1469 * for a wildcard name (ie. the name matches the wildcard exactly)
1470 * then we can finish on any (first) match.
1471 * This speeds up large directory searches. JRA.
1477 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1480 /* Check if we can close the dirptr */
1481 if(close_after_first
|| (finished
&& close_if_end
)) {
1482 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
1483 dptr_close(&dptr_num
);
1487 * If there are no matching entries we must return ERRDOS/ERRnofiles -
1488 * from observation of NT.
1491 if(numentries
== 0) {
1492 dptr_close(&dptr_num
);
1493 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1496 /* At this point pdata points to numentries directory entries. */
1498 /* Set up the return parameter block */
1499 SSVAL(params
,0,dptr_num
);
1500 SSVAL(params
,2,numentries
);
1501 SSVAL(params
,4,finished
);
1502 SSVAL(params
,6,0); /* Never an EA error */
1503 SSVAL(params
,8,last_entry_off
);
1505 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
));
1507 if ((! *directory
) && dptr_path(dptr_num
))
1508 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1510 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1511 smb_fn_name(CVAL(inbuf
,smb_com
)),
1512 mask
, directory
, dirtype
, numentries
) );
1515 * Force a name mangle here to ensure that the
1516 * mask as an 8.3 name is top of the mangled cache.
1517 * The reasons for this are subtle. Don't remove
1518 * this code unless you know what you are doing
1519 * (see PR#13758). JRA.
1522 if(!mangle_is_8_3_wildcards( mask
, False
))
1523 mangle_map(mask
, True
, True
, SNUM(conn
));
1528 /****************************************************************************
1529 Reply to a TRANS2_FINDNEXT.
1530 ****************************************************************************/
1532 static int call_trans2findnext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1533 char **pparams
, int total_params
, char **ppdata
, int total_data
,
1534 unsigned int max_data_bytes
)
1536 /* We must be careful here that we don't return more than the
1537 allowed number of data bytes. If this means returning fewer than
1538 maxentries then so be it. We assume that the redirector has
1539 enough room for the fixed number of parameter bytes it has
1541 char *params
= *pparams
;
1542 char *pdata
= *ppdata
;
1543 int dptr_num
= SVAL(params
,0);
1544 int maxentries
= SVAL(params
,2);
1545 uint16 info_level
= SVAL(params
,4);
1546 uint32 resume_key
= IVAL(params
,6);
1547 uint16 findnext_flags
= SVAL(params
,10);
1548 BOOL close_after_request
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE
);
1549 BOOL close_if_end
= (findnext_flags
& FLAG_TRANS2_FIND_CLOSE_IF_END
);
1550 BOOL requires_resume_key
= (findnext_flags
& FLAG_TRANS2_FIND_REQUIRE_RESUME
);
1551 BOOL continue_bit
= (findnext_flags
& FLAG_TRANS2_FIND_CONTINUE
);
1552 pstring resume_name
;
1558 int i
, last_entry_off
=0;
1559 BOOL finished
= False
;
1560 BOOL dont_descend
= False
;
1561 BOOL out_of_space
= False
;
1562 int space_remaining
;
1563 NTSTATUS ntstatus
= NT_STATUS_OK
;
1565 if (total_params
< 12)
1566 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1568 *mask
= *directory
= *resume_name
= 0;
1570 srvstr_get_path(inbuf
, resume_name
, params
+12, sizeof(resume_name
), -1, STR_TERMINATE
, &ntstatus
, True
);
1571 if (!NT_STATUS_IS_OK(ntstatus
)) {
1572 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
1573 complain (it thinks we're asking for the directory above the shared
1574 path or an invalid name). Catch this as the resume name is only compared, never used in
1575 a file access. JRA. */
1576 if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_OBJECT_PATH_SYNTAX_BAD
)) {
1577 pstrcpy(resume_name
, "..");
1578 } else if (NT_STATUS_EQUAL(ntstatus
,NT_STATUS_OBJECT_NAME_INVALID
)) {
1579 pstrcpy(resume_name
, ".");
1581 return ERROR_NT(ntstatus
);
1585 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1586 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1587 resume_key = %d resume name = %s continue=%d level = %d\n",
1588 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
1589 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
1592 /* W2K3 seems to treat zero as 1. */
1596 switch (info_level
) {
1597 case SMB_INFO_STANDARD
:
1598 case SMB_INFO_QUERY_EA_SIZE
:
1599 case SMB_FIND_FILE_DIRECTORY_INFO
:
1600 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1601 case SMB_FIND_FILE_NAMES_INFO
:
1602 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1604 case SMB_FIND_FILE_UNIX
:
1605 if (!lp_unix_extensions())
1606 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1609 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1612 pdata
= SMB_REALLOC( *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1614 return ERROR_DOS(ERRDOS
,ERRnomem
);
1617 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1619 /* Realloc the params space */
1620 params
= SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
1621 if( params
== NULL
)
1622 return ERROR_DOS(ERRDOS
,ERRnomem
);
1626 /* Check that the dptr is valid */
1627 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
)))
1628 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1630 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1632 /* Get the wildcard mask from the dptr */
1633 if((p
= dptr_wcard(dptr_num
))== NULL
) {
1634 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
1635 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1639 pstrcpy(directory
,conn
->dirpath
);
1641 /* Get the attr mask from the dptr */
1642 dirtype
= dptr_attr(dptr_num
);
1644 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
1645 dptr_num
, mask
, dirtype
,
1647 dptr_TellDir(conn
->dirptr
)));
1649 /* We don't need to check for VOL here as this is returned by
1650 a different TRANS2 call. */
1652 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1653 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
1654 dont_descend
= True
;
1657 space_remaining
= max_data_bytes
;
1658 out_of_space
= False
;
1661 * Seek to the correct position. We no longer use the resume key but
1662 * depend on the last file name instead.
1665 if(*resume_name
&& !continue_bit
) {
1668 long current_pos
= 0;
1670 * Remember, mangle_map is called by
1671 * get_lanman2_dir_entry(), so the resume name
1672 * could be mangled. Ensure we check the unmangled name.
1675 if (mangle_is_mangled(resume_name
)) {
1676 mangle_check_cache(resume_name
, sizeof(resume_name
)-1);
1680 * Fix for NT redirector problem triggered by resume key indexes
1681 * changing between directory scans. We now return a resume key of 0
1682 * and instead look for the filename to continue from (also given
1683 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1684 * findfirst/findnext (as is usual) then the directory pointer
1685 * should already be at the correct place.
1688 finished
= !dptr_SearchDir(conn
->dirptr
, resume_name
, ¤t_pos
, &st
);
1689 } /* end if resume_name && !continue_bit */
1691 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
1692 BOOL got_exact_match
= False
;
1694 /* this is a heuristic to avoid seeking the dirptr except when
1695 absolutely necessary. It allows for a filename of about 40 chars */
1696 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1697 out_of_space
= True
;
1700 finished
= !get_lanman2_dir_entry(conn
,
1702 mask
,dirtype
,info_level
,
1703 requires_resume_key
,dont_descend
,
1704 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1708 if (finished
&& out_of_space
)
1711 if (!finished
&& !out_of_space
)
1715 * As an optimisation if we know we aren't looking
1716 * for a wildcard name (ie. the name matches the wildcard exactly)
1717 * then we can finish on any (first) match.
1718 * This speeds up large directory searches. JRA.
1724 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1727 /* Check if we can close the dirptr */
1728 if(close_after_request
|| (finished
&& close_if_end
)) {
1729 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
1730 dptr_close(&dptr_num
); /* This frees up the saved mask */
1733 /* Set up the return parameter block */
1734 SSVAL(params
,0,numentries
);
1735 SSVAL(params
,2,finished
);
1736 SSVAL(params
,4,0); /* Never an EA error */
1737 SSVAL(params
,6,last_entry_off
);
1739 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
1741 if ((! *directory
) && dptr_path(dptr_num
))
1742 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1744 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1745 smb_fn_name(CVAL(inbuf
,smb_com
)),
1746 mask
, directory
, dirtype
, numentries
) );
1751 /****************************************************************************
1752 Reply to a TRANS2_QFSINFO (query filesystem info).
1753 ****************************************************************************/
1755 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1756 char **pparams
, int total_params
, char **ppdata
, int total_data
,
1757 unsigned int max_data_bytes
)
1759 char *pdata
= *ppdata
;
1760 char *params
= *pparams
;
1761 uint16 info_level
= SVAL(params
,0);
1764 char *vname
= volume_label(SNUM(conn
));
1765 int snum
= SNUM(conn
);
1766 char *fstype
= lp_fstype(SNUM(conn
));
1769 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
1771 if(SMB_VFS_STAT(conn
,".",&st
)!=0) {
1772 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
1773 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
1776 pdata
= SMB_REALLOC(*ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1777 if ( pdata
== NULL
)
1778 return ERROR_DOS(ERRDOS
,ERRnomem
);
1781 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1783 switch (info_level
) {
1784 case SMB_INFO_ALLOCATION
:
1786 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1788 if (SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (SMB_BIG_UINT
)-1) {
1789 return(UNIXERROR(ERRHRD
,ERRgeneral
));
1792 block_size
= lp_block_size(snum
);
1793 if (bsize
< block_size
) {
1794 SMB_BIG_UINT factor
= block_size
/bsize
;
1799 if (bsize
> block_size
) {
1800 SMB_BIG_UINT factor
= bsize
/block_size
;
1805 bytes_per_sector
= 512;
1806 sectors_per_unit
= bsize
/bytes_per_sector
;
1808 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1809 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1810 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1812 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
1813 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
1814 SIVAL(pdata
,l1_cUnit
,dsize
);
1815 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
1816 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
1820 case SMB_INFO_VOLUME
:
1821 /* Return volume name */
1823 * Add volume serial number - hash of a combination of
1824 * the called hostname and the service name.
1826 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
1827 len
= srvstr_push(outbuf
, pdata
+l2_vol_szVolLabel
, vname
, -1, STR_NOALIGN
);
1828 SCVAL(pdata
,l2_vol_cch
,len
);
1829 data_len
= l2_vol_szVolLabel
+ len
;
1830 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1831 (unsigned)st
.st_ctime
, len
, vname
));
1834 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
1835 case SMB_FS_ATTRIBUTE_INFORMATION
:
1838 #if defined(HAVE_SYS_QUOTAS)
1839 quota_flag
= FILE_VOLUME_QUOTAS
;
1842 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
1843 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)|
1844 quota_flag
); /* FS ATTRIBUTES */
1846 SIVAL(pdata
,4,255); /* Max filename component length */
1847 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1848 and will think we can't do long filenames */
1849 len
= srvstr_push(outbuf
, pdata
+12, fstype
, -1, STR_UNICODE
);
1851 data_len
= 12 + len
;
1854 case SMB_QUERY_FS_LABEL_INFO
:
1855 case SMB_FS_LABEL_INFORMATION
:
1856 len
= srvstr_push(outbuf
, pdata
+4, vname
, -1, 0);
1861 case SMB_QUERY_FS_VOLUME_INFO
:
1862 case SMB_FS_VOLUME_INFORMATION
:
1865 * Add volume serial number - hash of a combination of
1866 * the called hostname and the service name.
1868 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
1869 (str_checksum(get_local_machine_name())<<16));
1871 len
= srvstr_push(outbuf
, pdata
+18, vname
, -1, STR_UNICODE
);
1872 SIVAL(pdata
,12,len
);
1874 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1875 (int)strlen(vname
),vname
, lp_servicename(snum
)));
1878 case SMB_QUERY_FS_SIZE_INFO
:
1879 case SMB_FS_SIZE_INFORMATION
:
1881 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1883 if (SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (SMB_BIG_UINT
)-1) {
1884 return(UNIXERROR(ERRHRD
,ERRgeneral
));
1886 block_size
= lp_block_size(snum
);
1887 if (bsize
< block_size
) {
1888 SMB_BIG_UINT factor
= block_size
/bsize
;
1893 if (bsize
> block_size
) {
1894 SMB_BIG_UINT factor
= bsize
/block_size
;
1899 bytes_per_sector
= 512;
1900 sectors_per_unit
= bsize
/bytes_per_sector
;
1901 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1902 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1903 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1904 SBIG_UINT(pdata
,0,dsize
);
1905 SBIG_UINT(pdata
,8,dfree
);
1906 SIVAL(pdata
,16,sectors_per_unit
);
1907 SIVAL(pdata
,20,bytes_per_sector
);
1911 case SMB_FS_FULL_SIZE_INFORMATION
:
1913 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1915 if (SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
) == (SMB_BIG_UINT
)-1) {
1916 return(UNIXERROR(ERRHRD
,ERRgeneral
));
1918 block_size
= lp_block_size(snum
);
1919 if (bsize
< block_size
) {
1920 SMB_BIG_UINT factor
= block_size
/bsize
;
1925 if (bsize
> block_size
) {
1926 SMB_BIG_UINT factor
= bsize
/block_size
;
1931 bytes_per_sector
= 512;
1932 sectors_per_unit
= bsize
/bytes_per_sector
;
1933 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1934 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1935 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1936 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
1937 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
1938 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
1939 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
1940 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
1944 case SMB_QUERY_FS_DEVICE_INFO
:
1945 case SMB_FS_DEVICE_INFORMATION
:
1947 SIVAL(pdata
,0,0); /* dev type */
1948 SIVAL(pdata
,4,0); /* characteristics */
1951 #ifdef HAVE_SYS_QUOTAS
1952 case SMB_FS_QUOTA_INFORMATION
:
1954 * what we have to send --metze:
1956 * Unknown1: 24 NULL bytes
1957 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1958 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1959 * Quota Flags: 2 byte :
1960 * Unknown3: 6 NULL bytes
1964 * details for Quota Flags:
1966 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1967 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1968 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1969 * 0x0001 Enable Quotas: enable quota for this fs
1973 /* we need to fake up a fsp here,
1974 * because its not send in this call
1977 SMB_NTQUOTA_STRUCT quotas
;
1980 ZERO_STRUCT(quotas
);
1987 if (current_user
.uid
!= 0) {
1988 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1989 lp_servicename(SNUM(conn
)),conn
->user
));
1990 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
1993 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
1994 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
1995 return ERROR_DOS(ERRSRV
,ERRerror
);
2000 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn
))));
2002 /* Unknown1 24 NULL bytes*/
2003 SBIG_UINT(pdata
,0,(SMB_BIG_UINT
)0);
2004 SBIG_UINT(pdata
,8,(SMB_BIG_UINT
)0);
2005 SBIG_UINT(pdata
,16,(SMB_BIG_UINT
)0);
2007 /* Default Soft Quota 8 bytes */
2008 SBIG_UINT(pdata
,24,quotas
.softlim
);
2010 /* Default Hard Quota 8 bytes */
2011 SBIG_UINT(pdata
,32,quotas
.hardlim
);
2013 /* Quota flag 2 bytes */
2014 SSVAL(pdata
,40,quotas
.qflags
);
2016 /* Unknown3 6 NULL bytes */
2022 #endif /* HAVE_SYS_QUOTAS */
2023 case SMB_FS_OBJECTID_INFORMATION
:
2028 * Query the version and capabilities of the CIFS UNIX extensions
2032 case SMB_QUERY_CIFS_UNIX_INFO
:
2033 if (!lp_unix_extensions())
2034 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2036 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
2037 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
2038 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)CIFS_UNIX_POSIX_ACLS_CAP
)); /* We have POSIX ACLs. */
2041 case SMB_MAC_QUERY_FS_INFO
:
2043 * Thursby MAC extension... ONLY on NTFS filesystems
2044 * once we do streams then we don't need this
2046 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
2048 SIVAL(pdata
,84,0x100); /* Don't support mac... */
2053 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2057 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
2059 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
2064 #ifdef HAVE_SYS_QUOTAS
2065 /****************************************************************************
2066 Reply to a TRANS2_SETFSINFO (set filesystem info).
2067 ****************************************************************************/
2069 static int call_trans2setfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2070 char **pparams
, int total_params
, char **ppdata
, int total_data
,
2071 unsigned int max_data_bytes
)
2073 char *pdata
= *ppdata
;
2074 char *params
= *pparams
;
2075 files_struct
*fsp
= NULL
;
2078 SMB_NTQUOTA_STRUCT quotas
;
2080 ZERO_STRUCT(quotas
);
2082 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn
))));
2085 if ((current_user
.uid
!= 0)||!CAN_WRITE(conn
)) {
2086 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2087 lp_servicename(SNUM(conn
)),conn
->user
));
2088 return ERROR_DOS(ERRSRV
,ERRaccess
);
2092 if (total_params
< 4) {
2093 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2095 return ERROR_DOS(ERRDOS
,ERRinvalidparam
);
2098 fsp
= file_fsp(params
,0);
2100 if (!CHECK_NTQUOTA_HANDLE_OK(fsp
,conn
)) {
2101 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2102 return ERROR_NT(NT_STATUS_INVALID_HANDLE
);
2105 info_level
= SVAL(params
,2);
2107 switch(info_level
) {
2108 case SMB_FS_QUOTA_INFORMATION
:
2109 /* note: normaly there're 48 bytes,
2110 * but we didn't use the last 6 bytes for now
2113 if (total_data
< 42) {
2114 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2116 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2119 /* unknown_1 24 NULL bytes in pdata*/
2121 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2122 quotas
.softlim
= (SMB_BIG_UINT
)IVAL(pdata
,24);
2123 #ifdef LARGE_SMB_OFF_T
2124 quotas
.softlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,28)) << 32);
2125 #else /* LARGE_SMB_OFF_T */
2126 if ((IVAL(pdata
,28) != 0)&&
2127 ((quotas
.softlim
!= 0xFFFFFFFF)||
2128 (IVAL(pdata
,28)!=0xFFFFFFFF))) {
2129 /* more than 32 bits? */
2130 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2132 #endif /* LARGE_SMB_OFF_T */
2134 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2135 quotas
.hardlim
= (SMB_BIG_UINT
)IVAL(pdata
,32);
2136 #ifdef LARGE_SMB_OFF_T
2137 quotas
.hardlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,36)) << 32);
2138 #else /* LARGE_SMB_OFF_T */
2139 if ((IVAL(pdata
,36) != 0)&&
2140 ((quotas
.hardlim
!= 0xFFFFFFFF)||
2141 (IVAL(pdata
,36)!=0xFFFFFFFF))) {
2142 /* more than 32 bits? */
2143 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2145 #endif /* LARGE_SMB_OFF_T */
2147 /* quota_flags 2 bytes **/
2148 quotas
.qflags
= SVAL(pdata
,40);
2150 /* unknown_2 6 NULL bytes follow*/
2152 /* now set the quotas */
2153 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
2154 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
2155 return ERROR_DOS(ERRSRV
,ERRerror
);
2160 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2162 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2167 * sending this reply works fine,
2168 * but I'm not sure it's the same
2169 * like windows do...
2172 outsize
= set_message(outbuf
,10,0,True
);
2176 #endif /* HAVE_SYS_QUOTAS */
2178 /****************************************************************************
2179 Utility function to set bad path error.
2180 ****************************************************************************/
2182 int set_bad_path_error(int err
, BOOL bad_path
, char *outbuf
, int def_class
, uint32 def_code
)
2184 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2185 err
, (int)bad_path
));
2189 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
2191 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2194 return UNIXERROR(def_class
,def_code
);
2197 #if defined(HAVE_POSIX_ACLS)
2198 /****************************************************************************
2199 Utility function to count the number of entries in a POSIX acl.
2200 ****************************************************************************/
2202 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
2204 unsigned int ace_count
= 0;
2205 int entry_id
= SMB_ACL_FIRST_ENTRY
;
2206 SMB_ACL_ENTRY_T entry
;
2208 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
2210 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
2211 entry_id
= SMB_ACL_NEXT_ENTRY
;
2218 /****************************************************************************
2219 Utility function to marshall a POSIX acl into wire format.
2220 ****************************************************************************/
2222 static BOOL
marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
2224 int entry_id
= SMB_ACL_FIRST_ENTRY
;
2225 SMB_ACL_ENTRY_T entry
;
2227 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
2228 SMB_ACL_TAG_T tagtype
;
2229 SMB_ACL_PERMSET_T permset
;
2230 unsigned char perms
= 0;
2231 unsigned int own_grp
;
2234 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
2235 entry_id
= SMB_ACL_NEXT_ENTRY
;
2238 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn
, entry
, &tagtype
) == -1) {
2239 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2243 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn
, entry
, &permset
) == -1) {
2244 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2248 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
2249 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
2250 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
2252 SCVAL(pdata
,1,perms
);
2255 case SMB_ACL_USER_OBJ
:
2256 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
2257 own_grp
= (unsigned int)pst
->st_uid
;
2258 SIVAL(pdata
,2,own_grp
);
2263 uid_t
*puid
= (uid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
2265 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2267 own_grp
= (unsigned int)*puid
;
2268 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)puid
,tagtype
);
2269 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
2270 SIVAL(pdata
,2,own_grp
);
2274 case SMB_ACL_GROUP_OBJ
:
2275 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
2276 own_grp
= (unsigned int)pst
->st_gid
;
2277 SIVAL(pdata
,2,own_grp
);
2282 gid_t
*pgid
= (gid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
2284 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2286 own_grp
= (unsigned int)*pgid
;
2287 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)pgid
,tagtype
);
2288 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
2289 SIVAL(pdata
,2,own_grp
);
2294 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
2295 SIVAL(pdata
,2,0xFFFFFFFF);
2296 SIVAL(pdata
,6,0xFFFFFFFF);
2299 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
2300 SIVAL(pdata
,2,0xFFFFFFFF);
2301 SIVAL(pdata
,6,0xFFFFFFFF);
2304 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2307 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
2314 /****************************************************************************
2315 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2316 file name or file id).
2317 ****************************************************************************/
2319 static int call_trans2qfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2320 char **pparams
, int total_params
, char **ppdata
, int total_data
,
2321 unsigned int max_data_bytes
)
2323 char *params
= *pparams
;
2324 char *pdata
= *ppdata
;
2325 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2328 SMB_OFF_T file_size
=0;
2329 SMB_BIG_UINT allocation_size
=0;
2330 unsigned int data_size
;
2331 unsigned int param_size
= 2;
2332 SMB_STRUCT_STAT sbuf
;
2333 pstring fname
, dos_fname
;
2338 BOOL bad_path
= False
;
2339 BOOL delete_pending
= False
;
2342 files_struct
*fsp
= NULL
;
2343 uint32 desired_access
= 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2346 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2350 if (tran_call
== TRANSACT2_QFILEINFO
) {
2351 if (total_params
< 4)
2352 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2354 fsp
= file_fsp(params
,0);
2355 info_level
= SVAL(params
,2);
2357 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
2359 if(fsp
&& (fsp
->fake_file_handle
)) {
2361 * This is actually for the QUOTA_FAKE_FILE --metze
2364 pstrcpy(fname
, fsp
->fsp_name
);
2365 /* We know this name is ok, it's already passed the checks. */
2367 } else if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2369 * This is actually a QFILEINFO on a directory
2370 * handle (returned from an NT SMB). NT5.0 seems
2371 * to do this call. JRA.
2373 /* We know this name is ok, it's already passed the checks. */
2374 pstrcpy(fname
, fsp
->fsp_name
);
2376 if (INFO_LEVEL_IS_UNIX(info_level
)) {
2377 /* Always do lstat for UNIX calls. */
2378 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
2379 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
2380 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2382 } else if (SMB_VFS_STAT(conn
,fname
,&sbuf
)) {
2383 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
2384 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2387 delete_pending
= fsp
->is_directory
? fsp
->directory_delete_on_close
: 0;
2390 * Original code - this is an open file.
2392 CHECK_FSP(fsp
,conn
);
2394 pstrcpy(fname
, fsp
->fsp_name
);
2395 if (SMB_VFS_FSTAT(fsp
,fsp
->fd
,&sbuf
) != 0) {
2396 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp
->fnum
, strerror(errno
)));
2397 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2399 pos
= fsp
->position_information
;
2400 delete_pending
= fsp
->delete_on_close
;
2401 desired_access
= fsp
->desired_access
;
2404 NTSTATUS status
= NT_STATUS_OK
;
2407 if (total_params
< 6)
2408 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2410 info_level
= SVAL(params
,0);
2412 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
2414 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
, &status
, False
);
2415 if (!NT_STATUS_IS_OK(status
)) {
2416 return ERROR_NT(status
);
2419 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
2421 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2423 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
2425 if (!check_name(fname
,conn
)) {
2426 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2427 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2430 if (INFO_LEVEL_IS_UNIX(info_level
)) {
2431 /* Always do lstat for UNIX calls. */
2432 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
2433 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
2434 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2436 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,fname
,&sbuf
) && (info_level
!= SMB_INFO_IS_NAME_VALID
)) {
2437 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
2438 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2442 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2443 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2445 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2446 fname
,fsp
? fsp
->fnum
: -1, info_level
,tran_call
,total_data
));
2448 p
= strrchr_m(fname
,'/');
2454 mode
= dos_mode(conn
,fname
,&sbuf
);
2456 mode
= FILE_ATTRIBUTE_NORMAL
;
2458 fullpathname
= fname
;
2459 file_size
= get_file_size(sbuf
);
2460 allocation_size
= get_allocation_size(conn
,fsp
,&sbuf
);
2462 /* This is necessary, as otherwise the desktop.ini file in
2463 * this folder is ignored */
2464 mode
|= (lp_profile_acls(SNUM(conn
)) ? aRONLY
: 0);
2468 params
= SMB_REALLOC(*pparams
,2);
2470 return ERROR_DOS(ERRDOS
,ERRnomem
);
2472 memset((char *)params
,'\0',2);
2473 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
2474 pdata
= SMB_REALLOC(*ppdata
, data_size
);
2475 if ( pdata
== NULL
)
2476 return ERROR_DOS(ERRDOS
,ERRnomem
);
2479 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
2480 /* uggh, EAs for OS2 */
2481 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
2482 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
2485 memset((char *)pdata
,'\0',data_size
);
2487 c_time
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
2490 if (fsp
->pending_modtime
) {
2491 /* the pending modtime overrides the current modtime */
2492 sbuf
.st_mtime
= fsp
->pending_modtime
;
2495 /* Do we have this path open ? */
2496 files_struct
*fsp1
= file_find_di_first(sbuf
.st_dev
, sbuf
.st_ino
);
2497 if (fsp1
&& fsp1
->pending_modtime
) {
2498 /* the pending modtime overrides the current modtime */
2499 sbuf
.st_mtime
= fsp1
->pending_modtime
;
2503 if (lp_dos_filetime_resolution(SNUM(conn
))) {
2505 sbuf
.st_atime
&= ~1;
2506 sbuf
.st_ctime
&= ~1;
2507 sbuf
.st_mtime
&= ~1;
2510 /* NT expects the name to be in an exact form of the *full*
2511 filename. See the trans2 torture test */
2512 if (strequal(base_name
,".")) {
2513 pstrcpy(dos_fname
, "\\");
2515 pstr_sprintf(dos_fname
, "\\%s", fname
);
2516 string_replace(dos_fname
, '/', '\\');
2519 switch (info_level
) {
2520 case SMB_INFO_STANDARD
:
2521 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2523 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
2524 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
2525 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
2526 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
2527 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
2528 SSVAL(pdata
,l1_attrFile
,mode
);
2531 case SMB_INFO_QUERY_EA_SIZE
:
2533 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2534 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2536 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
2537 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
2538 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
2539 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
2540 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
2541 SSVAL(pdata
,l1_attrFile
,mode
);
2542 SIVAL(pdata
,l1_attrFile
+2,ea_size
);
2546 case SMB_INFO_IS_NAME_VALID
:
2547 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2548 if (tran_call
== TRANSACT2_QFILEINFO
) {
2549 /* os/2 needs this ? really ?*/
2550 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
2556 case SMB_INFO_QUERY_EAS_FROM_LIST
:
2557 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2559 put_dos_date2(pdata
,0,c_time
);
2560 put_dos_date2(pdata
,4,sbuf
.st_atime
);
2561 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
2562 SIVAL(pdata
,12,(uint32
)file_size
);
2563 SIVAL(pdata
,16,(uint32
)allocation_size
);
2564 SIVAL(pdata
,20,mode
);
2567 case SMB_INFO_QUERY_ALL_EAS
:
2568 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2569 /* We have data_size bytes to put EA's into. */
2570 data_size
= fill_ea_buffer(pdata
, data_size
, conn
, fsp
, fname
);
2573 case SMB_FILE_BASIC_INFORMATION
:
2574 case SMB_QUERY_FILE_BASIC_INFO
:
2576 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
2577 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2578 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
2580 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2584 put_long_date(pdata
,c_time
);
2585 put_long_date(pdata
+8,sbuf
.st_atime
);
2586 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2587 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2588 SIVAL(pdata
,32,mode
);
2590 DEBUG(5,("SMB_QFBI - "));
2592 time_t create_time
= c_time
;
2593 DEBUG(5,("create: %s ", ctime(&create_time
)));
2595 DEBUG(5,("access: %s ", ctime(&sbuf
.st_atime
)));
2596 DEBUG(5,("write: %s ", ctime(&sbuf
.st_mtime
)));
2597 DEBUG(5,("change: %s ", ctime(&sbuf
.st_mtime
)));
2598 DEBUG(5,("mode: %x\n", mode
));
2602 case SMB_FILE_STANDARD_INFORMATION
:
2603 case SMB_QUERY_FILE_STANDARD_INFO
:
2605 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2607 SOFF_T(pdata
,0,allocation_size
);
2608 SOFF_T(pdata
,8,file_size
);
2609 if (delete_pending
& sbuf
.st_nlink
)
2610 SIVAL(pdata
,16,sbuf
.st_nlink
- 1);
2612 SIVAL(pdata
,16,sbuf
.st_nlink
);
2614 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
2617 case SMB_FILE_EA_INFORMATION
:
2618 case SMB_QUERY_FILE_EA_INFO
:
2620 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2621 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2623 SIVAL(pdata
,0,ea_size
);
2627 /* Get the 8.3 name - used if NT SMB was negotiated. */
2628 case SMB_QUERY_FILE_ALT_NAME_INFO
:
2629 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
2633 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2634 pstrcpy(short_name
,base_name
);
2635 /* Mangle if not already 8.3 */
2636 if(!mangle_is_8_3(short_name
, True
)) {
2637 mangle_map(short_name
,True
,True
,SNUM(conn
));
2639 len
= srvstr_push(outbuf
, pdata
+4, short_name
, -1, STR_UNICODE
);
2640 data_size
= 4 + len
;
2645 case SMB_QUERY_FILE_NAME_INFO
:
2647 this must be *exactly* right for ACLs on mapped drives to work
2649 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
2650 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2651 data_size
= 4 + len
;
2655 case SMB_FILE_ALLOCATION_INFORMATION
:
2656 case SMB_QUERY_FILE_ALLOCATION_INFO
:
2657 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2659 SOFF_T(pdata
,0,allocation_size
);
2662 case SMB_FILE_END_OF_FILE_INFORMATION
:
2663 case SMB_QUERY_FILE_END_OF_FILEINFO
:
2664 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2666 SOFF_T(pdata
,0,file_size
);
2669 case SMB_QUERY_FILE_ALL_INFO
:
2670 case SMB_FILE_ALL_INFORMATION
:
2672 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2673 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2674 put_long_date(pdata
,c_time
);
2675 put_long_date(pdata
+8,sbuf
.st_atime
);
2676 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2677 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2678 SIVAL(pdata
,32,mode
);
2680 SOFF_T(pdata
,0,allocation_size
);
2681 SOFF_T(pdata
,8,file_size
);
2682 if (delete_pending
&& sbuf
.st_nlink
)
2683 SIVAL(pdata
,16,sbuf
.st_nlink
- 1);
2685 SIVAL(pdata
,16,sbuf
.st_nlink
);
2686 SCVAL(pdata
,20,delete_pending
);
2687 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
2689 SIVAL(pdata
,0,ea_size
);
2690 pdata
+= 4; /* EA info */
2691 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
2694 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2697 case SMB_FILE_INTERNAL_INFORMATION
:
2698 /* This should be an index number - looks like
2701 I think this causes us to fail the IFSKIT
2702 BasicFileInformationTest. -tpot */
2704 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2705 SIVAL(pdata
,0,sbuf
.st_dev
);
2706 SIVAL(pdata
,4,sbuf
.st_ino
);
2710 case SMB_FILE_ACCESS_INFORMATION
:
2711 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2712 SIVAL(pdata
,0,desired_access
);
2716 case SMB_FILE_NAME_INFORMATION
:
2717 /* Pathname with leading '\'. */
2720 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
2721 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2722 SIVAL(pdata
,0,byte_len
);
2723 data_size
= 4 + byte_len
;
2727 case SMB_FILE_DISPOSITION_INFORMATION
:
2728 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2730 SCVAL(pdata
,0,delete_pending
);
2733 case SMB_FILE_POSITION_INFORMATION
:
2734 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2736 SOFF_T(pdata
,0,pos
);
2739 case SMB_FILE_MODE_INFORMATION
:
2740 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2741 SIVAL(pdata
,0,mode
);
2745 case SMB_FILE_ALIGNMENT_INFORMATION
:
2746 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2747 SIVAL(pdata
,0,0); /* No alignment needed. */
2753 * NT4 server just returns "invalid query" to this - if we try to answer
2754 * it then NTws gets a BSOD! (tridge).
2755 * W2K seems to want this. JRA.
2757 case SMB_QUERY_FILE_STREAM_INFO
:
2759 case SMB_FILE_STREAM_INFORMATION
:
2760 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2764 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", 0xE, False
);
2765 SIVAL(pdata
,0,0); /* ??? */
2766 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
2767 SOFF_T(pdata
,8,file_size
);
2768 SIVAL(pdata
,16,allocation_size
);
2769 SIVAL(pdata
,20,0); /* ??? */
2770 data_size
= 24 + byte_len
;
2774 case SMB_QUERY_COMPRESSION_INFO
:
2775 case SMB_FILE_COMPRESSION_INFORMATION
:
2776 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2777 SOFF_T(pdata
,0,file_size
);
2778 SIVAL(pdata
,8,0); /* ??? */
2779 SIVAL(pdata
,12,0); /* ??? */
2783 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
2784 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2785 put_long_date(pdata
,c_time
);
2786 put_long_date(pdata
+8,sbuf
.st_atime
);
2787 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2788 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2789 SIVAL(pdata
,32,allocation_size
);
2790 SOFF_T(pdata
,40,file_size
);
2791 SIVAL(pdata
,48,mode
);
2792 SIVAL(pdata
,52,0); /* ??? */
2796 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
2797 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2798 SIVAL(pdata
,0,mode
);
2804 * CIFS UNIX Extensions.
2807 case SMB_QUERY_FILE_UNIX_BASIC
:
2809 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2810 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf
.st_mode
));
2812 SOFF_T(pdata
,0,get_file_size(sbuf
)); /* File size 64 Bit */
2815 SOFF_T(pdata
,0,get_allocation_size(conn
,fsp
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
2818 put_long_date(pdata
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
2819 put_long_date(pdata
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
2820 put_long_date(pdata
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
2823 SIVAL(pdata
,0,sbuf
.st_uid
); /* user id for the owner */
2827 SIVAL(pdata
,0,sbuf
.st_gid
); /* group id of owner */
2831 SIVAL(pdata
,0,unix_filetype(sbuf
.st_mode
));
2834 SIVAL(pdata
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
2838 SIVAL(pdata
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
2842 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
2845 SIVAL(pdata
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
2849 SIVAL(pdata
,0,sbuf
.st_nlink
); /* number of hard links */
2852 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2856 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2858 for (i
=0; i
<100; i
++)
2859 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
2865 case SMB_QUERY_FILE_UNIX_LINK
:
2869 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2871 if(!S_ISLNK(sbuf
.st_mode
))
2872 return(UNIXERROR(ERRSRV
,ERRbadlink
));
2874 return(UNIXERROR(ERRDOS
,ERRbadlink
));
2876 len
= SMB_VFS_READLINK(conn
,fullpathname
, buffer
, sizeof(pstring
)-1); /* read link */
2878 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2880 len
= srvstr_push(outbuf
, pdata
, buffer
, -1, STR_TERMINATE
);
2882 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2887 #if defined(HAVE_POSIX_ACLS)
2888 case SMB_QUERY_POSIX_ACL
:
2890 SMB_ACL_T file_acl
= NULL
;
2891 SMB_ACL_T def_acl
= NULL
;
2892 uint16 num_file_acls
= 0;
2893 uint16 num_def_acls
= 0;
2895 if (fsp
&& !fsp
->is_directory
&& (fsp
->fd
!= -1)) {
2896 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
, fsp
->fd
);
2898 file_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fname
, SMB_ACL_TYPE_ACCESS
);
2901 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
2902 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
2904 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED
);
2907 if (S_ISDIR(sbuf
.st_mode
)) {
2908 if (fsp
&& fsp
->is_directory
) {
2909 def_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fsp
->fsp_name
, SMB_ACL_TYPE_DEFAULT
);
2911 def_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fname
, SMB_ACL_TYPE_DEFAULT
);
2913 def_acl
= free_empty_sys_acl(conn
, def_acl
);
2916 num_file_acls
= count_acl_entries(conn
, file_acl
);
2917 num_def_acls
= count_acl_entries(conn
, def_acl
);
2919 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
2920 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
2922 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
2923 SMB_POSIX_ACL_HEADER_SIZE
) ));
2925 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
2928 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
2930 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL
);
2933 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
2934 SSVAL(pdata
,2,num_file_acls
);
2935 SSVAL(pdata
,4,num_def_acls
);
2936 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, &sbuf
, file_acl
)) {
2938 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
2941 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
2943 return ERROR_NT(NT_STATUS_INTERNAL_ERROR
);
2945 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), &sbuf
, def_acl
)) {
2947 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
2950 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
2952 return ERROR_NT(NT_STATUS_INTERNAL_ERROR
);
2956 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
2959 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
2961 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
2967 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2970 send_trans2_replies(outbuf
, bufsize
, params
, param_size
, *ppdata
, data_size
);
2975 /****************************************************************************
2976 Deal with the internal needs of setting the delete on close flag. Note that
2977 as the tdb locking is recursive, it is safe to call this from within
2978 open_file_shared. JRA.
2979 ****************************************************************************/
2981 NTSTATUS
set_delete_on_close_internal(files_struct
*fsp
, BOOL delete_on_close
, uint32 dosmode
)
2983 if (delete_on_close
) {
2985 * Only allow delete on close for writable files.
2988 if (!lp_delete_readonly(SNUM(fsp
->conn
))) {
2989 if (dosmode
& aRONLY
) {
2990 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
2992 return NT_STATUS_CANNOT_DELETE
;
2997 * Only allow delete on close for writable shares.
3000 if (!CAN_WRITE(fsp
->conn
)) {
3001 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
3003 return NT_STATUS_ACCESS_DENIED
;
3007 * Only allow delete on close for files/directories opened with delete intent.
3010 if (!(fsp
->desired_access
& DELETE_ACCESS
)) {
3011 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
3013 return NT_STATUS_ACCESS_DENIED
;
3017 if(fsp
->is_directory
) {
3018 fsp
->directory_delete_on_close
= delete_on_close
;
3019 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
3020 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
3022 fsp
->delete_on_close
= delete_on_close
;
3023 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
3024 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
3027 return NT_STATUS_OK
;
3030 /****************************************************************************
3031 Sets the delete on close flag over all share modes on this file.
3032 Modify the share mode entry for all files open
3033 on this device and inode to tell other smbds we have
3034 changed the delete on close flag. This will be noticed
3035 in the close code, the last closer will delete the file
3037 ****************************************************************************/
3039 NTSTATUS
set_delete_on_close_over_all(files_struct
*fsp
, BOOL delete_on_close
)
3041 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
3042 delete_on_close
? "Adding" : "Removing", fsp
->fnum
, fsp
->fsp_name
));
3044 if (fsp
->is_directory
|| fsp
->is_stat
)
3045 return NT_STATUS_OK
;
3047 if (lock_share_entry_fsp(fsp
) == False
)
3048 return NT_STATUS_ACCESS_DENIED
;
3050 if (!modify_delete_flag(fsp
->dev
, fsp
->inode
, delete_on_close
)) {
3051 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
3053 unlock_share_entry_fsp(fsp
);
3054 return NT_STATUS_ACCESS_DENIED
;
3057 unlock_share_entry_fsp(fsp
);
3058 return NT_STATUS_OK
;
3061 /****************************************************************************
3062 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3064 ****************************************************************************/
3066 NTSTATUS
hardlink_internals(connection_struct
*conn
, char *oldname
, char *newname
)
3068 BOOL bad_path_oldname
= False
;
3069 BOOL bad_path_newname
= False
;
3070 SMB_STRUCT_STAT sbuf1
, sbuf2
;
3071 pstring last_component_oldname
;
3072 pstring last_component_newname
;
3073 NTSTATUS status
= NT_STATUS_OK
;
3079 if (ms_has_wild(newname
) || ms_has_wild(oldname
)) {
3080 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD
;
3083 unix_convert(oldname
,conn
,last_component_oldname
,&bad_path_oldname
,&sbuf1
);
3084 if (bad_path_oldname
) {
3085 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
3088 /* Quick check for "." and ".." */
3089 if (last_component_oldname
[0] == '.') {
3090 if (!last_component_oldname
[1] || (last_component_oldname
[1] == '.' && !last_component_oldname
[2])) {
3091 return NT_STATUS_OBJECT_NAME_INVALID
;
3095 /* source must already exist. */
3096 if (!VALID_STAT(sbuf1
)) {
3097 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3100 if (!check_name(oldname
,conn
)) {
3101 return NT_STATUS_ACCESS_DENIED
;
3104 unix_convert(newname
,conn
,last_component_newname
,&bad_path_newname
,&sbuf2
);
3105 if (bad_path_newname
) {
3106 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
3109 /* Quick check for "." and ".." */
3110 if (last_component_newname
[0] == '.') {
3111 if (!last_component_newname
[1] || (last_component_newname
[1] == '.' && !last_component_newname
[2])) {
3112 return NT_STATUS_OBJECT_NAME_INVALID
;
3116 /* Disallow if newname already exists. */
3117 if (VALID_STAT(sbuf2
)) {
3118 return NT_STATUS_OBJECT_NAME_COLLISION
;
3121 if (!check_name(newname
,conn
)) {
3122 return NT_STATUS_ACCESS_DENIED
;
3125 /* No links from a directory. */
3126 if (S_ISDIR(sbuf1
.st_mode
)) {
3127 return NT_STATUS_FILE_IS_A_DIRECTORY
;
3130 /* Ensure this is within the share. */
3131 if (!reduce_name(conn
, oldname
) != 0)
3132 return NT_STATUS_ACCESS_DENIED
;
3134 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname
, oldname
));
3136 if (SMB_VFS_LINK(conn
,oldname
,newname
) != 0) {
3137 status
= map_nt_error_from_unix(errno
);
3138 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3139 nt_errstr(status
), newname
, oldname
));
3145 /****************************************************************************
3146 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3147 ****************************************************************************/
3149 static int call_trans2setfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
3150 char **pparams
, int total_params
, char **ppdata
, int total_data
,
3151 unsigned int max_data_bytes
)
3153 char *params
= *pparams
;
3154 char *pdata
= *ppdata
;
3155 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
3160 SMB_STRUCT_STAT sbuf
;
3163 BOOL bad_path
= False
;
3164 files_struct
*fsp
= NULL
;
3165 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
3166 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
3167 mode_t unixmode
= 0;
3168 NTSTATUS status
= NT_STATUS_OK
;
3171 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3175 if (tran_call
== TRANSACT2_SETFILEINFO
) {
3176 if (total_params
< 4)
3177 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3179 fsp
= file_fsp(params
,0);
3180 info_level
= SVAL(params
,2);
3182 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
3184 * This is actually a SETFILEINFO on a directory
3185 * handle (returned from an NT SMB). NT5.0 seems
3186 * to do this call. JRA.
3188 pstrcpy(fname
, fsp
->fsp_name
);
3189 if (SMB_VFS_STAT(conn
,fname
,&sbuf
) != 0) {
3190 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
3191 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3193 } else if (fsp
&& fsp
->print_file
) {
3195 * Doing a DELETE_ON_CLOSE should cancel a print job.
3197 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
3198 fsp
->share_mode
= FILE_DELETE_ON_CLOSE
;
3200 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp
->fsp_name
));
3203 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3206 return (UNIXERROR(ERRDOS
,ERRbadpath
));
3209 * Original code - this is an open file.
3211 CHECK_FSP(fsp
,conn
);
3213 pstrcpy(fname
, fsp
->fsp_name
);
3216 if (SMB_VFS_FSTAT(fsp
,fd
,&sbuf
) != 0) {
3217 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
3218 return(UNIXERROR(ERRDOS
,ERRbadfid
));
3223 if (total_params
< 6)
3224 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3226 info_level
= SVAL(params
,0);
3227 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
, &status
, False
);
3228 if (!NT_STATUS_IS_OK(status
)) {
3229 return ERROR_NT(status
);
3231 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
3233 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
3237 * For CIFS UNIX extensions the target name may not exist.
3240 if(!VALID_STAT(sbuf
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
3241 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname
, strerror(errno
)));
3242 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3245 if(!check_name(fname
, conn
)) {
3246 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3251 if (!CAN_WRITE(conn
))
3252 return ERROR_DOS(ERRSRV
,ERRaccess
);
3254 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
3255 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3257 if (VALID_STAT(sbuf
))
3258 unixmode
= sbuf
.st_mode
;
3260 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3261 tran_call
,fname
, fsp
? fsp
->fnum
: -1, info_level
,total_data
));
3263 /* Realloc the parameter and data sizes */
3264 params
= SMB_REALLOC(*pparams
,2);
3266 return ERROR_DOS(ERRDOS
,ERRnomem
);
3271 if (fsp
&& fsp
->pending_modtime
) {
3272 /* the pending modtime overrides the current modtime */
3273 sbuf
.st_mtime
= fsp
->pending_modtime
;
3276 size
= get_file_size(sbuf
);
3277 tvs
.modtime
= sbuf
.st_mtime
;
3278 tvs
.actime
= sbuf
.st_atime
;
3279 dosmode
= dos_mode(conn
,fname
,&sbuf
);
3280 unixmode
= sbuf
.st_mode
;
3282 set_owner
= VALID_STAT(sbuf
) ? sbuf
.st_uid
: (uid_t
)SMB_UID_NO_CHANGE
;
3283 set_grp
= VALID_STAT(sbuf
) ? sbuf
.st_gid
: (gid_t
)SMB_GID_NO_CHANGE
;
3285 switch (info_level
) {
3286 case SMB_INFO_STANDARD
:
3288 if (total_data
< 12)
3289 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3292 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
3294 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
3298 case SMB_INFO_SET_EA
:
3299 status
= set_ea(conn
, fsp
, fname
, pdata
, total_data
);
3300 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3301 return ERROR_NT(status
);
3304 /* XXXX um, i don't think this is right.
3305 it's also not in the cifs6.txt spec.
3307 case SMB_INFO_QUERY_EAS_FROM_LIST
:
3308 if (total_data
< 28)
3309 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3311 tvs
.actime
= make_unix_date2(pdata
+8);
3312 tvs
.modtime
= make_unix_date2(pdata
+12);
3313 size
= IVAL(pdata
,16);
3314 dosmode
= IVAL(pdata
,24);
3317 /* XXXX nor this. not in cifs6.txt, either. */
3318 case SMB_INFO_QUERY_ALL_EAS
:
3319 if (total_data
< 28)
3320 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3322 tvs
.actime
= make_unix_date2(pdata
+8);
3323 tvs
.modtime
= make_unix_date2(pdata
+12);
3324 size
= IVAL(pdata
,16);
3325 dosmode
= IVAL(pdata
,24);
3328 case SMB_SET_FILE_BASIC_INFO
:
3329 case SMB_FILE_BASIC_INFORMATION
:
3331 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3333 time_t changed_time
;
3335 if (total_data
< 36)
3336 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3338 /* Ignore create time at offset pdata. */
3341 tvs
.actime
= interpret_long_date(pdata
+8);
3343 write_time
= interpret_long_date(pdata
+16);
3344 changed_time
= interpret_long_date(pdata
+24);
3346 tvs
.modtime
= MIN(write_time
, changed_time
);
3348 if (write_time
> tvs
.modtime
&& write_time
!= (time_t)-1) {
3349 tvs
.modtime
= write_time
;
3351 /* Prefer a defined time to an undefined one. */
3352 if (null_mtime(tvs
.modtime
)) {
3353 tvs
.modtime
= null_mtime(write_time
) ? changed_time
: write_time
;
3357 dosmode
= IVAL(pdata
,32);
3361 case SMB_FILE_ALLOCATION_INFORMATION
:
3362 case SMB_SET_FILE_ALLOCATION_INFO
:
3365 SMB_BIG_UINT allocation_size
;
3368 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3370 allocation_size
= (SMB_BIG_UINT
)IVAL(pdata
,0);
3371 #ifdef LARGE_SMB_OFF_T
3372 allocation_size
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
3373 #else /* LARGE_SMB_OFF_T */
3374 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3375 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3376 #endif /* LARGE_SMB_OFF_T */
3377 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3378 fname
, (double)allocation_size
));
3380 if (allocation_size
) {
3381 allocation_size
= smb_roundup(conn
, allocation_size
);
3384 if(allocation_size
!= get_file_size(sbuf
)) {
3385 SMB_STRUCT_STAT new_sbuf
;
3387 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3388 fname
, (double)allocation_size
));
3391 files_struct
*new_fsp
= NULL
;
3392 int access_mode
= 0;
3395 if(global_oplock_break
) {
3396 /* Queue this file modify as we are the process of an oplock break. */
3398 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3399 DEBUGADD(2,( "in oplock break state.\n"));
3401 push_oplock_pending_smb_message(inbuf
, length
);
3405 new_fsp
= open_file_shared1(conn
, fname
, &sbuf
,FILE_WRITE_DATA
,
3406 SET_OPEN_MODE(DOS_OPEN_RDWR
),
3407 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
3408 FILE_ATTRIBUTE_NORMAL
,
3409 INTERNAL_OPEN_ONLY
, &access_mode
, &action
);
3411 if (new_fsp
== NULL
)
3412 return(UNIXERROR(ERRDOS
,ERRbadpath
));
3413 ret
= vfs_allocate_file_space(new_fsp
, allocation_size
);
3414 if (SMB_VFS_FSTAT(new_fsp
,new_fsp
->fd
,&new_sbuf
) != 0) {
3415 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3416 new_fsp
->fnum
, strerror(errno
)));
3419 close_file(new_fsp
,True
);
3421 ret
= vfs_allocate_file_space(fsp
, allocation_size
);
3422 if (SMB_VFS_FSTAT(fsp
,fd
,&new_sbuf
) != 0) {
3423 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3424 fsp
->fnum
, strerror(errno
)));
3429 return ERROR_NT(NT_STATUS_DISK_FULL
);
3431 /* Allocate can truncate size... */
3432 size
= get_file_size(new_sbuf
);
3438 case SMB_FILE_END_OF_FILE_INFORMATION
:
3439 case SMB_SET_FILE_END_OF_FILE_INFO
:
3442 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3444 size
= IVAL(pdata
,0);
3445 #ifdef LARGE_SMB_OFF_T
3446 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
3447 #else /* LARGE_SMB_OFF_T */
3448 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3449 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3450 #endif /* LARGE_SMB_OFF_T */
3451 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname
, (double)size
));
3455 case SMB_FILE_DISPOSITION_INFORMATION
:
3456 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
3458 BOOL delete_on_close
;
3461 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3463 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
3465 /* Just ignore this set on a path. */
3466 if (tran_call
!= TRANSACT2_SETFILEINFO
)
3470 return(UNIXERROR(ERRDOS
,ERRbadfid
));
3472 status
= set_delete_on_close_internal(fsp
, delete_on_close
, dosmode
);
3474 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3475 return ERROR_NT(status
);
3477 /* The set is across all open files on this dev/inode pair. */
3478 status
=set_delete_on_close_over_all(fsp
, delete_on_close
);
3479 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3480 return ERROR_NT(status
);
3485 case SMB_FILE_POSITION_INFORMATION
:
3487 SMB_BIG_UINT position_information
;
3490 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3492 position_information
= (SMB_BIG_UINT
)IVAL(pdata
,0);
3493 #ifdef LARGE_SMB_OFF_T
3494 position_information
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
3495 #else /* LARGE_SMB_OFF_T */
3496 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3497 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3498 #endif /* LARGE_SMB_OFF_T */
3499 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3500 fname
, (double)position_information
));
3502 fsp
->position_information
= position_information
;
3507 * CIFS UNIX extensions.
3510 case SMB_SET_FILE_UNIX_BASIC
:
3512 uint32 raw_unixmode
;
3514 if (total_data
< 100)
3515 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3517 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
3518 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
3519 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
3520 #ifdef LARGE_SMB_OFF_T
3521 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
3522 #else /* LARGE_SMB_OFF_T */
3523 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3524 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3525 #endif /* LARGE_SMB_OFF_T */
3527 pdata
+=24; /* ctime & st_blocks are not changed */
3528 tvs
.actime
= interpret_long_date(pdata
); /* access_time */
3529 tvs
.modtime
= interpret_long_date(pdata
+8); /* modification_time */
3531 set_owner
= (uid_t
)IVAL(pdata
,0);
3533 set_grp
= (gid_t
)IVAL(pdata
,0);
3535 raw_unixmode
= IVAL(pdata
,28);
3536 unixmode
= unix_perms_from_wire(conn
, &sbuf
, raw_unixmode
);
3537 dosmode
= 0; /* Ensure dos mode change doesn't override this. */
3539 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3540 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3541 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
3543 if (!VALID_STAT(sbuf
)) {
3546 * The only valid use of this is to create character and block
3547 * devices, and named pipes. This is deprecated (IMHO) and
3548 * a new info level should be used for mknod. JRA.
3551 uint32 file_type
= IVAL(pdata
,0);
3552 #if defined(HAVE_MAKEDEV)
3553 uint32 dev_major
= IVAL(pdata
,4);
3554 uint32 dev_minor
= IVAL(pdata
,12);
3557 uid_t myuid
= geteuid();
3558 gid_t mygid
= getegid();
3559 SMB_DEV_T dev
= (SMB_DEV_T
)0;
3561 if (tran_call
== TRANSACT2_SETFILEINFO
)
3562 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3564 if (raw_unixmode
== SMB_MODE_NO_CHANGE
)
3565 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3567 #if defined(HAVE_MAKEDEV)
3568 dev
= makedev(dev_major
, dev_minor
);
3571 /* We can only create as the owner/group we are. */
3573 if ((set_owner
!= myuid
) && (set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
))
3574 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3575 if ((set_grp
!= mygid
) && (set_grp
!= (gid_t
)SMB_GID_NO_CHANGE
))
3576 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3578 switch (file_type
) {
3579 #if defined(S_IFIFO)
3580 case UNIX_TYPE_FIFO
:
3581 unixmode
|= S_IFIFO
;
3584 #if defined(S_IFSOCK)
3585 case UNIX_TYPE_SOCKET
:
3586 unixmode
|= S_IFSOCK
;
3589 #if defined(S_IFCHR)
3590 case UNIX_TYPE_CHARDEV
:
3591 unixmode
|= S_IFCHR
;
3594 #if defined(S_IFBLK)
3595 case UNIX_TYPE_BLKDEV
:
3596 unixmode
|= S_IFBLK
;
3600 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3603 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3604 0%o for file %s\n", (double)dev
, unixmode
, fname
));
3606 /* Ok - do the mknod. */
3607 if (SMB_VFS_MKNOD(conn
,fname
, unixmode
, dev
) != 0)
3608 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3610 inherit_access_acl(conn
, fname
, unixmode
);
3613 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3618 * Deal with the UNIX specific mode set.
3621 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
3622 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3623 (unsigned int)unixmode
, fname
));
3624 if (SMB_VFS_CHMOD(conn
,fname
,unixmode
) != 0)
3625 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3629 * Deal with the UNIX specific uid set.
3632 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) && (sbuf
.st_uid
!= set_owner
)) {
3633 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3634 (unsigned int)set_owner
, fname
));
3635 if (SMB_VFS_CHOWN(conn
,fname
,set_owner
, (gid_t
)-1) != 0)
3636 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3640 * Deal with the UNIX specific gid set.
3643 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) && (sbuf
.st_gid
!= set_grp
)) {
3644 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3645 (unsigned int)set_owner
, fname
));
3646 if (SMB_VFS_CHOWN(conn
,fname
,(uid_t
)-1, set_grp
) != 0)
3647 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3652 case SMB_SET_FILE_UNIX_LINK
:
3654 pstring link_target
;
3655 char *newname
= fname
;
3657 /* Set a symbolic link. */
3658 /* Don't allow this if follow links is false. */
3660 if (!lp_symlinks(SNUM(conn
)))
3661 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3663 srvstr_pull(inbuf
, link_target
, pdata
, sizeof(link_target
), -1, STR_TERMINATE
);
3665 /* !widelinks forces the target path to be within the share. */
3666 /* This means we can interpret the target as a pathname. */
3667 if (!lp_widelinks(SNUM(conn
))) {
3669 char *last_dirp
= NULL
;
3671 unix_format(link_target
);
3672 if (*link_target
== '/') {
3673 /* No absolute paths allowed. */
3674 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3676 pstrcpy(rel_name
, newname
);
3677 last_dirp
= strrchr_m(rel_name
, '/');
3679 last_dirp
[1] = '\0';
3681 pstrcpy(rel_name
, "./");
3683 pstrcat(rel_name
, link_target
);
3685 if (!check_name(rel_name
, conn
)) {
3686 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3690 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3691 fname
, link_target
));
3693 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0)
3694 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3696 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3700 case SMB_SET_FILE_UNIX_HLINK
:
3703 char *newname
= fname
;
3705 /* Set a hard link. */
3706 srvstr_get_path(inbuf
, oldname
, pdata
, sizeof(oldname
), -1, STR_TERMINATE
, &status
, False
);
3707 if (!NT_STATUS_IS_OK(status
)) {
3708 return ERROR_NT(status
);
3711 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3714 status
= hardlink_internals(conn
, oldname
, newname
);
3715 if (!NT_STATUS_IS_OK(status
)) {
3716 return ERROR_NT(status
);
3720 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3724 case SMB_FILE_RENAME_INFORMATION
:
3733 if (total_data
< 12)
3734 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3736 overwrite
= (CVAL(pdata
,0) ? True
: False
);
3737 root_fid
= IVAL(pdata
,4);
3738 len
= IVAL(pdata
,8);
3739 srvstr_get_path(inbuf
, newname
, &pdata
[12], sizeof(newname
), len
, 0, &status
, False
);
3740 if (!NT_STATUS_IS_OK(status
)) {
3741 return ERROR_NT(status
);
3744 /* Check the new name has no '/' characters. */
3745 if (strchr_m(newname
, '/'))
3746 return ERROR_NT(NT_STATUS_NOT_SUPPORTED
);
3748 RESOLVE_DFSPATH(newname
, conn
, inbuf
, outbuf
);
3750 /* Create the base directory. */
3751 pstrcpy(base_name
, fname
);
3752 p
= strrchr_m(base_name
, '/');
3755 /* Append the new name. */
3756 pstrcat(base_name
, "/");
3757 pstrcat(base_name
, newname
);
3760 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3761 fsp
->fnum
, fsp
->fsp_name
, base_name
));
3762 status
= rename_internals_fsp(conn
, fsp
, base_name
, 0, overwrite
);
3764 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3766 status
= rename_internals(conn
, fname
, base_name
, 0, overwrite
);
3768 if (!NT_STATUS_IS_OK(status
)) {
3769 return ERROR_NT(status
);
3771 process_pending_change_notify_queue((time_t)0);
3773 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3777 #if defined(HAVE_POSIX_ACLS)
3778 case SMB_SET_POSIX_ACL
:
3780 uint16 posix_acl_version
;
3781 uint16 num_file_acls
;
3782 uint16 num_def_acls
;
3783 BOOL valid_file_acls
= True
;
3784 BOOL valid_def_acls
= True
;
3786 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
3787 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3789 posix_acl_version
= SVAL(pdata
,0);
3790 num_file_acls
= SVAL(pdata
,2);
3791 num_def_acls
= SVAL(pdata
,4);
3793 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
3794 valid_file_acls
= False
;
3798 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
3799 valid_def_acls
= False
;
3803 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
3804 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3807 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
3808 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
3809 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3812 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
, fname
, num_file_acls
,
3813 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
3814 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3817 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
, fname
, &sbuf
, num_def_acls
,
3818 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
3819 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
3820 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3824 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3830 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3833 /* get some defaults (no modifications) if any info is zero or -1. */
3834 if (null_mtime(tvs
.actime
)) {
3835 tvs
.actime
= sbuf
.st_atime
;
3838 if (null_mtime(tvs
.modtime
)) {
3839 tvs
.modtime
= sbuf
.st_mtime
;
3842 DEBUG(6,("actime: %s " , ctime(&tvs
.actime
)));
3843 DEBUG(6,("modtime: %s ", ctime(&tvs
.modtime
)));
3844 DEBUG(6,("size: %.0f ", (double)size
));
3847 if (S_ISDIR(sbuf
.st_mode
))
3853 DEBUG(6,("dosmode: %x\n" , dosmode
));
3855 if(!((info_level
== SMB_SET_FILE_END_OF_FILE_INFO
) ||
3856 (info_level
== SMB_SET_FILE_ALLOCATION_INFO
) ||
3857 (info_level
== SMB_FILE_ALLOCATION_INFORMATION
) ||
3858 (info_level
== SMB_FILE_END_OF_FILE_INFORMATION
))) {
3861 * Only do this test if we are not explicitly
3862 * changing the size of a file.
3865 size
= get_file_size(sbuf
);
3869 * Try and set the times, size and mode of this file -
3870 * if they are different from the current values
3873 /* check the mode isn't different, before changing it */
3874 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, fname
, &sbuf
))) {
3876 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname
, dosmode
));
3878 if(file_set_dosmode(conn
, fname
, dosmode
, &sbuf
, False
)) {
3879 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname
, strerror(errno
)));
3880 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3885 if (size
!= get_file_size(sbuf
)) {
3889 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3890 fname
, (double)size
));
3893 files_struct
*new_fsp
= NULL
;
3894 int access_mode
= 0;
3897 if(global_oplock_break
) {
3898 /* Queue this file modify as we are the process of an oplock break. */
3900 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3901 DEBUGADD(2,( "in oplock break state.\n"));
3903 push_oplock_pending_smb_message(inbuf
, length
);
3907 new_fsp
= open_file_shared(conn
, fname
, &sbuf
,
3908 SET_OPEN_MODE(DOS_OPEN_RDWR
),
3909 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
3910 FILE_ATTRIBUTE_NORMAL
,
3911 INTERNAL_OPEN_ONLY
, &access_mode
, &action
);
3913 if (new_fsp
== NULL
)
3914 return(UNIXERROR(ERRDOS
,ERRbadpath
));
3915 ret
= vfs_set_filelen(new_fsp
, size
);
3916 close_file(new_fsp
,True
);
3918 ret
= vfs_set_filelen(fsp
, size
);
3922 return (UNIXERROR(ERRHRD
,ERRdiskfull
));
3926 * Finally the times.
3928 if (sbuf
.st_mtime
!= tvs
.modtime
|| sbuf
.st_atime
!= tvs
.actime
) {
3931 * This was a setfileinfo on an open file.
3932 * NT does this a lot. We also need to
3933 * set the time here, as it can be read by
3934 * FindFirst/FindNext and with the patch for bug #2045
3935 * in smbd/fileio.c it ensures that this timestamp is
3936 * kept sticky even after a write. We save the request
3937 * away and will set it on file close and after a write. JRA.
3940 if (tvs
.modtime
!= (time_t)0 && tvs
.modtime
!= (time_t)-1) {
3941 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs
.modtime
) ));
3942 fsp_set_pending_modtime(fsp
, tvs
.modtime
);
3946 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3948 if(file_utime(conn
, fname
, &tvs
)!=0) {
3949 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3954 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3959 /****************************************************************************
3960 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3961 ****************************************************************************/
3963 static int call_trans2mkdir(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
3964 char **pparams
, int total_params
, char **ppdata
, int total_data
,
3965 unsigned int max_data_bytes
)
3967 char *params
= *pparams
;
3970 SMB_STRUCT_STAT sbuf
;
3971 BOOL bad_path
= False
;
3972 NTSTATUS status
= NT_STATUS_OK
;
3974 if (!CAN_WRITE(conn
))
3975 return ERROR_DOS(ERRSRV
,ERRaccess
);
3977 if (total_params
< 4)
3978 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3980 srvstr_get_path(inbuf
, directory
, ¶ms
[4], sizeof(directory
), -1, STR_TERMINATE
, &status
, False
);
3981 if (!NT_STATUS_IS_OK(status
)) {
3982 return ERROR_NT(status
);
3985 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
3987 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
3989 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
3991 if (check_name(directory
,conn
))
3992 ret
= vfs_MkDir(conn
,directory
,unix_mode(conn
,aDIR
,directory
,True
));
3995 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno
)));
3996 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRnoaccess
);
3999 /* Realloc the parameter and data sizes */
4000 params
= SMB_REALLOC(*pparams
,2);
4002 return ERROR_DOS(ERRDOS
,ERRnomem
);
4007 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
4012 /****************************************************************************
4013 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
4014 We don't actually do this - we just send a null response.
4015 ****************************************************************************/
4017 static int call_trans2findnotifyfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
4018 char **pparams
, int total_params
, char **ppdata
, int total_data
,
4019 unsigned int max_data_bytes
)
4021 static uint16 fnf_handle
= 257;
4022 char *params
= *pparams
;
4025 if (total_params
< 6)
4026 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
4028 info_level
= SVAL(params
,4);
4029 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
4031 switch (info_level
) {
4036 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
4039 /* Realloc the parameter and data sizes */
4040 params
= SMB_REALLOC(*pparams
,6);
4042 return ERROR_DOS(ERRDOS
,ERRnomem
);
4045 SSVAL(params
,0,fnf_handle
);
4046 SSVAL(params
,2,0); /* No changes */
4047 SSVAL(params
,4,0); /* No EA errors */
4054 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0);
4059 /****************************************************************************
4060 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4061 changes). Currently this does nothing.
4062 ****************************************************************************/
4064 static int call_trans2findnotifynext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
4065 char **pparams
, int total_params
, char **ppdata
, int total_data
,
4066 unsigned int max_data_bytes
)
4068 char *params
= *pparams
;
4070 DEBUG(3,("call_trans2findnotifynext\n"));
4072 /* Realloc the parameter and data sizes */
4073 params
= SMB_REALLOC(*pparams
,4);
4075 return ERROR_DOS(ERRDOS
,ERRnomem
);
4078 SSVAL(params
,0,0); /* No changes */
4079 SSVAL(params
,2,0); /* No EA errors */
4081 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0);
4086 /****************************************************************************
4087 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4088 ****************************************************************************/
4090 static int call_trans2getdfsreferral(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
4091 char **pparams
, int total_params
, char **ppdata
, int total_data
,
4092 unsigned int max_data_bytes
)
4094 char *params
= *pparams
;
4097 int max_referral_level
;
4099 DEBUG(10,("call_trans2getdfsreferral\n"));
4101 if (total_params
< 2)
4102 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
4104 max_referral_level
= SVAL(params
,0);
4106 if(!lp_host_msdfs())
4107 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
4109 srvstr_pull(inbuf
, pathname
, ¶ms
[2], sizeof(pathname
), -1, STR_TERMINATE
);
4110 if((reply_size
= setup_dfs_referral(conn
, pathname
,max_referral_level
,ppdata
)) < 0)
4111 return UNIXERROR(ERRDOS
,ERRbadfile
);
4113 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
4114 send_trans2_replies(outbuf
,bufsize
,0,0,*ppdata
,reply_size
);
4119 #define LMCAT_SPL 0x53
4120 #define LMFUNC_GETJOBID 0x60
4122 /****************************************************************************
4123 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4124 ****************************************************************************/
4126 static int call_trans2ioctl(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
4127 char **pparams
, int total_params
, char **ppdata
, int total_data
,
4128 unsigned int max_data_bytes
)
4130 char *pdata
= *ppdata
;
4131 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv15
);
4133 /* check for an invalid fid before proceeding */
4136 return(ERROR_DOS(ERRDOS
,ERRbadfid
));
4138 if ((SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
4139 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
4140 pdata
= SMB_REALLOC(*ppdata
, 32);
4142 return ERROR_DOS(ERRDOS
,ERRnomem
);
4145 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
4146 CAN ACCEPT THIS IN UNICODE. JRA. */
4148 SSVAL(pdata
,0,fsp
->rap_print_jobid
); /* Job number */
4149 srvstr_push( outbuf
, pdata
+ 2, global_myname(), 15, STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
4150 srvstr_push( outbuf
, pdata
+18, lp_servicename(SNUM(conn
)), 13, STR_ASCII
|STR_TERMINATE
); /* Service name */
4151 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32);
4154 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
4155 return ERROR_DOS(ERRSRV
,ERRerror
);
4159 /****************************************************************************
4160 Reply to a SMBfindclose (stop trans2 directory search).
4161 ****************************************************************************/
4163 int reply_findclose(connection_struct
*conn
,
4164 char *inbuf
,char *outbuf
,int length
,int bufsize
)
4167 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
4168 START_PROFILE(SMBfindclose
);
4170 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
4172 dptr_close(&dptr_num
);
4174 outsize
= set_message(outbuf
,0,0,True
);
4176 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
4178 END_PROFILE(SMBfindclose
);
4182 /****************************************************************************
4183 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
4184 ****************************************************************************/
4186 int reply_findnclose(connection_struct
*conn
,
4187 char *inbuf
,char *outbuf
,int length
,int bufsize
)
4191 START_PROFILE(SMBfindnclose
);
4193 dptr_num
= SVAL(inbuf
,smb_vwv0
);
4195 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
4197 /* We never give out valid handles for a
4198 findnotifyfirst - so any dptr_num is ok here.
4201 outsize
= set_message(outbuf
,0,0,True
);
4203 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
4205 END_PROFILE(SMBfindnclose
);
4209 /****************************************************************************
4210 Reply to a SMBtranss2 - just ignore it!
4211 ****************************************************************************/
4213 int reply_transs2(connection_struct
*conn
,
4214 char *inbuf
,char *outbuf
,int length
,int bufsize
)
4216 START_PROFILE(SMBtranss2
);
4217 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
4218 END_PROFILE(SMBtranss2
);
4222 /****************************************************************************
4223 Reply to a SMBtrans2.
4224 ****************************************************************************/
4226 int reply_trans2(connection_struct
*conn
,
4227 char *inbuf
,char *outbuf
,int length
,int bufsize
)
4230 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
4231 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
4232 unsigned int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
4234 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
4235 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
4236 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
4237 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
4238 int32 timeout
= IVALS(inbuf
,smb_timeout
);
4240 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
4241 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
4242 char *params
= NULL
, *data
= NULL
;
4243 unsigned int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
4244 START_PROFILE(SMBtrans2
);
4246 if(global_oplock_break
&& (tran_call
== TRANSACT2_OPEN
)) {
4247 /* Queue this open message as we are the process of an
4250 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4251 DEBUGADD(2,( "in oplock break state.\n"));
4253 push_oplock_pending_smb_message(inbuf
, length
);
4254 END_PROFILE(SMBtrans2
);
4258 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
4259 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
4260 END_PROFILE(SMBtrans2
);
4261 return ERROR_DOS(ERRSRV
,ERRaccess
);
4264 outsize
= set_message(outbuf
,0,0,True
);
4266 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4267 is so as a sanity check */
4270 * Need to have rc=0 for ioctl to get job id for OS/2.
4271 * Network printing will fail if function is not successful.
4272 * Similar function in reply.c will be used if protocol
4273 * is LANMAN1.0 instead of LM1.2X002.
4274 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4275 * outbuf doesn't have to be set(only job id is used).
4277 if ( (suwcnt
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
4278 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
4279 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
4280 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4282 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt
));
4283 DEBUG(2,("Transaction is %d\n",tran_call
));
4284 END_PROFILE(SMBtrans2
);
4285 ERROR_DOS(ERRDOS
,ERRinvalidparam
);
4289 /* Allocate the space for the maximum needed parameters and data */
4290 if (total_params
> 0)
4291 params
= (char *)SMB_MALLOC(total_params
);
4293 data
= (char *)SMB_MALLOC(total_data
);
4295 if ((total_params
&& !params
) || (total_data
&& !data
)) {
4296 DEBUG(2,("Out of memory in reply_trans2\n"));
4299 END_PROFILE(SMBtrans2
);
4300 return ERROR_DOS(ERRDOS
,ERRnomem
);
4303 /* Copy the param and data bytes sent with this request into
4304 the params buffer */
4305 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
4306 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
4308 if (num_params
> total_params
|| num_data
> total_data
)
4309 exit_server("invalid params in reply_trans2");
4312 unsigned int psoff
= SVAL(inbuf
, smb_psoff
);
4313 if ((psoff
+ num_params
< psoff
) || (psoff
+ num_params
< num_params
))
4315 if ((smb_base(inbuf
) + psoff
+ num_params
> inbuf
+ length
) ||
4316 (smb_base(inbuf
) + psoff
+ num_params
< smb_base(inbuf
)))
4318 memcpy( params
, smb_base(inbuf
) + psoff
, num_params
);
4321 unsigned int dsoff
= SVAL(inbuf
, smb_dsoff
);
4322 if ((dsoff
+ num_data
< dsoff
) || (dsoff
+ num_data
< num_data
))
4324 if ((smb_base(inbuf
) + dsoff
+ num_data
> inbuf
+ length
) ||
4325 (smb_base(inbuf
) + dsoff
+ num_data
< smb_base(inbuf
)))
4327 memcpy( data
, smb_base(inbuf
) + dsoff
, num_data
);
4330 srv_signing_trans_start(SVAL(inbuf
,smb_mid
));
4332 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
) {
4333 /* We need to send an interim response then receive the rest
4334 of the parameter/data bytes */
4335 outsize
= set_message(outbuf
,0,0,True
);
4336 srv_signing_trans_stop();
4337 if (!send_smb(smbd_server_fd(),outbuf
))
4338 exit_server("reply_trans2: send_smb failed.");
4340 while (num_data_sofar
< total_data
||
4341 num_params_sofar
< total_params
) {
4343 unsigned int param_disp
;
4344 unsigned int param_off
;
4345 unsigned int data_disp
;
4346 unsigned int data_off
;
4348 ret
= receive_next_smb(inbuf
,bufsize
,SMB_SECONDARY_WAIT
);
4351 * The sequence number for the trans reply is always
4352 * based on the last secondary received.
4355 srv_signing_trans_start(SVAL(inbuf
,smb_mid
));
4358 (CVAL(inbuf
, smb_com
) != SMBtranss2
)) || !ret
) {
4359 outsize
= set_message(outbuf
,0,0,True
);
4361 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4363 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4364 (smb_read_error
== READ_ERROR
) ? "error" : "timeout" ));
4368 /* Revise total_params and total_data in case
4369 they have changed downwards */
4370 if (SVAL(inbuf
, smb_tpscnt
) < total_params
)
4371 total_params
= SVAL(inbuf
, smb_tpscnt
);
4372 if (SVAL(inbuf
, smb_tdscnt
) < total_data
)
4373 total_data
= SVAL(inbuf
, smb_tdscnt
);
4375 num_params
= SVAL(inbuf
,smb_spscnt
);
4376 param_off
= SVAL(inbuf
, smb_spsoff
);
4377 param_disp
= SVAL(inbuf
, smb_spsdisp
);
4378 num_params_sofar
+= num_params
;
4380 num_data
= SVAL(inbuf
, smb_sdscnt
);
4381 data_off
= SVAL(inbuf
, smb_sdsoff
);
4382 data_disp
= SVAL(inbuf
, smb_sdsdisp
);
4383 num_data_sofar
+= num_data
;
4385 if (num_params_sofar
> total_params
|| num_data_sofar
> total_data
)
4389 if (param_disp
+ num_params
> total_params
)
4391 if ((param_disp
+ num_params
< param_disp
) ||
4392 (param_disp
+ num_params
< num_params
))
4394 if (param_disp
> total_params
)
4396 if ((smb_base(inbuf
) + param_off
+ num_params
>= inbuf
+ bufsize
) ||
4397 (smb_base(inbuf
) + param_off
+ num_params
< smb_base(inbuf
)))
4399 if (params
+ param_disp
< params
)
4402 memcpy( ¶ms
[param_disp
], smb_base(inbuf
) + param_off
, num_params
);
4405 if (data_disp
+ num_data
> total_data
)
4407 if ((data_disp
+ num_data
< data_disp
) ||
4408 (data_disp
+ num_data
< num_data
))
4410 if (data_disp
> total_data
)
4412 if ((smb_base(inbuf
) + data_off
+ num_data
>= inbuf
+ bufsize
) ||
4413 (smb_base(inbuf
) + data_off
+ num_data
< smb_base(inbuf
)))
4415 if (data
+ data_disp
< data
)
4418 memcpy( &data
[data_disp
], smb_base(inbuf
) + data_off
, num_data
);
4423 if (Protocol
>= PROTOCOL_NT1
) {
4424 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | 0x40); /* IS_LONG_NAME */
4427 /* Now we must call the relevant TRANS2 function */
4429 case TRANSACT2_OPEN
:
4430 START_PROFILE_NESTED(Trans2_open
);
4431 outsize
= call_trans2open(conn
, inbuf
, outbuf
, bufsize
,
4432 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4433 END_PROFILE_NESTED(Trans2_open
);
4436 case TRANSACT2_FINDFIRST
:
4437 START_PROFILE_NESTED(Trans2_findfirst
);
4438 outsize
= call_trans2findfirst(conn
, inbuf
, outbuf
, bufsize
,
4439 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4440 END_PROFILE_NESTED(Trans2_findfirst
);
4443 case TRANSACT2_FINDNEXT
:
4444 START_PROFILE_NESTED(Trans2_findnext
);
4445 outsize
= call_trans2findnext(conn
, inbuf
, outbuf
, length
, bufsize
,
4446 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4447 END_PROFILE_NESTED(Trans2_findnext
);
4450 case TRANSACT2_QFSINFO
:
4451 START_PROFILE_NESTED(Trans2_qfsinfo
);
4452 outsize
= call_trans2qfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4453 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4454 END_PROFILE_NESTED(Trans2_qfsinfo
);
4457 #ifdef HAVE_SYS_QUOTAS
4458 case TRANSACT2_SETFSINFO
:
4459 START_PROFILE_NESTED(Trans2_setfsinfo
);
4460 outsize
= call_trans2setfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4461 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4462 END_PROFILE_NESTED(Trans2_setfsinfo
);
4465 case TRANSACT2_QPATHINFO
:
4466 case TRANSACT2_QFILEINFO
:
4467 START_PROFILE_NESTED(Trans2_qpathinfo
);
4468 outsize
= call_trans2qfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4469 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4470 END_PROFILE_NESTED(Trans2_qpathinfo
);
4472 case TRANSACT2_SETPATHINFO
:
4473 case TRANSACT2_SETFILEINFO
:
4474 START_PROFILE_NESTED(Trans2_setpathinfo
);
4475 outsize
= call_trans2setfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4476 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4477 END_PROFILE_NESTED(Trans2_setpathinfo
);
4480 case TRANSACT2_FINDNOTIFYFIRST
:
4481 START_PROFILE_NESTED(Trans2_findnotifyfirst
);
4482 outsize
= call_trans2findnotifyfirst(conn
, inbuf
, outbuf
, length
, bufsize
,
4483 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4484 END_PROFILE_NESTED(Trans2_findnotifyfirst
);
4487 case TRANSACT2_FINDNOTIFYNEXT
:
4488 START_PROFILE_NESTED(Trans2_findnotifynext
);
4489 outsize
= call_trans2findnotifynext(conn
, inbuf
, outbuf
, length
, bufsize
,
4490 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4491 END_PROFILE_NESTED(Trans2_findnotifynext
);
4493 case TRANSACT2_MKDIR
:
4494 START_PROFILE_NESTED(Trans2_mkdir
);
4495 outsize
= call_trans2mkdir(conn
, inbuf
, outbuf
, length
, bufsize
,
4496 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4497 END_PROFILE_NESTED(Trans2_mkdir
);
4500 case TRANSACT2_GET_DFS_REFERRAL
:
4501 START_PROFILE_NESTED(Trans2_get_dfs_referral
);
4502 outsize
= call_trans2getdfsreferral(conn
,inbuf
,outbuf
,length
, bufsize
,
4503 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4504 END_PROFILE_NESTED(Trans2_get_dfs_referral
);
4506 case TRANSACT2_IOCTL
:
4507 START_PROFILE_NESTED(Trans2_ioctl
);
4508 outsize
= call_trans2ioctl(conn
,inbuf
,outbuf
,length
, bufsize
,
4509 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4510 END_PROFILE_NESTED(Trans2_ioctl
);
4513 /* Error in request */
4514 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call
));
4517 END_PROFILE(SMBtrans2
);
4518 srv_signing_trans_stop();
4519 return ERROR_DOS(ERRSRV
,ERRerror
);
4522 /* As we do not know how many data packets will need to be
4523 returned here the various call_trans2xxxx calls
4524 must send their own. Thus a call_trans2xxx routine only
4525 returns a value other than -1 when it wants to send
4529 srv_signing_trans_stop();
4533 END_PROFILE(SMBtrans2
);
4534 return outsize
; /* If a correct response was needed the
4535 call_trans2xxx calls have already sent
4536 it. If outsize != -1 then it is returning */
4540 srv_signing_trans_stop();
4543 END_PROFILE(SMBtrans2
);
4544 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);