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.
27 extern int smb_read_error
;
28 extern fstring local_machine
;
29 extern int global_oplock_break
;
30 extern uint32 global_client_caps
;
31 extern struct current_user current_user
;
33 #define get_file_size(sbuf) ((sbuf).st_size)
34 #define DIR_ENTRY_SAFETY_MARGIN 4096
36 /********************************************************************
37 Roundup a value to the nearest SMB_ROUNDUP_ALLOCATION_SIZE boundary.
38 Only do this for Windows clients.
39 ********************************************************************/
41 SMB_BIG_UINT
smb_roundup(SMB_BIG_UINT val
)
43 /* Only roundup for Windows clients. */
44 enum remote_arch_types ra_type
= get_remote_arch();
45 if ((ra_type
!= RA_SAMBA
) && (ra_type
!= RA_CIFSFS
)) {
46 val
= SMB_ROUNDUP(val
,SMB_ROUNDUP_ALLOCATION_SIZE
);
51 /********************************************************************
52 Given a stat buffer return the allocated size on disk, taking into
54 ********************************************************************/
56 SMB_BIG_UINT
get_allocation_size(files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
60 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
61 ret
= (SMB_BIG_UINT
)STAT_ST_BLOCKSIZE
* (SMB_BIG_UINT
)sbuf
->st_blocks
;
63 ret
= (SMB_BIG_UINT
)get_file_size(*sbuf
);
66 if (!ret
&& fsp
&& fsp
->initial_allocation_size
)
67 ret
= fsp
->initial_allocation_size
;
69 ret
= smb_roundup(ret
);
74 /****************************************************************************
75 Utility functions for dealing with extended attributes.
76 ****************************************************************************/
78 static const char *prohibited_ea_names
[] = {
79 SAMBA_POSIX_INHERITANCE_EA_NAME
,
80 SAMBA_XATTR_DOS_ATTRIB
,
84 /****************************************************************************
85 Refuse to allow clients to overwrite our private xattrs.
86 ****************************************************************************/
88 static BOOL
samba_private_attr_name(const char *unix_ea_name
)
92 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
93 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
100 struct ea_list
*next
, *prev
;
104 /****************************************************************************
105 Get one EA value. Fill in a struct ea_struct.
106 ****************************************************************************/
108 static BOOL
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
109 const char *fname
, char *ea_name
, struct ea_struct
*pea
)
111 /* Get the value of this xattr. Max size is 64k. */
112 size_t attr_size
= 256;
118 val
= talloc_realloc(mem_ctx
, val
, attr_size
);
123 if (fsp
&& fsp
->fd
!= -1) {
124 sizeret
= SMB_VFS_FGETXATTR(fsp
, fsp
->fd
, ea_name
, val
, attr_size
);
126 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
129 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
138 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name
, sizeret
));
139 dump_data(10, val
, sizeret
);
142 if (strnequal(ea_name
, "user.", 5)) {
143 pea
->name
= &ea_name
[5];
147 pea
->value
.data
= val
;
148 pea
->value
.length
= (size_t)sizeret
;
152 /****************************************************************************
153 Return a linked list of the total EA's. Plus the total size
154 ****************************************************************************/
156 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
)
158 /* Get a list of all xattrs. Max namesize is 64k. */
159 size_t ea_namelist_size
= 1024;
164 struct ea_list
*ea_list_head
= NULL
;
168 if (!lp_ea_support(SNUM(conn
))) {
172 for (i
= 0, ea_namelist
= talloc(mem_ctx
, ea_namelist_size
); i
< 6;
173 ea_namelist
= talloc_realloc(mem_ctx
, ea_namelist
, ea_namelist_size
), i
++) {
174 if (fsp
&& fsp
->fd
!= -1) {
175 sizeret
= SMB_VFS_FLISTXATTR(fsp
, fsp
->fd
, ea_namelist
, ea_namelist_size
);
177 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
, ea_namelist_size
);
180 if (sizeret
== -1 && errno
== ERANGE
) {
181 ea_namelist_size
*= 2;
190 DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret
));
193 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
) + 1) {
194 struct ea_list
*listp
, *tmp
;
196 if (strnequal(p
, "system.", 7) || samba_private_attr_name(p
))
199 listp
= talloc(mem_ctx
, sizeof(struct ea_list
));
203 if (!get_ea_value(mem_ctx
, conn
, fsp
, fname
, p
, &listp
->ea
)) {
209 push_ascii_fstring(dos_ea_name
, listp
->ea
.name
);
210 *pea_total_len
+= 4 + strlen(dos_ea_name
) + 1 + listp
->ea
.value
.length
;
211 DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
212 *pea_total_len
, dos_ea_name
,
213 (unsigned int)listp
->ea
.value
.length
));
215 DLIST_ADD_END(ea_list_head
, listp
, tmp
);
217 /* Add on 4 for total length. */
218 if (*pea_total_len
) {
223 DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len
));
227 /****************************************************************************
228 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
230 ****************************************************************************/
232 static unsigned int fill_ea_buffer(char *pdata
, unsigned int total_data_size
,
233 connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
235 unsigned int ret_data_size
= 4;
239 struct ea_list
*ea_list
;
241 SMB_ASSERT(total_data_size
>= 4);
244 if (!lp_ea_support(SNUM(conn
))) {
247 mem_ctx
= talloc_init("fill_ea_buffer");
252 ea_list
= get_ea_list(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
254 talloc_destroy(mem_ctx
);
258 if (total_ea_len
> total_data_size
) {
259 talloc_destroy(mem_ctx
);
263 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
266 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
267 dos_namelen
= strlen(dos_ea_name
);
268 if (dos_namelen
> 255 || dos_namelen
== 0) {
271 if (ea_list
->ea
.value
.length
> 65535) {
274 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
278 /* We know we have room. */
279 SCVAL(p
,0,ea_list
->ea
.flags
);
280 SCVAL(p
,1,dos_namelen
);
281 SSVAL(p
,2,ea_list
->ea
.value
.length
);
282 fstrcpy(p
+4, dos_ea_name
);
283 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
285 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
286 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
289 ret_data_size
= PTR_DIFF(p
, pdata
);
290 DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
291 ret_data_size
, total_ea_len
));
292 talloc_destroy(mem_ctx
);
293 SIVAL(pdata
,0,ret_data_size
);
294 return ret_data_size
;
297 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
299 size_t total_ea_len
= 0;
300 TALLOC_CTX
*mem_ctx
= NULL
;
302 if (!lp_ea_support(SNUM(conn
))) {
305 mem_ctx
= talloc_init("estimate_ea_size");
306 (void)get_ea_list(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
307 talloc_destroy(mem_ctx
);
311 /****************************************************************************
312 Ensure the EA name is case insensitive by matching any existing EA name.
313 ****************************************************************************/
315 static void canonicalize_ea_name(connection_struct
*conn
, files_struct
*fsp
, const char *fname
, fstring unix_ea_name
)
318 TALLOC_CTX
*mem_ctx
= talloc_init("canonicalize_ea_name");
319 struct ea_list
*ea_list
= get_ea_list(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
321 for (; ea_list
; ea_list
= ea_list
->next
) {
322 if (strequal(&unix_ea_name
[5], ea_list
->ea
.name
)) {
323 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
324 &unix_ea_name
[5], ea_list
->ea
.name
));
325 safe_strcpy(&unix_ea_name
[5], ea_list
->ea
.name
, sizeof(fstring
)-6);
329 talloc_destroy(mem_ctx
);
332 /****************************************************************************
333 Set or delete an extended attribute.
334 ****************************************************************************/
336 static NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
, const char *fname
,
337 char *pdata
, int total_data
)
339 unsigned int namelen
;
342 fstring unix_ea_name
;
344 if (!lp_ea_support(SNUM(conn
))) {
345 return NT_STATUS_EAS_NOT_SUPPORTED
;
348 if (total_data
< 8) {
349 return NT_STATUS_INVALID_PARAMETER
;
352 if (IVAL(pdata
,0) > total_data
) {
353 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata
,0), (unsigned int)total_data
));
354 return NT_STATUS_INVALID_PARAMETER
;
358 namelen
= CVAL(pdata
,1);
359 ealen
= SVAL(pdata
,2);
361 if (total_data
< 8 + namelen
+ 1 + ealen
) {
362 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
363 (unsigned int)total_data
, namelen
, ealen
));
364 return NT_STATUS_INVALID_PARAMETER
;
367 if (pdata
[namelen
] != '\0') {
368 DEBUG(10,("set_ea: ea name not null terminated\n"));
369 return NT_STATUS_INVALID_PARAMETER
;
372 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
373 pull_ascii(&unix_ea_name
[5], pdata
, sizeof(fstring
) - 5, -1, STR_TERMINATE
);
374 pdata
+= (namelen
+ 1);
376 canonicalize_ea_name(conn
, fsp
, fname
, unix_ea_name
);
378 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, ealen
));
380 DEBUG(10,("set_ea: data :\n"));
381 dump_data(10, pdata
, ealen
);
384 if (samba_private_attr_name(unix_ea_name
)) {
385 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
386 return NT_STATUS_ACCESS_DENIED
;
390 /* Remove the attribute. */
391 if (fsp
&& (fsp
->fd
!= -1)) {
392 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
393 unix_ea_name
, fsp
->fsp_name
));
394 ret
= SMB_VFS_FREMOVEXATTR(fsp
, fsp
->fd
, unix_ea_name
);
396 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
397 unix_ea_name
, fname
));
398 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
401 /* Removing a non existent attribute always succeeds. */
402 if (ret
== -1 && errno
== ENOATTR
) {
403 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name
));
408 if (fsp
&& (fsp
->fd
!= -1)) {
409 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
410 unix_ea_name
, fsp
->fsp_name
));
411 ret
= SMB_VFS_FSETXATTR(fsp
, fsp
->fd
, unix_ea_name
, pdata
, ealen
, 0);
413 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
414 unix_ea_name
, fname
));
415 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
, pdata
, ealen
, 0);
421 if (errno
== ENOTSUP
) {
422 return NT_STATUS_EAS_NOT_SUPPORTED
;
425 return map_nt_error_from_unix(errno
);
431 /****************************************************************************
432 Send the required number of replies back.
433 We assume all fields other than the data fields are
434 set correctly for the type of call.
435 HACK ! Always assumes smb_setup field is zero.
436 ****************************************************************************/
438 static int send_trans2_replies(char *outbuf
,
445 /* As we are using a protocol > LANMAN1 then the max_send
446 variable must have been set in the sessetupX call.
447 This takes precedence over the max_xmit field in the
448 global struct. These different max_xmit variables should
449 be merged as this is now too confusing */
452 int data_to_send
= datasize
;
453 int params_to_send
= paramsize
;
457 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
458 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
459 int data_alignment_offset
= 0;
461 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
463 set_message(outbuf
,10,0,True
);
465 /* If there genuinely are no parameters or data to send just send the empty packet */
467 if(params_to_send
== 0 && data_to_send
== 0) {
468 if (!send_smb(smbd_server_fd(),outbuf
))
469 exit_server("send_trans2_replies: send_smb failed.");
473 /* When sending params and data ensure that both are nicely aligned */
474 /* Only do this alignment when there is also data to send - else
475 can cause NT redirector problems. */
477 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
478 data_alignment_offset
= 4 - (params_to_send
% 4);
480 /* Space is bufsize minus Netbios over TCP header minus SMB header */
481 /* The alignment_offset is to align the param bytes on an even byte
482 boundary. NT 4.0 Beta needs this to work correctly. */
484 useable_space
= bufsize
- ((smb_buf(outbuf
)+ alignment_offset
+data_alignment_offset
) - outbuf
);
486 /* useable_space can never be more than max_send minus the alignment offset. */
488 useable_space
= MIN(useable_space
, max_send
- (alignment_offset
+data_alignment_offset
));
490 while (params_to_send
|| data_to_send
) {
491 /* Calculate whether we will totally or partially fill this packet */
493 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
+ data_alignment_offset
;
495 /* We can never send more than useable_space */
497 * Note that 'useable_space' does not include the alignment offsets,
498 * but we must include the alignment offsets in the calculation of
499 * the length of the data we send over the wire, as the alignment offsets
500 * are sent here. Fix from Marc_Jacobsen@hp.com.
503 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
+ alignment_offset
+ data_alignment_offset
);
505 set_message(outbuf
, 10, total_sent_thistime
, True
);
507 /* Set total params and data to be sent */
508 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
509 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
511 /* Calculate how many parameters and data we can fit into
512 * this packet. Parameters get precedence
515 params_sent_thistime
= MIN(params_to_send
,useable_space
);
516 data_sent_thistime
= useable_space
- params_sent_thistime
;
517 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
519 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
521 /* smb_proff is the offset from the start of the SMB header to the
522 parameter bytes, however the first 4 bytes of outbuf are
523 the Netbios over TCP header. Thus use smb_base() to subtract
524 them from the calculation */
526 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
528 if(params_sent_thistime
== 0)
529 SSVAL(outbuf
,smb_prdisp
,0);
531 /* Absolute displacement of param bytes sent in this packet */
532 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
534 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
535 if(data_sent_thistime
== 0) {
536 SSVAL(outbuf
,smb_droff
,0);
537 SSVAL(outbuf
,smb_drdisp
, 0);
539 /* The offset of the data bytes is the offset of the
540 parameter bytes plus the number of parameters being sent this time */
541 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
542 smb_base(outbuf
)) + params_sent_thistime
+ data_alignment_offset
);
543 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
546 /* Copy the param bytes into the packet */
548 if(params_sent_thistime
)
549 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
551 /* Copy in the data bytes */
552 if(data_sent_thistime
)
553 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
+
554 data_alignment_offset
,pd
,data_sent_thistime
);
556 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
557 params_sent_thistime
, data_sent_thistime
, useable_space
));
558 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
559 params_to_send
, data_to_send
, paramsize
, datasize
));
561 /* Send the packet */
562 if (!send_smb(smbd_server_fd(),outbuf
))
563 exit_server("send_trans2_replies: send_smb failed.");
565 pp
+= params_sent_thistime
;
566 pd
+= data_sent_thistime
;
568 params_to_send
-= params_sent_thistime
;
569 data_to_send
-= data_sent_thistime
;
572 if(params_to_send
< 0 || data_to_send
< 0) {
573 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
574 params_to_send
, data_to_send
));
582 /****************************************************************************
583 Reply to a TRANSACT2_OPEN.
584 ****************************************************************************/
586 static int call_trans2open(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
587 char **pparams
, int total_params
, char **ppdata
, int total_data
)
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
= 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 Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
805 ****************************************************************************/
807 time_t interpret_long_unix_date(char *p
)
809 DEBUG(10,("interpret_long_unix_date\n"));
810 if(IVAL(p
,0) == SMB_TIME_NO_CHANGE_LO
&&
811 IVAL(p
,4) == SMB_TIME_NO_CHANGE_HI
) {
814 return interpret_long_date(p
);
818 /****************************************************************************
819 Get a level dependent lanman2 dir entry.
820 ****************************************************************************/
822 static BOOL
get_lanman2_dir_entry(connection_struct
*conn
,
823 void *inbuf
, void *outbuf
,
824 char *path_mask
,int dirtype
,int info_level
,
825 int requires_resume_key
,
826 BOOL dont_descend
,char **ppdata
,
827 char *base_data
, int space_remaining
,
828 BOOL
*out_of_space
, BOOL
*got_exact_match
,
833 SMB_STRUCT_STAT sbuf
;
837 char *p
, *q
, *pdata
= *ppdata
;
841 SMB_OFF_T file_size
= 0;
842 SMB_BIG_UINT allocation_size
= 0;
844 time_t mdate
=0, adate
=0, cdate
=0;
847 int nt_extmode
; /* Used for NT connections instead of mode */
848 BOOL needslash
= ( conn
->dirpath
[strlen(conn
->dirpath
) -1] != '/');
851 *out_of_space
= False
;
852 *got_exact_match
= False
;
857 p
= strrchr_m(path_mask
,'/');
864 pstrcpy(mask
, path_mask
);
869 /* Needed if we run out of space */
870 prev_dirpos
= TellDir(conn
->dirptr
);
871 dname
= ReadDirName(conn
->dirptr
);
874 * Due to bugs in NT client redirectors we are not using
875 * resume keys any more - set them to zero.
876 * Check out the related comments in findfirst/findnext.
882 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
883 (long)conn
->dirptr
,TellDir(conn
->dirptr
)));
888 pstrcpy(fname
,dname
);
890 if(!(got_match
= *got_exact_match
= exact_match(fname
, mask
, conn
->case_sensitive
)))
891 got_match
= mask_match(fname
, mask
, conn
->case_sensitive
);
893 if(!got_match
&& !mangle_is_8_3(fname
, False
)) {
896 * It turns out that NT matches wildcards against
897 * both long *and* short names. This may explain some
898 * of the wildcard wierdness from old DOS clients
899 * that some people have been seeing.... JRA.
903 pstrcpy( newname
, fname
);
904 mangle_map( newname
, True
, False
, SNUM(conn
));
905 if(!(got_match
= *got_exact_match
= exact_match(newname
, mask
, conn
->case_sensitive
)))
906 got_match
= mask_match(newname
, mask
, conn
->case_sensitive
);
910 BOOL isdots
= (strequal(fname
,"..") || strequal(fname
,"."));
911 if (dont_descend
&& !isdots
)
914 pstrcpy(pathreal
,conn
->dirpath
);
916 pstrcat(pathreal
,"/");
917 pstrcat(pathreal
,dname
);
919 if (INFO_LEVEL_IS_UNIX(info_level
)) {
920 if (SMB_VFS_LSTAT(conn
,pathreal
,&sbuf
) != 0) {
921 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
922 pathreal
,strerror(errno
)));
925 } else if (SMB_VFS_STAT(conn
,pathreal
,&sbuf
) != 0) {
927 /* Needed to show the msdfs symlinks as
930 if(lp_host_msdfs() &&
931 lp_msdfs_root(SNUM(conn
)) &&
932 is_msdfs_link(conn
, pathreal
, NULL
, NULL
,
935 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal
));
936 sbuf
.st_mode
= (sbuf
.st_mode
& 0xFFF) | S_IFDIR
;
940 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
941 pathreal
,strerror(errno
)));
946 mode
= dos_mode(conn
,pathreal
,&sbuf
);
948 if (!dir_check_ftype(conn
,mode
,&sbuf
,dirtype
)) {
949 DEBUG(5,("[%s] attribs didn't match %x\n",fname
,dirtype
));
953 file_size
= get_file_size(sbuf
);
954 allocation_size
= get_allocation_size(NULL
,&sbuf
);
955 mdate
= sbuf
.st_mtime
;
956 adate
= sbuf
.st_atime
;
957 cdate
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
959 if (lp_dos_filetime_resolution(SNUM(conn
))) {
968 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal
,fname
));
974 mangle_map(fname
,False
,True
,SNUM(conn
));
979 nt_extmode
= mode
? mode
: FILE_ATTRIBUTE_NORMAL
;
981 switch (info_level
) {
982 case SMB_INFO_STANDARD
:
983 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
984 if(requires_resume_key
) {
988 put_dos_date2(p
,l1_fdateCreation
,cdate
);
989 put_dos_date2(p
,l1_fdateLastAccess
,adate
);
990 put_dos_date2(p
,l1_fdateLastWrite
,mdate
);
991 SIVAL(p
,l1_cbFile
,(uint32
)file_size
);
992 SIVAL(p
,l1_cbFileAlloc
,(uint32
)allocation_size
);
993 SSVAL(p
,l1_attrFile
,mode
);
996 p
+= align_string(outbuf
, p
, 0);
997 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
998 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
) {
1000 SCVAL(nameptr
, -1, len
- 2);
1002 SCVAL(nameptr
, -1, 0);
1006 SCVAL(nameptr
, -1, len
- 1);
1008 SCVAL(nameptr
, -1, 0);
1014 case SMB_INFO_QUERY_EA_SIZE
:
1015 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
1016 if(requires_resume_key
) {
1020 put_dos_date2(p
,l2_fdateCreation
,cdate
);
1021 put_dos_date2(p
,l2_fdateLastAccess
,adate
);
1022 put_dos_date2(p
,l2_fdateLastWrite
,mdate
);
1023 SIVAL(p
,l2_cbFile
,(uint32
)file_size
);
1024 SIVAL(p
,l2_cbFileAlloc
,(uint32
)allocation_size
);
1025 SSVAL(p
,l2_attrFile
,mode
);
1027 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1028 SIVAL(p
,l2_cbList
,ea_size
); /* Extended attributes */
1032 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
| STR_NOALIGN
);
1033 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
) {
1046 SCVAL(nameptr
,0,len
);
1048 SCVAL(p
,0,0); p
+= 1; /* Extra zero byte ? - why.. */
1051 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1052 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1053 was_8_3
= mangle_is_8_3(fname
, True
);
1055 SIVAL(p
,0,reskey
); p
+= 4;
1056 put_long_date(p
,cdate
); p
+= 8;
1057 put_long_date(p
,adate
); p
+= 8;
1058 put_long_date(p
,mdate
); p
+= 8;
1059 put_long_date(p
,mdate
); p
+= 8;
1060 SOFF_T(p
,0,file_size
); p
+= 8;
1061 SOFF_T(p
,0,allocation_size
); p
+= 8;
1062 SIVAL(p
,0,nt_extmode
); p
+= 4;
1063 q
= p
; p
+= 4; /* q is placeholder for name length. */
1065 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1066 SIVAL(p
,0,ea_size
); /* Extended attributes */
1069 /* Clear the short name buffer. This is
1070 * IMPORTANT as not doing so will trigger
1071 * a Win2k client bug. JRA.
1074 if (!was_8_3
&& lp_manglednames(SNUM(conn
))) {
1075 pstring mangled_name
;
1076 pstrcpy(mangled_name
, fname
);
1077 mangle_map(mangled_name
,True
,True
,SNUM(conn
));
1078 mangled_name
[12] = 0;
1079 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
|STR_UNICODE
);
1086 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1089 len
= PTR_DIFF(p
, pdata
);
1090 len
= (len
+ 3) & ~3;
1095 case SMB_FIND_FILE_DIRECTORY_INFO
:
1096 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1098 SIVAL(p
,0,reskey
); p
+= 4;
1099 put_long_date(p
,cdate
); p
+= 8;
1100 put_long_date(p
,adate
); p
+= 8;
1101 put_long_date(p
,mdate
); p
+= 8;
1102 put_long_date(p
,mdate
); p
+= 8;
1103 SOFF_T(p
,0,file_size
); p
+= 8;
1104 SOFF_T(p
,0,allocation_size
); p
+= 8;
1105 SIVAL(p
,0,nt_extmode
); p
+= 4;
1106 len
= srvstr_push(outbuf
, p
+ 4, fname
, -1, STR_TERMINATE_ASCII
);
1109 len
= PTR_DIFF(p
, pdata
);
1110 len
= (len
+ 3) & ~3;
1115 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1116 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1118 SIVAL(p
,0,reskey
); p
+= 4;
1119 put_long_date(p
,cdate
); p
+= 8;
1120 put_long_date(p
,adate
); p
+= 8;
1121 put_long_date(p
,mdate
); p
+= 8;
1122 put_long_date(p
,mdate
); p
+= 8;
1123 SOFF_T(p
,0,file_size
); p
+= 8;
1124 SOFF_T(p
,0,allocation_size
); p
+= 8;
1125 SIVAL(p
,0,nt_extmode
); p
+= 4;
1126 q
= p
; p
+= 4; /* q is placeholder for name length. */
1128 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1129 SIVAL(p
,0,ea_size
); /* Extended attributes */
1132 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1136 len
= PTR_DIFF(p
, pdata
);
1137 len
= (len
+ 3) & ~3;
1142 case SMB_FIND_FILE_NAMES_INFO
:
1143 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1145 SIVAL(p
,0,reskey
); p
+= 4;
1147 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1148 acl on a dir (tridge) */
1149 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1152 len
= PTR_DIFF(p
, pdata
);
1153 len
= (len
+ 3) & ~3;
1158 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1159 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1161 SIVAL(p
,0,reskey
); p
+= 4;
1162 put_long_date(p
,cdate
); p
+= 8;
1163 put_long_date(p
,adate
); p
+= 8;
1164 put_long_date(p
,mdate
); p
+= 8;
1165 put_long_date(p
,mdate
); p
+= 8;
1166 SOFF_T(p
,0,file_size
); p
+= 8;
1167 SOFF_T(p
,0,allocation_size
); p
+= 8;
1168 SIVAL(p
,0,nt_extmode
); p
+= 4;
1169 q
= p
; p
+= 4; /* q is placeholder for name length. */
1171 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1172 SIVAL(p
,0,ea_size
); /* Extended attributes */
1175 SIVAL(p
,0,0); p
+= 4; /* Unknown - reserved ? */
1176 SIVAL(p
,0,sbuf
.st_dev
); p
+= 4;
1177 SIVAL(p
,0,sbuf
.st_ino
); p
+= 4;
1178 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1181 len
= PTR_DIFF(p
, pdata
);
1182 len
= (len
+ 3) & ~3;
1187 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1188 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1189 was_8_3
= mangle_is_8_3(fname
, True
);
1191 SIVAL(p
,0,reskey
); p
+= 4;
1192 put_long_date(p
,cdate
); p
+= 8;
1193 put_long_date(p
,adate
); p
+= 8;
1194 put_long_date(p
,mdate
); p
+= 8;
1195 put_long_date(p
,mdate
); p
+= 8;
1196 SOFF_T(p
,0,file_size
); p
+= 8;
1197 SOFF_T(p
,0,allocation_size
); p
+= 8;
1198 SIVAL(p
,0,nt_extmode
); p
+= 4;
1199 q
= p
; p
+= 4; /* q is placeholder for name length */
1201 unsigned int ea_size
= estimate_ea_size(conn
, NULL
, pathreal
);
1202 SIVAL(p
,0,ea_size
); /* Extended attributes */
1205 /* Clear the short name buffer. This is
1206 * IMPORTANT as not doing so will trigger
1207 * a Win2k client bug. JRA.
1210 if (!was_8_3
&& lp_manglednames(SNUM(conn
))) {
1211 pstring mangled_name
;
1212 pstrcpy(mangled_name
, fname
);
1213 mangle_map(mangled_name
,True
,True
,SNUM(conn
));
1214 mangled_name
[12] = 0;
1215 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
|STR_UNICODE
);
1222 SSVAL(p
,0,0); p
+= 2; /* Reserved ? */
1223 SIVAL(p
,0,sbuf
.st_dev
); p
+= 4;
1224 SIVAL(p
,0,sbuf
.st_ino
); p
+= 4;
1225 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1228 len
= PTR_DIFF(p
, pdata
);
1229 len
= (len
+ 3) & ~3;
1234 /* CIFS UNIX Extension. */
1236 case SMB_FIND_FILE_UNIX
:
1237 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1239 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
1241 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1242 SOFF_T(p
,0,get_file_size(sbuf
)); /* File size 64 Bit */
1245 SOFF_T(p
,0,get_allocation_size(NULL
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
1248 put_long_date(p
,sbuf
.st_ctime
); /* Inode change Time 64 Bit */
1249 put_long_date(p
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
1250 put_long_date(p
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
1253 SIVAL(p
,0,sbuf
.st_uid
); /* user id for the owner */
1257 SIVAL(p
,0,sbuf
.st_gid
); /* group id of owner */
1261 SIVAL(p
,0,unix_filetype(sbuf
.st_mode
));
1264 SIVAL(p
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
1268 SIVAL(p
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
1272 SINO_T(p
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
1275 SIVAL(p
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
1279 SIVAL(p
,0,sbuf
.st_nlink
); /* number of hard links */
1283 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
1286 len
= PTR_DIFF(p
, pdata
);
1287 len
= (len
+ 3) & ~3;
1288 SIVAL(pdata
,0,len
); /* Offset from this structure to the beginning of the next one */
1290 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1299 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
1300 /* Move the dirptr back to prev_dirpos */
1301 SeekDir(conn
->dirptr
, prev_dirpos
);
1302 *out_of_space
= True
;
1303 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1304 return False
; /* Not finished - just out of space */
1307 /* Setup the last_filename pointer, as an offset from base_data */
1308 *last_name_off
= PTR_DIFF(nameptr
,base_data
);
1309 /* Advance the data pointer to the next slot */
1315 /****************************************************************************
1316 Reply to a TRANS2_FINDFIRST.
1317 ****************************************************************************/
1319 static int call_trans2findfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
1320 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1322 /* We must be careful here that we don't return more than the
1323 allowed number of data bytes. If this means returning fewer than
1324 maxentries then so be it. We assume that the redirector has
1325 enough room for the fixed number of parameter bytes it has
1327 uint32 max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1328 char *params
= *pparams
;
1329 char *pdata
= *ppdata
;
1330 int dirtype
= SVAL(params
,0);
1331 int maxentries
= SVAL(params
,2);
1332 BOOL close_after_first
= BITSETW(params
+4,0);
1333 BOOL close_if_end
= BITSETW(params
+4,1);
1334 BOOL requires_resume_key
= BITSETW(params
+4,2);
1335 int info_level
= SVAL(params
,6);
1339 int last_name_off
=0;
1343 BOOL finished
= False
;
1344 BOOL dont_descend
= False
;
1345 BOOL out_of_space
= False
;
1346 int space_remaining
;
1347 BOOL bad_path
= False
;
1348 SMB_STRUCT_STAT sbuf
;
1349 NTSTATUS ntstatus
= NT_STATUS_OK
;
1351 if (total_params
< 12)
1352 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1354 *directory
= *mask
= 0;
1356 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1357 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1358 dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
1359 info_level
, max_data_bytes
));
1362 /* W2K3 seems to treat zero as 1. */
1366 switch (info_level
) {
1367 case SMB_INFO_STANDARD
:
1368 case SMB_INFO_QUERY_EA_SIZE
:
1369 case SMB_FIND_FILE_DIRECTORY_INFO
:
1370 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1371 case SMB_FIND_FILE_NAMES_INFO
:
1372 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1373 case SMB_FIND_ID_FULL_DIRECTORY_INFO
:
1374 case SMB_FIND_ID_BOTH_DIRECTORY_INFO
:
1376 case SMB_FIND_FILE_UNIX
:
1377 if (!lp_unix_extensions())
1378 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1381 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1384 srvstr_get_path(inbuf
, directory
, params
+12, sizeof(directory
), -1, STR_TERMINATE
, &ntstatus
, True
);
1385 if (!NT_STATUS_IS_OK(ntstatus
)) {
1386 return ERROR_NT(ntstatus
);
1389 RESOLVE_FINDFIRST_DFSPATH(directory
, conn
, inbuf
, outbuf
);
1391 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
1393 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
1395 if(!check_name(directory
,conn
)) {
1396 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
1399 p
= strrchr_m(directory
,'/');
1401 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1402 if((directory
[0] == '.') && (directory
[1] == '\0'))
1405 pstrcpy(mask
,directory
);
1406 pstrcpy(directory
,"./");
1412 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
1414 pdata
= Realloc(*ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1416 return(ERROR_DOS(ERRDOS
,ERRnomem
));
1419 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1421 /* Realloc the params space */
1422 params
= Realloc(*pparams
, 10);
1424 return ERROR_DOS(ERRDOS
,ERRnomem
);
1427 dptr_num
= dptr_create(conn
,directory
, False
, True
,SVAL(inbuf
,smb_pid
));
1429 return(UNIXERROR(ERRDOS
,ERRbadfile
));
1431 /* Save the wildcard match and attribs we are using on this directory -
1432 needed as lanman2 assumes these are being saved between calls */
1434 if(!(wcard
= strdup(mask
))) {
1435 dptr_close(&dptr_num
);
1436 return ERROR_DOS(ERRDOS
,ERRnomem
);
1439 dptr_set_wcard(dptr_num
, wcard
);
1440 dptr_set_attr(dptr_num
, dirtype
);
1442 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num
, wcard
, dirtype
));
1444 /* We don't need to check for VOL here as this is returned by
1445 a different TRANS2 call. */
1447 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1448 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
1449 dont_descend
= True
;
1452 space_remaining
= max_data_bytes
;
1453 out_of_space
= False
;
1455 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
1456 BOOL got_exact_match
= False
;
1458 /* this is a heuristic to avoid seeking the dirptr except when
1459 absolutely necessary. It allows for a filename of about 40 chars */
1460 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1461 out_of_space
= True
;
1464 finished
= !get_lanman2_dir_entry(conn
,
1466 mask
,dirtype
,info_level
,
1467 requires_resume_key
,dont_descend
,
1468 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1472 if (finished
&& out_of_space
)
1475 if (!finished
&& !out_of_space
)
1479 * As an optimisation if we know we aren't looking
1480 * for a wildcard name (ie. the name matches the wildcard exactly)
1481 * then we can finish on any (first) match.
1482 * This speeds up large directory searches. JRA.
1488 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1491 /* Check if we can close the dirptr */
1492 if(close_after_first
|| (finished
&& close_if_end
)) {
1493 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
1494 dptr_close(&dptr_num
);
1498 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1499 * from observation of NT.
1502 if(numentries
== 0) {
1503 dptr_close(&dptr_num
);
1504 return ERROR_DOS(ERRDOS
,ERRbadfile
);
1507 /* At this point pdata points to numentries directory entries. */
1509 /* Set up the return parameter block */
1510 SSVAL(params
,0,dptr_num
);
1511 SSVAL(params
,2,numentries
);
1512 SSVAL(params
,4,finished
);
1513 SSVAL(params
,6,0); /* Never an EA error */
1514 SSVAL(params
,8,last_name_off
);
1516 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
));
1518 if ((! *directory
) && dptr_path(dptr_num
))
1519 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1521 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1522 smb_fn_name(CVAL(inbuf
,smb_com
)),
1523 mask
, directory
, dirtype
, numentries
) );
1526 * Force a name mangle here to ensure that the
1527 * mask as an 8.3 name is top of the mangled cache.
1528 * The reasons for this are subtle. Don't remove
1529 * this code unless you know what you are doing
1530 * (see PR#13758). JRA.
1533 if(!mangle_is_8_3_wildcards( mask
, False
))
1534 mangle_map(mask
, True
, True
, SNUM(conn
));
1539 /****************************************************************************
1540 Reply to a TRANS2_FINDNEXT.
1541 ****************************************************************************/
1543 static int call_trans2findnext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1544 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1546 /* We must be careful here that we don't return more than the
1547 allowed number of data bytes. If this means returning fewer than
1548 maxentries then so be it. We assume that the redirector has
1549 enough room for the fixed number of parameter bytes it has
1551 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1552 char *params
= *pparams
;
1553 char *pdata
= *ppdata
;
1554 int dptr_num
= SVAL(params
,0);
1555 int maxentries
= SVAL(params
,2);
1556 uint16 info_level
= SVAL(params
,4);
1557 uint32 resume_key
= IVAL(params
,6);
1558 BOOL close_after_request
= BITSETW(params
+10,0);
1559 BOOL close_if_end
= BITSETW(params
+10,1);
1560 BOOL requires_resume_key
= BITSETW(params
+10,2);
1561 BOOL continue_bit
= BITSETW(params
+10,3);
1562 pstring resume_name
;
1568 int i
, last_name_off
=0;
1569 BOOL finished
= False
;
1570 BOOL dont_descend
= False
;
1571 BOOL out_of_space
= False
;
1572 int space_remaining
;
1573 NTSTATUS ntstatus
= NT_STATUS_OK
;
1575 if (total_params
< 12)
1576 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1578 *mask
= *directory
= *resume_name
= 0;
1580 srvstr_get_path(inbuf
, resume_name
, params
+12, sizeof(resume_name
), -1, STR_TERMINATE
, &ntstatus
, True
);
1581 if (!NT_STATUS_IS_OK(ntstatus
)) {
1582 return ERROR_NT(ntstatus
);
1585 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1586 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1587 resume_key = %d resume name = %s continue=%d level = %d\n",
1588 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
1589 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
1592 /* W2K3 seems to treat zero as 1. */
1596 switch (info_level
) {
1597 case SMB_INFO_STANDARD
:
1598 case SMB_INFO_QUERY_EA_SIZE
:
1599 case SMB_FIND_FILE_DIRECTORY_INFO
:
1600 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1601 case SMB_FIND_FILE_NAMES_INFO
:
1602 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1604 case SMB_FIND_FILE_UNIX
:
1605 if (!lp_unix_extensions())
1606 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1609 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1612 pdata
= Realloc( *ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1614 return ERROR_DOS(ERRDOS
,ERRnomem
);
1617 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1619 /* Realloc the params space */
1620 params
= Realloc(*pparams
, 6*SIZEOFWORD
);
1621 if( params
== NULL
)
1622 return ERROR_DOS(ERRDOS
,ERRnomem
);
1626 /* Check that the dptr is valid */
1627 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
)))
1628 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1630 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1632 /* Get the wildcard mask from the dptr */
1633 if((p
= dptr_wcard(dptr_num
))== NULL
) {
1634 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
1635 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1639 pstrcpy(directory
,conn
->dirpath
);
1641 /* Get the attr mask from the dptr */
1642 dirtype
= dptr_attr(dptr_num
);
1644 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1645 dptr_num
, mask
, dirtype
,
1647 TellDir(conn
->dirptr
)));
1649 /* We don't need to check for VOL here as this is returned by
1650 a different TRANS2 call. */
1652 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1653 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),conn
->case_sensitive
))
1654 dont_descend
= True
;
1657 space_remaining
= max_data_bytes
;
1658 out_of_space
= False
;
1661 * Seek to the correct position. We no longer use the resume key but
1662 * depend on the last file name instead.
1665 if(requires_resume_key
&& *resume_name
&& !continue_bit
) {
1668 * Fix for NT redirector problem triggered by resume key indexes
1669 * changing between directory scans. We now return a resume key of 0
1670 * and instead look for the filename to continue from (also given
1671 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1672 * findfirst/findnext (as is usual) then the directory pointer
1673 * should already be at the correct place. Check this by scanning
1674 * backwards looking for an exact (ie. case sensitive) filename match.
1675 * If we get to the beginning of the directory and haven't found it then scan
1676 * forwards again looking for a match. JRA.
1679 int current_pos
, start_pos
;
1680 const char *dname
= NULL
;
1681 pstring dname_pstring
;
1682 void *dirptr
= conn
->dirptr
;
1683 start_pos
= TellDir(dirptr
);
1684 for(current_pos
= start_pos
; current_pos
>= 0; current_pos
--) {
1685 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos
));
1687 SeekDir(dirptr
, current_pos
);
1688 dname
= ReadDirName(dirptr
);
1691 * Remember, mangle_map is called by
1692 * get_lanman2_dir_entry(), so the resume name
1693 * could be mangled. Ensure we do the same
1697 /* make sure we get a copy that mangle_map can modify */
1699 pstrcpy(dname_pstring
, dname
);
1700 mangle_map( dname_pstring
, False
, True
, SNUM(conn
));
1702 if(strcsequal( resume_name
, dname_pstring
)) {
1703 SeekDir(dirptr
, current_pos
+1);
1704 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1711 * Scan forward from start if not found going backwards.
1714 if(current_pos
< 0) {
1715 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos
));
1716 SeekDir(dirptr
, start_pos
);
1717 for(current_pos
= start_pos
; (dname
= ReadDirName(dirptr
)) != NULL
; SeekDir(dirptr
,++current_pos
)) {
1720 * Remember, mangle_map is called by
1721 * get_lanman2_dir_entry(), so the resume name
1722 * could be mangled. Ensure we do the same
1727 /* make sure we get a copy that mangle_map can modify */
1729 pstrcpy(dname_pstring
, dname
);
1730 mangle_map(dname_pstring
, False
, True
, SNUM(conn
));
1732 if(strcsequal( resume_name
, dname_pstring
)) {
1733 SeekDir(dirptr
, current_pos
+1);
1734 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1739 } /* end if current_pos */
1740 } /* end if requires_resume_key && !continue_bit */
1742 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
1743 BOOL got_exact_match
= False
;
1745 /* this is a heuristic to avoid seeking the dirptr except when
1746 absolutely necessary. It allows for a filename of about 40 chars */
1747 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1748 out_of_space
= True
;
1751 finished
= !get_lanman2_dir_entry(conn
,
1753 mask
,dirtype
,info_level
,
1754 requires_resume_key
,dont_descend
,
1755 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1759 if (finished
&& out_of_space
)
1762 if (!finished
&& !out_of_space
)
1766 * As an optimisation if we know we aren't looking
1767 * for a wildcard name (ie. the name matches the wildcard exactly)
1768 * then we can finish on any (first) match.
1769 * This speeds up large directory searches. JRA.
1775 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1778 /* Check if we can close the dirptr */
1779 if(close_after_request
|| (finished
&& close_if_end
)) {
1780 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
1781 dptr_close(&dptr_num
); /* This frees up the saved mask */
1784 /* Set up the return parameter block */
1785 SSVAL(params
,0,numentries
);
1786 SSVAL(params
,2,finished
);
1787 SSVAL(params
,4,0); /* Never an EA error */
1788 SSVAL(params
,6,last_name_off
);
1790 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
1792 if ((! *directory
) && dptr_path(dptr_num
))
1793 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1795 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1796 smb_fn_name(CVAL(inbuf
,smb_com
)),
1797 mask
, directory
, dirtype
, numentries
) );
1802 /****************************************************************************
1803 Reply to a TRANS2_QFSINFO (query filesystem info).
1804 ****************************************************************************/
1806 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
,
1807 int length
, int bufsize
,
1808 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1810 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1811 char *pdata
= *ppdata
;
1812 char *params
= *pparams
;
1813 uint16 info_level
= SVAL(params
,0);
1816 char *vname
= volume_label(SNUM(conn
));
1817 int snum
= SNUM(conn
);
1818 char *fstype
= lp_fstype(SNUM(conn
));
1821 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
1823 if(SMB_VFS_STAT(conn
,".",&st
)!=0) {
1824 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
1825 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
1828 pdata
= Realloc(*ppdata
, max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1829 if ( pdata
== NULL
)
1830 return ERROR_DOS(ERRDOS
,ERRnomem
);
1833 memset((char *)pdata
,'\0',max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
);
1835 switch (info_level
) {
1836 case SMB_INFO_ALLOCATION
:
1838 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1840 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1841 block_size
= lp_block_size(snum
);
1842 if (bsize
< block_size
) {
1843 SMB_BIG_UINT factor
= block_size
/bsize
;
1848 if (bsize
> block_size
) {
1849 SMB_BIG_UINT factor
= bsize
/block_size
;
1854 bytes_per_sector
= 512;
1855 sectors_per_unit
= bsize
/bytes_per_sector
;
1857 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1858 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1859 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1861 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
1862 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
1863 SIVAL(pdata
,l1_cUnit
,dsize
);
1864 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
1865 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
1869 case SMB_INFO_VOLUME
:
1870 /* Return volume name */
1872 * Add volume serial number - hash of a combination of
1873 * the called hostname and the service name.
1875 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(local_machine
)<<16) );
1876 len
= srvstr_push(outbuf
, pdata
+l2_vol_szVolLabel
, vname
, -1, STR_NOALIGN
);
1877 SCVAL(pdata
,l2_vol_cch
,len
);
1878 data_len
= l2_vol_szVolLabel
+ len
;
1879 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1880 (unsigned)st
.st_ctime
, len
, vname
));
1883 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
1884 case SMB_FS_ATTRIBUTE_INFORMATION
:
1887 #if defined(HAVE_SYS_QUOTAS)
1888 quota_flag
= FILE_VOLUME_QUOTAS
;
1891 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
1892 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)|
1893 quota_flag
); /* FS ATTRIBUTES */
1895 SIVAL(pdata
,4,255); /* Max filename component length */
1896 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1897 and will think we can't do long filenames */
1898 len
= srvstr_push(outbuf
, pdata
+12, fstype
, -1, STR_UNICODE
);
1900 data_len
= 12 + len
;
1903 case SMB_QUERY_FS_LABEL_INFO
:
1904 case SMB_FS_LABEL_INFORMATION
:
1905 len
= srvstr_push(outbuf
, pdata
+4, vname
, -1, 0);
1910 case SMB_QUERY_FS_VOLUME_INFO
:
1911 case SMB_FS_VOLUME_INFORMATION
:
1914 * Add volume serial number - hash of a combination of
1915 * the called hostname and the service name.
1917 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
1918 (str_checksum(local_machine
)<<16));
1920 len
= srvstr_push(outbuf
, pdata
+18, vname
, -1, STR_UNICODE
);
1921 SIVAL(pdata
,12,len
);
1923 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1924 (int)strlen(vname
),vname
, lp_servicename(snum
)));
1927 case SMB_QUERY_FS_SIZE_INFO
:
1928 case SMB_FS_SIZE_INFORMATION
:
1930 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1932 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1933 block_size
= lp_block_size(snum
);
1934 if (bsize
< block_size
) {
1935 SMB_BIG_UINT factor
= block_size
/bsize
;
1940 if (bsize
> block_size
) {
1941 SMB_BIG_UINT factor
= bsize
/block_size
;
1946 bytes_per_sector
= 512;
1947 sectors_per_unit
= bsize
/bytes_per_sector
;
1948 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1949 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1950 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1951 SBIG_UINT(pdata
,0,dsize
);
1952 SBIG_UINT(pdata
,8,dfree
);
1953 SIVAL(pdata
,16,sectors_per_unit
);
1954 SIVAL(pdata
,20,bytes_per_sector
);
1958 case SMB_FS_FULL_SIZE_INFORMATION
:
1960 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1962 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1963 block_size
= lp_block_size(snum
);
1964 if (bsize
< block_size
) {
1965 SMB_BIG_UINT factor
= block_size
/bsize
;
1970 if (bsize
> block_size
) {
1971 SMB_BIG_UINT factor
= bsize
/block_size
;
1976 bytes_per_sector
= 512;
1977 sectors_per_unit
= bsize
/bytes_per_sector
;
1978 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1979 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1980 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1981 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
1982 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
1983 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
1984 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
1985 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
1989 case SMB_QUERY_FS_DEVICE_INFO
:
1990 case SMB_FS_DEVICE_INFORMATION
:
1992 SIVAL(pdata
,0,0); /* dev type */
1993 SIVAL(pdata
,4,0); /* characteristics */
1996 #ifdef HAVE_SYS_QUOTAS
1997 case SMB_FS_QUOTA_INFORMATION
:
1999 * what we have to send --metze:
2001 * Unknown1: 24 NULL bytes
2002 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2003 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2004 * Quota Flags: 2 byte :
2005 * Unknown3: 6 NULL bytes
2009 * details for Quota Flags:
2011 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2012 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2013 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2014 * 0x0001 Enable Quotas: enable quota for this fs
2018 /* we need to fake up a fsp here,
2019 * because its not send in this call
2022 SMB_NTQUOTA_STRUCT quotas
;
2025 ZERO_STRUCT(quotas
);
2032 if (current_user
.uid
!= 0) {
2033 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2034 lp_servicename(SNUM(conn
)),conn
->user
));
2035 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
2038 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
2039 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
2040 return ERROR_DOS(ERRSRV
,ERRerror
);
2045 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn
))));
2047 /* Unknown1 24 NULL bytes*/
2048 SBIG_UINT(pdata
,0,(SMB_BIG_UINT
)0);
2049 SBIG_UINT(pdata
,8,(SMB_BIG_UINT
)0);
2050 SBIG_UINT(pdata
,16,(SMB_BIG_UINT
)0);
2052 /* Default Soft Quota 8 bytes */
2053 SBIG_UINT(pdata
,24,quotas
.softlim
);
2055 /* Default Hard Quota 8 bytes */
2056 SBIG_UINT(pdata
,32,quotas
.hardlim
);
2058 /* Quota flag 2 bytes */
2059 SSVAL(pdata
,40,quotas
.qflags
);
2061 /* Unknown3 6 NULL bytes */
2067 #endif /* HAVE_SYS_QUOTAS */
2068 case SMB_FS_OBJECTID_INFORMATION
:
2073 * Query the version and capabilities of the CIFS UNIX extensions
2077 case SMB_QUERY_CIFS_UNIX_INFO
:
2078 if (!lp_unix_extensions())
2079 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2081 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
2082 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
2083 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)0)); /* No capabilities for now... */
2086 case SMB_MAC_QUERY_FS_INFO
:
2088 * Thursby MAC extension... ONLY on NTFS filesystems
2089 * once we do streams then we don't need this
2091 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
2093 SIVAL(pdata
,84,0x100); /* Don't support mac... */
2098 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2102 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
2104 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
2109 #ifdef HAVE_SYS_QUOTAS
2110 /****************************************************************************
2111 Reply to a TRANS2_SETFSINFO (set filesystem info).
2112 ****************************************************************************/
2114 static int call_trans2setfsinfo(connection_struct
*conn
,
2115 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2116 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2118 char *pdata
= *ppdata
;
2119 char *params
= *pparams
;
2120 files_struct
*fsp
= NULL
;
2123 SMB_NTQUOTA_STRUCT quotas
;
2125 ZERO_STRUCT(quotas
);
2127 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn
))));
2130 if ((current_user
.uid
!= 0)||!CAN_WRITE(conn
)) {
2131 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2132 lp_servicename(SNUM(conn
)),conn
->user
));
2133 return ERROR_DOS(ERRSRV
,ERRaccess
);
2137 if (total_params
< 4) {
2138 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2140 return ERROR_DOS(ERRDOS
,ERRinvalidparam
);
2143 fsp
= file_fsp(params
,0);
2145 if (!CHECK_NTQUOTA_HANDLE_OK(fsp
,conn
)) {
2146 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2147 return ERROR_NT(NT_STATUS_INVALID_HANDLE
);
2150 info_level
= SVAL(params
,2);
2152 switch(info_level
) {
2153 case SMB_FS_QUOTA_INFORMATION
:
2154 /* note: normaly there're 48 bytes,
2155 * but we didn't use the last 6 bytes for now
2158 if (total_data
< 42) {
2159 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2161 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2164 /* unknown_1 24 NULL bytes in pdata*/
2166 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2167 quotas
.softlim
= (SMB_BIG_UINT
)IVAL(pdata
,24);
2168 #ifdef LARGE_SMB_OFF_T
2169 quotas
.softlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,28)) << 32);
2170 #else /* LARGE_SMB_OFF_T */
2171 if ((IVAL(pdata
,28) != 0)&&
2172 ((quotas
.softlim
!= 0xFFFFFFFF)||
2173 (IVAL(pdata
,28)!=0xFFFFFFFF))) {
2174 /* more than 32 bits? */
2175 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2177 #endif /* LARGE_SMB_OFF_T */
2179 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2180 quotas
.hardlim
= (SMB_BIG_UINT
)IVAL(pdata
,32);
2181 #ifdef LARGE_SMB_OFF_T
2182 quotas
.hardlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,36)) << 32);
2183 #else /* LARGE_SMB_OFF_T */
2184 if ((IVAL(pdata
,36) != 0)&&
2185 ((quotas
.hardlim
!= 0xFFFFFFFF)||
2186 (IVAL(pdata
,36)!=0xFFFFFFFF))) {
2187 /* more than 32 bits? */
2188 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2190 #endif /* LARGE_SMB_OFF_T */
2192 /* quota_flags 2 bytes **/
2193 quotas
.qflags
= SVAL(pdata
,40);
2195 /* unknown_2 6 NULL bytes follow*/
2197 /* now set the quotas */
2198 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
2199 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
2200 return ERROR_DOS(ERRSRV
,ERRerror
);
2205 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2207 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2212 * sending this reply works fine,
2213 * but I'm not sure it's the same
2214 * like windows do...
2217 outsize
= set_message(outbuf
,10,0,True
);
2221 #endif /* HAVE_SYS_QUOTAS */
2223 /****************************************************************************
2224 * Utility function to set bad path error.
2225 ****************************************************************************/
2227 int set_bad_path_error(int err
, BOOL bad_path
, char *outbuf
, int def_class
, uint32 def_code
)
2229 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2230 err
, (int)bad_path
));
2234 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
2236 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2239 return UNIXERROR(def_class
,def_code
);
2242 /****************************************************************************
2243 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2244 file name or file id).
2245 ****************************************************************************/
2247 static int call_trans2qfilepathinfo(connection_struct
*conn
,
2248 char *inbuf
, char *outbuf
, int length
,
2250 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2252 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
2253 char *params
= *pparams
;
2254 char *pdata
= *ppdata
;
2255 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2258 SMB_OFF_T file_size
=0;
2259 SMB_BIG_UINT allocation_size
=0;
2260 unsigned int data_size
;
2261 unsigned int param_size
= 2;
2262 SMB_STRUCT_STAT sbuf
;
2263 pstring fname
, dos_fname
;
2268 BOOL bad_path
= False
;
2269 BOOL delete_pending
= False
;
2272 files_struct
*fsp
= NULL
;
2273 uint32 desired_access
= 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2276 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2280 if (tran_call
== TRANSACT2_QFILEINFO
) {
2281 if (total_params
< 4)
2282 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2284 fsp
= file_fsp(params
,0);
2285 info_level
= SVAL(params
,2);
2287 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
2289 if(fsp
&& (fsp
->fake_file_handle
)) {
2291 * This is actually for the QUOTA_FAKE_FILE --metze
2294 pstrcpy(fname
, fsp
->fsp_name
);
2295 /* We know this name is ok, it's already passed the checks. */
2297 } else if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2299 * This is actually a QFILEINFO on a directory
2300 * handle (returned from an NT SMB). NT5.0 seems
2301 * to do this call. JRA.
2303 /* We know this name is ok, it's already passed the checks. */
2304 pstrcpy(fname
, fsp
->fsp_name
);
2306 if (INFO_LEVEL_IS_UNIX(info_level
)) {
2307 /* Always do lstat for UNIX calls. */
2308 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
2309 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
2310 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2312 } else if (SMB_VFS_STAT(conn
,fname
,&sbuf
)) {
2313 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
2314 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2317 delete_pending
= fsp
->is_directory
? fsp
->directory_delete_on_close
: 0;
2320 * Original code - this is an open file.
2322 CHECK_FSP(fsp
,conn
);
2324 pstrcpy(fname
, fsp
->fsp_name
);
2325 if (SMB_VFS_FSTAT(fsp
,fsp
->fd
,&sbuf
) != 0) {
2326 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp
->fnum
, strerror(errno
)));
2327 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2329 pos
= fsp
->position_information
;
2330 delete_pending
= fsp
->delete_on_close
;
2331 desired_access
= fsp
->desired_access
;
2334 NTSTATUS status
= NT_STATUS_OK
;
2337 if (total_params
< 6)
2338 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2340 info_level
= SVAL(params
,0);
2342 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
2344 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
, &status
, False
);
2345 if (!NT_STATUS_IS_OK(status
)) {
2346 return ERROR_NT(status
);
2349 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
2351 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2353 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
2355 if (!check_name(fname
,conn
)) {
2356 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2357 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2360 if (INFO_LEVEL_IS_UNIX(info_level
)) {
2361 /* Always do lstat for UNIX calls. */
2362 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
2363 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
2364 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2366 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,fname
,&sbuf
) && (info_level
!= SMB_INFO_IS_NAME_VALID
)) {
2367 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
2368 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2372 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2373 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2375 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2376 fname
,fsp
? fsp
->fnum
: -1, info_level
,tran_call
,total_data
));
2378 p
= strrchr_m(fname
,'/');
2384 mode
= dos_mode(conn
,fname
,&sbuf
);
2386 mode
= FILE_ATTRIBUTE_NORMAL
;
2388 fullpathname
= fname
;
2389 file_size
= get_file_size(sbuf
);
2390 allocation_size
= get_allocation_size(fsp
,&sbuf
);
2394 params
= Realloc(*pparams
,2);
2396 return ERROR_DOS(ERRDOS
,ERRnomem
);
2398 memset((char *)params
,'\0',2);
2399 data_size
= max_data_bytes
+ DIR_ENTRY_SAFETY_MARGIN
;
2400 pdata
= Realloc(*ppdata
, data_size
);
2401 if ( pdata
== NULL
)
2402 return ERROR_DOS(ERRDOS
,ERRnomem
);
2405 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
2406 /* uggh, EAs for OS2 */
2407 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
2408 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
2411 memset((char *)pdata
,'\0',data_size
);
2413 c_time
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
2415 if (lp_dos_filetime_resolution(SNUM(conn
))) {
2417 sbuf
.st_atime
&= ~1;
2418 sbuf
.st_ctime
&= ~1;
2419 sbuf
.st_mtime
&= ~1;
2422 /* NT expects the name to be in an exact form of the *full*
2423 filename. See the trans2 torture test */
2424 if (strequal(base_name
,".")) {
2425 pstrcpy(dos_fname
, "\\");
2427 pstr_sprintf(dos_fname
, "\\%s", fname
);
2428 string_replace(dos_fname
, '/', '\\');
2431 switch (info_level
) {
2432 case SMB_INFO_STANDARD
:
2433 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2435 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
2436 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
2437 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
2438 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
2439 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
2440 SSVAL(pdata
,l1_attrFile
,mode
);
2443 case SMB_INFO_QUERY_EA_SIZE
:
2445 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2446 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2448 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
2449 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
2450 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
2451 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
2452 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
2453 SSVAL(pdata
,l1_attrFile
,mode
);
2454 SIVAL(pdata
,l1_attrFile
+2,ea_size
);
2458 case SMB_INFO_IS_NAME_VALID
:
2459 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2460 if (tran_call
== TRANSACT2_QFILEINFO
) {
2461 /* os/2 needs this ? really ?*/
2462 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
2468 case SMB_INFO_QUERY_EAS_FROM_LIST
:
2469 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2471 put_dos_date2(pdata
,0,c_time
);
2472 put_dos_date2(pdata
,4,sbuf
.st_atime
);
2473 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
2474 SIVAL(pdata
,12,(uint32
)file_size
);
2475 SIVAL(pdata
,16,(uint32
)allocation_size
);
2476 SIVAL(pdata
,20,mode
);
2479 case SMB_INFO_QUERY_ALL_EAS
:
2480 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2481 /* We have data_size bytes to put EA's into. */
2482 data_size
= fill_ea_buffer(pdata
, data_size
, conn
, fsp
, fname
);
2485 case SMB_FILE_BASIC_INFORMATION
:
2486 case SMB_QUERY_FILE_BASIC_INFO
:
2488 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
) {
2489 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2490 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
2492 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2496 put_long_date(pdata
,c_time
);
2497 put_long_date(pdata
+8,sbuf
.st_atime
);
2498 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2499 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2500 SIVAL(pdata
,32,mode
);
2502 DEBUG(5,("SMB_QFBI - "));
2504 time_t create_time
= c_time
;
2505 DEBUG(5,("create: %s ", ctime(&create_time
)));
2507 DEBUG(5,("access: %s ", ctime(&sbuf
.st_atime
)));
2508 DEBUG(5,("write: %s ", ctime(&sbuf
.st_mtime
)));
2509 DEBUG(5,("change: %s ", ctime(&sbuf
.st_mtime
)));
2510 DEBUG(5,("mode: %x\n", mode
));
2514 case SMB_FILE_STANDARD_INFORMATION
:
2515 case SMB_QUERY_FILE_STANDARD_INFO
:
2517 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2519 SOFF_T(pdata
,0,allocation_size
);
2520 SOFF_T(pdata
,8,file_size
);
2521 if (delete_pending
& sbuf
.st_nlink
)
2522 SIVAL(pdata
,16,sbuf
.st_nlink
- 1);
2524 SIVAL(pdata
,16,sbuf
.st_nlink
);
2526 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
2529 case SMB_FILE_EA_INFORMATION
:
2530 case SMB_QUERY_FILE_EA_INFO
:
2532 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2533 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2535 SIVAL(pdata
,0,ea_size
);
2539 /* Get the 8.3 name - used if NT SMB was negotiated. */
2540 case SMB_QUERY_FILE_ALT_NAME_INFO
:
2541 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
2545 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2546 pstrcpy(short_name
,base_name
);
2547 /* Mangle if not already 8.3 */
2548 if(!mangle_is_8_3(short_name
, True
)) {
2549 mangle_map(short_name
,True
,True
,SNUM(conn
));
2551 len
= srvstr_push(outbuf
, pdata
+4, short_name
, -1, STR_UNICODE
);
2552 data_size
= 4 + len
;
2557 case SMB_QUERY_FILE_NAME_INFO
:
2559 this must be *exactly* right for ACLs on mapped drives to work
2561 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
2562 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2563 data_size
= 4 + len
;
2567 case SMB_FILE_ALLOCATION_INFORMATION
:
2568 case SMB_QUERY_FILE_ALLOCATION_INFO
:
2569 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2571 SOFF_T(pdata
,0,allocation_size
);
2574 case SMB_FILE_END_OF_FILE_INFORMATION
:
2575 case SMB_QUERY_FILE_END_OF_FILEINFO
:
2576 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2578 SOFF_T(pdata
,0,file_size
);
2581 case SMB_QUERY_FILE_ALL_INFO
:
2582 case SMB_FILE_ALL_INFORMATION
:
2584 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2585 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2586 put_long_date(pdata
,c_time
);
2587 put_long_date(pdata
+8,sbuf
.st_atime
);
2588 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2589 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2590 SIVAL(pdata
,32,mode
);
2592 SOFF_T(pdata
,0,allocation_size
);
2593 SOFF_T(pdata
,8,file_size
);
2594 if (delete_pending
&& sbuf
.st_nlink
)
2595 SIVAL(pdata
,16,sbuf
.st_nlink
- 1);
2597 SIVAL(pdata
,16,sbuf
.st_nlink
);
2598 SCVAL(pdata
,20,delete_pending
);
2599 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
2601 SIVAL(pdata
,0,ea_size
);
2602 pdata
+= 4; /* EA info */
2603 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
2606 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2609 case SMB_FILE_INTERNAL_INFORMATION
:
2610 /* This should be an index number - looks like
2613 I think this causes us to fail the IFSKIT
2614 BasicFileInformationTest. -tpot */
2616 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2617 SIVAL(pdata
,0,sbuf
.st_dev
);
2618 SIVAL(pdata
,4,sbuf
.st_ino
);
2622 case SMB_FILE_ACCESS_INFORMATION
:
2623 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2624 SIVAL(pdata
,0,desired_access
);
2628 case SMB_FILE_NAME_INFORMATION
:
2629 /* Pathname with leading '\'. */
2632 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
2633 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2634 SIVAL(pdata
,0,byte_len
);
2635 data_size
= 4 + byte_len
;
2639 case SMB_FILE_DISPOSITION_INFORMATION
:
2640 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2642 SCVAL(pdata
,0,delete_pending
);
2645 case SMB_FILE_POSITION_INFORMATION
:
2646 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2648 SOFF_T(pdata
,0,pos
);
2651 case SMB_FILE_MODE_INFORMATION
:
2652 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2653 SIVAL(pdata
,0,mode
);
2657 case SMB_FILE_ALIGNMENT_INFORMATION
:
2658 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2659 SIVAL(pdata
,0,0); /* No alignment needed. */
2665 * NT4 server just returns "invalid query" to this - if we try to answer
2666 * it then NTws gets a BSOD! (tridge).
2667 * W2K seems to want this. JRA.
2669 case SMB_QUERY_FILE_STREAM_INFO
:
2671 case SMB_FILE_STREAM_INFORMATION
:
2672 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2676 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", 0xE, False
);
2677 SIVAL(pdata
,0,0); /* ??? */
2678 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
2679 SOFF_T(pdata
,8,file_size
);
2680 SIVAL(pdata
,16,allocation_size
);
2681 SIVAL(pdata
,20,0); /* ??? */
2682 data_size
= 24 + byte_len
;
2686 case SMB_QUERY_COMPRESSION_INFO
:
2687 case SMB_FILE_COMPRESSION_INFORMATION
:
2688 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2689 SOFF_T(pdata
,0,file_size
);
2690 SIVAL(pdata
,8,0); /* ??? */
2691 SIVAL(pdata
,12,0); /* ??? */
2695 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
2696 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2697 put_long_date(pdata
,c_time
);
2698 put_long_date(pdata
+8,sbuf
.st_atime
);
2699 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2700 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2701 SIVAL(pdata
,32,allocation_size
);
2702 SOFF_T(pdata
,40,file_size
);
2703 SIVAL(pdata
,48,mode
);
2704 SIVAL(pdata
,52,0); /* ??? */
2708 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
2709 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2710 SIVAL(pdata
,0,mode
);
2716 * CIFS UNIX Extensions.
2719 case SMB_QUERY_FILE_UNIX_BASIC
:
2721 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2722 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf
.st_mode
));
2724 SOFF_T(pdata
,0,get_file_size(sbuf
)); /* File size 64 Bit */
2727 SOFF_T(pdata
,0,get_allocation_size(fsp
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
2730 put_long_date(pdata
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
2731 put_long_date(pdata
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
2732 put_long_date(pdata
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
2735 SIVAL(pdata
,0,sbuf
.st_uid
); /* user id for the owner */
2739 SIVAL(pdata
,0,sbuf
.st_gid
); /* group id of owner */
2743 SIVAL(pdata
,0,unix_filetype(sbuf
.st_mode
));
2746 SIVAL(pdata
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
2750 SIVAL(pdata
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
2754 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
2757 SIVAL(pdata
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
2761 SIVAL(pdata
,0,sbuf
.st_nlink
); /* number of hard links */
2764 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2768 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2770 for (i
=0; i
<100; i
++)
2771 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
2777 case SMB_QUERY_FILE_UNIX_LINK
:
2781 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2783 if(!S_ISLNK(sbuf
.st_mode
))
2784 return(UNIXERROR(ERRSRV
,ERRbadlink
));
2786 return(UNIXERROR(ERRDOS
,ERRbadlink
));
2788 len
= SMB_VFS_READLINK(conn
,fullpathname
, buffer
, sizeof(pstring
)-1); /* read link */
2790 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2792 len
= srvstr_push(outbuf
, pdata
, buffer
, -1, STR_TERMINATE
);
2794 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2800 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2803 send_trans2_replies(outbuf
, bufsize
, params
, param_size
, *ppdata
, data_size
);
2808 /****************************************************************************
2809 Deal with the internal needs of setting the delete on close flag. Note that
2810 as the tdb locking is recursive, it is safe to call this from within
2811 open_file_shared. JRA.
2812 ****************************************************************************/
2814 NTSTATUS
set_delete_on_close_internal(files_struct
*fsp
, BOOL delete_on_close
, uint32 dosmode
)
2816 if (delete_on_close
) {
2818 * Only allow delete on close for writable files.
2821 if (dosmode
& aRONLY
) {
2822 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
2824 return NT_STATUS_CANNOT_DELETE
;
2828 * Only allow delete on close for writable shares.
2831 if (!CAN_WRITE(fsp
->conn
)) {
2832 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2834 return NT_STATUS_ACCESS_DENIED
;
2838 * Only allow delete on close for files/directories opened with delete intent.
2841 if (!(fsp
->desired_access
& DELETE_ACCESS
)) {
2842 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2844 return NT_STATUS_ACCESS_DENIED
;
2848 if(fsp
->is_directory
) {
2849 fsp
->directory_delete_on_close
= delete_on_close
;
2850 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2851 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2853 fsp
->delete_on_close
= delete_on_close
;
2854 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2855 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2858 return NT_STATUS_OK
;
2861 /****************************************************************************
2862 Sets the delete on close flag over all share modes on this file.
2863 Modify the share mode entry for all files open
2864 on this device and inode to tell other smbds we have
2865 changed the delete on close flag. This will be noticed
2866 in the close code, the last closer will delete the file
2868 ****************************************************************************/
2870 NTSTATUS
set_delete_on_close_over_all(files_struct
*fsp
, BOOL delete_on_close
)
2872 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2873 delete_on_close
? "Adding" : "Removing", fsp
->fnum
, fsp
->fsp_name
));
2875 if (fsp
->is_directory
|| fsp
->is_stat
)
2876 return NT_STATUS_OK
;
2878 if (lock_share_entry_fsp(fsp
) == False
)
2879 return NT_STATUS_ACCESS_DENIED
;
2881 if (!modify_delete_flag(fsp
->dev
, fsp
->inode
, delete_on_close
)) {
2882 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
2884 unlock_share_entry_fsp(fsp
);
2885 return NT_STATUS_ACCESS_DENIED
;
2888 unlock_share_entry_fsp(fsp
);
2889 return NT_STATUS_OK
;
2892 /****************************************************************************
2893 Set a hard link (called by UNIX extensions and by NT rename with HARD link
2895 ****************************************************************************/
2897 NTSTATUS
hardlink_internals(connection_struct
*conn
, char *oldname
, char *newname
)
2899 BOOL bad_path_oldname
= False
;
2900 BOOL bad_path_newname
= False
;
2901 SMB_STRUCT_STAT sbuf1
, sbuf2
;
2902 pstring last_component_oldname
;
2903 pstring last_component_newname
;
2904 NTSTATUS status
= NT_STATUS_OK
;
2910 if (ms_has_wild(newname
) || ms_has_wild(oldname
)) {
2911 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD
;
2914 unix_convert(oldname
,conn
,last_component_oldname
,&bad_path_oldname
,&sbuf1
);
2915 if (bad_path_oldname
) {
2916 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
2919 /* Quick check for "." and ".." */
2920 if (last_component_oldname
[0] == '.') {
2921 if (!last_component_oldname
[1] || (last_component_oldname
[1] == '.' && !last_component_oldname
[2])) {
2922 return NT_STATUS_OBJECT_NAME_INVALID
;
2926 /* source must already exist. */
2927 if (!VALID_STAT(sbuf1
)) {
2928 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2931 if (!check_name(oldname
,conn
)) {
2932 return NT_STATUS_ACCESS_DENIED
;
2935 unix_convert(newname
,conn
,last_component_newname
,&bad_path_newname
,&sbuf2
);
2936 if (bad_path_newname
) {
2937 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
2940 /* Quick check for "." and ".." */
2941 if (last_component_newname
[0] == '.') {
2942 if (!last_component_newname
[1] || (last_component_newname
[1] == '.' && !last_component_newname
[2])) {
2943 return NT_STATUS_OBJECT_NAME_INVALID
;
2947 /* Disallow if newname already exists. */
2948 if (VALID_STAT(sbuf2
)) {
2949 return NT_STATUS_OBJECT_NAME_COLLISION
;
2952 if (!check_name(newname
,conn
)) {
2953 return NT_STATUS_ACCESS_DENIED
;
2956 /* No links from a directory. */
2957 if (S_ISDIR(sbuf1
.st_mode
)) {
2958 return NT_STATUS_FILE_IS_A_DIRECTORY
;
2961 /* Ensure this is within the share. */
2962 if (!reduce_name(conn
, oldname
) != 0)
2963 return NT_STATUS_ACCESS_DENIED
;
2965 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname
, oldname
));
2967 if (SMB_VFS_LINK(conn
,oldname
,newname
) != 0) {
2968 status
= map_nt_error_from_unix(errno
);
2969 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
2970 nt_errstr(status
), newname
, oldname
));
2976 /****************************************************************************
2977 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2978 ****************************************************************************/
2980 static int call_trans2setfilepathinfo(connection_struct
*conn
,
2981 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2982 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2984 char *params
= *pparams
;
2985 char *pdata
= *ppdata
;
2986 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2991 SMB_STRUCT_STAT sbuf
;
2994 BOOL bad_path
= False
;
2995 files_struct
*fsp
= NULL
;
2996 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
2997 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
2998 mode_t unixmode
= 0;
2999 NTSTATUS status
= NT_STATUS_OK
;
3002 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
3006 if (tran_call
== TRANSACT2_SETFILEINFO
) {
3007 if (total_params
< 4)
3008 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3010 fsp
= file_fsp(params
,0);
3011 info_level
= SVAL(params
,2);
3013 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
3015 * This is actually a SETFILEINFO on a directory
3016 * handle (returned from an NT SMB). NT5.0 seems
3017 * to do this call. JRA.
3019 pstrcpy(fname
, fsp
->fsp_name
);
3020 if (SMB_VFS_STAT(conn
,fname
,&sbuf
) != 0) {
3021 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
3022 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3024 } else if (fsp
&& fsp
->print_file
) {
3026 * Doing a DELETE_ON_CLOSE should cancel a print job.
3028 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
3029 fsp
->share_mode
= FILE_DELETE_ON_CLOSE
;
3031 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp
->fsp_name
));
3034 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3037 return (UNIXERROR(ERRDOS
,ERRbadpath
));
3040 * Original code - this is an open file.
3042 CHECK_FSP(fsp
,conn
);
3044 pstrcpy(fname
, fsp
->fsp_name
);
3047 if (SMB_VFS_FSTAT(fsp
,fd
,&sbuf
) != 0) {
3048 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
3049 return(UNIXERROR(ERRDOS
,ERRbadfid
));
3054 if (total_params
< 6)
3055 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3057 info_level
= SVAL(params
,0);
3058 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
, &status
, False
);
3059 if (!NT_STATUS_IS_OK(status
)) {
3060 return ERROR_NT(status
);
3062 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
3064 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
3068 * For CIFS UNIX extensions the target name may not exist.
3071 if(!VALID_STAT(sbuf
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
3072 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname
, strerror(errno
)));
3073 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3076 if(!check_name(fname
, conn
)) {
3077 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
3082 if (!CAN_WRITE(conn
))
3083 return ERROR_DOS(ERRSRV
,ERRaccess
);
3085 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
3086 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3088 if (VALID_STAT(sbuf
))
3089 unixmode
= sbuf
.st_mode
;
3091 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3092 tran_call
,fname
, fsp
? fsp
->fnum
: -1, info_level
,total_data
));
3094 /* Realloc the parameter and data sizes */
3095 params
= Realloc(*pparams
,2);
3097 return ERROR_DOS(ERRDOS
,ERRnomem
);
3103 /* the pending modtime overrides the current modtime */
3104 sbuf
.st_mtime
= fsp
->pending_modtime
;
3107 size
= get_file_size(sbuf
);
3108 tvs
.modtime
= sbuf
.st_mtime
;
3109 tvs
.actime
= sbuf
.st_atime
;
3110 dosmode
= dos_mode(conn
,fname
,&sbuf
);
3111 unixmode
= sbuf
.st_mode
;
3113 set_owner
= VALID_STAT(sbuf
) ? sbuf
.st_uid
: (uid_t
)SMB_UID_NO_CHANGE
;
3114 set_grp
= VALID_STAT(sbuf
) ? sbuf
.st_gid
: (gid_t
)SMB_GID_NO_CHANGE
;
3116 switch (info_level
) {
3117 case SMB_INFO_STANDARD
:
3119 if (total_data
< 12)
3120 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3123 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
3125 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
3129 case SMB_INFO_SET_EA
:
3130 status
= set_ea(conn
, fsp
, fname
, pdata
, total_data
);
3131 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3132 return ERROR_NT(status
);
3135 /* XXXX um, i don't think this is right.
3136 it's also not in the cifs6.txt spec.
3138 case SMB_INFO_QUERY_EAS_FROM_LIST
:
3139 if (total_data
< 28)
3140 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3142 tvs
.actime
= make_unix_date2(pdata
+8);
3143 tvs
.modtime
= make_unix_date2(pdata
+12);
3144 size
= IVAL(pdata
,16);
3145 dosmode
= IVAL(pdata
,24);
3148 /* XXXX nor this. not in cifs6.txt, either. */
3149 case SMB_INFO_QUERY_ALL_EAS
:
3150 if (total_data
< 28)
3151 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3153 tvs
.actime
= make_unix_date2(pdata
+8);
3154 tvs
.modtime
= make_unix_date2(pdata
+12);
3155 size
= IVAL(pdata
,16);
3156 dosmode
= IVAL(pdata
,24);
3159 case SMB_SET_FILE_BASIC_INFO
:
3160 case SMB_FILE_BASIC_INFORMATION
:
3162 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3164 time_t changed_time
;
3166 if (total_data
< 36)
3167 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3169 /* Ignore create time at offset pdata. */
3172 tvs
.actime
= interpret_long_date(pdata
+8);
3174 write_time
= interpret_long_date(pdata
+16);
3175 changed_time
= interpret_long_date(pdata
+24);
3177 tvs
.modtime
= MIN(write_time
, changed_time
);
3179 if (write_time
> tvs
.modtime
&& write_time
!= 0xffffffff) {
3180 tvs
.modtime
= write_time
;
3182 /* Prefer a defined time to an undefined one. */
3183 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
3184 tvs
.modtime
= (write_time
== (time_t)0 || write_time
== (time_t)-1
3185 ? changed_time
: write_time
);
3188 dosmode
= IVAL(pdata
,32);
3192 case SMB_FILE_ALLOCATION_INFORMATION
:
3193 case SMB_SET_FILE_ALLOCATION_INFO
:
3196 SMB_BIG_UINT allocation_size
;
3199 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3201 allocation_size
= (SMB_BIG_UINT
)IVAL(pdata
,0);
3202 #ifdef LARGE_SMB_OFF_T
3203 allocation_size
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
3204 #else /* LARGE_SMB_OFF_T */
3205 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3206 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3207 #endif /* LARGE_SMB_OFF_T */
3208 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3209 fname
, (double)allocation_size
));
3211 if (allocation_size
)
3212 allocation_size
= smb_roundup(allocation_size
);
3214 if(allocation_size
!= get_file_size(sbuf
)) {
3215 SMB_STRUCT_STAT new_sbuf
;
3217 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3218 fname
, (double)allocation_size
));
3221 files_struct
*new_fsp
= NULL
;
3222 int access_mode
= 0;
3225 if(global_oplock_break
) {
3226 /* Queue this file modify as we are the process of an oplock break. */
3228 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3229 DEBUGADD(2,( "in oplock break state.\n"));
3231 push_oplock_pending_smb_message(inbuf
, length
);
3235 new_fsp
= open_file_shared1(conn
, fname
, &sbuf
,FILE_WRITE_DATA
,
3236 SET_OPEN_MODE(DOS_OPEN_RDWR
),
3237 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
3238 FILE_ATTRIBUTE_NORMAL
,
3239 INTERNAL_OPEN_ONLY
, &access_mode
, &action
);
3241 if (new_fsp
== NULL
)
3242 return(UNIXERROR(ERRDOS
,ERRbadpath
));
3243 ret
= vfs_allocate_file_space(new_fsp
, allocation_size
);
3244 if (SMB_VFS_FSTAT(new_fsp
,new_fsp
->fd
,&new_sbuf
) != 0) {
3245 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3246 new_fsp
->fnum
, strerror(errno
)));
3249 close_file(new_fsp
,True
);
3251 ret
= vfs_allocate_file_space(fsp
, allocation_size
);
3252 if (SMB_VFS_FSTAT(fsp
,fd
,&new_sbuf
) != 0) {
3253 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3254 fsp
->fnum
, strerror(errno
)));
3259 return ERROR_NT(NT_STATUS_DISK_FULL
);
3261 /* Allocate can truncate size... */
3262 size
= get_file_size(new_sbuf
);
3268 case SMB_FILE_END_OF_FILE_INFORMATION
:
3269 case SMB_SET_FILE_END_OF_FILE_INFO
:
3272 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3274 size
= IVAL(pdata
,0);
3275 #ifdef LARGE_SMB_OFF_T
3276 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
3277 #else /* LARGE_SMB_OFF_T */
3278 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3279 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3280 #endif /* LARGE_SMB_OFF_T */
3281 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname
, (double)size
));
3285 case SMB_FILE_DISPOSITION_INFORMATION
:
3286 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
3288 BOOL delete_on_close
;
3291 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3293 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
3295 /* Just ignore this set on a path. */
3296 if (tran_call
!= TRANSACT2_SETFILEINFO
)
3300 return(UNIXERROR(ERRDOS
,ERRbadfid
));
3302 status
= set_delete_on_close_internal(fsp
, delete_on_close
, dosmode
);
3304 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3305 return ERROR_NT(status
);
3307 /* The set is across all open files on this dev/inode pair. */
3308 status
=set_delete_on_close_over_all(fsp
, delete_on_close
);
3309 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3310 return ERROR_NT(status
);
3315 case SMB_FILE_POSITION_INFORMATION
:
3317 SMB_BIG_UINT position_information
;
3320 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3322 position_information
= (SMB_BIG_UINT
)IVAL(pdata
,0);
3323 #ifdef LARGE_SMB_OFF_T
3324 position_information
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
3325 #else /* LARGE_SMB_OFF_T */
3326 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3327 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3328 #endif /* LARGE_SMB_OFF_T */
3329 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3330 fname
, (double)position_information
));
3332 fsp
->position_information
= position_information
;
3337 * CIFS UNIX extensions.
3340 case SMB_SET_FILE_UNIX_BASIC
:
3342 uint32 raw_unixmode
;
3344 if (total_data
< 100)
3345 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3347 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
3348 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
3349 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
3350 #ifdef LARGE_SMB_OFF_T
3351 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
3352 #else /* LARGE_SMB_OFF_T */
3353 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3354 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3355 #endif /* LARGE_SMB_OFF_T */
3357 pdata
+=24; /* ctime & st_blocks are not changed */
3358 tvs
.actime
= interpret_long_unix_date(pdata
); /* access_time */
3359 tvs
.modtime
= interpret_long_unix_date(pdata
+8); /* modification_time */
3361 set_owner
= (uid_t
)IVAL(pdata
,0);
3363 set_grp
= (gid_t
)IVAL(pdata
,0);
3365 raw_unixmode
= IVAL(pdata
,28);
3366 unixmode
= unix_perms_from_wire(conn
, &sbuf
, raw_unixmode
);
3367 dosmode
= 0; /* Ensure dos mode change doesn't override this. */
3369 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3370 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3371 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
3373 if (!VALID_STAT(sbuf
)) {
3376 * The only valid use of this is to create character and block
3377 * devices, and named pipes. This is deprecated (IMHO) and
3378 * a new info level should be used for mknod. JRA.
3381 uint32 file_type
= IVAL(pdata
,0);
3382 #if defined(HAVE_MAKEDEV)
3383 uint32 dev_major
= IVAL(pdata
,4);
3384 uint32 dev_minor
= IVAL(pdata
,12);
3387 uid_t myuid
= geteuid();
3388 gid_t mygid
= getegid();
3389 SMB_DEV_T dev
= (SMB_DEV_T
)0;
3391 if (tran_call
== TRANSACT2_SETFILEINFO
)
3392 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3394 if (raw_unixmode
== SMB_MODE_NO_CHANGE
)
3395 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3397 #if defined(HAVE_MAKEDEV)
3398 dev
= makedev(dev_major
, dev_minor
);
3401 /* We can only create as the owner/group we are. */
3403 if ((set_owner
!= myuid
) && (set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
))
3404 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3405 if ((set_grp
!= mygid
) && (set_grp
!= (gid_t
)SMB_GID_NO_CHANGE
))
3406 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3408 switch (file_type
) {
3409 #if defined(S_IFIFO)
3410 case UNIX_TYPE_FIFO
:
3411 unixmode
|= S_IFIFO
;
3414 #if defined(S_IFSOCK)
3415 case UNIX_TYPE_SOCKET
:
3416 unixmode
|= S_IFSOCK
;
3419 #if defined(S_IFCHR)
3420 case UNIX_TYPE_CHARDEV
:
3421 unixmode
|= S_IFCHR
;
3424 #if defined(S_IFBLK)
3425 case UNIX_TYPE_BLKDEV
:
3426 unixmode
|= S_IFBLK
;
3430 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3433 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3434 0%o for file %s\n", (double)dev
, unixmode
, fname
));
3436 /* Ok - do the mknod. */
3437 if (SMB_VFS_MKNOD(conn
,fname
, unixmode
, dev
) != 0)
3438 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3440 inherit_access_acl(conn
, fname
, unixmode
);
3443 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3448 * Deal with the UNIX specific mode set.
3451 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
3452 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3453 (unsigned int)unixmode
, fname
));
3454 if (SMB_VFS_CHMOD(conn
,fname
,unixmode
) != 0)
3455 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3459 * Deal with the UNIX specific uid set.
3462 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) && (sbuf
.st_uid
!= set_owner
)) {
3463 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3464 (unsigned int)set_owner
, fname
));
3465 if (SMB_VFS_CHOWN(conn
,fname
,set_owner
, (gid_t
)-1) != 0)
3466 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3470 * Deal with the UNIX specific gid set.
3473 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) && (sbuf
.st_gid
!= set_grp
)) {
3474 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3475 (unsigned int)set_owner
, fname
));
3476 if (SMB_VFS_CHOWN(conn
,fname
,(uid_t
)-1, set_grp
) != 0)
3477 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3482 case SMB_SET_FILE_UNIX_LINK
:
3484 pstring link_target
;
3485 char *newname
= fname
;
3487 /* Set a symbolic link. */
3488 /* Don't allow this if follow links is false. */
3490 if (!lp_symlinks(SNUM(conn
)))
3491 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3493 srvstr_pull(inbuf
, link_target
, pdata
, sizeof(link_target
), -1, STR_TERMINATE
);
3495 /* !widelinks forces the target path to be within the share. */
3496 /* This means we can interpret the target as a pathname. */
3497 if (!lp_widelinks(SNUM(conn
))) {
3499 char *last_dirp
= NULL
;
3501 unix_format(link_target
);
3502 if (*link_target
== '/') {
3503 /* No absolute paths allowed. */
3504 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3506 pstrcpy(rel_name
, newname
);
3507 last_dirp
= strrchr_m(rel_name
, '/');
3509 last_dirp
[1] = '\0';
3511 pstrcpy(rel_name
, "./");
3513 pstrcat(rel_name
, link_target
);
3515 if (!check_name(rel_name
, conn
)) {
3516 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3520 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3521 fname
, link_target
));
3523 if (SMB_VFS_SYMLINK(conn
,link_target
,newname
) != 0)
3524 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3526 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3530 case SMB_SET_FILE_UNIX_HLINK
:
3533 char *newname
= fname
;
3535 /* Set a hard link. */
3536 srvstr_get_path(inbuf
, oldname
, pdata
, sizeof(oldname
), -1, STR_TERMINATE
, &status
, False
);
3537 if (!NT_STATUS_IS_OK(status
)) {
3538 return ERROR_NT(status
);
3541 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3544 status
= hardlink_internals(conn
, oldname
, newname
);
3545 if (!NT_STATUS_IS_OK(status
)) {
3546 return ERROR_NT(status
);
3550 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3554 case SMB_FILE_RENAME_INFORMATION
:
3563 if (total_data
< 12)
3564 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3566 overwrite
= (CVAL(pdata
,0) ? True
: False
);
3567 root_fid
= IVAL(pdata
,4);
3568 len
= IVAL(pdata
,8);
3569 srvstr_get_path(inbuf
, newname
, &pdata
[12], sizeof(newname
), len
, 0, &status
, False
);
3570 if (!NT_STATUS_IS_OK(status
)) {
3571 return ERROR_NT(status
);
3574 /* Check the new name has no '/' characters. */
3575 if (strchr_m(newname
, '/'))
3576 return ERROR_NT(NT_STATUS_NOT_SUPPORTED
);
3578 RESOLVE_DFSPATH(newname
, conn
, inbuf
, outbuf
);
3580 /* Create the base directory. */
3581 pstrcpy(base_name
, fname
);
3582 p
= strrchr_m(base_name
, '/');
3585 /* Append the new name. */
3586 pstrcat(base_name
, "/");
3587 pstrcat(base_name
, newname
);
3590 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3591 fsp
->fnum
, fsp
->fsp_name
, base_name
));
3592 status
= rename_internals_fsp(conn
, fsp
, base_name
, 0, overwrite
);
3594 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3596 status
= rename_internals(conn
, fname
, base_name
, 0, overwrite
);
3598 if (!NT_STATUS_IS_OK(status
)) {
3599 return ERROR_NT(status
);
3601 process_pending_change_notify_queue((time_t)0);
3603 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3607 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3610 /* get some defaults (no modifications) if any info is zero or -1. */
3611 if (tvs
.actime
== (time_t)0 || tvs
.actime
== (time_t)-1)
3612 tvs
.actime
= sbuf
.st_atime
;
3614 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
3615 tvs
.modtime
= sbuf
.st_mtime
;
3617 DEBUG(6,("actime: %s " , ctime(&tvs
.actime
)));
3618 DEBUG(6,("modtime: %s ", ctime(&tvs
.modtime
)));
3619 DEBUG(6,("size: %.0f ", (double)size
));
3622 if (S_ISDIR(sbuf
.st_mode
))
3628 DEBUG(6,("dosmode: %x\n" , dosmode
));
3630 if(!((info_level
== SMB_SET_FILE_END_OF_FILE_INFO
) ||
3631 (info_level
== SMB_SET_FILE_ALLOCATION_INFO
) ||
3632 (info_level
== SMB_FILE_ALLOCATION_INFORMATION
) ||
3633 (info_level
== SMB_FILE_END_OF_FILE_INFORMATION
))) {
3636 * Only do this test if we are not explicitly
3637 * changing the size of a file.
3640 size
= get_file_size(sbuf
);
3644 * Try and set the times, size and mode of this file -
3645 * if they are different from the current values
3647 if (sbuf
.st_mtime
!= tvs
.modtime
|| sbuf
.st_atime
!= tvs
.actime
) {
3650 * This was a setfileinfo on an open file.
3651 * NT does this a lot. It's actually pointless
3652 * setting the time here, as it will be overwritten
3653 * on the next write, so we save the request
3654 * away and will set it on file close. JRA.
3657 if (tvs
.modtime
!= (time_t)0 && tvs
.modtime
!= (time_t)-1) {
3658 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs
.modtime
) ));
3659 fsp
->pending_modtime
= tvs
.modtime
;
3664 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3666 if(file_utime(conn
, fname
, &tvs
)!=0)
3667 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3671 /* check the mode isn't different, before changing it */
3672 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, fname
, &sbuf
))) {
3674 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname
, dosmode
));
3676 if(file_set_dosmode(conn
, fname
, dosmode
, NULL
)) {
3677 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname
, strerror(errno
)));
3678 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3682 if (size
!= get_file_size(sbuf
)) {
3686 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3687 fname
, (double)size
));
3690 files_struct
*new_fsp
= NULL
;
3691 int access_mode
= 0;
3694 if(global_oplock_break
) {
3695 /* Queue this file modify as we are the process of an oplock break. */
3697 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3698 DEBUGADD(2,( "in oplock break state.\n"));
3700 push_oplock_pending_smb_message(inbuf
, length
);
3704 new_fsp
= open_file_shared(conn
, fname
, &sbuf
,
3705 SET_OPEN_MODE(DOS_OPEN_RDWR
),
3706 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
3707 FILE_ATTRIBUTE_NORMAL
,
3708 INTERNAL_OPEN_ONLY
, &access_mode
, &action
);
3710 if (new_fsp
== NULL
)
3711 return(UNIXERROR(ERRDOS
,ERRbadpath
));
3712 ret
= vfs_set_filelen(new_fsp
, size
);
3713 close_file(new_fsp
,True
);
3715 ret
= vfs_set_filelen(fsp
, size
);
3719 return (UNIXERROR(ERRHRD
,ERRdiskfull
));
3723 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3728 /****************************************************************************
3729 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3730 ****************************************************************************/
3732 static int call_trans2mkdir(connection_struct
*conn
,
3733 char *inbuf
, char *outbuf
, int length
, int bufsize
,
3734 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3736 char *params
= *pparams
;
3739 SMB_STRUCT_STAT sbuf
;
3740 BOOL bad_path
= False
;
3741 NTSTATUS status
= NT_STATUS_OK
;
3743 if (!CAN_WRITE(conn
))
3744 return ERROR_DOS(ERRSRV
,ERRaccess
);
3746 if (total_params
< 4)
3747 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3749 srvstr_get_path(inbuf
, directory
, ¶ms
[4], sizeof(directory
), -1, STR_TERMINATE
, &status
, False
);
3750 if (!NT_STATUS_IS_OK(status
)) {
3751 return ERROR_NT(status
);
3754 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
3756 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
3758 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
3760 if (check_name(directory
,conn
))
3761 ret
= vfs_MkDir(conn
,directory
,unix_mode(conn
,aDIR
,directory
));
3764 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno
)));
3765 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRnoaccess
);
3768 /* Realloc the parameter and data sizes */
3769 params
= Realloc(*pparams
,2);
3771 return ERROR_DOS(ERRDOS
,ERRnomem
);
3776 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3781 /****************************************************************************
3782 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3783 We don't actually do this - we just send a null response.
3784 ****************************************************************************/
3786 static int call_trans2findnotifyfirst(connection_struct
*conn
,
3787 char *inbuf
, char *outbuf
, int length
, int bufsize
,
3788 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3790 static uint16 fnf_handle
= 257;
3791 char *params
= *pparams
;
3794 if (total_params
< 6)
3795 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3797 info_level
= SVAL(params
,4);
3798 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
3800 switch (info_level
) {
3805 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3808 /* Realloc the parameter and data sizes */
3809 params
= Realloc(*pparams
,6);
3811 return ERROR_DOS(ERRDOS
,ERRnomem
);
3814 SSVAL(params
,0,fnf_handle
);
3815 SSVAL(params
,2,0); /* No changes */
3816 SSVAL(params
,4,0); /* No EA errors */
3823 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0);
3828 /****************************************************************************
3829 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3830 changes). Currently this does nothing.
3831 ****************************************************************************/
3833 static int call_trans2findnotifynext(connection_struct
*conn
,
3834 char *inbuf
, char *outbuf
, int length
, int bufsize
,
3835 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3837 char *params
= *pparams
;
3839 DEBUG(3,("call_trans2findnotifynext\n"));
3841 /* Realloc the parameter and data sizes */
3842 params
= Realloc(*pparams
,4);
3844 return ERROR_DOS(ERRDOS
,ERRnomem
);
3847 SSVAL(params
,0,0); /* No changes */
3848 SSVAL(params
,2,0); /* No EA errors */
3850 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0);
3855 /****************************************************************************
3856 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3857 ****************************************************************************/
3859 static int call_trans2getdfsreferral(connection_struct
*conn
, char* inbuf
,
3860 char* outbuf
, int length
, int bufsize
,
3861 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3863 char *params
= *pparams
;
3866 int max_referral_level
;
3868 DEBUG(10,("call_trans2getdfsreferral\n"));
3870 if (total_params
< 2)
3871 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3873 max_referral_level
= SVAL(params
,0);
3875 if(!lp_host_msdfs())
3876 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
3878 srvstr_pull(inbuf
, pathname
, ¶ms
[2], sizeof(pathname
), -1, STR_TERMINATE
);
3879 if((reply_size
= setup_dfs_referral(conn
, pathname
,max_referral_level
,ppdata
)) < 0)
3880 return UNIXERROR(ERRDOS
,ERRbadfile
);
3882 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
3883 send_trans2_replies(outbuf
,bufsize
,0,0,*ppdata
,reply_size
);
3888 #define LMCAT_SPL 0x53
3889 #define LMFUNC_GETJOBID 0x60
3891 /****************************************************************************
3892 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3893 ****************************************************************************/
3895 static int call_trans2ioctl(connection_struct
*conn
, char* inbuf
,
3896 char* outbuf
, int length
, int bufsize
,
3897 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3899 char *pdata
= *ppdata
;
3900 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv15
);
3902 /* check for an invalid fid before proceeding */
3905 return(ERROR_DOS(ERRDOS
,ERRbadfid
));
3907 if ((SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3908 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3909 pdata
= Realloc(*ppdata
, 32);
3911 return ERROR_DOS(ERRDOS
,ERRnomem
);
3914 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3915 CAN ACCEPT THIS IN UNICODE. JRA. */
3917 SSVAL(pdata
,0,fsp
->rap_print_jobid
); /* Job number */
3918 srvstr_push( outbuf
, pdata
+ 2, global_myname(), 15, STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
3919 srvstr_push( outbuf
, pdata
+18, lp_servicename(SNUM(conn
)), 13, STR_ASCII
|STR_TERMINATE
); /* Service name */
3920 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32);
3923 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3924 return ERROR_DOS(ERRSRV
,ERRerror
);
3928 /****************************************************************************
3929 Reply to a SMBfindclose (stop trans2 directory search).
3930 ****************************************************************************/
3932 int reply_findclose(connection_struct
*conn
,
3933 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3936 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
3937 START_PROFILE(SMBfindclose
);
3939 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
3941 dptr_close(&dptr_num
);
3943 outsize
= set_message(outbuf
,0,0,True
);
3945 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
3947 END_PROFILE(SMBfindclose
);
3951 /****************************************************************************
3952 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3953 ****************************************************************************/
3955 int reply_findnclose(connection_struct
*conn
,
3956 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3960 START_PROFILE(SMBfindnclose
);
3962 dptr_num
= SVAL(inbuf
,smb_vwv0
);
3964 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
3966 /* We never give out valid handles for a
3967 findnotifyfirst - so any dptr_num is ok here.
3970 outsize
= set_message(outbuf
,0,0,True
);
3972 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
3974 END_PROFILE(SMBfindnclose
);
3978 /****************************************************************************
3979 Reply to a SMBtranss2 - just ignore it!
3980 ****************************************************************************/
3982 int reply_transs2(connection_struct
*conn
,
3983 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3985 START_PROFILE(SMBtranss2
);
3986 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
3987 END_PROFILE(SMBtranss2
);
3991 /****************************************************************************
3992 Reply to a SMBtrans2.
3993 ****************************************************************************/
3995 int reply_trans2(connection_struct
*conn
,
3996 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3999 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
4000 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
4002 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
4003 unsigned int max_data_reply
= SVAL(inbuf
, smb_mdrcnt
);
4004 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
4005 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
4006 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
4007 int32 timeout
= IVALS(inbuf
,smb_timeout
);
4009 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
4010 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
4011 char *params
= NULL
, *data
= NULL
;
4012 unsigned int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
4013 START_PROFILE(SMBtrans2
);
4015 if(global_oplock_break
&& (tran_call
== TRANSACT2_OPEN
)) {
4016 /* Queue this open message as we are the process of an
4019 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4020 DEBUGADD(2,( "in oplock break state.\n"));
4022 push_oplock_pending_smb_message(inbuf
, length
);
4023 END_PROFILE(SMBtrans2
);
4027 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
4028 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
4029 END_PROFILE(SMBtrans2
);
4030 return ERROR_DOS(ERRSRV
,ERRaccess
);
4033 outsize
= set_message(outbuf
,0,0,True
);
4035 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4036 is so as a sanity check */
4039 * Need to have rc=0 for ioctl to get job id for OS/2.
4040 * Network printing will fail if function is not successful.
4041 * Similar function in reply.c will be used if protocol
4042 * is LANMAN1.0 instead of LM1.2X002.
4043 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4044 * outbuf doesn't have to be set(only job id is used).
4046 if ( (suwcnt
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
4047 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
4048 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
4049 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4051 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt
));
4052 DEBUG(2,("Transaction is %d\n",tran_call
));
4053 END_PROFILE(SMBtrans2
);
4054 ERROR_DOS(ERRDOS
,ERRinvalidparam
);
4058 /* Allocate the space for the maximum needed parameters and data */
4059 if (total_params
> 0)
4060 params
= (char *)malloc(total_params
);
4062 data
= (char *)malloc(total_data
);
4064 if ((total_params
&& !params
) || (total_data
&& !data
)) {
4065 DEBUG(2,("Out of memory in reply_trans2\n"));
4068 END_PROFILE(SMBtrans2
);
4069 return ERROR_DOS(ERRDOS
,ERRnomem
);
4072 /* Copy the param and data bytes sent with this request into
4073 the params buffer */
4074 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
4075 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
4077 if (num_params
> total_params
|| num_data
> total_data
)
4078 exit_server("invalid params in reply_trans2");
4081 unsigned int psoff
= SVAL(inbuf
, smb_psoff
);
4082 if ((psoff
+ num_params
< psoff
) || (psoff
+ num_params
< num_params
))
4084 if ((smb_base(inbuf
) + psoff
+ num_params
> inbuf
+ length
) ||
4085 (smb_base(inbuf
) + psoff
+ num_params
< smb_base(inbuf
)))
4087 memcpy( params
, smb_base(inbuf
) + psoff
, num_params
);
4090 unsigned int dsoff
= SVAL(inbuf
, smb_dsoff
);
4091 if ((dsoff
+ num_data
< dsoff
) || (dsoff
+ num_data
< num_data
))
4093 if ((smb_base(inbuf
) + dsoff
+ num_data
> inbuf
+ length
) ||
4094 (smb_base(inbuf
) + dsoff
+ num_data
< smb_base(inbuf
)))
4096 memcpy( data
, smb_base(inbuf
) + dsoff
, num_data
);
4099 srv_signing_trans_start(SVAL(inbuf
,smb_mid
));
4101 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
) {
4102 /* We need to send an interim response then receive the rest
4103 of the parameter/data bytes */
4104 outsize
= set_message(outbuf
,0,0,True
);
4105 srv_signing_trans_stop();
4106 if (!send_smb(smbd_server_fd(),outbuf
))
4107 exit_server("reply_trans2: send_smb failed.");
4109 while (num_data_sofar
< total_data
||
4110 num_params_sofar
< total_params
) {
4112 unsigned int param_disp
;
4113 unsigned int param_off
;
4114 unsigned int data_disp
;
4115 unsigned int data_off
;
4117 ret
= receive_next_smb(inbuf
,bufsize
,SMB_SECONDARY_WAIT
);
4120 * The sequence number for the trans reply is always
4121 * based on the last secondary received.
4124 srv_signing_trans_start(SVAL(inbuf
,smb_mid
));
4127 (CVAL(inbuf
, smb_com
) != SMBtranss2
)) || !ret
) {
4128 outsize
= set_message(outbuf
,0,0,True
);
4130 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4132 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4133 (smb_read_error
== READ_ERROR
) ? "error" : "timeout" ));
4137 /* Revise total_params and total_data in case
4138 they have changed downwards */
4139 if (SVAL(inbuf
, smb_tpscnt
) < total_params
)
4140 total_params
= SVAL(inbuf
, smb_tpscnt
);
4141 if (SVAL(inbuf
, smb_tdscnt
) < total_data
)
4142 total_data
= SVAL(inbuf
, smb_tdscnt
);
4144 num_params
= SVAL(inbuf
,smb_spscnt
);
4145 param_off
= SVAL(inbuf
, smb_spsoff
);
4146 param_disp
= SVAL(inbuf
, smb_spsdisp
);
4147 num_params_sofar
+= num_params
;
4149 num_data
= SVAL(inbuf
, smb_sdscnt
);
4150 data_off
= SVAL(inbuf
, smb_sdsoff
);
4151 data_disp
= SVAL(inbuf
, smb_sdsdisp
);
4152 num_data_sofar
+= num_data
;
4154 if (num_params_sofar
> total_params
|| num_data_sofar
> total_data
)
4158 if (param_disp
+ num_params
>= total_params
)
4160 if ((param_disp
+ num_params
< param_disp
) ||
4161 (param_disp
+ num_params
< num_params
))
4163 if (param_disp
> total_params
)
4165 if ((smb_base(inbuf
) + param_off
+ num_params
>= inbuf
+ bufsize
) ||
4166 (smb_base(inbuf
) + param_off
+ num_params
< smb_base(inbuf
)))
4168 if (params
+ param_disp
< params
)
4171 memcpy( ¶ms
[param_disp
], smb_base(inbuf
) + param_off
, num_params
);
4174 if (data_disp
+ num_data
>= total_data
)
4176 if ((data_disp
+ num_data
< data_disp
) ||
4177 (data_disp
+ num_data
< num_data
))
4179 if (data_disp
> total_data
)
4181 if ((smb_base(inbuf
) + data_off
+ num_data
>= inbuf
+ bufsize
) ||
4182 (smb_base(inbuf
) + data_off
+ num_data
< smb_base(inbuf
)))
4184 if (data
+ data_disp
< data
)
4187 memcpy( &data
[data_disp
], smb_base(inbuf
) + data_off
, num_data
);
4192 if (Protocol
>= PROTOCOL_NT1
) {
4193 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | 0x40); /* IS_LONG_NAME */
4196 /* Now we must call the relevant TRANS2 function */
4198 case TRANSACT2_OPEN
:
4199 START_PROFILE_NESTED(Trans2_open
);
4200 outsize
= call_trans2open(conn
, inbuf
, outbuf
, bufsize
,
4201 ¶ms
, total_params
, &data
, total_data
);
4202 END_PROFILE_NESTED(Trans2_open
);
4205 case TRANSACT2_FINDFIRST
:
4206 START_PROFILE_NESTED(Trans2_findfirst
);
4207 outsize
= call_trans2findfirst(conn
, inbuf
, outbuf
, bufsize
,
4208 ¶ms
, total_params
, &data
, total_data
);
4209 END_PROFILE_NESTED(Trans2_findfirst
);
4212 case TRANSACT2_FINDNEXT
:
4213 START_PROFILE_NESTED(Trans2_findnext
);
4214 outsize
= call_trans2findnext(conn
, inbuf
, outbuf
, length
, bufsize
,
4215 ¶ms
, total_params
, &data
, total_data
);
4216 END_PROFILE_NESTED(Trans2_findnext
);
4219 case TRANSACT2_QFSINFO
:
4220 START_PROFILE_NESTED(Trans2_qfsinfo
);
4221 outsize
= call_trans2qfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4222 ¶ms
, total_params
, &data
, total_data
);
4223 END_PROFILE_NESTED(Trans2_qfsinfo
);
4226 #ifdef HAVE_SYS_QUOTAS
4227 case TRANSACT2_SETFSINFO
:
4228 START_PROFILE_NESTED(Trans2_setfsinfo
);
4229 outsize
= call_trans2setfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4230 ¶ms
, total_params
, &data
, total_data
);
4231 END_PROFILE_NESTED(Trans2_setfsinfo
);
4234 case TRANSACT2_QPATHINFO
:
4235 case TRANSACT2_QFILEINFO
:
4236 START_PROFILE_NESTED(Trans2_qpathinfo
);
4237 outsize
= call_trans2qfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4238 ¶ms
, total_params
, &data
, total_data
);
4239 END_PROFILE_NESTED(Trans2_qpathinfo
);
4241 case TRANSACT2_SETPATHINFO
:
4242 case TRANSACT2_SETFILEINFO
:
4243 START_PROFILE_NESTED(Trans2_setpathinfo
);
4244 outsize
= call_trans2setfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4245 ¶ms
, total_params
, &data
, total_data
);
4246 END_PROFILE_NESTED(Trans2_setpathinfo
);
4249 case TRANSACT2_FINDNOTIFYFIRST
:
4250 START_PROFILE_NESTED(Trans2_findnotifyfirst
);
4251 outsize
= call_trans2findnotifyfirst(conn
, inbuf
, outbuf
, length
, bufsize
,
4252 ¶ms
, total_params
, &data
, total_data
);
4253 END_PROFILE_NESTED(Trans2_findnotifyfirst
);
4256 case TRANSACT2_FINDNOTIFYNEXT
:
4257 START_PROFILE_NESTED(Trans2_findnotifynext
);
4258 outsize
= call_trans2findnotifynext(conn
, inbuf
, outbuf
, length
, bufsize
,
4259 ¶ms
, total_params
, &data
, total_data
);
4260 END_PROFILE_NESTED(Trans2_findnotifynext
);
4262 case TRANSACT2_MKDIR
:
4263 START_PROFILE_NESTED(Trans2_mkdir
);
4264 outsize
= call_trans2mkdir(conn
, inbuf
, outbuf
, length
, bufsize
,
4265 ¶ms
, total_params
, &data
, total_data
);
4266 END_PROFILE_NESTED(Trans2_mkdir
);
4269 case TRANSACT2_GET_DFS_REFERRAL
:
4270 START_PROFILE_NESTED(Trans2_get_dfs_referral
);
4271 outsize
= call_trans2getdfsreferral(conn
,inbuf
,outbuf
,length
, bufsize
,
4272 ¶ms
, total_params
, &data
, total_data
);
4273 END_PROFILE_NESTED(Trans2_get_dfs_referral
);
4275 case TRANSACT2_IOCTL
:
4276 START_PROFILE_NESTED(Trans2_ioctl
);
4277 outsize
= call_trans2ioctl(conn
,inbuf
,outbuf
,length
, bufsize
,
4278 ¶ms
, total_params
, &data
, total_data
);
4279 END_PROFILE_NESTED(Trans2_ioctl
);
4282 /* Error in request */
4283 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call
));
4286 END_PROFILE(SMBtrans2
);
4287 srv_signing_trans_stop();
4288 return ERROR_DOS(ERRSRV
,ERRerror
);
4291 /* As we do not know how many data packets will need to be
4292 returned here the various call_trans2xxxx calls
4293 must send their own. Thus a call_trans2xxx routine only
4294 returns a value other than -1 when it wants to send
4298 srv_signing_trans_stop();
4302 END_PROFILE(SMBtrans2
);
4303 return outsize
; /* If a correct response was needed the
4304 call_trans2xxx calls have already sent
4305 it. If outsize != -1 then it is returning */
4309 srv_signing_trans_stop();
4312 END_PROFILE(SMBtrans2
);
4313 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);