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/ERRbadfile -
1488 * from observation of NT.
1491 if(numentries
== 0) {
1492 dptr_close(&dptr_num
);
1493 return ERROR_DOS(ERRDOS
,ERRbadfile
);
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 return ERROR_NT(ntstatus
);
1575 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1576 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1577 resume_key = %d resume name = %s continue=%d level = %d\n",
1578 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
1579 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
1582 /* W2K3 seems to treat zero as 1. */
1586 switch (info_level
) {
1587 case SMB_INFO_STANDARD
:
1588 case SMB_INFO_QUERY_EA_SIZE
:
1589 case SMB_FIND_FILE_DIRECTORY_INFO
:
1590 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1591 case SMB_FIND_FILE_NAMES_INFO
:
1592 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1594 case SMB_FIND_FILE_UNIX
:
1595 if (!lp_unix_extensions())
1596 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1599 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1602 pdata
= SMB_REALLOC( *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1604 return ERROR_DOS(ERRDOS
,ERRnomem
);
1607 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1609 /* Realloc the params space */
1610 params
= SMB_REALLOC(*pparams
, 6*SIZEOFWORD
);
1611 if( params
== NULL
)
1612 return ERROR_DOS(ERRDOS
,ERRnomem
);
1616 /* Check that the dptr is valid */
1617 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
)))
1618 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1620 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1622 /* Get the wildcard mask from the dptr */
1623 if((p
= dptr_wcard(dptr_num
))== NULL
) {
1624 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
1625 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1629 pstrcpy(directory
,conn
->dirpath
);
1631 /* Get the attr mask from the dptr */
1632 dirtype
= dptr_attr(dptr_num
);
1634 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
1635 dptr_num
, mask
, dirtype
,
1637 dptr_TellDir(conn
->dirptr
)));
1639 /* We don't need to check for VOL here as this is returned by
1640 a different TRANS2 call. */
1642 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1643 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
1644 dont_descend
= True
;
1647 space_remaining
= max_data_bytes
;
1648 out_of_space
= False
;
1651 * Seek to the correct position. We no longer use the resume key but
1652 * depend on the last file name instead.
1655 if(*resume_name
&& !continue_bit
) {
1658 long current_pos
= 0;
1660 * Remember, mangle_map is called by
1661 * get_lanman2_dir_entry(), so the resume name
1662 * could be mangled. Ensure we check the unmangled name.
1665 if (mangle_is_mangled(resume_name
)) {
1666 mangle_check_cache(resume_name
, sizeof(resume_name
)-1);
1670 * Fix for NT redirector problem triggered by resume key indexes
1671 * changing between directory scans. We now return a resume key of 0
1672 * and instead look for the filename to continue from (also given
1673 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1674 * findfirst/findnext (as is usual) then the directory pointer
1675 * should already be at the correct place.
1678 finished
= !dptr_SearchDir(conn
->dirptr
, resume_name
, ¤t_pos
, &st
);
1679 } /* end if resume_name && !continue_bit */
1681 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
1682 BOOL got_exact_match
= False
;
1684 /* this is a heuristic to avoid seeking the dirptr except when
1685 absolutely necessary. It allows for a filename of about 40 chars */
1686 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1687 out_of_space
= True
;
1690 finished
= !get_lanman2_dir_entry(conn
,
1692 mask
,dirtype
,info_level
,
1693 requires_resume_key
,dont_descend
,
1694 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1698 if (finished
&& out_of_space
)
1701 if (!finished
&& !out_of_space
)
1705 * As an optimisation if we know we aren't looking
1706 * for a wildcard name (ie. the name matches the wildcard exactly)
1707 * then we can finish on any (first) match.
1708 * This speeds up large directory searches. JRA.
1714 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1717 /* Check if we can close the dirptr */
1718 if(close_after_request
|| (finished
&& close_if_end
)) {
1719 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
1720 dptr_close(&dptr_num
); /* This frees up the saved mask */
1723 /* Set up the return parameter block */
1724 SSVAL(params
,0,numentries
);
1725 SSVAL(params
,2,finished
);
1726 SSVAL(params
,4,0); /* Never an EA error */
1727 SSVAL(params
,6,last_entry_off
);
1729 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
1731 if ((! *directory
) && dptr_path(dptr_num
))
1732 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1734 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1735 smb_fn_name(CVAL(inbuf
,smb_com
)),
1736 mask
, directory
, dirtype
, numentries
) );
1741 /****************************************************************************
1742 Reply to a TRANS2_QFSINFO (query filesystem info).
1743 ****************************************************************************/
1745 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1746 char **pparams
, int total_params
, char **ppdata
, int total_data
,
1747 unsigned int max_data_bytes
)
1749 char *pdata
= *ppdata
;
1750 char *params
= *pparams
;
1751 uint16 info_level
= SVAL(params
,0);
1754 char *vname
= volume_label(SNUM(conn
));
1755 int snum
= SNUM(conn
);
1756 char *fstype
= lp_fstype(SNUM(conn
));
1759 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
1761 if(SMB_VFS_STAT(conn
,".",&st
)!=0) {
1762 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
1763 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
1766 pdata
= SMB_REALLOC(*ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1767 if ( pdata
== NULL
)
1768 return ERROR_DOS(ERRDOS
,ERRnomem
);
1771 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1773 switch (info_level
) {
1774 case SMB_INFO_ALLOCATION
:
1776 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1778 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1779 block_size
= lp_block_size(snum
);
1780 if (bsize
< block_size
) {
1781 SMB_BIG_UINT factor
= block_size
/bsize
;
1786 if (bsize
> block_size
) {
1787 SMB_BIG_UINT factor
= bsize
/block_size
;
1792 bytes_per_sector
= 512;
1793 sectors_per_unit
= bsize
/bytes_per_sector
;
1795 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1796 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1797 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1799 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
1800 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
1801 SIVAL(pdata
,l1_cUnit
,dsize
);
1802 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
1803 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
1807 case SMB_INFO_VOLUME
:
1808 /* Return volume name */
1810 * Add volume serial number - hash of a combination of
1811 * the called hostname and the service name.
1813 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(get_local_machine_name())<<16) );
1814 len
= srvstr_push(outbuf
, pdata
+l2_vol_szVolLabel
, vname
, -1, STR_NOALIGN
);
1815 SCVAL(pdata
,l2_vol_cch
,len
);
1816 data_len
= l2_vol_szVolLabel
+ len
;
1817 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1818 (unsigned)st
.st_ctime
, len
, vname
));
1821 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
1822 case SMB_FS_ATTRIBUTE_INFORMATION
:
1825 #if defined(HAVE_SYS_QUOTAS)
1826 quota_flag
= FILE_VOLUME_QUOTAS
;
1829 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
1830 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)|
1831 quota_flag
); /* FS ATTRIBUTES */
1833 SIVAL(pdata
,4,255); /* Max filename component length */
1834 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1835 and will think we can't do long filenames */
1836 len
= srvstr_push(outbuf
, pdata
+12, fstype
, -1, STR_UNICODE
);
1838 data_len
= 12 + len
;
1841 case SMB_QUERY_FS_LABEL_INFO
:
1842 case SMB_FS_LABEL_INFORMATION
:
1843 len
= srvstr_push(outbuf
, pdata
+4, vname
, -1, 0);
1848 case SMB_QUERY_FS_VOLUME_INFO
:
1849 case SMB_FS_VOLUME_INFORMATION
:
1852 * Add volume serial number - hash of a combination of
1853 * the called hostname and the service name.
1855 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
1856 (str_checksum(get_local_machine_name())<<16));
1858 len
= srvstr_push(outbuf
, pdata
+18, vname
, -1, STR_UNICODE
);
1859 SIVAL(pdata
,12,len
);
1861 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1862 (int)strlen(vname
),vname
, lp_servicename(snum
)));
1865 case SMB_QUERY_FS_SIZE_INFO
:
1866 case SMB_FS_SIZE_INFORMATION
:
1868 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1870 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1871 block_size
= lp_block_size(snum
);
1872 if (bsize
< block_size
) {
1873 SMB_BIG_UINT factor
= block_size
/bsize
;
1878 if (bsize
> block_size
) {
1879 SMB_BIG_UINT factor
= bsize
/block_size
;
1884 bytes_per_sector
= 512;
1885 sectors_per_unit
= bsize
/bytes_per_sector
;
1886 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1887 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1888 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1889 SBIG_UINT(pdata
,0,dsize
);
1890 SBIG_UINT(pdata
,8,dfree
);
1891 SIVAL(pdata
,16,sectors_per_unit
);
1892 SIVAL(pdata
,20,bytes_per_sector
);
1896 case SMB_FS_FULL_SIZE_INFORMATION
:
1898 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1900 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1901 block_size
= lp_block_size(snum
);
1902 if (bsize
< block_size
) {
1903 SMB_BIG_UINT factor
= block_size
/bsize
;
1908 if (bsize
> block_size
) {
1909 SMB_BIG_UINT factor
= bsize
/block_size
;
1914 bytes_per_sector
= 512;
1915 sectors_per_unit
= bsize
/bytes_per_sector
;
1916 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1917 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1918 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1919 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
1920 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
1921 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
1922 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
1923 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
1927 case SMB_QUERY_FS_DEVICE_INFO
:
1928 case SMB_FS_DEVICE_INFORMATION
:
1930 SIVAL(pdata
,0,0); /* dev type */
1931 SIVAL(pdata
,4,0); /* characteristics */
1934 #ifdef HAVE_SYS_QUOTAS
1935 case SMB_FS_QUOTA_INFORMATION
:
1937 * what we have to send --metze:
1939 * Unknown1: 24 NULL bytes
1940 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1941 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1942 * Quota Flags: 2 byte :
1943 * Unknown3: 6 NULL bytes
1947 * details for Quota Flags:
1949 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1950 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1951 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1952 * 0x0001 Enable Quotas: enable quota for this fs
1956 /* we need to fake up a fsp here,
1957 * because its not send in this call
1960 SMB_NTQUOTA_STRUCT quotas
;
1963 ZERO_STRUCT(quotas
);
1970 if (current_user
.uid
!= 0) {
1971 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1972 lp_servicename(SNUM(conn
)),conn
->user
));
1973 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
1976 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
1977 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
1978 return ERROR_DOS(ERRSRV
,ERRerror
);
1983 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn
))));
1985 /* Unknown1 24 NULL bytes*/
1986 SBIG_UINT(pdata
,0,(SMB_BIG_UINT
)0);
1987 SBIG_UINT(pdata
,8,(SMB_BIG_UINT
)0);
1988 SBIG_UINT(pdata
,16,(SMB_BIG_UINT
)0);
1990 /* Default Soft Quota 8 bytes */
1991 SBIG_UINT(pdata
,24,quotas
.softlim
);
1993 /* Default Hard Quota 8 bytes */
1994 SBIG_UINT(pdata
,32,quotas
.hardlim
);
1996 /* Quota flag 2 bytes */
1997 SSVAL(pdata
,40,quotas
.qflags
);
1999 /* Unknown3 6 NULL bytes */
2005 #endif /* HAVE_SYS_QUOTAS */
2006 case SMB_FS_OBJECTID_INFORMATION
:
2011 * Query the version and capabilities of the CIFS UNIX extensions
2015 case SMB_QUERY_CIFS_UNIX_INFO
:
2016 if (!lp_unix_extensions())
2017 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2019 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
2020 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
2021 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)CIFS_UNIX_POSIX_ACLS_CAP
)); /* We have POSIX ACLs. */
2024 case SMB_MAC_QUERY_FS_INFO
:
2026 * Thursby MAC extension... ONLY on NTFS filesystems
2027 * once we do streams then we don't need this
2029 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
2031 SIVAL(pdata
,84,0x100); /* Don't support mac... */
2036 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2040 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
2042 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
2047 #ifdef HAVE_SYS_QUOTAS
2048 /****************************************************************************
2049 Reply to a TRANS2_SETFSINFO (set filesystem info).
2050 ****************************************************************************/
2052 static int call_trans2setfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2053 char **pparams
, int total_params
, char **ppdata
, int total_data
,
2054 unsigned int max_data_bytes
)
2056 char *pdata
= *ppdata
;
2057 char *params
= *pparams
;
2058 files_struct
*fsp
= NULL
;
2061 SMB_NTQUOTA_STRUCT quotas
;
2063 ZERO_STRUCT(quotas
);
2065 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn
))));
2068 if ((current_user
.uid
!= 0)||!CAN_WRITE(conn
)) {
2069 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2070 lp_servicename(SNUM(conn
)),conn
->user
));
2071 return ERROR_DOS(ERRSRV
,ERRaccess
);
2075 if (total_params
< 4) {
2076 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2078 return ERROR_DOS(ERRDOS
,ERRinvalidparam
);
2081 fsp
= file_fsp(params
,0);
2083 if (!CHECK_NTQUOTA_HANDLE_OK(fsp
,conn
)) {
2084 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2085 return ERROR_NT(NT_STATUS_INVALID_HANDLE
);
2088 info_level
= SVAL(params
,2);
2090 switch(info_level
) {
2091 case SMB_FS_QUOTA_INFORMATION
:
2092 /* note: normaly there're 48 bytes,
2093 * but we didn't use the last 6 bytes for now
2096 if (total_data
< 42) {
2097 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2099 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2102 /* unknown_1 24 NULL bytes in pdata*/
2104 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2105 quotas
.softlim
= (SMB_BIG_UINT
)IVAL(pdata
,24);
2106 #ifdef LARGE_SMB_OFF_T
2107 quotas
.softlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,28)) << 32);
2108 #else /* LARGE_SMB_OFF_T */
2109 if ((IVAL(pdata
,28) != 0)&&
2110 ((quotas
.softlim
!= 0xFFFFFFFF)||
2111 (IVAL(pdata
,28)!=0xFFFFFFFF))) {
2112 /* more than 32 bits? */
2113 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2115 #endif /* LARGE_SMB_OFF_T */
2117 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2118 quotas
.hardlim
= (SMB_BIG_UINT
)IVAL(pdata
,32);
2119 #ifdef LARGE_SMB_OFF_T
2120 quotas
.hardlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,36)) << 32);
2121 #else /* LARGE_SMB_OFF_T */
2122 if ((IVAL(pdata
,36) != 0)&&
2123 ((quotas
.hardlim
!= 0xFFFFFFFF)||
2124 (IVAL(pdata
,36)!=0xFFFFFFFF))) {
2125 /* more than 32 bits? */
2126 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2128 #endif /* LARGE_SMB_OFF_T */
2130 /* quota_flags 2 bytes **/
2131 quotas
.qflags
= SVAL(pdata
,40);
2133 /* unknown_2 6 NULL bytes follow*/
2135 /* now set the quotas */
2136 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
2137 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
2138 return ERROR_DOS(ERRSRV
,ERRerror
);
2143 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2145 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2150 * sending this reply works fine,
2151 * but I'm not sure it's the same
2152 * like windows do...
2155 outsize
= set_message(outbuf
,10,0,True
);
2159 #endif /* HAVE_SYS_QUOTAS */
2161 /****************************************************************************
2162 Utility function to set bad path error.
2163 ****************************************************************************/
2165 int set_bad_path_error(int err
, BOOL bad_path
, char *outbuf
, int def_class
, uint32 def_code
)
2167 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2168 err
, (int)bad_path
));
2172 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
2174 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2177 return UNIXERROR(def_class
,def_code
);
2180 #if defined(HAVE_POSIX_ACLS)
2181 /****************************************************************************
2182 Utility function to count the number of entries in a POSIX acl.
2183 ****************************************************************************/
2185 static unsigned int count_acl_entries(connection_struct
*conn
, SMB_ACL_T posix_acl
)
2187 unsigned int ace_count
= 0;
2188 int entry_id
= SMB_ACL_FIRST_ENTRY
;
2189 SMB_ACL_ENTRY_T entry
;
2191 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
2193 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
2194 entry_id
= SMB_ACL_NEXT_ENTRY
;
2201 /****************************************************************************
2202 Utility function to marshall a POSIX acl into wire format.
2203 ****************************************************************************/
2205 static BOOL
marshall_posix_acl(connection_struct
*conn
, char *pdata
, SMB_STRUCT_STAT
*pst
, SMB_ACL_T posix_acl
)
2207 int entry_id
= SMB_ACL_FIRST_ENTRY
;
2208 SMB_ACL_ENTRY_T entry
;
2210 while ( posix_acl
&& (SMB_VFS_SYS_ACL_GET_ENTRY(conn
, posix_acl
, entry_id
, &entry
) == 1)) {
2211 SMB_ACL_TAG_T tagtype
;
2212 SMB_ACL_PERMSET_T permset
;
2213 unsigned char perms
= 0;
2214 unsigned int own_grp
;
2217 if (entry_id
== SMB_ACL_FIRST_ENTRY
) {
2218 entry_id
= SMB_ACL_NEXT_ENTRY
;
2221 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn
, entry
, &tagtype
) == -1) {
2222 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2226 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn
, entry
, &permset
) == -1) {
2227 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2231 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_READ
) ? SMB_POSIX_ACL_READ
: 0);
2232 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_WRITE
) ? SMB_POSIX_ACL_WRITE
: 0);
2233 perms
|= (SMB_VFS_SYS_ACL_GET_PERM(conn
, permset
, SMB_ACL_EXECUTE
) ? SMB_POSIX_ACL_EXECUTE
: 0);
2235 SCVAL(pdata
,1,perms
);
2238 case SMB_ACL_USER_OBJ
:
2239 SCVAL(pdata
,0,SMB_POSIX_ACL_USER_OBJ
);
2240 own_grp
= (unsigned int)pst
->st_uid
;
2241 SIVAL(pdata
,2,own_grp
);
2246 uid_t
*puid
= (uid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
2248 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2250 own_grp
= (unsigned int)*puid
;
2251 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)puid
,tagtype
);
2252 SCVAL(pdata
,0,SMB_POSIX_ACL_USER
);
2253 SIVAL(pdata
,2,own_grp
);
2257 case SMB_ACL_GROUP_OBJ
:
2258 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP_OBJ
);
2259 own_grp
= (unsigned int)pst
->st_gid
;
2260 SIVAL(pdata
,2,own_grp
);
2265 gid_t
*pgid
= (gid_t
*)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn
, entry
);
2267 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2269 own_grp
= (unsigned int)*pgid
;
2270 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn
, (void *)pgid
,tagtype
);
2271 SCVAL(pdata
,0,SMB_POSIX_ACL_GROUP
);
2272 SIVAL(pdata
,2,own_grp
);
2277 SCVAL(pdata
,0,SMB_POSIX_ACL_MASK
);
2278 SIVAL(pdata
,2,0xFFFFFFFF);
2279 SIVAL(pdata
,6,0xFFFFFFFF);
2282 SCVAL(pdata
,0,SMB_POSIX_ACL_OTHER
);
2283 SIVAL(pdata
,2,0xFFFFFFFF);
2284 SIVAL(pdata
,6,0xFFFFFFFF);
2287 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2290 pdata
+= SMB_POSIX_ACL_ENTRY_SIZE
;
2297 /****************************************************************************
2298 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2299 file name or file id).
2300 ****************************************************************************/
2302 static int call_trans2qfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2303 char **pparams
, int total_params
, char **ppdata
, int total_data
,
2304 unsigned int max_data_bytes
)
2306 char *params
= *pparams
;
2307 char *pdata
= *ppdata
;
2308 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2311 SMB_OFF_T file_size
=0;
2312 SMB_BIG_UINT allocation_size
=0;
2313 unsigned int data_size
;
2314 unsigned int param_size
= 2;
2315 SMB_STRUCT_STAT sbuf
;
2316 pstring fname
, dos_fname
;
2321 BOOL bad_path
= False
;
2322 BOOL delete_pending
= False
;
2325 files_struct
*fsp
= NULL
;
2326 uint32 desired_access
= 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2329 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2333 if (tran_call
== TRANSACT2_QFILEINFO
) {
2334 if (total_params
< 4)
2335 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2337 fsp
= file_fsp(params
,0);
2338 info_level
= SVAL(params
,2);
2340 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
2342 if(fsp
&& (fsp
->fake_file_handle
)) {
2344 * This is actually for the QUOTA_FAKE_FILE --metze
2347 pstrcpy(fname
, fsp
->fsp_name
);
2348 /* We know this name is ok, it's already passed the checks. */
2350 } else if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2352 * This is actually a QFILEINFO on a directory
2353 * handle (returned from an NT SMB). NT5.0 seems
2354 * to do this call. JRA.
2356 /* We know this name is ok, it's already passed the checks. */
2357 pstrcpy(fname
, fsp
->fsp_name
);
2359 if (INFO_LEVEL_IS_UNIX(info_level
)) {
2360 /* Always do lstat for UNIX calls. */
2361 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
2362 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
2363 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2365 } else if (SMB_VFS_STAT(conn
,fname
,&sbuf
)) {
2366 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
2367 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2370 delete_pending
= fsp
->is_directory
? fsp
->directory_delete_on_close
: 0;
2373 * Original code - this is an open file.
2375 CHECK_FSP(fsp
,conn
);
2377 pstrcpy(fname
, fsp
->fsp_name
);
2378 if (SMB_VFS_FSTAT(fsp
,fsp
->fd
,&sbuf
) != 0) {
2379 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp
->fnum
, strerror(errno
)));
2380 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2382 pos
= fsp
->position_information
;
2383 delete_pending
= fsp
->delete_on_close
;
2384 desired_access
= fsp
->desired_access
;
2387 NTSTATUS status
= NT_STATUS_OK
;
2390 if (total_params
< 6)
2391 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2393 info_level
= SVAL(params
,0);
2395 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
2397 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
, &status
, False
);
2398 if (!NT_STATUS_IS_OK(status
)) {
2399 return ERROR_NT(status
);
2402 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
2404 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2406 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
2408 if (!check_name(fname
,conn
)) {
2409 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2410 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2413 if (INFO_LEVEL_IS_UNIX(info_level
)) {
2414 /* Always do lstat for UNIX calls. */
2415 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
2416 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
2417 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2419 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,fname
,&sbuf
) && (info_level
!= SMB_INFO_IS_NAME_VALID
)) {
2420 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
2421 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2425 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2426 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2428 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2429 fname
,fsp
? fsp
->fnum
: -1, info_level
,tran_call
,total_data
));
2431 p
= strrchr_m(fname
,'/');
2437 mode
= dos_mode(conn
,fname
,&sbuf
);
2439 mode
= FILE_ATTRIBUTE_NORMAL
;
2441 fullpathname
= fname
;
2442 file_size
= get_file_size(sbuf
);
2443 allocation_size
= get_allocation_size(conn
,fsp
,&sbuf
);
2445 /* This is necessary, as otherwise the desktop.ini file in
2446 * this folder is ignored */
2447 mode
|= (lp_profile_acls(SNUM(conn
)) ? aRONLY
: 0);
2451 params
= SMB_REALLOC(*pparams
,2);
2453 return ERROR_DOS(ERRDOS
,ERRnomem
);
2455 memset((char *)params
,'\0',2);
2456 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
2457 pdata
= SMB_REALLOC(*ppdata
, data_size
);
2458 if ( pdata
== NULL
)
2459 return ERROR_DOS(ERRDOS
,ERRnomem
);
2462 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
2463 /* uggh, EAs for OS2 */
2464 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
2465 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
2468 memset((char *)pdata
,'\0',data_size
);
2470 c_time
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
2473 if (fsp
->pending_modtime
) {
2474 /* the pending modtime overrides the current modtime */
2475 sbuf
.st_mtime
= fsp
->pending_modtime
;
2478 /* Do we have this path open ? */
2479 files_struct
*fsp1
= file_find_di_first(sbuf
.st_dev
, sbuf
.st_ino
);
2480 if (fsp1
&& fsp1
->pending_modtime
) {
2481 /* the pending modtime overrides the current modtime */
2482 sbuf
.st_mtime
= fsp1
->pending_modtime
;
2486 if (lp_dos_filetime_resolution(SNUM(conn
))) {
2488 sbuf
.st_atime
&= ~1;
2489 sbuf
.st_ctime
&= ~1;
2490 sbuf
.st_mtime
&= ~1;
2493 /* NT expects the name to be in an exact form of the *full*
2494 filename. See the trans2 torture test */
2495 if (strequal(base_name
,".")) {
2496 pstrcpy(dos_fname
, "\\");
2498 pstr_sprintf(dos_fname
, "\\%s", fname
);
2499 string_replace(dos_fname
, '/', '\\');
2502 switch (info_level
) {
2503 case SMB_INFO_STANDARD
:
2504 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2506 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
2507 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
2508 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
2509 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
2510 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
2511 SSVAL(pdata
,l1_attrFile
,mode
);
2514 case SMB_INFO_QUERY_EA_SIZE
:
2516 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2517 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2519 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
2520 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
2521 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
2522 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
2523 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
2524 SSVAL(pdata
,l1_attrFile
,mode
);
2525 SIVAL(pdata
,l1_attrFile
+2,ea_size
);
2529 case SMB_INFO_IS_NAME_VALID
:
2530 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2531 if (tran_call
== TRANSACT2_QFILEINFO
) {
2532 /* os/2 needs this ? really ?*/
2533 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
2539 case SMB_INFO_QUERY_EAS_FROM_LIST
:
2540 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2542 put_dos_date2(pdata
,0,c_time
);
2543 put_dos_date2(pdata
,4,sbuf
.st_atime
);
2544 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
2545 SIVAL(pdata
,12,(uint32
)file_size
);
2546 SIVAL(pdata
,16,(uint32
)allocation_size
);
2547 SIVAL(pdata
,20,mode
);
2550 case SMB_INFO_QUERY_ALL_EAS
:
2551 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2552 /* We have data_size bytes to put EA's into. */
2553 data_size
= fill_ea_buffer(pdata
, data_size
, conn
, fsp
, fname
);
2556 case SMB_FILE_BASIC_INFORMATION
:
2557 case SMB_QUERY_FILE_BASIC_INFO
:
2559 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
2560 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2561 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
2563 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2567 put_long_date(pdata
,c_time
);
2568 put_long_date(pdata
+8,sbuf
.st_atime
);
2569 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2570 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2571 SIVAL(pdata
,32,mode
);
2573 DEBUG(5,("SMB_QFBI - "));
2575 time_t create_time
= c_time
;
2576 DEBUG(5,("create: %s ", ctime(&create_time
)));
2578 DEBUG(5,("access: %s ", ctime(&sbuf
.st_atime
)));
2579 DEBUG(5,("write: %s ", ctime(&sbuf
.st_mtime
)));
2580 DEBUG(5,("change: %s ", ctime(&sbuf
.st_mtime
)));
2581 DEBUG(5,("mode: %x\n", mode
));
2585 case SMB_FILE_STANDARD_INFORMATION
:
2586 case SMB_QUERY_FILE_STANDARD_INFO
:
2588 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2590 SOFF_T(pdata
,0,allocation_size
);
2591 SOFF_T(pdata
,8,file_size
);
2592 if (delete_pending
& sbuf
.st_nlink
)
2593 SIVAL(pdata
,16,sbuf
.st_nlink
- 1);
2595 SIVAL(pdata
,16,sbuf
.st_nlink
);
2597 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
2600 case SMB_FILE_EA_INFORMATION
:
2601 case SMB_QUERY_FILE_EA_INFO
:
2603 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2604 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2606 SIVAL(pdata
,0,ea_size
);
2610 /* Get the 8.3 name - used if NT SMB was negotiated. */
2611 case SMB_QUERY_FILE_ALT_NAME_INFO
:
2612 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
2616 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2617 pstrcpy(short_name
,base_name
);
2618 /* Mangle if not already 8.3 */
2619 if(!mangle_is_8_3(short_name
, True
)) {
2620 mangle_map(short_name
,True
,True
,SNUM(conn
));
2622 len
= srvstr_push(outbuf
, pdata
+4, short_name
, -1, STR_UNICODE
);
2623 data_size
= 4 + len
;
2628 case SMB_QUERY_FILE_NAME_INFO
:
2630 this must be *exactly* right for ACLs on mapped drives to work
2632 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
2633 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2634 data_size
= 4 + len
;
2638 case SMB_FILE_ALLOCATION_INFORMATION
:
2639 case SMB_QUERY_FILE_ALLOCATION_INFO
:
2640 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2642 SOFF_T(pdata
,0,allocation_size
);
2645 case SMB_FILE_END_OF_FILE_INFORMATION
:
2646 case SMB_QUERY_FILE_END_OF_FILEINFO
:
2647 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2649 SOFF_T(pdata
,0,file_size
);
2652 case SMB_QUERY_FILE_ALL_INFO
:
2653 case SMB_FILE_ALL_INFORMATION
:
2655 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2656 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2657 put_long_date(pdata
,c_time
);
2658 put_long_date(pdata
+8,sbuf
.st_atime
);
2659 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2660 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2661 SIVAL(pdata
,32,mode
);
2663 SOFF_T(pdata
,0,allocation_size
);
2664 SOFF_T(pdata
,8,file_size
);
2665 if (delete_pending
&& sbuf
.st_nlink
)
2666 SIVAL(pdata
,16,sbuf
.st_nlink
- 1);
2668 SIVAL(pdata
,16,sbuf
.st_nlink
);
2669 SCVAL(pdata
,20,delete_pending
);
2670 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
2672 SIVAL(pdata
,0,ea_size
);
2673 pdata
+= 4; /* EA info */
2674 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
2677 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2680 case SMB_FILE_INTERNAL_INFORMATION
:
2681 /* This should be an index number - looks like
2684 I think this causes us to fail the IFSKIT
2685 BasicFileInformationTest. -tpot */
2687 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2688 SIVAL(pdata
,0,sbuf
.st_dev
);
2689 SIVAL(pdata
,4,sbuf
.st_ino
);
2693 case SMB_FILE_ACCESS_INFORMATION
:
2694 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2695 SIVAL(pdata
,0,desired_access
);
2699 case SMB_FILE_NAME_INFORMATION
:
2700 /* Pathname with leading '\'. */
2703 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
2704 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2705 SIVAL(pdata
,0,byte_len
);
2706 data_size
= 4 + byte_len
;
2710 case SMB_FILE_DISPOSITION_INFORMATION
:
2711 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2713 SCVAL(pdata
,0,delete_pending
);
2716 case SMB_FILE_POSITION_INFORMATION
:
2717 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2719 SOFF_T(pdata
,0,pos
);
2722 case SMB_FILE_MODE_INFORMATION
:
2723 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2724 SIVAL(pdata
,0,mode
);
2728 case SMB_FILE_ALIGNMENT_INFORMATION
:
2729 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2730 SIVAL(pdata
,0,0); /* No alignment needed. */
2736 * NT4 server just returns "invalid query" to this - if we try to answer
2737 * it then NTws gets a BSOD! (tridge).
2738 * W2K seems to want this. JRA.
2740 case SMB_QUERY_FILE_STREAM_INFO
:
2742 case SMB_FILE_STREAM_INFORMATION
:
2743 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2747 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", 0xE, False
);
2748 SIVAL(pdata
,0,0); /* ??? */
2749 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
2750 SOFF_T(pdata
,8,file_size
);
2751 SIVAL(pdata
,16,allocation_size
);
2752 SIVAL(pdata
,20,0); /* ??? */
2753 data_size
= 24 + byte_len
;
2757 case SMB_QUERY_COMPRESSION_INFO
:
2758 case SMB_FILE_COMPRESSION_INFORMATION
:
2759 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2760 SOFF_T(pdata
,0,file_size
);
2761 SIVAL(pdata
,8,0); /* ??? */
2762 SIVAL(pdata
,12,0); /* ??? */
2766 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
2767 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2768 put_long_date(pdata
,c_time
);
2769 put_long_date(pdata
+8,sbuf
.st_atime
);
2770 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2771 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2772 SIVAL(pdata
,32,allocation_size
);
2773 SOFF_T(pdata
,40,file_size
);
2774 SIVAL(pdata
,48,mode
);
2775 SIVAL(pdata
,52,0); /* ??? */
2779 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
2780 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2781 SIVAL(pdata
,0,mode
);
2787 * CIFS UNIX Extensions.
2790 case SMB_QUERY_FILE_UNIX_BASIC
:
2792 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2793 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf
.st_mode
));
2795 SOFF_T(pdata
,0,get_file_size(sbuf
)); /* File size 64 Bit */
2798 SOFF_T(pdata
,0,get_allocation_size(conn
,fsp
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
2801 put_long_date(pdata
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
2802 put_long_date(pdata
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
2803 put_long_date(pdata
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
2806 SIVAL(pdata
,0,sbuf
.st_uid
); /* user id for the owner */
2810 SIVAL(pdata
,0,sbuf
.st_gid
); /* group id of owner */
2814 SIVAL(pdata
,0,unix_filetype(sbuf
.st_mode
));
2817 SIVAL(pdata
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
2821 SIVAL(pdata
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
2825 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
2828 SIVAL(pdata
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
2832 SIVAL(pdata
,0,sbuf
.st_nlink
); /* number of hard links */
2835 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2839 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2841 for (i
=0; i
<100; i
++)
2842 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
2848 case SMB_QUERY_FILE_UNIX_LINK
:
2852 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2854 if(!S_ISLNK(sbuf
.st_mode
))
2855 return(UNIXERROR(ERRSRV
,ERRbadlink
));
2857 return(UNIXERROR(ERRDOS
,ERRbadlink
));
2859 len
= SMB_VFS_READLINK(conn
,fullpathname
, buffer
, sizeof(pstring
)-1); /* read link */
2861 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2863 len
= srvstr_push(outbuf
, pdata
, buffer
, -1, STR_TERMINATE
);
2865 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2870 #if defined(HAVE_POSIX_ACLS)
2871 case SMB_QUERY_POSIX_ACL
:
2873 SMB_ACL_T file_acl
= NULL
;
2874 SMB_ACL_T def_acl
= NULL
;
2875 uint16 num_file_acls
= 0;
2876 uint16 num_def_acls
= 0;
2878 if (fsp
&& !fsp
->is_directory
&& (fsp
->fd
!= -1)) {
2879 file_acl
= SMB_VFS_SYS_ACL_GET_FD(fsp
, fsp
->fd
);
2881 file_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fname
, SMB_ACL_TYPE_ACCESS
);
2884 if (file_acl
== NULL
&& no_acl_syscall_error(errno
)) {
2885 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
2887 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED
);
2890 if (S_ISDIR(sbuf
.st_mode
)) {
2891 if (fsp
&& fsp
->is_directory
) {
2892 def_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fsp
->fsp_name
, SMB_ACL_TYPE_DEFAULT
);
2894 def_acl
= SMB_VFS_SYS_ACL_GET_FILE(conn
, fname
, SMB_ACL_TYPE_DEFAULT
);
2896 def_acl
= free_empty_sys_acl(conn
, def_acl
);
2899 num_file_acls
= count_acl_entries(conn
, file_acl
);
2900 num_def_acls
= count_acl_entries(conn
, def_acl
);
2902 if ( data_size
< (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
) {
2903 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
2905 (unsigned int)((num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+
2906 SMB_POSIX_ACL_HEADER_SIZE
) ));
2908 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
2911 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
2913 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL
);
2916 SSVAL(pdata
,0,SMB_POSIX_ACL_VERSION
);
2917 SSVAL(pdata
,2,num_file_acls
);
2918 SSVAL(pdata
,4,num_def_acls
);
2919 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
, &sbuf
, file_acl
)) {
2921 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
2924 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
2926 return ERROR_NT(NT_STATUS_INTERNAL_ERROR
);
2928 if (!marshall_posix_acl(conn
, pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+ (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
), &sbuf
, def_acl
)) {
2930 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
2933 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
2935 return ERROR_NT(NT_STATUS_INTERNAL_ERROR
);
2939 SMB_VFS_SYS_ACL_FREE_ACL(conn
, file_acl
);
2942 SMB_VFS_SYS_ACL_FREE_ACL(conn
, def_acl
);
2944 data_size
= (num_file_acls
+ num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
+ SMB_POSIX_ACL_HEADER_SIZE
;
2950 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2953 send_trans2_replies(outbuf
, bufsize
, params
, param_size
, *ppdata
, data_size
);
2958 /****************************************************************************
2959 Deal with the internal needs of setting the delete on close flag. Note that
2960 as the tdb locking is recursive, it is safe to call this from within
2961 open_file_shared. JRA.
2962 ****************************************************************************/
2964 NTSTATUS
set_delete_on_close_internal(files_struct
*fsp
, BOOL delete_on_close
, uint32 dosmode
)
2966 if (delete_on_close
) {
2968 * Only allow delete on close for writable files.
2971 if (!lp_delete_readonly(SNUM(fsp
->conn
))) {
2972 if (dosmode
& aRONLY
) {
2973 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
2975 return NT_STATUS_CANNOT_DELETE
;
2980 * Only allow delete on close for writable shares.
2983 if (!CAN_WRITE(fsp
->conn
)) {
2984 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2986 return NT_STATUS_ACCESS_DENIED
;
2990 * Only allow delete on close for files/directories opened with delete intent.
2993 if (!(fsp
->desired_access
& DELETE_ACCESS
)) {
2994 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2996 return NT_STATUS_ACCESS_DENIED
;
3000 if(fsp
->is_directory
) {
3001 fsp
->directory_delete_on_close
= delete_on_close
;
3002 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
3003 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
3005 fsp
->delete_on_close
= delete_on_close
;
3006 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
3007 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
3010 return NT_STATUS_OK
;
3013 /****************************************************************************
3014 Sets the delete on close flag over all share modes on this file.
3015 Modify the share mode entry for all files open
3016 on this device and inode to tell other smbds we have
3017 changed the delete on close flag. This will be noticed
3018 in the close code, the last closer will delete the file
3020 ****************************************************************************/
3022 NTSTATUS
set_delete_on_close_over_all(files_struct
*fsp
, BOOL delete_on_close
)
3024 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
3025 delete_on_close
? "Adding" : "Removing", fsp
->fnum
, fsp
->fsp_name
));
3027 if (fsp
->is_directory
|| fsp
->is_stat
)
3028 return NT_STATUS_OK
;
3030 if (lock_share_entry_fsp(fsp
) == False
)
3031 return NT_STATUS_ACCESS_DENIED
;
3033 if (!modify_delete_flag(fsp
->dev
, fsp
->inode
, delete_on_close
)) {
3034 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
3036 unlock_share_entry_fsp(fsp
);
3037 return NT_STATUS_ACCESS_DENIED
;
3040 unlock_share_entry_fsp(fsp
);
3041 return NT_STATUS_OK
;
3044 /****************************************************************************
3045 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3047 ****************************************************************************/
3049 NTSTATUS
hardlink_internals(connection_struct
*conn
, char *oldname
, char *newname
)
3051 BOOL bad_path_oldname
= False
;
3052 BOOL bad_path_newname
= False
;
3053 SMB_STRUCT_STAT sbuf1
, sbuf2
;
3054 pstring last_component_oldname
;
3055 pstring last_component_newname
;
3056 NTSTATUS status
= NT_STATUS_OK
;
3062 if (ms_has_wild(newname
) || ms_has_wild(oldname
)) {
3063 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD
;
3066 unix_convert(oldname
,conn
,last_component_oldname
,&bad_path_oldname
,&sbuf1
);
3067 if (bad_path_oldname
) {
3068 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
3071 /* Quick check for "." and ".." */
3072 if (last_component_oldname
[0] == '.') {
3073 if (!last_component_oldname
[1] || (last_component_oldname
[1] == '.' && !last_component_oldname
[2])) {
3074 return NT_STATUS_OBJECT_NAME_INVALID
;
3078 /* source must already exist. */
3079 if (!VALID_STAT(sbuf1
)) {
3080 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3083 if (!check_name(oldname
,conn
)) {
3084 return NT_STATUS_ACCESS_DENIED
;
3087 unix_convert(newname
,conn
,last_component_newname
,&bad_path_newname
,&sbuf2
);
3088 if (bad_path_newname
) {
3089 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
3092 /* Quick check for "." and ".." */
3093 if (last_component_newname
[0] == '.') {
3094 if (!last_component_newname
[1] || (last_component_newname
[1] == '.' && !last_component_newname
[2])) {
3095 return NT_STATUS_OBJECT_NAME_INVALID
;
3099 /* Disallow if newname already exists. */
3100 if (VALID_STAT(sbuf2
)) {
3101 return NT_STATUS_OBJECT_NAME_COLLISION
;
3104 if (!check_name(newname
,conn
)) {
3105 return NT_STATUS_ACCESS_DENIED
;
3108 /* No links from a directory. */
3109 if (S_ISDIR(sbuf1
.st_mode
)) {
3110 return NT_STATUS_FILE_IS_A_DIRECTORY
;
3113 /* Ensure this is within the share. */
3114 if (!reduce_name(conn
, oldname
) != 0)
3115 return NT_STATUS_ACCESS_DENIED
;
3117 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname
, oldname
));
3119 if (SMB_VFS_LINK(conn
,oldname
,newname
) != 0) {
3120 status
= map_nt_error_from_unix(errno
);
3121 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3122 nt_errstr(status
), newname
, oldname
));
3128 /****************************************************************************
3129 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3130 ****************************************************************************/
3132 static int call_trans2setfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
3133 char **pparams
, int total_params
, char **ppdata
, int total_data
,
3134 unsigned int max_data_bytes
)
3136 char *params
= *pparams
;
3137 char *pdata
= *ppdata
;
3138 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
3143 SMB_STRUCT_STAT sbuf
;
3146 BOOL bad_path
= False
;
3147 files_struct
*fsp
= NULL
;
3148 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
3149 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
3150 mode_t unixmode
= 0;
3151 NTSTATUS status
= NT_STATUS_OK
;
3154 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3158 if (tran_call
== TRANSACT2_SETFILEINFO
) {
3159 if (total_params
< 4)
3160 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3162 fsp
= file_fsp(params
,0);
3163 info_level
= SVAL(params
,2);
3165 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
3167 * This is actually a SETFILEINFO on a directory
3168 * handle (returned from an NT SMB). NT5.0 seems
3169 * to do this call. JRA.
3171 pstrcpy(fname
, fsp
->fsp_name
);
3172 if (SMB_VFS_STAT(conn
,fname
,&sbuf
) != 0) {
3173 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
3174 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3176 } else if (fsp
&& fsp
->print_file
) {
3178 * Doing a DELETE_ON_CLOSE should cancel a print job.
3180 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
3181 fsp
->share_mode
= FILE_DELETE_ON_CLOSE
;
3183 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp
->fsp_name
));
3186 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3189 return (UNIXERROR(ERRDOS
,ERRbadpath
));
3192 * Original code - this is an open file.
3194 CHECK_FSP(fsp
,conn
);
3196 pstrcpy(fname
, fsp
->fsp_name
);
3199 if (SMB_VFS_FSTAT(fsp
,fd
,&sbuf
) != 0) {
3200 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
3201 return(UNIXERROR(ERRDOS
,ERRbadfid
));
3206 if (total_params
< 6)
3207 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3209 info_level
= SVAL(params
,0);
3210 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
, &status
, False
);
3211 if (!NT_STATUS_IS_OK(status
)) {
3212 return ERROR_NT(status
);
3214 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
3216 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
3220 * For CIFS UNIX extensions the target name may not exist.
3223 if(!VALID_STAT(sbuf
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
3224 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname
, strerror(errno
)));
3225 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3228 if(!check_name(fname
, conn
)) {
3229 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3234 if (!CAN_WRITE(conn
))
3235 return ERROR_DOS(ERRSRV
,ERRaccess
);
3237 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
3238 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3240 if (VALID_STAT(sbuf
))
3241 unixmode
= sbuf
.st_mode
;
3243 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3244 tran_call
,fname
, fsp
? fsp
->fnum
: -1, info_level
,total_data
));
3246 /* Realloc the parameter and data sizes */
3247 params
= SMB_REALLOC(*pparams
,2);
3249 return ERROR_DOS(ERRDOS
,ERRnomem
);
3254 if (fsp
&& fsp
->pending_modtime
) {
3255 /* the pending modtime overrides the current modtime */
3256 sbuf
.st_mtime
= fsp
->pending_modtime
;
3259 size
= get_file_size(sbuf
);
3260 tvs
.modtime
= sbuf
.st_mtime
;
3261 tvs
.actime
= sbuf
.st_atime
;
3262 dosmode
= dos_mode(conn
,fname
,&sbuf
);
3263 unixmode
= sbuf
.st_mode
;
3265 set_owner
= VALID_STAT(sbuf
) ? sbuf
.st_uid
: (uid_t
)SMB_UID_NO_CHANGE
;
3266 set_grp
= VALID_STAT(sbuf
) ? sbuf
.st_gid
: (gid_t
)SMB_GID_NO_CHANGE
;
3268 switch (info_level
) {
3269 case SMB_INFO_STANDARD
:
3271 if (total_data
< 12)
3272 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3275 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
3277 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
3281 case SMB_INFO_SET_EA
:
3282 status
= set_ea(conn
, fsp
, fname
, pdata
, total_data
);
3283 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3284 return ERROR_NT(status
);
3287 /* XXXX um, i don't think this is right.
3288 it's also not in the cifs6.txt spec.
3290 case SMB_INFO_QUERY_EAS_FROM_LIST
:
3291 if (total_data
< 28)
3292 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3294 tvs
.actime
= make_unix_date2(pdata
+8);
3295 tvs
.modtime
= make_unix_date2(pdata
+12);
3296 size
= IVAL(pdata
,16);
3297 dosmode
= IVAL(pdata
,24);
3300 /* XXXX nor this. not in cifs6.txt, either. */
3301 case SMB_INFO_QUERY_ALL_EAS
:
3302 if (total_data
< 28)
3303 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3305 tvs
.actime
= make_unix_date2(pdata
+8);
3306 tvs
.modtime
= make_unix_date2(pdata
+12);
3307 size
= IVAL(pdata
,16);
3308 dosmode
= IVAL(pdata
,24);
3311 case SMB_SET_FILE_BASIC_INFO
:
3312 case SMB_FILE_BASIC_INFORMATION
:
3314 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3316 time_t changed_time
;
3318 if (total_data
< 36)
3319 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3321 /* Ignore create time at offset pdata. */
3324 tvs
.actime
= interpret_long_date(pdata
+8);
3326 write_time
= interpret_long_date(pdata
+16);
3327 changed_time
= interpret_long_date(pdata
+24);
3329 tvs
.modtime
= MIN(write_time
, changed_time
);
3331 if (write_time
> tvs
.modtime
&& write_time
!= (time_t)-1) {
3332 tvs
.modtime
= write_time
;
3334 /* Prefer a defined time to an undefined one. */
3335 if (null_mtime(tvs
.modtime
)) {
3336 tvs
.modtime
= null_mtime(write_time
) ? changed_time
: write_time
;
3340 dosmode
= IVAL(pdata
,32);
3344 case SMB_FILE_ALLOCATION_INFORMATION
:
3345 case SMB_SET_FILE_ALLOCATION_INFO
:
3348 SMB_BIG_UINT allocation_size
;
3351 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3353 allocation_size
= (SMB_BIG_UINT
)IVAL(pdata
,0);
3354 #ifdef LARGE_SMB_OFF_T
3355 allocation_size
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
3356 #else /* LARGE_SMB_OFF_T */
3357 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3358 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3359 #endif /* LARGE_SMB_OFF_T */
3360 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3361 fname
, (double)allocation_size
));
3363 if (allocation_size
) {
3364 allocation_size
= smb_roundup(conn
, allocation_size
);
3367 if(allocation_size
!= get_file_size(sbuf
)) {
3368 SMB_STRUCT_STAT new_sbuf
;
3370 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3371 fname
, (double)allocation_size
));
3374 files_struct
*new_fsp
= NULL
;
3375 int access_mode
= 0;
3378 if(global_oplock_break
) {
3379 /* Queue this file modify as we are the process of an oplock break. */
3381 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3382 DEBUGADD(2,( "in oplock break state.\n"));
3384 push_oplock_pending_smb_message(inbuf
, length
);
3388 new_fsp
= open_file_shared1(conn
, fname
, &sbuf
,FILE_WRITE_DATA
,
3389 SET_OPEN_MODE(DOS_OPEN_RDWR
),
3390 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
3391 FILE_ATTRIBUTE_NORMAL
,
3392 INTERNAL_OPEN_ONLY
, &access_mode
, &action
);
3394 if (new_fsp
== NULL
)
3395 return(UNIXERROR(ERRDOS
,ERRbadpath
));
3396 ret
= vfs_allocate_file_space(new_fsp
, allocation_size
);
3397 if (SMB_VFS_FSTAT(new_fsp
,new_fsp
->fd
,&new_sbuf
) != 0) {
3398 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3399 new_fsp
->fnum
, strerror(errno
)));
3402 close_file(new_fsp
,True
);
3404 ret
= vfs_allocate_file_space(fsp
, allocation_size
);
3405 if (SMB_VFS_FSTAT(fsp
,fd
,&new_sbuf
) != 0) {
3406 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3407 fsp
->fnum
, strerror(errno
)));
3412 return ERROR_NT(NT_STATUS_DISK_FULL
);
3414 /* Allocate can truncate size... */
3415 size
= get_file_size(new_sbuf
);
3421 case SMB_FILE_END_OF_FILE_INFORMATION
:
3422 case SMB_SET_FILE_END_OF_FILE_INFO
:
3425 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3427 size
= IVAL(pdata
,0);
3428 #ifdef LARGE_SMB_OFF_T
3429 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
3430 #else /* LARGE_SMB_OFF_T */
3431 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3432 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3433 #endif /* LARGE_SMB_OFF_T */
3434 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname
, (double)size
));
3438 case SMB_FILE_DISPOSITION_INFORMATION
:
3439 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
3441 BOOL delete_on_close
;
3444 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3446 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
3448 /* Just ignore this set on a path. */
3449 if (tran_call
!= TRANSACT2_SETFILEINFO
)
3453 return(UNIXERROR(ERRDOS
,ERRbadfid
));
3455 status
= set_delete_on_close_internal(fsp
, delete_on_close
, dosmode
);
3457 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3458 return ERROR_NT(status
);
3460 /* The set is across all open files on this dev/inode pair. */
3461 status
=set_delete_on_close_over_all(fsp
, delete_on_close
);
3462 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3463 return ERROR_NT(status
);
3468 case SMB_FILE_POSITION_INFORMATION
:
3470 SMB_BIG_UINT position_information
;
3473 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3475 position_information
= (SMB_BIG_UINT
)IVAL(pdata
,0);
3476 #ifdef LARGE_SMB_OFF_T
3477 position_information
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
3478 #else /* LARGE_SMB_OFF_T */
3479 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3480 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3481 #endif /* LARGE_SMB_OFF_T */
3482 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3483 fname
, (double)position_information
));
3485 fsp
->position_information
= position_information
;
3490 * CIFS UNIX extensions.
3493 case SMB_SET_FILE_UNIX_BASIC
:
3495 uint32 raw_unixmode
;
3497 if (total_data
< 100)
3498 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3500 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
3501 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
3502 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
3503 #ifdef LARGE_SMB_OFF_T
3504 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
3505 #else /* LARGE_SMB_OFF_T */
3506 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3507 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3508 #endif /* LARGE_SMB_OFF_T */
3510 pdata
+=24; /* ctime & st_blocks are not changed */
3511 tvs
.actime
= interpret_long_date(pdata
); /* access_time */
3512 tvs
.modtime
= interpret_long_date(pdata
+8); /* modification_time */
3514 set_owner
= (uid_t
)IVAL(pdata
,0);
3516 set_grp
= (gid_t
)IVAL(pdata
,0);
3518 raw_unixmode
= IVAL(pdata
,28);
3519 unixmode
= unix_perms_from_wire(conn
, &sbuf
, raw_unixmode
);
3520 dosmode
= 0; /* Ensure dos mode change doesn't override this. */
3522 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3523 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3524 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
3526 if (!VALID_STAT(sbuf
)) {
3529 * The only valid use of this is to create character and block
3530 * devices, and named pipes. This is deprecated (IMHO) and
3531 * a new info level should be used for mknod. JRA.
3534 uint32 file_type
= IVAL(pdata
,0);
3535 #if defined(HAVE_MAKEDEV)
3536 uint32 dev_major
= IVAL(pdata
,4);
3537 uint32 dev_minor
= IVAL(pdata
,12);
3540 uid_t myuid
= geteuid();
3541 gid_t mygid
= getegid();
3542 SMB_DEV_T dev
= (SMB_DEV_T
)0;
3544 if (tran_call
== TRANSACT2_SETFILEINFO
)
3545 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3547 if (raw_unixmode
== SMB_MODE_NO_CHANGE
)
3548 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3550 #if defined(HAVE_MAKEDEV)
3551 dev
= makedev(dev_major
, dev_minor
);
3554 /* We can only create as the owner/group we are. */
3556 if ((set_owner
!= myuid
) && (set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
))
3557 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3558 if ((set_grp
!= mygid
) && (set_grp
!= (gid_t
)SMB_GID_NO_CHANGE
))
3559 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3561 switch (file_type
) {
3562 #if defined(S_IFIFO)
3563 case UNIX_TYPE_FIFO
:
3564 unixmode
|= S_IFIFO
;
3567 #if defined(S_IFSOCK)
3568 case UNIX_TYPE_SOCKET
:
3569 unixmode
|= S_IFSOCK
;
3572 #if defined(S_IFCHR)
3573 case UNIX_TYPE_CHARDEV
:
3574 unixmode
|= S_IFCHR
;
3577 #if defined(S_IFBLK)
3578 case UNIX_TYPE_BLKDEV
:
3579 unixmode
|= S_IFBLK
;
3583 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3586 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3587 0%o for file %s\n", (double)dev
, unixmode
, fname
));
3589 /* Ok - do the mknod. */
3590 if (SMB_VFS_MKNOD(conn
,fname
, unixmode
, dev
) != 0)
3591 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3593 inherit_access_acl(conn
, fname
, unixmode
);
3596 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3601 * Deal with the UNIX specific mode set.
3604 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
3605 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3606 (unsigned int)unixmode
, fname
));
3607 if (SMB_VFS_CHMOD(conn
,fname
,unixmode
) != 0)
3608 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3612 * Deal with the UNIX specific uid set.
3615 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) && (sbuf
.st_uid
!= set_owner
)) {
3616 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3617 (unsigned int)set_owner
, fname
));
3618 if (SMB_VFS_CHOWN(conn
,fname
,set_owner
, (gid_t
)-1) != 0)
3619 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3623 * Deal with the UNIX specific gid set.
3626 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) && (sbuf
.st_gid
!= set_grp
)) {
3627 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3628 (unsigned int)set_owner
, fname
));
3629 if (SMB_VFS_CHOWN(conn
,fname
,(uid_t
)-1, set_grp
) != 0)
3630 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3635 case SMB_SET_FILE_UNIX_LINK
:
3637 pstring link_target
;
3638 char *newname
= fname
;
3640 /* Set a symbolic link. */
3641 /* Don't allow this if follow links is false. */
3643 if (!lp_symlinks(SNUM(conn
)))
3644 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3646 srvstr_pull(inbuf
, link_target
, pdata
, sizeof(link_target
), -1, STR_TERMINATE
);
3648 /* !widelinks forces the target path to be within the share. */
3649 /* This means we can interpret the target as a pathname. */
3650 if (!lp_widelinks(SNUM(conn
))) {
3652 char *last_dirp
= NULL
;
3654 unix_format(link_target
);
3655 if (*link_target
== '/') {
3656 /* No absolute paths allowed. */
3657 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3659 pstrcpy(rel_name
, newname
);
3660 last_dirp
= strrchr_m(rel_name
, '/');
3662 last_dirp
[1] = '\0';
3664 pstrcpy(rel_name
, "./");
3666 pstrcat(rel_name
, link_target
);
3668 if (!check_name(rel_name
, conn
)) {
3669 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3673 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3674 fname
, link_target
));
3676 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0)
3677 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3679 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3683 case SMB_SET_FILE_UNIX_HLINK
:
3686 char *newname
= fname
;
3688 /* Set a hard link. */
3689 srvstr_get_path(inbuf
, oldname
, pdata
, sizeof(oldname
), -1, STR_TERMINATE
, &status
, False
);
3690 if (!NT_STATUS_IS_OK(status
)) {
3691 return ERROR_NT(status
);
3694 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3697 status
= hardlink_internals(conn
, oldname
, newname
);
3698 if (!NT_STATUS_IS_OK(status
)) {
3699 return ERROR_NT(status
);
3703 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3707 case SMB_FILE_RENAME_INFORMATION
:
3716 if (total_data
< 12)
3717 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3719 overwrite
= (CVAL(pdata
,0) ? True
: False
);
3720 root_fid
= IVAL(pdata
,4);
3721 len
= IVAL(pdata
,8);
3722 srvstr_get_path(inbuf
, newname
, &pdata
[12], sizeof(newname
), len
, 0, &status
, False
);
3723 if (!NT_STATUS_IS_OK(status
)) {
3724 return ERROR_NT(status
);
3727 /* Check the new name has no '/' characters. */
3728 if (strchr_m(newname
, '/'))
3729 return ERROR_NT(NT_STATUS_NOT_SUPPORTED
);
3731 RESOLVE_DFSPATH(newname
, conn
, inbuf
, outbuf
);
3733 /* Create the base directory. */
3734 pstrcpy(base_name
, fname
);
3735 p
= strrchr_m(base_name
, '/');
3738 /* Append the new name. */
3739 pstrcat(base_name
, "/");
3740 pstrcat(base_name
, newname
);
3743 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3744 fsp
->fnum
, fsp
->fsp_name
, base_name
));
3745 status
= rename_internals_fsp(conn
, fsp
, base_name
, 0, overwrite
);
3747 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3749 status
= rename_internals(conn
, fname
, base_name
, 0, overwrite
);
3751 if (!NT_STATUS_IS_OK(status
)) {
3752 return ERROR_NT(status
);
3754 process_pending_change_notify_queue((time_t)0);
3756 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3760 #if defined(HAVE_POSIX_ACLS)
3761 case SMB_SET_POSIX_ACL
:
3763 uint16 posix_acl_version
;
3764 uint16 num_file_acls
;
3765 uint16 num_def_acls
;
3766 BOOL valid_file_acls
= True
;
3767 BOOL valid_def_acls
= True
;
3769 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
) {
3770 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3772 posix_acl_version
= SVAL(pdata
,0);
3773 num_file_acls
= SVAL(pdata
,2);
3774 num_def_acls
= SVAL(pdata
,4);
3776 if (num_file_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
3777 valid_file_acls
= False
;
3781 if (num_def_acls
== SMB_POSIX_IGNORE_ACE_ENTRIES
) {
3782 valid_def_acls
= False
;
3786 if (posix_acl_version
!= SMB_POSIX_ACL_VERSION
) {
3787 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3790 if (total_data
< SMB_POSIX_ACL_HEADER_SIZE
+
3791 (num_file_acls
+num_def_acls
)*SMB_POSIX_ACL_ENTRY_SIZE
) {
3792 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3795 if (valid_file_acls
&& !set_unix_posix_acl(conn
, fsp
, fname
, num_file_acls
,
3796 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
)) {
3797 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3800 if (valid_def_acls
&& !set_unix_posix_default_acl(conn
, fname
, &sbuf
, num_def_acls
,
3801 pdata
+ SMB_POSIX_ACL_HEADER_SIZE
+
3802 (num_file_acls
*SMB_POSIX_ACL_ENTRY_SIZE
))) {
3803 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3807 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3813 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3816 /* get some defaults (no modifications) if any info is zero or -1. */
3817 if (null_mtime(tvs
.actime
)) {
3818 tvs
.actime
= sbuf
.st_atime
;
3821 if (null_mtime(tvs
.modtime
)) {
3822 tvs
.modtime
= sbuf
.st_mtime
;
3825 DEBUG(6,("actime: %s " , ctime(&tvs
.actime
)));
3826 DEBUG(6,("modtime: %s ", ctime(&tvs
.modtime
)));
3827 DEBUG(6,("size: %.0f ", (double)size
));
3830 if (S_ISDIR(sbuf
.st_mode
))
3836 DEBUG(6,("dosmode: %x\n" , dosmode
));
3838 if(!((info_level
== SMB_SET_FILE_END_OF_FILE_INFO
) ||
3839 (info_level
== SMB_SET_FILE_ALLOCATION_INFO
) ||
3840 (info_level
== SMB_FILE_ALLOCATION_INFORMATION
) ||
3841 (info_level
== SMB_FILE_END_OF_FILE_INFORMATION
))) {
3844 * Only do this test if we are not explicitly
3845 * changing the size of a file.
3848 size
= get_file_size(sbuf
);
3852 * Try and set the times, size and mode of this file -
3853 * if they are different from the current values
3856 /* check the mode isn't different, before changing it */
3857 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, fname
, &sbuf
))) {
3859 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname
, dosmode
));
3861 if(file_set_dosmode(conn
, fname
, dosmode
, &sbuf
, False
)) {
3862 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname
, strerror(errno
)));
3863 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3868 if (size
!= get_file_size(sbuf
)) {
3872 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3873 fname
, (double)size
));
3876 files_struct
*new_fsp
= NULL
;
3877 int access_mode
= 0;
3880 if(global_oplock_break
) {
3881 /* Queue this file modify as we are the process of an oplock break. */
3883 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3884 DEBUGADD(2,( "in oplock break state.\n"));
3886 push_oplock_pending_smb_message(inbuf
, length
);
3890 new_fsp
= open_file_shared(conn
, fname
, &sbuf
,
3891 SET_OPEN_MODE(DOS_OPEN_RDWR
),
3892 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
3893 FILE_ATTRIBUTE_NORMAL
,
3894 INTERNAL_OPEN_ONLY
, &access_mode
, &action
);
3896 if (new_fsp
== NULL
)
3897 return(UNIXERROR(ERRDOS
,ERRbadpath
));
3898 ret
= vfs_set_filelen(new_fsp
, size
);
3899 close_file(new_fsp
,True
);
3901 ret
= vfs_set_filelen(fsp
, size
);
3905 return (UNIXERROR(ERRHRD
,ERRdiskfull
));
3909 * Finally the times.
3911 if (sbuf
.st_mtime
!= tvs
.modtime
|| sbuf
.st_atime
!= tvs
.actime
) {
3914 * This was a setfileinfo on an open file.
3915 * NT does this a lot. We also need to
3916 * set the time here, as it can be read by
3917 * FindFirst/FindNext and with the patch for bug #2045
3918 * in smbd/fileio.c it ensures that this timestamp is
3919 * kept sticky even after a write. We save the request
3920 * away and will set it on file close and after a write. JRA.
3923 if (tvs
.modtime
!= (time_t)0 && tvs
.modtime
!= (time_t)-1) {
3924 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs
.modtime
) ));
3925 fsp_set_pending_modtime(fsp
, tvs
.modtime
);
3929 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3931 if(file_utime(conn
, fname
, &tvs
)!=0) {
3932 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3937 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3942 /****************************************************************************
3943 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3944 ****************************************************************************/
3946 static int call_trans2mkdir(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
3947 char **pparams
, int total_params
, char **ppdata
, int total_data
,
3948 unsigned int max_data_bytes
)
3950 char *params
= *pparams
;
3953 SMB_STRUCT_STAT sbuf
;
3954 BOOL bad_path
= False
;
3955 NTSTATUS status
= NT_STATUS_OK
;
3957 if (!CAN_WRITE(conn
))
3958 return ERROR_DOS(ERRSRV
,ERRaccess
);
3960 if (total_params
< 4)
3961 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3963 srvstr_get_path(inbuf
, directory
, ¶ms
[4], sizeof(directory
), -1, STR_TERMINATE
, &status
, False
);
3964 if (!NT_STATUS_IS_OK(status
)) {
3965 return ERROR_NT(status
);
3968 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
3970 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
3972 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
3974 if (check_name(directory
,conn
))
3975 ret
= vfs_MkDir(conn
,directory
,unix_mode(conn
,aDIR
,directory
,True
));
3978 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno
)));
3979 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRnoaccess
);
3982 /* Realloc the parameter and data sizes */
3983 params
= SMB_REALLOC(*pparams
,2);
3985 return ERROR_DOS(ERRDOS
,ERRnomem
);
3990 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3995 /****************************************************************************
3996 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3997 We don't actually do this - we just send a null response.
3998 ****************************************************************************/
4000 static int call_trans2findnotifyfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
4001 char **pparams
, int total_params
, char **ppdata
, int total_data
,
4002 unsigned int max_data_bytes
)
4004 static uint16 fnf_handle
= 257;
4005 char *params
= *pparams
;
4008 if (total_params
< 6)
4009 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
4011 info_level
= SVAL(params
,4);
4012 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
4014 switch (info_level
) {
4019 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
4022 /* Realloc the parameter and data sizes */
4023 params
= SMB_REALLOC(*pparams
,6);
4025 return ERROR_DOS(ERRDOS
,ERRnomem
);
4028 SSVAL(params
,0,fnf_handle
);
4029 SSVAL(params
,2,0); /* No changes */
4030 SSVAL(params
,4,0); /* No EA errors */
4037 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0);
4042 /****************************************************************************
4043 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4044 changes). Currently this does nothing.
4045 ****************************************************************************/
4047 static int call_trans2findnotifynext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
4048 char **pparams
, int total_params
, char **ppdata
, int total_data
,
4049 unsigned int max_data_bytes
)
4051 char *params
= *pparams
;
4053 DEBUG(3,("call_trans2findnotifynext\n"));
4055 /* Realloc the parameter and data sizes */
4056 params
= SMB_REALLOC(*pparams
,4);
4058 return ERROR_DOS(ERRDOS
,ERRnomem
);
4061 SSVAL(params
,0,0); /* No changes */
4062 SSVAL(params
,2,0); /* No EA errors */
4064 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0);
4069 /****************************************************************************
4070 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4071 ****************************************************************************/
4073 static int call_trans2getdfsreferral(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
4074 char **pparams
, int total_params
, char **ppdata
, int total_data
,
4075 unsigned int max_data_bytes
)
4077 char *params
= *pparams
;
4080 int max_referral_level
;
4082 DEBUG(10,("call_trans2getdfsreferral\n"));
4084 if (total_params
< 2)
4085 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
4087 max_referral_level
= SVAL(params
,0);
4089 if(!lp_host_msdfs())
4090 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
4092 srvstr_pull(inbuf
, pathname
, ¶ms
[2], sizeof(pathname
), -1, STR_TERMINATE
);
4093 if((reply_size
= setup_dfs_referral(conn
, pathname
,max_referral_level
,ppdata
)) < 0)
4094 return UNIXERROR(ERRDOS
,ERRbadfile
);
4096 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
4097 send_trans2_replies(outbuf
,bufsize
,0,0,*ppdata
,reply_size
);
4102 #define LMCAT_SPL 0x53
4103 #define LMFUNC_GETJOBID 0x60
4105 /****************************************************************************
4106 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4107 ****************************************************************************/
4109 static int call_trans2ioctl(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
4110 char **pparams
, int total_params
, char **ppdata
, int total_data
,
4111 unsigned int max_data_bytes
)
4113 char *pdata
= *ppdata
;
4114 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv15
);
4116 /* check for an invalid fid before proceeding */
4119 return(ERROR_DOS(ERRDOS
,ERRbadfid
));
4121 if ((SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
4122 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
4123 pdata
= SMB_REALLOC(*ppdata
, 32);
4125 return ERROR_DOS(ERRDOS
,ERRnomem
);
4128 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
4129 CAN ACCEPT THIS IN UNICODE. JRA. */
4131 SSVAL(pdata
,0,fsp
->rap_print_jobid
); /* Job number */
4132 srvstr_push( outbuf
, pdata
+ 2, global_myname(), 15, STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
4133 srvstr_push( outbuf
, pdata
+18, lp_servicename(SNUM(conn
)), 13, STR_ASCII
|STR_TERMINATE
); /* Service name */
4134 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32);
4137 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
4138 return ERROR_DOS(ERRSRV
,ERRerror
);
4142 /****************************************************************************
4143 Reply to a SMBfindclose (stop trans2 directory search).
4144 ****************************************************************************/
4146 int reply_findclose(connection_struct
*conn
,
4147 char *inbuf
,char *outbuf
,int length
,int bufsize
)
4150 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
4151 START_PROFILE(SMBfindclose
);
4153 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
4155 dptr_close(&dptr_num
);
4157 outsize
= set_message(outbuf
,0,0,True
);
4159 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
4161 END_PROFILE(SMBfindclose
);
4165 /****************************************************************************
4166 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
4167 ****************************************************************************/
4169 int reply_findnclose(connection_struct
*conn
,
4170 char *inbuf
,char *outbuf
,int length
,int bufsize
)
4174 START_PROFILE(SMBfindnclose
);
4176 dptr_num
= SVAL(inbuf
,smb_vwv0
);
4178 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
4180 /* We never give out valid handles for a
4181 findnotifyfirst - so any dptr_num is ok here.
4184 outsize
= set_message(outbuf
,0,0,True
);
4186 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
4188 END_PROFILE(SMBfindnclose
);
4192 /****************************************************************************
4193 Reply to a SMBtranss2 - just ignore it!
4194 ****************************************************************************/
4196 int reply_transs2(connection_struct
*conn
,
4197 char *inbuf
,char *outbuf
,int length
,int bufsize
)
4199 START_PROFILE(SMBtranss2
);
4200 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
4201 END_PROFILE(SMBtranss2
);
4205 /****************************************************************************
4206 Reply to a SMBtrans2.
4207 ****************************************************************************/
4209 int reply_trans2(connection_struct
*conn
,
4210 char *inbuf
,char *outbuf
,int length
,int bufsize
)
4213 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
4214 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
4215 unsigned int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
4217 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
4218 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
4219 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
4220 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
4221 int32 timeout
= IVALS(inbuf
,smb_timeout
);
4223 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
4224 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
4225 char *params
= NULL
, *data
= NULL
;
4226 unsigned int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
4227 START_PROFILE(SMBtrans2
);
4229 if(global_oplock_break
&& (tran_call
== TRANSACT2_OPEN
)) {
4230 /* Queue this open message as we are the process of an
4233 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4234 DEBUGADD(2,( "in oplock break state.\n"));
4236 push_oplock_pending_smb_message(inbuf
, length
);
4237 END_PROFILE(SMBtrans2
);
4241 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
4242 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
4243 END_PROFILE(SMBtrans2
);
4244 return ERROR_DOS(ERRSRV
,ERRaccess
);
4247 outsize
= set_message(outbuf
,0,0,True
);
4249 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4250 is so as a sanity check */
4253 * Need to have rc=0 for ioctl to get job id for OS/2.
4254 * Network printing will fail if function is not successful.
4255 * Similar function in reply.c will be used if protocol
4256 * is LANMAN1.0 instead of LM1.2X002.
4257 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4258 * outbuf doesn't have to be set(only job id is used).
4260 if ( (suwcnt
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
4261 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
4262 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
4263 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4265 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt
));
4266 DEBUG(2,("Transaction is %d\n",tran_call
));
4267 END_PROFILE(SMBtrans2
);
4268 ERROR_DOS(ERRDOS
,ERRinvalidparam
);
4272 /* Allocate the space for the maximum needed parameters and data */
4273 if (total_params
> 0)
4274 params
= (char *)SMB_MALLOC(total_params
);
4276 data
= (char *)SMB_MALLOC(total_data
);
4278 if ((total_params
&& !params
) || (total_data
&& !data
)) {
4279 DEBUG(2,("Out of memory in reply_trans2\n"));
4282 END_PROFILE(SMBtrans2
);
4283 return ERROR_DOS(ERRDOS
,ERRnomem
);
4286 /* Copy the param and data bytes sent with this request into
4287 the params buffer */
4288 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
4289 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
4291 if (num_params
> total_params
|| num_data
> total_data
)
4292 exit_server("invalid params in reply_trans2");
4295 unsigned int psoff
= SVAL(inbuf
, smb_psoff
);
4296 if ((psoff
+ num_params
< psoff
) || (psoff
+ num_params
< num_params
))
4298 if ((smb_base(inbuf
) + psoff
+ num_params
> inbuf
+ length
) ||
4299 (smb_base(inbuf
) + psoff
+ num_params
< smb_base(inbuf
)))
4301 memcpy( params
, smb_base(inbuf
) + psoff
, num_params
);
4304 unsigned int dsoff
= SVAL(inbuf
, smb_dsoff
);
4305 if ((dsoff
+ num_data
< dsoff
) || (dsoff
+ num_data
< num_data
))
4307 if ((smb_base(inbuf
) + dsoff
+ num_data
> inbuf
+ length
) ||
4308 (smb_base(inbuf
) + dsoff
+ num_data
< smb_base(inbuf
)))
4310 memcpy( data
, smb_base(inbuf
) + dsoff
, num_data
);
4313 srv_signing_trans_start(SVAL(inbuf
,smb_mid
));
4315 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
) {
4316 /* We need to send an interim response then receive the rest
4317 of the parameter/data bytes */
4318 outsize
= set_message(outbuf
,0,0,True
);
4319 srv_signing_trans_stop();
4320 if (!send_smb(smbd_server_fd(),outbuf
))
4321 exit_server("reply_trans2: send_smb failed.");
4323 while (num_data_sofar
< total_data
||
4324 num_params_sofar
< total_params
) {
4326 unsigned int param_disp
;
4327 unsigned int param_off
;
4328 unsigned int data_disp
;
4329 unsigned int data_off
;
4331 ret
= receive_next_smb(inbuf
,bufsize
,SMB_SECONDARY_WAIT
);
4334 * The sequence number for the trans reply is always
4335 * based on the last secondary received.
4338 srv_signing_trans_start(SVAL(inbuf
,smb_mid
));
4341 (CVAL(inbuf
, smb_com
) != SMBtranss2
)) || !ret
) {
4342 outsize
= set_message(outbuf
,0,0,True
);
4344 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4346 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4347 (smb_read_error
== READ_ERROR
) ? "error" : "timeout" ));
4351 /* Revise total_params and total_data in case
4352 they have changed downwards */
4353 if (SVAL(inbuf
, smb_tpscnt
) < total_params
)
4354 total_params
= SVAL(inbuf
, smb_tpscnt
);
4355 if (SVAL(inbuf
, smb_tdscnt
) < total_data
)
4356 total_data
= SVAL(inbuf
, smb_tdscnt
);
4358 num_params
= SVAL(inbuf
,smb_spscnt
);
4359 param_off
= SVAL(inbuf
, smb_spsoff
);
4360 param_disp
= SVAL(inbuf
, smb_spsdisp
);
4361 num_params_sofar
+= num_params
;
4363 num_data
= SVAL(inbuf
, smb_sdscnt
);
4364 data_off
= SVAL(inbuf
, smb_sdsoff
);
4365 data_disp
= SVAL(inbuf
, smb_sdsdisp
);
4366 num_data_sofar
+= num_data
;
4368 if (num_params_sofar
> total_params
|| num_data_sofar
> total_data
)
4372 if (param_disp
+ num_params
> total_params
)
4374 if ((param_disp
+ num_params
< param_disp
) ||
4375 (param_disp
+ num_params
< num_params
))
4377 if (param_disp
> total_params
)
4379 if ((smb_base(inbuf
) + param_off
+ num_params
>= inbuf
+ bufsize
) ||
4380 (smb_base(inbuf
) + param_off
+ num_params
< smb_base(inbuf
)))
4382 if (params
+ param_disp
< params
)
4385 memcpy( ¶ms
[param_disp
], smb_base(inbuf
) + param_off
, num_params
);
4388 if (data_disp
+ num_data
> total_data
)
4390 if ((data_disp
+ num_data
< data_disp
) ||
4391 (data_disp
+ num_data
< num_data
))
4393 if (data_disp
> total_data
)
4395 if ((smb_base(inbuf
) + data_off
+ num_data
>= inbuf
+ bufsize
) ||
4396 (smb_base(inbuf
) + data_off
+ num_data
< smb_base(inbuf
)))
4398 if (data
+ data_disp
< data
)
4401 memcpy( &data
[data_disp
], smb_base(inbuf
) + data_off
, num_data
);
4406 if (Protocol
>= PROTOCOL_NT1
) {
4407 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | 0x40); /* IS_LONG_NAME */
4410 /* Now we must call the relevant TRANS2 function */
4412 case TRANSACT2_OPEN
:
4413 START_PROFILE_NESTED(Trans2_open
);
4414 outsize
= call_trans2open(conn
, inbuf
, outbuf
, bufsize
,
4415 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4416 END_PROFILE_NESTED(Trans2_open
);
4419 case TRANSACT2_FINDFIRST
:
4420 START_PROFILE_NESTED(Trans2_findfirst
);
4421 outsize
= call_trans2findfirst(conn
, inbuf
, outbuf
, bufsize
,
4422 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4423 END_PROFILE_NESTED(Trans2_findfirst
);
4426 case TRANSACT2_FINDNEXT
:
4427 START_PROFILE_NESTED(Trans2_findnext
);
4428 outsize
= call_trans2findnext(conn
, inbuf
, outbuf
, length
, bufsize
,
4429 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4430 END_PROFILE_NESTED(Trans2_findnext
);
4433 case TRANSACT2_QFSINFO
:
4434 START_PROFILE_NESTED(Trans2_qfsinfo
);
4435 outsize
= call_trans2qfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4436 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4437 END_PROFILE_NESTED(Trans2_qfsinfo
);
4440 #ifdef HAVE_SYS_QUOTAS
4441 case TRANSACT2_SETFSINFO
:
4442 START_PROFILE_NESTED(Trans2_setfsinfo
);
4443 outsize
= call_trans2setfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4444 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4445 END_PROFILE_NESTED(Trans2_setfsinfo
);
4448 case TRANSACT2_QPATHINFO
:
4449 case TRANSACT2_QFILEINFO
:
4450 START_PROFILE_NESTED(Trans2_qpathinfo
);
4451 outsize
= call_trans2qfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4452 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4453 END_PROFILE_NESTED(Trans2_qpathinfo
);
4455 case TRANSACT2_SETPATHINFO
:
4456 case TRANSACT2_SETFILEINFO
:
4457 START_PROFILE_NESTED(Trans2_setpathinfo
);
4458 outsize
= call_trans2setfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4459 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4460 END_PROFILE_NESTED(Trans2_setpathinfo
);
4463 case TRANSACT2_FINDNOTIFYFIRST
:
4464 START_PROFILE_NESTED(Trans2_findnotifyfirst
);
4465 outsize
= call_trans2findnotifyfirst(conn
, inbuf
, outbuf
, length
, bufsize
,
4466 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4467 END_PROFILE_NESTED(Trans2_findnotifyfirst
);
4470 case TRANSACT2_FINDNOTIFYNEXT
:
4471 START_PROFILE_NESTED(Trans2_findnotifynext
);
4472 outsize
= call_trans2findnotifynext(conn
, inbuf
, outbuf
, length
, bufsize
,
4473 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4474 END_PROFILE_NESTED(Trans2_findnotifynext
);
4476 case TRANSACT2_MKDIR
:
4477 START_PROFILE_NESTED(Trans2_mkdir
);
4478 outsize
= call_trans2mkdir(conn
, inbuf
, outbuf
, length
, bufsize
,
4479 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4480 END_PROFILE_NESTED(Trans2_mkdir
);
4483 case TRANSACT2_GET_DFS_REFERRAL
:
4484 START_PROFILE_NESTED(Trans2_get_dfs_referral
);
4485 outsize
= call_trans2getdfsreferral(conn
,inbuf
,outbuf
,length
, bufsize
,
4486 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4487 END_PROFILE_NESTED(Trans2_get_dfs_referral
);
4489 case TRANSACT2_IOCTL
:
4490 START_PROFILE_NESTED(Trans2_ioctl
);
4491 outsize
= call_trans2ioctl(conn
,inbuf
,outbuf
,length
, bufsize
,
4492 ¶ms
, total_params
, &data
, total_data
, max_data_bytes
);
4493 END_PROFILE_NESTED(Trans2_ioctl
);
4496 /* Error in request */
4497 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call
));
4500 END_PROFILE(SMBtrans2
);
4501 srv_signing_trans_stop();
4502 return ERROR_DOS(ERRSRV
,ERRerror
);
4505 /* As we do not know how many data packets will need to be
4506 returned here the various call_trans2xxxx calls
4507 must send their own. Thus a call_trans2xxx routine only
4508 returns a value other than -1 when it wants to send
4512 srv_signing_trans_stop();
4516 END_PROFILE(SMBtrans2
);
4517 return outsize
; /* If a correct response was needed the
4518 call_trans2xxx calls have already sent
4519 it. If outsize != -1 then it is returning */
4523 srv_signing_trans_stop();
4526 END_PROFILE(SMBtrans2
);
4527 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);