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 BOOL case_sensitive
;
28 extern int smb_read_error
;
29 extern fstring local_machine
;
30 extern int global_oplock_break
;
31 extern uint32 global_client_caps
;
32 extern struct current_user current_user
;
34 #define get_file_size(sbuf) ((sbuf).st_size)
36 /* given a stat buffer return the allocated size on disk, taking into
37 account sparse files */
38 SMB_BIG_UINT
get_allocation_size(files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
41 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
42 ret
= (SMB_BIG_UINT
)STAT_ST_BLOCKSIZE
* (SMB_BIG_UINT
)sbuf
->st_blocks
;
44 ret
= (SMB_BIG_UINT
)get_file_size(*sbuf
);
46 if (!ret
&& fsp
&& fsp
->initial_allocation_size
)
47 ret
= fsp
->initial_allocation_size
;
48 ret
= SMB_ROUNDUP(ret
,SMB_ROUNDUP_ALLOCATION_SIZE
);
52 /****************************************************************************
53 Utility functions for dealing with extended attributes.
54 ****************************************************************************/
56 static const char *prohibited_ea_names
[] = {
57 SAMBA_POSIX_INHERITANCE_EA_NAME
,
61 /****************************************************************************
62 Refuse to allow clients to overwrite our private xattrs.
63 ****************************************************************************/
65 static BOOL
samba_private_attr_name(const char *unix_ea_name
)
69 for (i
= 0; prohibited_ea_names
[i
]; i
++) {
70 if (strequal( prohibited_ea_names
[i
], unix_ea_name
))
77 struct ea_list
*next
, *prev
;
81 /****************************************************************************
82 Get one EA value. Fill in a struct ea_struct.
83 ****************************************************************************/
85 static BOOL
get_ea_value(TALLOC_CTX
*mem_ctx
, connection_struct
*conn
, files_struct
*fsp
,
86 const char *fname
, char *ea_name
, struct ea_struct
*pea
)
88 /* Get the value of this xattr. Max size is 64k. */
89 size_t attr_size
= 256;
95 val
= talloc_realloc(mem_ctx
, val
, attr_size
);
100 if (fsp
&& fsp
->fd
!= -1) {
101 sizeret
= SMB_VFS_FGETXATTR(fsp
, fsp
->fd
, ea_name
, val
, attr_size
);
103 sizeret
= SMB_VFS_GETXATTR(conn
, fname
, ea_name
, val
, attr_size
);
106 if (sizeret
== -1 && errno
== ERANGE
&& attr_size
!= 65536) {
115 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name
, sizeret
));
116 dump_data(10, val
, sizeret
);
119 if (strnequal(ea_name
, "user.", 5)) {
120 pea
->name
= &ea_name
[5];
124 pea
->value
.data
= val
;
125 pea
->value
.length
= (size_t)sizeret
;
129 /****************************************************************************
130 Return a linked list of the total EA's. Plus a guess as to the total size
131 (NB. The is not the total size on the wire - we need to convert to DOS
133 ****************************************************************************/
135 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
)
137 /* Get a list of all xattrs. Max namesize is 64k. */
138 size_t ea_namelist_size
= 1024;
143 struct ea_list
*ea_list_head
= NULL
;
149 if (!lp_ea_support(SNUM(conn
))) {
153 for (i
= 0, ea_namelist
= talloc(mem_ctx
, ea_namelist_size
); i
< 6;
154 ea_namelist
= talloc_realloc(mem_ctx
, ea_namelist
, ea_namelist_size
), i
++) {
155 if (fsp
&& fsp
->fd
!= -1) {
156 sizeret
= SMB_VFS_FLISTXATTR(fsp
, fsp
->fd
, ea_namelist
, ea_namelist_size
);
158 sizeret
= SMB_VFS_LISTXATTR(conn
, fname
, ea_namelist
, ea_namelist_size
);
161 if (sizeret
== -1 && errno
== ERANGE
) {
162 ea_namelist_size
*= 2;
171 DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret
));
174 for (p
= ea_namelist
; p
- ea_namelist
< sizeret
; p
+= strlen(p
) + 1) {
175 struct ea_list
*listp
, *tmp
;
177 if (strnequal(p
, "system.", 7) || samba_private_attr_name(p
))
180 listp
= talloc(mem_ctx
, sizeof(struct ea_list
));
184 if (!get_ea_value(mem_ctx
, conn
, fsp
, fname
, p
, &listp
->ea
)) {
189 *pea_total_len
+= 4 + strlen(p
) + 1 + listp
->ea
.value
.length
;
191 DLIST_ADD_END(ea_list_head
, listp
, tmp
);
195 /* Add on 4 for total length. */
202 /****************************************************************************
203 Fill a qfilepathinfo buffer with EA's.
204 ****************************************************************************/
206 static unsigned int fill_ea_buffer(char *pdata
, unsigned int total_data_size
,
207 connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
209 unsigned int ret_data_size
= 4;
212 TALLOC_CTX
*mem_ctx
= talloc_init("fill_ea_buffer");
213 struct ea_list
*ea_list
= get_ea_list(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
215 SMB_ASSERT(total_data_size
>= 4);
223 talloc_destroy(mem_ctx
);
227 if (total_ea_len
> total_data_size
) {
228 talloc_destroy(mem_ctx
);
232 total_data_size
-= 4;
233 for (p
= pdata
+ 4; ea_list
; ea_list
= ea_list
->next
) {
236 push_ascii_fstring(dos_ea_name
, ea_list
->ea
.name
);
237 dos_namelen
= strlen(dos_ea_name
);
238 if (dos_namelen
> 255 || dos_namelen
== 0) {
241 if (ea_list
->ea
.value
.length
> 65535) {
244 if (4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
> total_data_size
) {
248 /* We know we have room. */
249 SCVAL(p
,0,ea_list
->ea
.flags
);
250 SCVAL(p
,1,dos_namelen
);
251 SSVAL(p
,2,ea_list
->ea
.value
.length
);
252 fstrcpy(p
+4, dos_ea_name
);
253 memcpy( p
+ 4 + dos_namelen
+ 1, ea_list
->ea
.value
.data
, ea_list
->ea
.value
.length
);
255 total_data_size
-= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
256 p
+= 4 + dos_namelen
+ 1 + ea_list
->ea
.value
.length
;
259 ret_data_size
= PTR_DIFF(p
, pdata
);
260 talloc_destroy(mem_ctx
);
261 SIVAL(pdata
,0,ret_data_size
);
262 return ret_data_size
;
265 static unsigned int estimate_ea_size(connection_struct
*conn
, files_struct
*fsp
, const char *fname
)
267 size_t total_ea_len
= 0;
268 TALLOC_CTX
*mem_ctx
= talloc_init("estimate_ea_size");
270 (void)get_ea_list(mem_ctx
, conn
, fsp
, fname
, &total_ea_len
);
271 talloc_destroy(mem_ctx
);
275 /****************************************************************************
276 Set or delete an extended attribute.
277 ****************************************************************************/
279 static NTSTATUS
set_ea(connection_struct
*conn
, files_struct
*fsp
, const char *fname
,
280 char *pdata
, int total_data
)
282 unsigned int namelen
;
285 fstring unix_ea_name
;
287 if (!lp_ea_support(SNUM(conn
))) {
288 return NT_STATUS_EAS_NOT_SUPPORTED
;
291 if (total_data
< 8) {
292 return NT_STATUS_INVALID_PARAMETER
;
295 if (IVAL(pdata
,0) > total_data
) {
296 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata
,0), (unsigned int)total_data
));
297 return NT_STATUS_INVALID_PARAMETER
;
301 namelen
= CVAL(pdata
,1);
302 ealen
= SVAL(pdata
,2);
304 if (total_data
< 8 + namelen
+ 1 + ealen
) {
305 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
306 (unsigned int)total_data
, namelen
, ealen
));
307 return NT_STATUS_INVALID_PARAMETER
;
310 if (pdata
[namelen
] != '\0') {
311 DEBUG(10,("set_ea: ea name not null terminated\n"));
312 return NT_STATUS_INVALID_PARAMETER
;
315 fstrcpy(unix_ea_name
, "user."); /* All EA's must start with user. */
316 pull_ascii(&unix_ea_name
[5], pdata
, sizeof(fstring
) - 5, -1, STR_TERMINATE
);
317 pdata
+= (namelen
+ 1);
319 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name
, ealen
));
321 DEBUG(10,("set_ea: data :\n"));
322 dump_data(10, pdata
, ealen
);
325 if (samba_private_attr_name(unix_ea_name
)) {
326 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name
));
327 return NT_STATUS_ACCESS_DENIED
;
331 /* Remove the attribute. */
332 if (fsp
&& (fsp
->fd
!= -1)) {
333 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
334 unix_ea_name
, fsp
->fsp_name
));
335 ret
= SMB_VFS_FREMOVEXATTR(fsp
, fsp
->fd
, unix_ea_name
);
337 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
338 unix_ea_name
, fname
));
339 ret
= SMB_VFS_REMOVEXATTR(conn
, fname
, unix_ea_name
);
342 /* Removing a non existent attribute always succeeds. */
343 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name
));
344 if (ret
== -1 && errno
== ENOATTR
) {
349 if (fsp
&& (fsp
->fd
!= -1)) {
350 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
351 unix_ea_name
, fsp
->fsp_name
));
352 ret
= SMB_VFS_FSETXATTR(fsp
, fsp
->fd
, unix_ea_name
, pdata
, ealen
, 0);
354 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
355 unix_ea_name
, fname
));
356 ret
= SMB_VFS_SETXATTR(conn
, fname
, unix_ea_name
, pdata
, ealen
, 0);
361 if (errno
== ENOTSUP
) {
362 return NT_STATUS_EAS_NOT_SUPPORTED
;
364 return map_nt_error_from_unix(errno
);
370 /****************************************************************************
371 Send the required number of replies back.
372 We assume all fields other than the data fields are
373 set correctly for the type of call.
374 HACK ! Always assumes smb_setup field is zero.
375 ****************************************************************************/
377 static int send_trans2_replies(char *outbuf
,
384 /* As we are using a protocol > LANMAN1 then the max_send
385 variable must have been set in the sessetupX call.
386 This takes precedence over the max_xmit field in the
387 global struct. These different max_xmit variables should
388 be merged as this is now too confusing */
391 int data_to_send
= datasize
;
392 int params_to_send
= paramsize
;
396 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
397 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
398 int data_alignment_offset
= 0;
400 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
402 set_message(outbuf
,10,0,True
);
404 /* If there genuinely are no parameters or data to send just send the empty packet */
406 if(params_to_send
== 0 && data_to_send
== 0) {
407 if (!send_smb(smbd_server_fd(),outbuf
))
408 exit_server("send_trans2_replies: send_smb failed.");
412 /* When sending params and data ensure that both are nicely aligned */
413 /* Only do this alignment when there is also data to send - else
414 can cause NT redirector problems. */
416 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
417 data_alignment_offset
= 4 - (params_to_send
% 4);
419 /* Space is bufsize minus Netbios over TCP header minus SMB header */
420 /* The alignment_offset is to align the param bytes on an even byte
421 boundary. NT 4.0 Beta needs this to work correctly. */
423 useable_space
= bufsize
- ((smb_buf(outbuf
)+ alignment_offset
+data_alignment_offset
) - outbuf
);
425 /* useable_space can never be more than max_send minus the alignment offset. */
427 useable_space
= MIN(useable_space
, max_send
- (alignment_offset
+data_alignment_offset
));
429 while (params_to_send
|| data_to_send
) {
430 /* Calculate whether we will totally or partially fill this packet */
432 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
+ data_alignment_offset
;
434 /* We can never send more than useable_space */
436 * Note that 'useable_space' does not include the alignment offsets,
437 * but we must include the alignment offsets in the calculation of
438 * the length of the data we send over the wire, as the alignment offsets
439 * are sent here. Fix from Marc_Jacobsen@hp.com.
442 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
+ alignment_offset
+ data_alignment_offset
);
444 set_message(outbuf
, 10, total_sent_thistime
, True
);
446 /* Set total params and data to be sent */
447 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
448 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
450 /* Calculate how many parameters and data we can fit into
451 * this packet. Parameters get precedence
454 params_sent_thistime
= MIN(params_to_send
,useable_space
);
455 data_sent_thistime
= useable_space
- params_sent_thistime
;
456 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
458 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
460 /* smb_proff is the offset from the start of the SMB header to the
461 parameter bytes, however the first 4 bytes of outbuf are
462 the Netbios over TCP header. Thus use smb_base() to subtract
463 them from the calculation */
465 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
467 if(params_sent_thistime
== 0)
468 SSVAL(outbuf
,smb_prdisp
,0);
470 /* Absolute displacement of param bytes sent in this packet */
471 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
473 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
474 if(data_sent_thistime
== 0) {
475 SSVAL(outbuf
,smb_droff
,0);
476 SSVAL(outbuf
,smb_drdisp
, 0);
478 /* The offset of the data bytes is the offset of the
479 parameter bytes plus the number of parameters being sent this time */
480 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
481 smb_base(outbuf
)) + params_sent_thistime
+ data_alignment_offset
);
482 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
485 /* Copy the param bytes into the packet */
487 if(params_sent_thistime
)
488 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
490 /* Copy in the data bytes */
491 if(data_sent_thistime
)
492 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
+
493 data_alignment_offset
,pd
,data_sent_thistime
);
495 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
496 params_sent_thistime
, data_sent_thistime
, useable_space
));
497 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
498 params_to_send
, data_to_send
, paramsize
, datasize
));
500 /* Send the packet */
501 if (!send_smb(smbd_server_fd(),outbuf
))
502 exit_server("send_trans2_replies: send_smb failed.");
504 pp
+= params_sent_thistime
;
505 pd
+= data_sent_thistime
;
507 params_to_send
-= params_sent_thistime
;
508 data_to_send
-= data_sent_thistime
;
511 if(params_to_send
< 0 || data_to_send
< 0) {
512 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
513 params_to_send
, data_to_send
));
521 /****************************************************************************
522 Reply to a TRANSACT2_OPEN.
523 ****************************************************************************/
525 static int call_trans2open(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
526 char **pparams
, int total_params
, char **ppdata
, int total_data
)
528 char *params
= *pparams
;
533 BOOL return_additional_info
;
543 int fmode
=0,mtime
=0,rmode
;
545 SMB_STRUCT_STAT sbuf
;
547 BOOL bad_path
= False
;
552 * Ensure we have enough parameters to perform the operation.
555 if (total_params
< 29)
556 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
558 open_mode
= SVAL(params
, 2);
559 open_attr
= SVAL(params
,6);
560 oplock_request
= (((SVAL(params
,0)|(1<<1))>>1) | ((SVAL(params
,0)|(1<<2))>>1));
562 return_additional_info
= BITSETW(params
,0);
563 open_sattr
= SVAL(params
, 4);
564 open_time
= make_unix_date3(params
+8);
566 open_ofun
= SVAL(params
,12);
567 open_size
= IVAL(params
,14);
571 return(ERROR_DOS(ERRSRV
,ERRaccess
));
573 srvstr_get_path(inbuf
, fname
, pname
, sizeof(fname
), -1, STR_TERMINATE
, &status
);
574 if (!NT_STATUS_IS_OK(status
)) {
575 return ERROR_NT(status
);
578 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
579 fname
,open_mode
, open_attr
, open_ofun
, open_size
));
581 /* XXXX we need to handle passed times, sattr and flags */
583 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
585 if (!check_name(fname
,conn
)) {
586 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRnoaccess
);
589 unixmode
= unix_mode(conn
,open_attr
| aARCH
, fname
);
591 fsp
= open_file_shared(conn
,fname
,&sbuf
,open_mode
,open_ofun
,unixmode
,
592 oplock_request
, &rmode
,&smb_action
);
595 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRnoaccess
);
598 size
= get_file_size(sbuf
);
599 fmode
= dos_mode(conn
,fname
,&sbuf
);
600 mtime
= sbuf
.st_mtime
;
603 close_file(fsp
,False
);
604 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
607 /* Realloc the size of parameters and data we will return */
608 params
= Realloc(*pparams
, 28);
610 return(ERROR_DOS(ERRDOS
,ERRnomem
));
613 memset((char *)params
,'\0',28);
614 SSVAL(params
,0,fsp
->fnum
);
615 SSVAL(params
,2,fmode
);
616 put_dos_date2(params
,4, mtime
);
617 SIVAL(params
,8, (uint32
)size
);
618 SSVAL(params
,12,rmode
);
620 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
621 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
623 SSVAL(params
,18,smb_action
);
626 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
628 SIVAL(params
,20,inode
);
630 /* Send the required number of replies */
631 send_trans2_replies(outbuf
, bufsize
, params
, 28, *ppdata
, 0);
636 /*********************************************************
637 Routine to check if a given string matches exactly.
638 as a special case a mask of "." does NOT match. That
639 is required for correct wildcard semantics
640 Case can be significant or not.
641 **********************************************************/
643 static BOOL
exact_match(char *str
,char *mask
, BOOL case_sig
)
645 if (mask
[0] == '.' && mask
[1] == 0)
648 return strcmp(str
,mask
)==0;
649 if (StrCaseCmp(str
,mask
) != 0) {
652 if (ms_has_wild(str
)) {
658 /****************************************************************************
659 Return the filetype for UNIX extensions.
660 ****************************************************************************/
662 static uint32
unix_filetype(mode_t mode
)
665 return UNIX_TYPE_FILE
;
666 else if(S_ISDIR(mode
))
667 return UNIX_TYPE_DIR
;
669 else if(S_ISLNK(mode
))
670 return UNIX_TYPE_SYMLINK
;
673 else if(S_ISCHR(mode
))
674 return UNIX_TYPE_CHARDEV
;
677 else if(S_ISBLK(mode
))
678 return UNIX_TYPE_BLKDEV
;
681 else if(S_ISFIFO(mode
))
682 return UNIX_TYPE_FIFO
;
685 else if(S_ISSOCK(mode
))
686 return UNIX_TYPE_SOCKET
;
689 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode
));
690 return UNIX_TYPE_UNKNOWN
;
693 /****************************************************************************
694 Return the major devicenumber for UNIX extensions.
695 ****************************************************************************/
697 static uint32
unix_dev_major(SMB_DEV_T dev
)
699 #if defined(HAVE_DEVICE_MAJOR_FN)
700 return (uint32
)major(dev
);
702 return (uint32
)(dev
>> 8);
706 /****************************************************************************
707 Return the minor devicenumber for UNIX extensions.
708 ****************************************************************************/
710 static uint32
unix_dev_minor(SMB_DEV_T dev
)
712 #if defined(HAVE_DEVICE_MINOR_FN)
713 return (uint32
)minor(dev
);
715 return (uint32
)(dev
& 0xff);
719 /****************************************************************************
720 Map wire perms onto standard UNIX permissions. Obey share restrictions.
721 ****************************************************************************/
723 static mode_t
unix_perms_from_wire( connection_struct
*conn
, SMB_STRUCT_STAT
*pst
, uint32 perms
)
727 if (perms
== SMB_MODE_NO_CHANGE
)
730 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
731 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
732 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
733 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
734 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
735 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
736 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
737 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
738 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
740 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
743 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
746 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
749 if (VALID_STAT(*pst
) && S_ISDIR(pst
->st_mode
)) {
750 ret
&= lp_dir_mask(SNUM(conn
));
751 /* Add in force bits */
752 ret
|= lp_force_dir_mode(SNUM(conn
));
754 /* Apply mode mask */
755 ret
&= lp_create_mask(SNUM(conn
));
756 /* Add in force bits */
757 ret
|= lp_force_create_mode(SNUM(conn
));
763 /****************************************************************************
764 Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
765 ****************************************************************************/
767 time_t interpret_long_unix_date(char *p
)
769 DEBUG(1,("interpret_long_unix_date\n"));
770 if(IVAL(p
,0) == SMB_TIME_NO_CHANGE_LO
&&
771 IVAL(p
,4) == SMB_TIME_NO_CHANGE_HI
) {
774 return interpret_long_date(p
);
778 /****************************************************************************
779 Get a level dependent lanman2 dir entry.
780 ****************************************************************************/
782 static BOOL
get_lanman2_dir_entry(connection_struct
*conn
,
783 void *inbuf
, void *outbuf
,
784 char *path_mask
,int dirtype
,int info_level
,
785 int requires_resume_key
,
786 BOOL dont_descend
,char **ppdata
,
787 char *base_data
, int space_remaining
,
788 BOOL
*out_of_space
, BOOL
*got_exact_match
,
793 SMB_STRUCT_STAT sbuf
;
797 char *p
, *q
, *pdata
= *ppdata
;
801 SMB_OFF_T file_size
= 0;
802 SMB_BIG_UINT allocation_size
= 0;
804 time_t mdate
=0, adate
=0, cdate
=0;
807 int nt_extmode
; /* Used for NT connections instead of mode */
808 BOOL needslash
= ( conn
->dirpath
[strlen(conn
->dirpath
) -1] != '/');
811 *out_of_space
= False
;
812 *got_exact_match
= False
;
817 p
= strrchr_m(path_mask
,'/');
824 pstrcpy(mask
, path_mask
);
829 /* Needed if we run out of space */
830 prev_dirpos
= TellDir(conn
->dirptr
);
831 dname
= ReadDirName(conn
->dirptr
);
834 * Due to bugs in NT client redirectors we are not using
835 * resume keys any more - set them to zero.
836 * Check out the related comments in findfirst/findnext.
842 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
843 (long)conn
->dirptr
,TellDir(conn
->dirptr
)));
848 pstrcpy(fname
,dname
);
850 if(!(got_match
= *got_exact_match
= exact_match(fname
, mask
, case_sensitive
)))
851 got_match
= mask_match(fname
, mask
, case_sensitive
);
853 if(!got_match
&& !mangle_is_8_3(fname
, False
)) {
856 * It turns out that NT matches wildcards against
857 * both long *and* short names. This may explain some
858 * of the wildcard wierdness from old DOS clients
859 * that some people have been seeing.... JRA.
863 pstrcpy( newname
, fname
);
864 mangle_map( newname
, True
, False
, SNUM(conn
));
865 if(!(got_match
= *got_exact_match
= exact_match(newname
, mask
, case_sensitive
)))
866 got_match
= mask_match(newname
, mask
, case_sensitive
);
870 BOOL isdots
= (strequal(fname
,"..") || strequal(fname
,"."));
871 if (dont_descend
&& !isdots
)
874 pstrcpy(pathreal
,conn
->dirpath
);
876 pstrcat(pathreal
,"/");
877 pstrcat(pathreal
,dname
);
879 if (INFO_LEVEL_IS_UNIX(info_level
)) {
880 if (SMB_VFS_LSTAT(conn
,pathreal
,&sbuf
) != 0) {
881 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
882 pathreal
,strerror(errno
)));
885 } else if (SMB_VFS_STAT(conn
,pathreal
,&sbuf
) != 0) {
887 /* Needed to show the msdfs symlinks as
890 if(lp_host_msdfs() &&
891 lp_msdfs_root(SNUM(conn
)) &&
892 is_msdfs_link(conn
, pathreal
, NULL
, NULL
,
895 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal
));
896 sbuf
.st_mode
= (sbuf
.st_mode
& 0xFFF) | S_IFDIR
;
900 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
901 pathreal
,strerror(errno
)));
906 mode
= dos_mode(conn
,pathreal
,&sbuf
);
908 if (!dir_check_ftype(conn
,mode
,&sbuf
,dirtype
)) {
909 DEBUG(5,("[%s] attribs didn't match %x\n",fname
,dirtype
));
913 file_size
= get_file_size(sbuf
);
914 allocation_size
= get_allocation_size(NULL
,&sbuf
);
915 mdate
= sbuf
.st_mtime
;
916 adate
= sbuf
.st_atime
;
917 cdate
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
919 if (lp_dos_filetime_resolution(SNUM(conn
))) {
928 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal
,fname
));
934 mangle_map(fname
,False
,True
,SNUM(conn
));
939 nt_extmode
= mode
? mode
: FILE_ATTRIBUTE_NORMAL
;
941 switch (info_level
) {
942 case SMB_INFO_STANDARD
:
943 if(requires_resume_key
) {
947 put_dos_date2(p
,l1_fdateCreation
,cdate
);
948 put_dos_date2(p
,l1_fdateLastAccess
,adate
);
949 put_dos_date2(p
,l1_fdateLastWrite
,mdate
);
950 SIVAL(p
,l1_cbFile
,(uint32
)file_size
);
951 SIVAL(p
,l1_cbFileAlloc
,(uint32
)allocation_size
);
952 SSVAL(p
,l1_attrFile
,mode
);
955 p
+= align_string(outbuf
, p
, 0);
956 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
957 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)
958 SCVAL(nameptr
, -1, len
-2);
960 SCVAL(nameptr
, -1, len
-1);
964 case SMB_INFO_QUERY_EA_SIZE
:
965 if(requires_resume_key
) {
969 put_dos_date2(p
,l2_fdateCreation
,cdate
);
970 put_dos_date2(p
,l2_fdateLastAccess
,adate
);
971 put_dos_date2(p
,l2_fdateLastWrite
,mdate
);
972 SIVAL(p
,l2_cbFile
,(uint32
)file_size
);
973 SIVAL(p
,l2_cbFileAlloc
,(uint32
)allocation_size
);
974 SSVAL(p
,l2_attrFile
,mode
);
975 SIVAL(p
,l2_cbList
,0); /* No extended attributes */
978 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
| STR_NOALIGN
);
979 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)
980 SCVAL(nameptr
, -1, len
-2);
982 SCVAL(nameptr
, -1, len
-1);
986 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
987 was_8_3
= mangle_is_8_3(fname
, True
);
989 SIVAL(p
,0,reskey
); p
+= 4;
990 put_long_date(p
,cdate
); p
+= 8;
991 put_long_date(p
,adate
); p
+= 8;
992 put_long_date(p
,mdate
); p
+= 8;
993 put_long_date(p
,mdate
); p
+= 8;
994 SOFF_T(p
,0,file_size
);
995 SOFF_T(p
,8,allocation_size
);
997 SIVAL(p
,0,nt_extmode
); p
+= 4;
999 SIVAL(p
,0,0); p
+= 4;
1000 /* Clear the short name buffer. This is
1001 * IMPORTANT as not doing so will trigger
1002 * a Win2k client bug. JRA.
1005 if (!was_8_3
&& lp_manglednames(SNUM(conn
))) {
1006 pstring mangled_name
;
1007 pstrcpy(mangled_name
, fname
);
1008 mangle_map(mangled_name
,True
,True
,SNUM(conn
));
1009 mangled_name
[12] = 0;
1010 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
|STR_UNICODE
);
1017 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1020 len
= PTR_DIFF(p
, pdata
);
1021 len
= (len
+ 3) & ~3;
1026 case SMB_FIND_FILE_DIRECTORY_INFO
:
1028 SIVAL(p
,0,reskey
); p
+= 4;
1029 put_long_date(p
,cdate
); p
+= 8;
1030 put_long_date(p
,adate
); p
+= 8;
1031 put_long_date(p
,mdate
); p
+= 8;
1032 put_long_date(p
,mdate
); p
+= 8;
1033 SOFF_T(p
,0,file_size
);
1034 SOFF_T(p
,8,allocation_size
);
1036 SIVAL(p
,0,nt_extmode
); p
+= 4;
1038 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1041 len
= PTR_DIFF(p
, pdata
);
1042 len
= (len
+ 3) & ~3;
1047 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1049 SIVAL(p
,0,reskey
); p
+= 4;
1050 put_long_date(p
,cdate
); p
+= 8;
1051 put_long_date(p
,adate
); p
+= 8;
1052 put_long_date(p
,mdate
); p
+= 8;
1053 put_long_date(p
,mdate
); p
+= 8;
1054 SOFF_T(p
,0,file_size
);
1055 SOFF_T(p
,8,allocation_size
);
1057 SIVAL(p
,0,nt_extmode
);
1060 SIVAL(p
,4,0); /* ea size */
1061 len
= srvstr_push(outbuf
, p
+8, fname
, -1, STR_TERMINATE_ASCII
);
1065 len
= PTR_DIFF(p
, pdata
);
1066 len
= (len
+ 3) & ~3;
1071 case SMB_FIND_FILE_NAMES_INFO
:
1073 SIVAL(p
,0,reskey
); p
+= 4;
1075 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1076 acl on a dir (tridge) */
1077 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1080 len
= PTR_DIFF(p
, pdata
);
1081 len
= (len
+ 3) & ~3;
1086 case SMB_FIND_FILE_LEVEL_261
:
1088 SIVAL(p
,0,reskey
); p
+= 4;
1089 put_long_date(p
,cdate
); p
+= 8;
1090 put_long_date(p
,adate
); p
+= 8;
1091 put_long_date(p
,mdate
); p
+= 8;
1092 put_long_date(p
,mdate
); p
+= 8;
1093 SOFF_T(p
,0,file_size
);
1094 SOFF_T(p
,8,allocation_size
);
1096 SIVAL(p
,0,nt_extmode
);
1098 len
= srvstr_push(outbuf
, p
+ 20, fname
, -1, STR_TERMINATE_ASCII
);
1100 memset(p
+4,'\0',16); /* EA size. Unknown 0 1 2 */
1101 p
+= 20 + len
; /* Strlen, EA size. Unknown 0 1 2, string itself */
1102 len
= PTR_DIFF(p
, pdata
);
1103 len
= (len
+ 3) & ~3;
1108 case SMB_FIND_FILE_LEVEL_262
:
1109 was_8_3
= mangle_is_8_3(fname
, True
);
1111 SIVAL(p
,0,reskey
); p
+= 4;
1112 put_long_date(p
,cdate
); p
+= 8;
1113 put_long_date(p
,adate
); p
+= 8;
1114 put_long_date(p
,mdate
); p
+= 8;
1115 put_long_date(p
,mdate
); p
+= 8;
1116 SOFF_T(p
,0,file_size
);
1117 SOFF_T(p
,8,allocation_size
);
1119 SIVAL(p
,0,nt_extmode
); p
+= 4;
1121 SIVAL(p
,0,0); p
+= 4;
1122 /* Clear the short name buffer. This is
1123 * IMPORTANT as not doing so will trigger
1124 * a Win2k client bug. JRA.
1127 if (!was_8_3
&& lp_manglednames(SNUM(conn
))) {
1128 pstring mangled_name
;
1129 pstrcpy(mangled_name
, fname
);
1130 mangle_map(mangled_name
,True
,True
,SNUM(conn
));
1131 mangled_name
[12] = 0;
1132 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
|STR_UNICODE
);
1139 memset(p
, '\0', 10); /* 2 4 byte unknowns plus a zero reserved. */
1141 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE_ASCII
);
1144 len
= PTR_DIFF(p
, pdata
);
1145 len
= (len
+ 3) & ~3;
1150 /* CIFS UNIX Extension. */
1152 case SMB_FIND_FILE_UNIX
:
1154 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
1156 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1157 SOFF_T(p
,0,get_file_size(sbuf
)); /* File size 64 Bit */
1160 SOFF_T(p
,0,get_allocation_size(NULL
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
1163 put_long_date(p
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
1164 put_long_date(p
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
1165 put_long_date(p
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
1168 SIVAL(p
,0,sbuf
.st_uid
); /* user id for the owner */
1172 SIVAL(p
,0,sbuf
.st_gid
); /* group id of owner */
1176 SIVAL(p
,0,unix_filetype(sbuf
.st_mode
));
1179 SIVAL(p
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
1183 SIVAL(p
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
1187 SINO_T(p
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
1190 SIVAL(p
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
1194 SIVAL(p
,0,sbuf
.st_nlink
); /* number of hard links */
1198 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
1201 len
= PTR_DIFF(p
, pdata
);
1202 len
= (len
+ 3) & ~3;
1203 SIVAL(pdata
,0,len
); /* Offset from this structure to the beginning of the next one */
1205 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1214 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
1215 /* Move the dirptr back to prev_dirpos */
1216 SeekDir(conn
->dirptr
, prev_dirpos
);
1217 *out_of_space
= True
;
1218 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1219 return False
; /* Not finished - just out of space */
1222 /* Setup the last_filename pointer, as an offset from base_data */
1223 *last_name_off
= PTR_DIFF(nameptr
,base_data
);
1224 /* Advance the data pointer to the next slot */
1230 /****************************************************************************
1231 Reply to a TRANS2_FINDFIRST.
1232 ****************************************************************************/
1234 static int call_trans2findfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
1235 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1237 /* We must be careful here that we don't return more than the
1238 allowed number of data bytes. If this means returning fewer than
1239 maxentries then so be it. We assume that the redirector has
1240 enough room for the fixed number of parameter bytes it has
1242 uint32 max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1243 char *params
= *pparams
;
1244 char *pdata
= *ppdata
;
1245 int dirtype
= SVAL(params
,0);
1246 int maxentries
= SVAL(params
,2);
1247 BOOL close_after_first
= BITSETW(params
+4,0);
1248 BOOL close_if_end
= BITSETW(params
+4,1);
1249 BOOL requires_resume_key
= BITSETW(params
+4,2);
1250 int info_level
= SVAL(params
,6);
1254 int last_name_off
=0;
1258 BOOL finished
= False
;
1259 BOOL dont_descend
= False
;
1260 BOOL out_of_space
= False
;
1261 int space_remaining
;
1262 BOOL bad_path
= False
;
1263 SMB_STRUCT_STAT sbuf
;
1264 NTSTATUS ntstatus
= NT_STATUS_OK
;
1266 if (total_params
< 12)
1267 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1269 *directory
= *mask
= 0;
1271 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1272 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
1273 dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
1274 info_level
, max_data_bytes
));
1276 switch (info_level
) {
1277 case SMB_INFO_STANDARD
:
1278 case SMB_INFO_QUERY_EA_SIZE
:
1279 case SMB_FIND_FILE_DIRECTORY_INFO
:
1280 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1281 case SMB_FIND_FILE_NAMES_INFO
:
1282 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1283 case SMB_FIND_FILE_LEVEL_261
:
1284 case SMB_FIND_FILE_LEVEL_262
:
1286 case SMB_FIND_FILE_UNIX
:
1287 if (!lp_unix_extensions())
1288 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1291 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1294 srvstr_get_path(inbuf
, directory
, params
+12, sizeof(directory
), -1, STR_TERMINATE
, &ntstatus
);
1295 if (!NT_STATUS_IS_OK(ntstatus
)) {
1296 return ERROR_NT(ntstatus
);
1299 RESOLVE_FINDFIRST_DFSPATH(directory
, conn
, inbuf
, outbuf
);
1301 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
1302 if(!check_name(directory
,conn
)) {
1303 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
1306 p
= strrchr_m(directory
,'/');
1308 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1309 if((directory
[0] == '.') && (directory
[1] == '\0'))
1312 pstrcpy(mask
,directory
);
1313 pstrcpy(directory
,"./");
1319 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
1321 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
1323 return(ERROR_DOS(ERRDOS
,ERRnomem
));
1326 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1328 /* Realloc the params space */
1329 params
= Realloc(*pparams
, 10);
1331 return ERROR_DOS(ERRDOS
,ERRnomem
);
1334 dptr_num
= dptr_create(conn
,directory
, False
, True
,SVAL(inbuf
,smb_pid
));
1336 return(UNIXERROR(ERRDOS
,ERRbadfile
));
1338 /* Save the wildcard match and attribs we are using on this directory -
1339 needed as lanman2 assumes these are being saved between calls */
1341 if(!(wcard
= strdup(mask
))) {
1342 dptr_close(&dptr_num
);
1343 return ERROR_DOS(ERRDOS
,ERRnomem
);
1346 dptr_set_wcard(dptr_num
, wcard
);
1347 dptr_set_attr(dptr_num
, dirtype
);
1349 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num
, wcard
, dirtype
));
1351 /* We don't need to check for VOL here as this is returned by
1352 a different TRANS2 call. */
1354 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1355 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
1356 dont_descend
= True
;
1359 space_remaining
= max_data_bytes
;
1360 out_of_space
= False
;
1362 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
1363 BOOL got_exact_match
= False
;
1365 /* this is a heuristic to avoid seeking the dirptr except when
1366 absolutely necessary. It allows for a filename of about 40 chars */
1367 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1368 out_of_space
= True
;
1371 finished
= !get_lanman2_dir_entry(conn
,
1373 mask
,dirtype
,info_level
,
1374 requires_resume_key
,dont_descend
,
1375 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1379 if (finished
&& out_of_space
)
1382 if (!finished
&& !out_of_space
)
1386 * As an optimisation if we know we aren't looking
1387 * for a wildcard name (ie. the name matches the wildcard exactly)
1388 * then we can finish on any (first) match.
1389 * This speeds up large directory searches. JRA.
1395 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1398 /* Check if we can close the dirptr */
1399 if(close_after_first
|| (finished
&& close_if_end
)) {
1400 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
1401 dptr_close(&dptr_num
);
1405 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1406 * from observation of NT.
1409 if(numentries
== 0) {
1410 dptr_close(&dptr_num
);
1411 return ERROR_DOS(ERRDOS
,ERRbadfile
);
1414 /* At this point pdata points to numentries directory entries. */
1416 /* Set up the return parameter block */
1417 SSVAL(params
,0,dptr_num
);
1418 SSVAL(params
,2,numentries
);
1419 SSVAL(params
,4,finished
);
1420 SSVAL(params
,6,0); /* Never an EA error */
1421 SSVAL(params
,8,last_name_off
);
1423 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
));
1425 if ((! *directory
) && dptr_path(dptr_num
))
1426 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1428 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1429 smb_fn_name(CVAL(inbuf
,smb_com
)),
1430 mask
, directory
, dirtype
, numentries
) );
1433 * Force a name mangle here to ensure that the
1434 * mask as an 8.3 name is top of the mangled cache.
1435 * The reasons for this are subtle. Don't remove
1436 * this code unless you know what you are doing
1437 * (see PR#13758). JRA.
1440 if(!mangle_is_8_3_wildcards( mask
, False
))
1441 mangle_map(mask
, True
, True
, SNUM(conn
));
1446 /****************************************************************************
1447 Reply to a TRANS2_FINDNEXT.
1448 ****************************************************************************/
1450 static int call_trans2findnext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1451 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1453 /* We must be careful here that we don't return more than the
1454 allowed number of data bytes. If this means returning fewer than
1455 maxentries then so be it. We assume that the redirector has
1456 enough room for the fixed number of parameter bytes it has
1458 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1459 char *params
= *pparams
;
1460 char *pdata
= *ppdata
;
1461 int dptr_num
= SVAL(params
,0);
1462 int maxentries
= SVAL(params
,2);
1463 uint16 info_level
= SVAL(params
,4);
1464 uint32 resume_key
= IVAL(params
,6);
1465 BOOL close_after_request
= BITSETW(params
+10,0);
1466 BOOL close_if_end
= BITSETW(params
+10,1);
1467 BOOL requires_resume_key
= BITSETW(params
+10,2);
1468 BOOL continue_bit
= BITSETW(params
+10,3);
1469 pstring resume_name
;
1475 int i
, last_name_off
=0;
1476 BOOL finished
= False
;
1477 BOOL dont_descend
= False
;
1478 BOOL out_of_space
= False
;
1479 int space_remaining
;
1480 NTSTATUS ntstatus
= NT_STATUS_OK
;
1482 if (total_params
< 12)
1483 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1485 *mask
= *directory
= *resume_name
= 0;
1487 srvstr_get_path(inbuf
, resume_name
, params
+12, sizeof(resume_name
), -1, STR_TERMINATE
, &ntstatus
);
1488 if (!NT_STATUS_IS_OK(ntstatus
)) {
1489 return ERROR_NT(ntstatus
);
1492 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1493 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1494 resume_key = %d resume name = %s continue=%d level = %d\n",
1495 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
1496 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
1498 switch (info_level
) {
1499 case SMB_INFO_STANDARD
:
1500 case SMB_INFO_QUERY_EA_SIZE
:
1501 case SMB_FIND_FILE_DIRECTORY_INFO
:
1502 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1503 case SMB_FIND_FILE_NAMES_INFO
:
1504 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1506 case SMB_FIND_FILE_UNIX
:
1507 if (!lp_unix_extensions())
1508 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1511 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1514 pdata
= Realloc( *ppdata
, max_data_bytes
+ 1024);
1516 return ERROR_DOS(ERRDOS
,ERRnomem
);
1519 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1521 /* Realloc the params space */
1522 params
= Realloc(*pparams
, 6*SIZEOFWORD
);
1523 if( params
== NULL
)
1524 return ERROR_DOS(ERRDOS
,ERRnomem
);
1528 /* Check that the dptr is valid */
1529 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
)))
1530 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1532 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1534 /* Get the wildcard mask from the dptr */
1535 if((p
= dptr_wcard(dptr_num
))== NULL
) {
1536 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
1537 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1541 pstrcpy(directory
,conn
->dirpath
);
1543 /* Get the attr mask from the dptr */
1544 dirtype
= dptr_attr(dptr_num
);
1546 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1547 dptr_num
, mask
, dirtype
,
1549 TellDir(conn
->dirptr
)));
1551 /* We don't need to check for VOL here as this is returned by
1552 a different TRANS2 call. */
1554 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1555 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
1556 dont_descend
= True
;
1559 space_remaining
= max_data_bytes
;
1560 out_of_space
= False
;
1563 * Seek to the correct position. We no longer use the resume key but
1564 * depend on the last file name instead.
1567 if(requires_resume_key
&& *resume_name
&& !continue_bit
) {
1570 * Fix for NT redirector problem triggered by resume key indexes
1571 * changing between directory scans. We now return a resume key of 0
1572 * and instead look for the filename to continue from (also given
1573 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1574 * findfirst/findnext (as is usual) then the directory pointer
1575 * should already be at the correct place. Check this by scanning
1576 * backwards looking for an exact (ie. case sensitive) filename match.
1577 * If we get to the beginning of the directory and haven't found it then scan
1578 * forwards again looking for a match. JRA.
1581 int current_pos
, start_pos
;
1582 const char *dname
= NULL
;
1583 pstring dname_pstring
;
1584 void *dirptr
= conn
->dirptr
;
1585 start_pos
= TellDir(dirptr
);
1586 for(current_pos
= start_pos
; current_pos
>= 0; current_pos
--) {
1587 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos
));
1589 SeekDir(dirptr
, current_pos
);
1590 dname
= ReadDirName(dirptr
);
1593 * Remember, mangle_map is called by
1594 * get_lanman2_dir_entry(), so the resume name
1595 * could be mangled. Ensure we do the same
1599 /* make sure we get a copy that mangle_map can modify */
1601 pstrcpy(dname_pstring
, dname
);
1602 mangle_map( dname_pstring
, False
, True
, SNUM(conn
));
1604 if(strcsequal( resume_name
, dname_pstring
)) {
1605 SeekDir(dirptr
, current_pos
+1);
1606 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1613 * Scan forward from start if not found going backwards.
1616 if(current_pos
< 0) {
1617 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos
));
1618 SeekDir(dirptr
, start_pos
);
1619 for(current_pos
= start_pos
; (dname
= ReadDirName(dirptr
)) != NULL
; SeekDir(dirptr
,++current_pos
)) {
1622 * Remember, mangle_map is called by
1623 * get_lanman2_dir_entry(), so the resume name
1624 * could be mangled. Ensure we do the same
1629 /* make sure we get a copy that mangle_map can modify */
1631 pstrcpy(dname_pstring
, dname
);
1632 mangle_map(dname_pstring
, False
, True
, SNUM(conn
));
1634 if(strcsequal( resume_name
, dname_pstring
)) {
1635 SeekDir(dirptr
, current_pos
+1);
1636 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1641 } /* end if current_pos */
1642 } /* end if requires_resume_key && !continue_bit */
1644 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
1645 BOOL got_exact_match
= False
;
1647 /* this is a heuristic to avoid seeking the dirptr except when
1648 absolutely necessary. It allows for a filename of about 40 chars */
1649 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1650 out_of_space
= True
;
1653 finished
= !get_lanman2_dir_entry(conn
,
1655 mask
,dirtype
,info_level
,
1656 requires_resume_key
,dont_descend
,
1657 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1661 if (finished
&& out_of_space
)
1664 if (!finished
&& !out_of_space
)
1668 * As an optimisation if we know we aren't looking
1669 * for a wildcard name (ie. the name matches the wildcard exactly)
1670 * then we can finish on any (first) match.
1671 * This speeds up large directory searches. JRA.
1677 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1680 /* Check if we can close the dirptr */
1681 if(close_after_request
|| (finished
&& close_if_end
)) {
1682 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
1683 dptr_close(&dptr_num
); /* This frees up the saved mask */
1686 /* Set up the return parameter block */
1687 SSVAL(params
,0,numentries
);
1688 SSVAL(params
,2,finished
);
1689 SSVAL(params
,4,0); /* Never an EA error */
1690 SSVAL(params
,6,last_name_off
);
1692 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
1694 if ((! *directory
) && dptr_path(dptr_num
))
1695 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1697 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1698 smb_fn_name(CVAL(inbuf
,smb_com
)),
1699 mask
, directory
, dirtype
, numentries
) );
1704 /****************************************************************************
1705 Reply to a TRANS2_QFSINFO (query filesystem info).
1706 ****************************************************************************/
1708 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
,
1709 int length
, int bufsize
,
1710 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1712 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1713 char *pdata
= *ppdata
;
1714 char *params
= *pparams
;
1715 uint16 info_level
= SVAL(params
,0);
1718 char *vname
= volume_label(SNUM(conn
));
1719 int snum
= SNUM(conn
);
1720 char *fstype
= lp_fstype(SNUM(conn
));
1723 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
1725 if(SMB_VFS_STAT(conn
,".",&st
)!=0) {
1726 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
1727 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
1730 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
1731 if ( pdata
== NULL
)
1732 return ERROR_DOS(ERRDOS
,ERRnomem
);
1735 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1737 switch (info_level
) {
1738 case SMB_INFO_ALLOCATION
:
1740 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1742 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1743 block_size
= lp_block_size(snum
);
1744 if (bsize
< block_size
) {
1745 SMB_BIG_UINT factor
= block_size
/bsize
;
1750 if (bsize
> block_size
) {
1751 SMB_BIG_UINT factor
= bsize
/block_size
;
1756 bytes_per_sector
= 512;
1757 sectors_per_unit
= bsize
/bytes_per_sector
;
1759 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1760 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st
.st_dev
, (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1761 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1763 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
1764 SIVAL(pdata
,l1_cSectorUnit
,sectors_per_unit
);
1765 SIVAL(pdata
,l1_cUnit
,dsize
);
1766 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
1767 SSVAL(pdata
,l1_cbSector
,bytes_per_sector
);
1771 case SMB_INFO_VOLUME
:
1772 /* Return volume name */
1774 * Add volume serial number - hash of a combination of
1775 * the called hostname and the service name.
1777 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(local_machine
)<<16) );
1778 len
= srvstr_push(outbuf
, pdata
+l2_vol_szVolLabel
, vname
, -1, STR_NOALIGN
);
1779 SCVAL(pdata
,l2_vol_cch
,len
);
1780 data_len
= l2_vol_szVolLabel
+ len
;
1781 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1782 (unsigned)st
.st_ctime
, len
, vname
));
1785 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
1786 case SMB_FS_ATTRIBUTE_INFORMATION
:
1789 #if defined(HAVE_SYS_QUOTAS)
1790 quota_flag
= FILE_VOLUME_QUOTAS
;
1793 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
1794 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)|
1795 quota_flag
); /* FS ATTRIBUTES */
1797 SIVAL(pdata
,4,255); /* Max filename component length */
1798 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1799 and will think we can't do long filenames */
1800 len
= srvstr_push(outbuf
, pdata
+12, fstype
, -1, STR_UNICODE
);
1802 data_len
= 12 + len
;
1805 case SMB_QUERY_FS_LABEL_INFO
:
1806 case SMB_FS_LABEL_INFORMATION
:
1807 len
= srvstr_push(outbuf
, pdata
+4, vname
, -1, 0);
1812 case SMB_QUERY_FS_VOLUME_INFO
:
1813 case SMB_FS_VOLUME_INFORMATION
:
1816 * Add volume serial number - hash of a combination of
1817 * the called hostname and the service name.
1819 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
1820 (str_checksum(local_machine
)<<16));
1822 len
= srvstr_push(outbuf
, pdata
+18, vname
, -1, STR_UNICODE
);
1823 SIVAL(pdata
,12,len
);
1825 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1826 (int)strlen(vname
),vname
, lp_servicename(snum
)));
1829 case SMB_QUERY_FS_SIZE_INFO
:
1830 case SMB_FS_SIZE_INFORMATION
:
1832 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1834 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1835 block_size
= lp_block_size(snum
);
1836 if (bsize
< block_size
) {
1837 SMB_BIG_UINT factor
= block_size
/bsize
;
1842 if (bsize
> block_size
) {
1843 SMB_BIG_UINT factor
= bsize
/block_size
;
1848 bytes_per_sector
= 512;
1849 sectors_per_unit
= bsize
/bytes_per_sector
;
1850 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1851 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1852 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1853 SBIG_UINT(pdata
,0,dsize
);
1854 SBIG_UINT(pdata
,8,dfree
);
1855 SIVAL(pdata
,16,sectors_per_unit
);
1856 SIVAL(pdata
,20,bytes_per_sector
);
1860 case SMB_FS_FULL_SIZE_INFORMATION
:
1862 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1864 SMB_VFS_DISK_FREE(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1865 block_size
= lp_block_size(snum
);
1866 if (bsize
< block_size
) {
1867 SMB_BIG_UINT factor
= block_size
/bsize
;
1872 if (bsize
> block_size
) {
1873 SMB_BIG_UINT factor
= bsize
/block_size
;
1878 bytes_per_sector
= 512;
1879 sectors_per_unit
= bsize
/bytes_per_sector
;
1880 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1881 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1882 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1883 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
1884 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
1885 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
1886 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
1887 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
1891 case SMB_QUERY_FS_DEVICE_INFO
:
1892 case SMB_FS_DEVICE_INFORMATION
:
1894 SIVAL(pdata
,0,0); /* dev type */
1895 SIVAL(pdata
,4,0); /* characteristics */
1898 #ifdef HAVE_SYS_QUOTAS
1899 case SMB_FS_QUOTA_INFORMATION
:
1901 * what we have to send --metze:
1903 * Unknown1: 24 NULL bytes
1904 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1905 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1906 * Quota Flags: 2 byte :
1907 * Unknown3: 6 NULL bytes
1911 * details for Quota Flags:
1913 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1914 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1915 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1916 * 0x0001 Enable Quotas: enable quota for this fs
1920 /* we need to fake up a fsp here,
1921 * because its not send in this call
1924 SMB_NTQUOTA_STRUCT quotas
;
1927 ZERO_STRUCT(quotas
);
1934 if (conn
->admin_user
!= True
) {
1935 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1936 lp_servicename(SNUM(conn
)),conn
->user
));
1937 return ERROR_DOS(ERRDOS
,ERRnoaccess
);
1940 if (vfs_get_ntquota(&fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
1941 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
1942 return ERROR_DOS(ERRSRV
,ERRerror
);
1947 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn
))));
1949 /* Unknown1 24 NULL bytes*/
1950 SBIG_UINT(pdata
,0,(SMB_BIG_UINT
)0);
1951 SBIG_UINT(pdata
,8,(SMB_BIG_UINT
)0);
1952 SBIG_UINT(pdata
,16,(SMB_BIG_UINT
)0);
1954 /* Default Soft Quota 8 bytes */
1955 SBIG_UINT(pdata
,24,quotas
.softlim
);
1957 /* Default Hard Quota 8 bytes */
1958 SBIG_UINT(pdata
,32,quotas
.hardlim
);
1960 /* Quota flag 2 bytes */
1961 SSVAL(pdata
,40,quotas
.qflags
);
1963 /* Unknown3 6 NULL bytes */
1969 #endif /* HAVE_SYS_QUOTAS */
1970 case SMB_FS_OBJECTID_INFORMATION
:
1975 * Query the version and capabilities of the CIFS UNIX extensions
1979 case SMB_QUERY_CIFS_UNIX_INFO
:
1980 if (!lp_unix_extensions())
1981 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1983 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
1984 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
1985 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)0)); /* No capabilities for now... */
1988 case SMB_MAC_QUERY_FS_INFO
:
1990 * Thursby MAC extension... ONLY on NTFS filesystems
1991 * once we do streams then we don't need this
1993 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
1995 SIVAL(pdata
,84,0x100); /* Don't support mac... */
2000 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2004 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
2006 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
2011 #ifdef HAVE_SYS_QUOTAS
2012 /****************************************************************************
2013 Reply to a TRANS2_SETFSINFO (set filesystem info).
2014 ****************************************************************************/
2016 static int call_trans2setfsinfo(connection_struct
*conn
,
2017 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2018 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2020 char *pdata
= *ppdata
;
2021 char *params
= *pparams
;
2022 files_struct
*fsp
= NULL
;
2025 SMB_NTQUOTA_STRUCT quotas
;
2027 ZERO_STRUCT(quotas
);
2029 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn
))));
2032 if ((conn
->admin_user
!= True
)||!CAN_WRITE(conn
)) {
2033 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2034 lp_servicename(SNUM(conn
)),conn
->user
));
2035 return ERROR_DOS(ERRSRV
,ERRaccess
);
2039 if (total_params
< 4) {
2040 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2042 return ERROR_DOS(ERRDOS
,ERRinvalidparam
);
2045 fsp
= file_fsp(params
,0);
2047 if (!CHECK_NTQUOTA_HANDLE_OK(fsp
,conn
)) {
2048 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2049 return ERROR_NT(NT_STATUS_INVALID_HANDLE
);
2052 info_level
= SVAL(params
,2);
2054 switch(info_level
) {
2055 case SMB_FS_QUOTA_INFORMATION
:
2056 /* note: normaly there're 48 bytes,
2057 * but we didn't use the last 6 bytes for now
2060 if (total_data
< 42) {
2061 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2063 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2066 /* unknown_1 24 NULL bytes in pdata*/
2068 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2069 quotas
.softlim
= (SMB_BIG_UINT
)IVAL(pdata
,24);
2070 #ifdef LARGE_SMB_OFF_T
2071 quotas
.softlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,28)) << 32);
2072 #else /* LARGE_SMB_OFF_T */
2073 if ((IVAL(pdata
,28) != 0)&&
2074 ((quotas
.softlim
!= 0xFFFFFFFF)||
2075 (IVAL(pdata
,28)!=0xFFFFFFFF))) {
2076 /* more than 32 bits? */
2077 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2079 #endif /* LARGE_SMB_OFF_T */
2081 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2082 quotas
.hardlim
= (SMB_BIG_UINT
)IVAL(pdata
,32);
2083 #ifdef LARGE_SMB_OFF_T
2084 quotas
.hardlim
|= (((SMB_BIG_UINT
)IVAL(pdata
,36)) << 32);
2085 #else /* LARGE_SMB_OFF_T */
2086 if ((IVAL(pdata
,36) != 0)&&
2087 ((quotas
.hardlim
!= 0xFFFFFFFF)||
2088 (IVAL(pdata
,36)!=0xFFFFFFFF))) {
2089 /* more than 32 bits? */
2090 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2092 #endif /* LARGE_SMB_OFF_T */
2094 /* quota_flags 2 bytes **/
2095 quotas
.qflags
= SVAL(pdata
,40);
2097 /* unknown_2 6 NULL bytes follow*/
2099 /* now set the quotas */
2100 if (vfs_set_ntquota(fsp
, SMB_USER_FS_QUOTA_TYPE
, NULL
, "as
)!=0) {
2101 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn
))));
2102 return ERROR_DOS(ERRSRV
,ERRerror
);
2107 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2109 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2114 * sending this reply works fine,
2115 * but I'm not sure it's the same
2116 * like windows do...
2119 outsize
= set_message(outbuf
,10,0,True
);
2123 #endif /* HAVE_SYS_QUOTAS */
2125 /****************************************************************************
2126 * Utility function to set bad path error.
2127 ****************************************************************************/
2129 int set_bad_path_error(int err
, BOOL bad_path
, char *outbuf
, int def_class
, uint32 def_code
)
2131 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2132 err
, (int)bad_path
));
2136 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND
);
2138 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2141 return UNIXERROR(def_class
,def_code
);
2144 /****************************************************************************
2145 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2146 file name or file id).
2147 ****************************************************************************/
2149 static int call_trans2qfilepathinfo(connection_struct
*conn
,
2150 char *inbuf
, char *outbuf
, int length
,
2152 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2154 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
2155 char *params
= *pparams
;
2156 char *pdata
= *ppdata
;
2157 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2160 SMB_OFF_T file_size
=0;
2161 SMB_BIG_UINT allocation_size
=0;
2162 unsigned int data_size
;
2163 unsigned int param_size
= 2;
2164 SMB_STRUCT_STAT sbuf
;
2165 pstring fname
, dos_fname
;
2170 BOOL bad_path
= False
;
2171 BOOL delete_pending
= False
;
2174 files_struct
*fsp
= NULL
;
2175 uint32 desired_access
= 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2178 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2180 if (tran_call
== TRANSACT2_QFILEINFO
) {
2181 if (total_params
< 4)
2182 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2184 fsp
= file_fsp(params
,0);
2185 info_level
= SVAL(params
,2);
2187 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
2189 if(fsp
&& (fsp
->fake_file_handle
)) {
2191 * This is actually for the QUOTA_FAKE_FILE --metze
2194 pstrcpy(fname
, fsp
->fsp_name
);
2195 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2196 if (!check_name(fname
,conn
)) {
2197 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname
,strerror(errno
)));
2198 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2201 } else if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2203 * This is actually a QFILEINFO on a directory
2204 * handle (returned from an NT SMB). NT5.0 seems
2205 * to do this call. JRA.
2207 pstrcpy(fname
, fsp
->fsp_name
);
2208 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2209 if (!check_name(fname
,conn
)) {
2210 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2211 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2214 if (INFO_LEVEL_IS_UNIX(info_level
)) {
2215 /* Always do lstat for UNIX calls. */
2216 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
2217 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
2218 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2220 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,fname
,&sbuf
)) {
2221 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
2222 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2225 delete_pending
= fsp
->directory_delete_on_close
;
2228 * Original code - this is an open file.
2230 CHECK_FSP(fsp
,conn
);
2232 pstrcpy(fname
, fsp
->fsp_name
);
2233 if (SMB_VFS_FSTAT(fsp
,fsp
->fd
,&sbuf
) != 0) {
2234 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp
->fnum
, strerror(errno
)));
2235 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2237 pos
= fsp
->position_information
;
2238 delete_pending
= fsp
->delete_on_close
;
2239 desired_access
= fsp
->desired_access
;
2242 NTSTATUS status
= NT_STATUS_OK
;
2245 if (total_params
< 6)
2246 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2248 info_level
= SVAL(params
,0);
2250 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
2252 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
, &status
);
2253 if (!NT_STATUS_IS_OK(status
)) {
2254 return ERROR_NT(status
);
2257 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
2259 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2260 if (!check_name(fname
,conn
)) {
2261 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2262 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2265 if (INFO_LEVEL_IS_UNIX(info_level
)) {
2266 /* Always do lstat for UNIX calls. */
2267 if (SMB_VFS_LSTAT(conn
,fname
,&sbuf
)) {
2268 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname
,strerror(errno
)));
2269 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2271 } else if (!VALID_STAT(sbuf
) && SMB_VFS_STAT(conn
,fname
,&sbuf
) && (info_level
!= SMB_INFO_IS_NAME_VALID
)) {
2272 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname
,strerror(errno
)));
2273 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2277 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2278 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2280 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2281 fname
,fsp
? fsp
->fnum
: -1, info_level
,tran_call
,total_data
));
2283 p
= strrchr_m(fname
,'/');
2289 mode
= dos_mode(conn
,fname
,&sbuf
);
2291 mode
= FILE_ATTRIBUTE_NORMAL
;
2293 fullpathname
= fname
;
2294 file_size
= get_file_size(sbuf
);
2295 allocation_size
= get_allocation_size(fsp
,&sbuf
);
2299 params
= Realloc(*pparams
,2);
2301 return ERROR_DOS(ERRDOS
,ERRnomem
);
2303 memset((char *)params
,'\0',2);
2304 data_size
= max_data_bytes
+ 1024;
2305 pdata
= Realloc(*ppdata
, data_size
);
2306 if ( pdata
== NULL
)
2307 return ERROR_DOS(ERRDOS
,ERRnomem
);
2310 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
2311 /* uggh, EAs for OS2 */
2312 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
2313 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
2316 memset((char *)pdata
,'\0',data_size
);
2318 c_time
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
2320 if (lp_dos_filetime_resolution(SNUM(conn
))) {
2322 sbuf
.st_atime
&= ~1;
2323 sbuf
.st_mtime
&= ~1;
2324 sbuf
.st_mtime
&= ~1;
2327 /* NT expects the name to be in an exact form of the *full*
2328 filename. See the trans2 torture test */
2329 if (strequal(base_name
,".")) {
2330 pstrcpy(dos_fname
, "\\");
2332 pstr_sprintf(dos_fname
, "\\%s", fname
);
2333 string_replace(dos_fname
, '/', '\\');
2336 switch (info_level
) {
2337 case SMB_INFO_STANDARD
:
2338 case SMB_INFO_QUERY_EA_SIZE
:
2339 data_size
= (info_level
==1?22:26);
2340 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
2341 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
2342 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
2343 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
2344 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
2345 SSVAL(pdata
,l1_attrFile
,mode
);
2346 SIVAL(pdata
,l1_attrFile
+2,0); /* this is what win2003 does */
2349 case SMB_INFO_IS_NAME_VALID
:
2350 if (tran_call
== TRANSACT2_QFILEINFO
) {
2351 /* os/2 needs this ? really ?*/
2352 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
2358 case SMB_INFO_QUERY_EAS_FROM_LIST
:
2360 put_dos_date2(pdata
,0,c_time
);
2361 put_dos_date2(pdata
,4,sbuf
.st_atime
);
2362 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
2363 SIVAL(pdata
,12,(uint32
)file_size
);
2364 SIVAL(pdata
,16,(uint32
)allocation_size
);
2365 SIVAL(pdata
,20,mode
);
2368 case SMB_INFO_QUERY_ALL_EAS
:
2369 /* We have data_size bytes to put EA's into. */
2370 data_size
= fill_ea_buffer(pdata
, data_size
, conn
, fsp
, fname
);
2373 case SMB_FILE_BASIC_INFORMATION
:
2374 case SMB_QUERY_FILE_BASIC_INFO
:
2376 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
)
2377 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
2382 put_long_date(pdata
,c_time
);
2383 put_long_date(pdata
+8,sbuf
.st_atime
);
2384 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2385 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2386 SIVAL(pdata
,32,mode
);
2388 DEBUG(5,("SMB_QFBI - "));
2390 time_t create_time
= c_time
;
2391 DEBUG(5,("create: %s ", ctime(&create_time
)));
2393 DEBUG(5,("access: %s ", ctime(&sbuf
.st_atime
)));
2394 DEBUG(5,("write: %s ", ctime(&sbuf
.st_mtime
)));
2395 DEBUG(5,("change: %s ", ctime(&sbuf
.st_mtime
)));
2396 DEBUG(5,("mode: %x\n", mode
));
2400 case SMB_FILE_STANDARD_INFORMATION
:
2401 case SMB_QUERY_FILE_STANDARD_INFO
:
2404 SOFF_T(pdata
,0,allocation_size
);
2405 SOFF_T(pdata
,8,file_size
);
2406 if (delete_pending
& sbuf
.st_nlink
)
2407 SIVAL(pdata
,16,sbuf
.st_nlink
- 1);
2409 SIVAL(pdata
,16,sbuf
.st_nlink
);
2411 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
2414 case SMB_FILE_EA_INFORMATION
:
2415 case SMB_QUERY_FILE_EA_INFO
:
2417 unsigned int ea_size
= estimate_ea_size(conn
, fsp
, fname
);
2419 SIVAL(pdata
,0,ea_size
);
2423 /* Get the 8.3 name - used if NT SMB was negotiated. */
2424 case SMB_QUERY_FILE_ALT_NAME_INFO
:
2425 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
2429 pstrcpy(short_name
,base_name
);
2430 /* Mangle if not already 8.3 */
2431 if(!mangle_is_8_3(short_name
, True
)) {
2432 mangle_map(short_name
,True
,True
,SNUM(conn
));
2434 len
= srvstr_push(outbuf
, pdata
+4, short_name
, -1, STR_UNICODE
);
2435 data_size
= 4 + len
;
2440 case SMB_QUERY_FILE_NAME_INFO
:
2442 this must be *exactly* right for ACLs on mapped drives to work
2444 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
2445 data_size
= 4 + len
;
2449 case SMB_FILE_ALLOCATION_INFORMATION
:
2450 case SMB_QUERY_FILE_ALLOCATION_INFO
:
2452 SOFF_T(pdata
,0,allocation_size
);
2455 case SMB_FILE_END_OF_FILE_INFORMATION
:
2456 case SMB_QUERY_FILE_END_OF_FILEINFO
:
2458 SOFF_T(pdata
,0,file_size
);
2461 case SMB_QUERY_FILE_ALL_INFO
:
2462 case SMB_FILE_ALL_INFORMATION
:
2463 put_long_date(pdata
,c_time
);
2464 put_long_date(pdata
+8,sbuf
.st_atime
);
2465 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2466 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2467 SIVAL(pdata
,32,mode
);
2469 SOFF_T(pdata
,0,allocation_size
);
2470 SOFF_T(pdata
,8,file_size
);
2471 if (delete_pending
&& sbuf
.st_nlink
)
2472 SIVAL(pdata
,16,sbuf
.st_nlink
- 1);
2474 SIVAL(pdata
,16,sbuf
.st_nlink
);
2475 SCVAL(pdata
,20,delete_pending
);
2476 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
2478 pdata
+= 4; /* EA info */
2479 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
2482 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2485 case SMB_FILE_INTERNAL_INFORMATION
:
2486 /* This should be an index number - looks like
2489 I think this causes us to fail the IFSKIT
2490 BasicFileInformationTest. -tpot */
2492 SIVAL(pdata
,0,sbuf
.st_dev
);
2493 SIVAL(pdata
,4,sbuf
.st_ino
);
2497 case SMB_FILE_ACCESS_INFORMATION
:
2498 SIVAL(pdata
,0,desired_access
);
2502 case SMB_FILE_NAME_INFORMATION
:
2503 /* Pathname with leading '\'. */
2506 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
2507 SIVAL(pdata
,0,byte_len
);
2508 data_size
= 4 + byte_len
;
2512 case SMB_FILE_DISPOSITION_INFORMATION
:
2514 SCVAL(pdata
,0,delete_pending
);
2517 case SMB_FILE_POSITION_INFORMATION
:
2519 SOFF_T(pdata
,0,pos
);
2522 case SMB_FILE_MODE_INFORMATION
:
2523 SIVAL(pdata
,0,mode
);
2527 case SMB_FILE_ALIGNMENT_INFORMATION
:
2528 SIVAL(pdata
,0,0); /* No alignment needed. */
2534 * NT4 server just returns "invalid query" to this - if we try to answer
2535 * it then NTws gets a BSOD! (tridge).
2536 * W2K seems to want this. JRA.
2538 case SMB_QUERY_FILE_STREAM_INFO
:
2540 case SMB_FILE_STREAM_INFORMATION
:
2544 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", 0xE, False
);
2545 SIVAL(pdata
,0,0); /* ??? */
2546 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
2547 SOFF_T(pdata
,8,file_size
);
2548 SIVAL(pdata
,16,allocation_size
);
2549 SIVAL(pdata
,20,0); /* ??? */
2550 data_size
= 24 + byte_len
;
2554 case SMB_QUERY_COMPRESSION_INFO
:
2555 case SMB_FILE_COMPRESSION_INFORMATION
:
2556 SOFF_T(pdata
,0,file_size
);
2557 SIVAL(pdata
,8,0); /* ??? */
2558 SIVAL(pdata
,12,0); /* ??? */
2562 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
2563 put_long_date(pdata
,c_time
);
2564 put_long_date(pdata
+8,sbuf
.st_atime
);
2565 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2566 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2567 SIVAL(pdata
,32,allocation_size
);
2568 SOFF_T(pdata
,40,file_size
);
2569 SIVAL(pdata
,48,mode
);
2570 SIVAL(pdata
,52,0); /* ??? */
2574 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
2575 SIVAL(pdata
,0,mode
);
2581 * CIFS UNIX Extensions.
2584 case SMB_QUERY_FILE_UNIX_BASIC
:
2586 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf
.st_mode
));
2588 SOFF_T(pdata
,0,get_file_size(sbuf
)); /* File size 64 Bit */
2591 SOFF_T(pdata
,0,get_allocation_size(fsp
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
2594 put_long_date(pdata
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
2595 put_long_date(pdata
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
2596 put_long_date(pdata
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
2599 SIVAL(pdata
,0,sbuf
.st_uid
); /* user id for the owner */
2603 SIVAL(pdata
,0,sbuf
.st_gid
); /* group id of owner */
2607 SIVAL(pdata
,0,unix_filetype(sbuf
.st_mode
));
2610 SIVAL(pdata
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
2614 SIVAL(pdata
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
2618 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
2621 SIVAL(pdata
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
2625 SIVAL(pdata
,0,sbuf
.st_nlink
); /* number of hard links */
2628 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2632 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2634 for (i
=0; i
<100; i
++)
2635 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
2641 case SMB_QUERY_FILE_UNIX_LINK
:
2646 if(!S_ISLNK(sbuf
.st_mode
))
2647 return(UNIXERROR(ERRSRV
,ERRbadlink
));
2649 return(UNIXERROR(ERRDOS
,ERRbadlink
));
2651 len
= SMB_VFS_READLINK(conn
,fullpathname
, buffer
, sizeof(pstring
)-1); /* read link */
2653 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2655 len
= srvstr_push(outbuf
, pdata
, buffer
, -1, STR_TERMINATE
);
2657 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2663 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2666 send_trans2_replies(outbuf
, bufsize
, params
, param_size
, *ppdata
, data_size
);
2671 /****************************************************************************
2672 Deal with the internal needs of setting the delete on close flag. Note that
2673 as the tdb locking is recursive, it is safe to call this from within
2674 open_file_shared. JRA.
2675 ****************************************************************************/
2677 NTSTATUS
set_delete_on_close_internal(files_struct
*fsp
, BOOL delete_on_close
)
2680 * Only allow delete on close for writable shares.
2683 if (delete_on_close
&& !CAN_WRITE(fsp
->conn
)) {
2684 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2686 return NT_STATUS_ACCESS_DENIED
;
2689 * Only allow delete on close for files/directories opened with delete intent.
2692 if (delete_on_close
&& !(fsp
->desired_access
& DELETE_ACCESS
)) {
2693 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2695 return NT_STATUS_ACCESS_DENIED
;
2698 if(fsp
->is_directory
) {
2699 fsp
->directory_delete_on_close
= delete_on_close
;
2700 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2701 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2703 fsp
->delete_on_close
= delete_on_close
;
2704 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2705 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2708 return NT_STATUS_OK
;
2711 /****************************************************************************
2712 Sets the delete on close flag over all share modes on this file.
2713 Modify the share mode entry for all files open
2714 on this device and inode to tell other smbds we have
2715 changed the delete on close flag. This will be noticed
2716 in the close code, the last closer will delete the file
2718 ****************************************************************************/
2720 NTSTATUS
set_delete_on_close_over_all(files_struct
*fsp
, BOOL delete_on_close
)
2722 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2723 delete_on_close
? "Adding" : "Removing", fsp
->fnum
, fsp
->fsp_name
));
2725 if (fsp
->is_directory
|| fsp
->is_stat
)
2726 return NT_STATUS_OK
;
2728 if (lock_share_entry_fsp(fsp
) == False
)
2729 return NT_STATUS_ACCESS_DENIED
;
2731 if (!modify_delete_flag(fsp
->dev
, fsp
->inode
, delete_on_close
)) {
2732 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2734 unlock_share_entry_fsp(fsp
);
2735 return NT_STATUS_ACCESS_DENIED
;
2738 unlock_share_entry_fsp(fsp
);
2739 return NT_STATUS_OK
;
2742 /****************************************************************************
2743 Returns true if this pathname is within the share, and thus safe.
2744 ****************************************************************************/
2746 static int ensure_link_is_safe(connection_struct
*conn
, const char *link_dest_in
, char *link_dest_out
)
2749 char resolved_name
[PATH_MAX
+1];
2751 pstring resolved_name
;
2753 fstring last_component
;
2757 BOOL bad_path
= False
;
2758 SMB_STRUCT_STAT sbuf
;
2760 pstrcpy(link_dest
, link_dest_in
);
2761 unix_convert(link_dest
,conn
,0,&bad_path
,&sbuf
);
2763 /* Store the UNIX converted path. */
2764 pstrcpy(link_dest_out
, link_dest
);
2766 p
= strrchr(link_dest
, '/');
2768 fstrcpy(last_component
, p
+1);
2771 fstrcpy(last_component
, link_dest
);
2772 pstrcpy(link_dest
, "./");
2775 if (SMB_VFS_REALPATH(conn
,link_dest
,resolved_name
) == NULL
)
2778 pstrcpy(link_dest
, resolved_name
);
2779 pstrcat(link_dest
, "/");
2780 pstrcat(link_dest
, last_component
);
2782 if (*link_dest
!= '/') {
2783 /* Relative path. */
2784 pstrcpy(link_test
, conn
->connectpath
);
2785 pstrcat(link_test
, "/");
2786 pstrcat(link_test
, link_dest
);
2788 pstrcpy(link_test
, link_dest
);
2792 * Check if the link is within the share.
2795 if (strncmp(conn
->connectpath
, link_test
, strlen(conn
->connectpath
))) {
2802 /****************************************************************************
2803 Set a hard link (called by UNIX extensions and by NT rename with HARD link
2805 ****************************************************************************/
2807 NTSTATUS
hardlink_internals(connection_struct
*conn
, char *name
, char *newname
)
2809 BOOL bad_path_src
= False
;
2810 BOOL bad_path_dest
= False
;
2811 SMB_STRUCT_STAT sbuf1
, sbuf2
;
2813 pstring last_component_src
;
2814 pstring last_component_dest
;
2815 NTSTATUS status
= NT_STATUS_OK
;
2821 if (ms_has_wild(name
) || ms_has_wild(newname
)) {
2822 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD
;
2825 rc
= unix_convert(name
,conn
,last_component_src
,&bad_path_src
,&sbuf1
);
2826 if (!rc
&& bad_path_src
) {
2827 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
2830 /* Quick check for "." and ".." */
2831 if (last_component_src
[0] == '.') {
2832 if (!last_component_src
[1] || (last_component_src
[1] == '.' && !last_component_src
[2])) {
2833 return NT_STATUS_OBJECT_NAME_INVALID
;
2837 /* source must already exist. */
2838 if (!VALID_STAT(sbuf1
)) {
2839 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2842 rcdest
= unix_convert(newname
,conn
,last_component_dest
,&bad_path_dest
,&sbuf2
);
2843 if (!rcdest
&& bad_path_dest
) {
2844 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
2847 /* Quick check for "." and ".." */
2848 if (last_component_dest
[0] == '.') {
2849 if (!last_component_dest
[1] || (last_component_dest
[1] == '.' && !last_component_dest
[2])) {
2850 return NT_STATUS_OBJECT_NAME_INVALID
;
2854 /* Disallow if already exists. */
2855 if (VALID_STAT(sbuf2
)) {
2856 return NT_STATUS_OBJECT_NAME_COLLISION
;
2859 /* No links from a directory. */
2860 if (S_ISDIR(sbuf1
.st_mode
)) {
2861 return NT_STATUS_FILE_IS_A_DIRECTORY
;
2864 if (ensure_link_is_safe(conn
, newname
, newname
) != 0)
2865 return NT_STATUS_ACCESS_DENIED
;
2867 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", name
, newname
));
2869 if (SMB_VFS_LINK(conn
,name
,newname
) != 0) {
2870 status
= map_nt_error_from_unix(errno
);
2871 DEBUG(3,("hardlink_internals: Error %s link %s -> %s\n",
2872 nt_errstr(status
), name
,newname
));
2878 /****************************************************************************
2879 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2880 ****************************************************************************/
2882 static int call_trans2setfilepathinfo(connection_struct
*conn
,
2883 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2884 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2886 char *params
= *pparams
;
2887 char *pdata
= *ppdata
;
2888 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2893 SMB_STRUCT_STAT sbuf
;
2896 BOOL bad_path
= False
;
2897 files_struct
*fsp
= NULL
;
2898 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
2899 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
2900 mode_t unixmode
= 0;
2901 NTSTATUS status
= NT_STATUS_OK
;
2904 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
2906 if (tran_call
== TRANSACT2_SETFILEINFO
) {
2907 if (total_params
< 4)
2908 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2910 fsp
= file_fsp(params
,0);
2911 info_level
= SVAL(params
,2);
2913 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2915 * This is actually a SETFILEINFO on a directory
2916 * handle (returned from an NT SMB). NT5.0 seems
2917 * to do this call. JRA.
2919 pstrcpy(fname
, fsp
->fsp_name
);
2920 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2921 if (!check_name(fname
,conn
) || (!VALID_STAT(sbuf
))) {
2922 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2923 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2925 } else if (fsp
&& fsp
->print_file
) {
2927 * Doing a DELETE_ON_CLOSE should cancel a print job.
2929 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
2930 fsp
->share_mode
= FILE_DELETE_ON_CLOSE
;
2932 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp
->fsp_name
));
2935 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2938 return (UNIXERROR(ERRDOS
,ERRbadpath
));
2941 * Original code - this is an open file.
2943 CHECK_FSP(fsp
,conn
);
2945 pstrcpy(fname
, fsp
->fsp_name
);
2948 if (SMB_VFS_FSTAT(fsp
,fd
,&sbuf
) != 0) {
2949 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
2950 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2955 if (total_params
< 6)
2956 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2958 info_level
= SVAL(params
,0);
2959 srvstr_get_path(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
, &status
);
2960 if (!NT_STATUS_IS_OK(status
)) {
2961 return ERROR_NT(status
);
2963 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2966 * For CIFS UNIX extensions the target name may not exist.
2969 if(!VALID_STAT(sbuf
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
2970 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname
, strerror(errno
)));
2971 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2974 if(!check_name(fname
, conn
)) {
2975 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRbadpath
);
2980 if (!CAN_WRITE(conn
))
2981 return ERROR_DOS(ERRSRV
,ERRaccess
);
2983 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2984 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2986 if (VALID_STAT(sbuf
))
2987 unixmode
= sbuf
.st_mode
;
2989 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
2990 tran_call
,fname
, fsp
? fsp
->fnum
: -1, info_level
,total_data
));
2992 /* Realloc the parameter and data sizes */
2993 params
= Realloc(*pparams
,2);
2995 return ERROR_DOS(ERRDOS
,ERRnomem
);
3001 /* the pending modtime overrides the current modtime */
3002 sbuf
.st_mtime
= fsp
->pending_modtime
;
3005 size
= get_file_size(sbuf
);
3006 tvs
.modtime
= sbuf
.st_mtime
;
3007 tvs
.actime
= sbuf
.st_atime
;
3008 dosmode
= dos_mode(conn
,fname
,&sbuf
);
3009 unixmode
= sbuf
.st_mode
;
3011 set_owner
= VALID_STAT(sbuf
) ? sbuf
.st_uid
: (uid_t
)SMB_UID_NO_CHANGE
;
3012 set_grp
= VALID_STAT(sbuf
) ? sbuf
.st_gid
: (gid_t
)SMB_GID_NO_CHANGE
;
3014 switch (info_level
) {
3015 case SMB_INFO_STANDARD
:
3017 if (total_data
< 12)
3018 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3021 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
3023 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
3027 case SMB_INFO_SET_EA
:
3028 status
= set_ea(conn
, fsp
, fname
, pdata
, total_data
);
3029 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3030 return ERROR_NT(status
);
3033 /* XXXX um, i don't think this is right.
3034 it's also not in the cifs6.txt spec.
3036 case SMB_INFO_QUERY_EAS_FROM_LIST
:
3037 if (total_data
< 28)
3038 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3040 tvs
.actime
= make_unix_date2(pdata
+8);
3041 tvs
.modtime
= make_unix_date2(pdata
+12);
3042 size
= IVAL(pdata
,16);
3043 dosmode
= IVAL(pdata
,24);
3046 /* XXXX nor this. not in cifs6.txt, either. */
3047 case SMB_INFO_QUERY_ALL_EAS
:
3048 if (total_data
< 28)
3049 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3051 tvs
.actime
= make_unix_date2(pdata
+8);
3052 tvs
.modtime
= make_unix_date2(pdata
+12);
3053 size
= IVAL(pdata
,16);
3054 dosmode
= IVAL(pdata
,24);
3057 case SMB_SET_FILE_BASIC_INFO
:
3058 case SMB_FILE_BASIC_INFORMATION
:
3060 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3062 time_t changed_time
;
3064 if (total_data
< 36)
3065 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3067 /* Ignore create time at offset pdata. */
3070 tvs
.actime
= interpret_long_date(pdata
+8);
3072 write_time
= interpret_long_date(pdata
+16);
3073 changed_time
= interpret_long_date(pdata
+24);
3075 tvs
.modtime
= MIN(write_time
, changed_time
);
3077 if (write_time
> tvs
.modtime
&& write_time
!= 0xffffffff) {
3078 tvs
.modtime
= write_time
;
3080 /* Prefer a defined time to an undefined one. */
3081 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
3082 tvs
.modtime
= (write_time
== (time_t)0 || write_time
== (time_t)-1
3083 ? changed_time
: write_time
);
3086 dosmode
= IVAL(pdata
,32);
3090 case SMB_FILE_ALLOCATION_INFORMATION
:
3091 case SMB_SET_FILE_ALLOCATION_INFO
:
3094 SMB_BIG_UINT allocation_size
;
3097 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3099 allocation_size
= (SMB_BIG_UINT
)IVAL(pdata
,0);
3100 #ifdef LARGE_SMB_OFF_T
3101 allocation_size
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
3102 #else /* LARGE_SMB_OFF_T */
3103 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3104 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3105 #endif /* LARGE_SMB_OFF_T */
3106 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3107 fname
, (double)allocation_size
));
3109 if (allocation_size
)
3110 allocation_size
= SMB_ROUNDUP(allocation_size
,SMB_ROUNDUP_ALLOCATION_SIZE
);
3112 if(allocation_size
!= get_file_size(sbuf
)) {
3113 SMB_STRUCT_STAT new_sbuf
;
3115 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3116 fname
, (double)allocation_size
));
3119 files_struct
*new_fsp
= NULL
;
3120 int access_mode
= 0;
3123 if(global_oplock_break
) {
3124 /* Queue this file modify as we are the process of an oplock break. */
3126 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3127 DEBUGADD(2,( "in oplock break state.\n"));
3129 push_oplock_pending_smb_message(inbuf
, length
);
3133 new_fsp
= open_file_shared1(conn
, fname
, &sbuf
,FILE_WRITE_DATA
,
3134 SET_OPEN_MODE(DOS_OPEN_RDWR
),
3135 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
3136 0, 0, &access_mode
, &action
);
3138 if (new_fsp
== NULL
)
3139 return(UNIXERROR(ERRDOS
,ERRbadpath
));
3140 ret
= vfs_allocate_file_space(new_fsp
, allocation_size
);
3141 if (SMB_VFS_FSTAT(new_fsp
,new_fsp
->fd
,&new_sbuf
) != 0) {
3142 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3143 new_fsp
->fnum
, strerror(errno
)));
3146 close_file(new_fsp
,True
);
3148 ret
= vfs_allocate_file_space(fsp
, allocation_size
);
3149 if (SMB_VFS_FSTAT(fsp
,fd
,&new_sbuf
) != 0) {
3150 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3151 fsp
->fnum
, strerror(errno
)));
3156 return ERROR_NT(NT_STATUS_DISK_FULL
);
3158 /* Allocate can truncate size... */
3159 size
= get_file_size(new_sbuf
);
3165 case SMB_FILE_END_OF_FILE_INFORMATION
:
3166 case SMB_SET_FILE_END_OF_FILE_INFO
:
3169 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3171 size
= IVAL(pdata
,0);
3172 #ifdef LARGE_SMB_OFF_T
3173 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
3174 #else /* LARGE_SMB_OFF_T */
3175 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3176 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3177 #endif /* LARGE_SMB_OFF_T */
3178 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname
, (double)size
));
3182 case SMB_FILE_DISPOSITION_INFORMATION
:
3183 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
3185 BOOL delete_on_close
;
3188 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3190 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
3192 /* Just ignore this set on a path. */
3193 if (tran_call
!= TRANSACT2_SETFILEINFO
)
3197 return(UNIXERROR(ERRDOS
,ERRbadfid
));
3199 status
= set_delete_on_close_internal(fsp
, delete_on_close
);
3201 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3202 return ERROR_NT(status
);
3204 /* The set is across all open files on this dev/inode pair. */
3205 status
=set_delete_on_close_over_all(fsp
, delete_on_close
);
3206 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
3207 return ERROR_NT(status
);
3212 case SMB_FILE_POSITION_INFORMATION
:
3214 SMB_BIG_UINT position_information
;
3217 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3219 position_information
= (SMB_BIG_UINT
)IVAL(pdata
,0);
3220 #ifdef LARGE_SMB_OFF_T
3221 position_information
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
3222 #else /* LARGE_SMB_OFF_T */
3223 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3224 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3225 #endif /* LARGE_SMB_OFF_T */
3226 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3227 fname
, (double)position_information
));
3229 fsp
->position_information
= position_information
;
3234 * CIFS UNIX extensions.
3237 case SMB_SET_FILE_UNIX_BASIC
:
3239 uint32 raw_unixmode
;
3241 if (total_data
< 100)
3242 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3244 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
3245 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
3246 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
3247 #ifdef LARGE_SMB_OFF_T
3248 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
3249 #else /* LARGE_SMB_OFF_T */
3250 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
3251 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3252 #endif /* LARGE_SMB_OFF_T */
3254 pdata
+=24; /* ctime & st_blocks are not changed */
3255 tvs
.actime
= interpret_long_unix_date(pdata
); /* access_time */
3256 tvs
.modtime
= interpret_long_unix_date(pdata
+8); /* modification_time */
3258 set_owner
= (uid_t
)IVAL(pdata
,0);
3260 set_grp
= (gid_t
)IVAL(pdata
,0);
3262 raw_unixmode
= IVAL(pdata
,28);
3263 unixmode
= unix_perms_from_wire(conn
, &sbuf
, raw_unixmode
);
3264 dosmode
= 0; /* Ensure dos mode change doesn't override this. */
3266 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3267 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3268 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
3270 if (!VALID_STAT(sbuf
)) {
3273 * The only valid use of this is to create character and block
3274 * devices, and named pipes. This is deprecated (IMHO) and
3275 * a new info level should be used for mknod. JRA.
3278 #if !defined(HAVE_MAKEDEV_FN)
3279 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3280 #else /* HAVE_MAKEDEV_FN */
3281 uint32 file_type
= IVAL(pdata
,0);
3282 uint32 dev_major
= IVAL(pdata
,4);
3283 uint32 dev_minor
= IVAL(pdata
,12);
3285 uid_t myuid
= geteuid();
3286 gid_t mygid
= getegid();
3289 if (tran_call
== TRANSACT2_SETFILEINFO
)
3290 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3292 if (raw_unixmode
== SMB_MODE_NO_CHANGE
)
3293 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3295 dev
= makedev(dev_major
, dev_minor
);
3297 /* We can only create as the owner/group we are. */
3299 if ((set_owner
!= myuid
) && (set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
))
3300 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3301 if ((set_grp
!= mygid
) && (set_grp
!= (gid_t
)SMB_GID_NO_CHANGE
))
3302 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3304 if (file_type
!= UNIX_TYPE_CHARDEV
&& file_type
!= UNIX_TYPE_BLKDEV
&&
3305 file_type
!= UNIX_TYPE_FIFO
)
3306 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3308 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3309 0%o for file %s\n", (double)dev
, unixmode
, fname
));
3311 /* Ok - do the mknod. */
3312 if (SMB_VFS_MKNOD(conn
,dos_to_unix_static(fname
), unixmode
, dev
) != 0)
3313 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3315 inherit_access_acl(conn
, fname
, unixmode
);
3318 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3320 #endif /* HAVE_MAKEDEV_FN */
3325 * Deal with the UNIX specific mode set.
3328 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
3329 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3330 (unsigned int)unixmode
, fname
));
3331 if (SMB_VFS_CHMOD(conn
,fname
,unixmode
) != 0)
3332 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3336 * Deal with the UNIX specific uid set.
3339 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) && (sbuf
.st_uid
!= set_owner
)) {
3340 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3341 (unsigned int)set_owner
, fname
));
3342 if (SMB_VFS_CHOWN(conn
,fname
,set_owner
, (gid_t
)-1) != 0)
3343 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3347 * Deal with the UNIX specific gid set.
3350 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) && (sbuf
.st_gid
!= set_grp
)) {
3351 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3352 (unsigned int)set_owner
, fname
));
3353 if (SMB_VFS_CHOWN(conn
,fname
,(uid_t
)-1, set_grp
) != 0)
3354 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3359 case SMB_SET_FILE_UNIX_LINK
:
3362 /* Set a symbolic link. */
3363 /* Don't allow this if follow links is false. */
3365 if (!lp_symlinks(SNUM(conn
)))
3366 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
3368 srvstr_get_path(inbuf
, link_dest
, pdata
, sizeof(link_dest
), -1, STR_TERMINATE
, &status
);
3369 if (!NT_STATUS_IS_OK(status
)) {
3370 return ERROR_NT(status
);
3373 if (ensure_link_is_safe(conn
, link_dest
, link_dest
) != 0)
3374 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3376 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3377 fname
, link_dest
));
3379 if (SMB_VFS_SYMLINK(conn
,link_dest
,fname
) != 0)
3380 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3382 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3386 case SMB_SET_FILE_UNIX_HLINK
:
3390 /* Set a hard link. */
3391 srvstr_get_path(inbuf
, link_dest
, pdata
, sizeof(link_dest
), -1, STR_TERMINATE
, &status
);
3392 if (!NT_STATUS_IS_OK(status
)) {
3393 return ERROR_NT(status
);
3396 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3397 fname
, link_dest
));
3399 status
= hardlink_internals(conn
, fname
, link_dest
);
3400 if (!NT_STATUS_IS_OK(status
)) {
3401 return ERROR_NT(status
);
3405 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3409 case SMB_FILE_RENAME_INFORMATION
:
3418 if (total_data
< 12)
3419 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3421 overwrite
= (CVAL(pdata
,0) ? True
: False
);
3422 root_fid
= IVAL(pdata
,4);
3423 len
= IVAL(pdata
,8);
3424 srvstr_get_path(inbuf
, newname
, &pdata
[12], sizeof(newname
), len
, 0, &status
);
3425 if (!NT_STATUS_IS_OK(status
)) {
3426 return ERROR_NT(status
);
3429 /* Check the new name has no '/' characters. */
3430 if (strchr_m(newname
, '/'))
3431 return ERROR_NT(NT_STATUS_NOT_SUPPORTED
);
3433 RESOLVE_DFSPATH(newname
, conn
, inbuf
, outbuf
);
3435 /* Create the base directory. */
3436 pstrcpy(base_name
, fname
);
3437 p
= strrchr_m(base_name
, '/');
3440 /* Append the new name. */
3441 pstrcat(base_name
, "/");
3442 pstrcat(base_name
, newname
);
3445 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3446 fsp
->fnum
, fsp
->fsp_name
, base_name
));
3447 status
= rename_internals_fsp(conn
, fsp
, base_name
, overwrite
);
3449 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3451 status
= rename_internals(conn
, fname
, base_name
, 0, overwrite
);
3453 if (!NT_STATUS_IS_OK(status
)) {
3454 return ERROR_NT(status
);
3456 process_pending_change_notify_queue((time_t)0);
3458 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3462 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3465 /* get some defaults (no modifications) if any info is zero or -1. */
3466 if (tvs
.actime
== (time_t)0 || tvs
.actime
== (time_t)-1)
3467 tvs
.actime
= sbuf
.st_atime
;
3469 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
3470 tvs
.modtime
= sbuf
.st_mtime
;
3472 DEBUG(6,("actime: %s " , ctime(&tvs
.actime
)));
3473 DEBUG(6,("modtime: %s ", ctime(&tvs
.modtime
)));
3474 DEBUG(6,("size: %.0f ", (double)size
));
3477 if (S_ISDIR(sbuf
.st_mode
))
3483 DEBUG(6,("dosmode: %x\n" , dosmode
));
3485 if(!((info_level
== SMB_SET_FILE_END_OF_FILE_INFO
) ||
3486 (info_level
== SMB_SET_FILE_ALLOCATION_INFO
) ||
3487 (info_level
== SMB_FILE_ALLOCATION_INFORMATION
) ||
3488 (info_level
== SMB_FILE_END_OF_FILE_INFORMATION
))) {
3491 * Only do this test if we are not explicitly
3492 * changing the size of a file.
3495 size
= get_file_size(sbuf
);
3499 * Try and set the times, size and mode of this file -
3500 * if they are different from the current values
3502 if (sbuf
.st_mtime
!= tvs
.modtime
|| sbuf
.st_atime
!= tvs
.actime
) {
3505 * This was a setfileinfo on an open file.
3506 * NT does this a lot. It's actually pointless
3507 * setting the time here, as it will be overwritten
3508 * on the next write, so we save the request
3509 * away and will set it on file close. JRA.
3512 if (tvs
.modtime
!= (time_t)0 && tvs
.modtime
!= (time_t)-1) {
3513 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs
.modtime
) ));
3514 fsp
->pending_modtime
= tvs
.modtime
;
3519 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3521 if(file_utime(conn
, fname
, &tvs
)!=0)
3522 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3526 /* check the mode isn't different, before changing it */
3527 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, fname
, &sbuf
))) {
3529 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname
, dosmode
));
3531 if(file_chmod(conn
, fname
, dosmode
, NULL
)) {
3532 DEBUG(2,("chmod of %s failed (%s)\n", fname
, strerror(errno
)));
3533 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
3537 if (size
!= get_file_size(sbuf
)) {
3541 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3542 fname
, (double)size
));
3545 files_struct
*new_fsp
= NULL
;
3546 int access_mode
= 0;
3549 if(global_oplock_break
) {
3550 /* Queue this file modify as we are the process of an oplock break. */
3552 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3553 DEBUGADD(2,( "in oplock break state.\n"));
3555 push_oplock_pending_smb_message(inbuf
, length
);
3559 new_fsp
= open_file_shared(conn
, fname
, &sbuf
,
3560 SET_OPEN_MODE(DOS_OPEN_RDWR
),
3561 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
3562 0, 0, &access_mode
, &action
);
3564 if (new_fsp
== NULL
)
3565 return(UNIXERROR(ERRDOS
,ERRbadpath
));
3566 ret
= vfs_set_filelen(new_fsp
, size
);
3567 close_file(new_fsp
,True
);
3569 ret
= vfs_set_filelen(fsp
, size
);
3573 return (UNIXERROR(ERRHRD
,ERRdiskfull
));
3577 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3582 /****************************************************************************
3583 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3584 ****************************************************************************/
3586 static int call_trans2mkdir(connection_struct
*conn
,
3587 char *inbuf
, char *outbuf
, int length
, int bufsize
,
3588 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3590 char *params
= *pparams
;
3593 SMB_STRUCT_STAT sbuf
;
3594 BOOL bad_path
= False
;
3595 NTSTATUS status
= NT_STATUS_OK
;
3597 if (!CAN_WRITE(conn
))
3598 return ERROR_DOS(ERRSRV
,ERRaccess
);
3600 if (total_params
< 4)
3601 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3603 srvstr_get_path(inbuf
, directory
, ¶ms
[4], sizeof(directory
), -1, STR_TERMINATE
, &status
);
3604 if (!NT_STATUS_IS_OK(status
)) {
3605 return ERROR_NT(status
);
3608 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
3610 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
3611 if (check_name(directory
,conn
))
3612 ret
= vfs_MkDir(conn
,directory
,unix_mode(conn
,aDIR
,directory
));
3615 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno
)));
3616 return set_bad_path_error(errno
, bad_path
, outbuf
, ERRDOS
,ERRnoaccess
);
3619 /* Realloc the parameter and data sizes */
3620 params
= Realloc(*pparams
,2);
3622 return ERROR_DOS(ERRDOS
,ERRnomem
);
3627 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
3632 /****************************************************************************
3633 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3634 We don't actually do this - we just send a null response.
3635 ****************************************************************************/
3637 static int call_trans2findnotifyfirst(connection_struct
*conn
,
3638 char *inbuf
, char *outbuf
, int length
, int bufsize
,
3639 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3641 static uint16 fnf_handle
= 257;
3642 char *params
= *pparams
;
3645 if (total_params
< 6)
3646 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3648 info_level
= SVAL(params
,4);
3649 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
3651 switch (info_level
) {
3656 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
3659 /* Realloc the parameter and data sizes */
3660 params
= Realloc(*pparams
,6);
3662 return ERROR_DOS(ERRDOS
,ERRnomem
);
3665 SSVAL(params
,0,fnf_handle
);
3666 SSVAL(params
,2,0); /* No changes */
3667 SSVAL(params
,4,0); /* No EA errors */
3674 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0);
3679 /****************************************************************************
3680 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3681 changes). Currently this does nothing.
3682 ****************************************************************************/
3684 static int call_trans2findnotifynext(connection_struct
*conn
,
3685 char *inbuf
, char *outbuf
, int length
, int bufsize
,
3686 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3688 char *params
= *pparams
;
3690 DEBUG(3,("call_trans2findnotifynext\n"));
3692 /* Realloc the parameter and data sizes */
3693 params
= Realloc(*pparams
,4);
3695 return ERROR_DOS(ERRDOS
,ERRnomem
);
3698 SSVAL(params
,0,0); /* No changes */
3699 SSVAL(params
,2,0); /* No EA errors */
3701 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0);
3706 /****************************************************************************
3707 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3708 ****************************************************************************/
3710 static int call_trans2getdfsreferral(connection_struct
*conn
, char* inbuf
,
3711 char* outbuf
, int length
, int bufsize
,
3712 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3714 char *params
= *pparams
;
3717 int max_referral_level
;
3719 DEBUG(10,("call_trans2getdfsreferral\n"));
3721 if (total_params
< 2)
3722 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3724 max_referral_level
= SVAL(params
,0);
3726 if(!lp_host_msdfs())
3727 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
3729 srvstr_pull(inbuf
, pathname
, ¶ms
[2], sizeof(pathname
), -1, STR_TERMINATE
);
3730 if((reply_size
= setup_dfs_referral(conn
, pathname
,max_referral_level
,ppdata
)) < 0)
3731 return UNIXERROR(ERRDOS
,ERRbadfile
);
3733 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
3734 send_trans2_replies(outbuf
,bufsize
,0,0,*ppdata
,reply_size
);
3739 #define LMCAT_SPL 0x53
3740 #define LMFUNC_GETJOBID 0x60
3742 /****************************************************************************
3743 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3744 ****************************************************************************/
3746 static int call_trans2ioctl(connection_struct
*conn
, char* inbuf
,
3747 char* outbuf
, int length
, int bufsize
,
3748 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3750 char *pdata
= *ppdata
;
3751 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv15
);
3753 /* check for an invalid fid before proceeding */
3756 return(ERROR_DOS(ERRDOS
,ERRbadfid
));
3758 if ((SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3759 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3760 pdata
= Realloc(*ppdata
, 32);
3762 return ERROR_DOS(ERRDOS
,ERRnomem
);
3765 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3766 CAN ACCEPT THIS IN UNICODE. JRA. */
3768 SSVAL(pdata
,0,fsp
->rap_print_jobid
); /* Job number */
3769 srvstr_push( outbuf
, pdata
+ 2, global_myname(), 15, STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
3770 srvstr_push( outbuf
, pdata
+18, lp_servicename(SNUM(conn
)), 13, STR_ASCII
|STR_TERMINATE
); /* Service name */
3771 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32);
3774 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3775 return ERROR_DOS(ERRSRV
,ERRerror
);
3779 /****************************************************************************
3780 Reply to a SMBfindclose (stop trans2 directory search).
3781 ****************************************************************************/
3783 int reply_findclose(connection_struct
*conn
,
3784 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3787 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
3788 START_PROFILE(SMBfindclose
);
3790 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
3792 dptr_close(&dptr_num
);
3794 outsize
= set_message(outbuf
,0,0,True
);
3796 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
3798 END_PROFILE(SMBfindclose
);
3802 /****************************************************************************
3803 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3804 ****************************************************************************/
3806 int reply_findnclose(connection_struct
*conn
,
3807 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3811 START_PROFILE(SMBfindnclose
);
3813 dptr_num
= SVAL(inbuf
,smb_vwv0
);
3815 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
3817 /* We never give out valid handles for a
3818 findnotifyfirst - so any dptr_num is ok here.
3821 outsize
= set_message(outbuf
,0,0,True
);
3823 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
3825 END_PROFILE(SMBfindnclose
);
3829 /****************************************************************************
3830 Reply to a SMBtranss2 - just ignore it!
3831 ****************************************************************************/
3833 int reply_transs2(connection_struct
*conn
,
3834 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3836 START_PROFILE(SMBtranss2
);
3837 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
3838 END_PROFILE(SMBtranss2
);
3842 /****************************************************************************
3843 Reply to a SMBtrans2.
3844 ****************************************************************************/
3846 int reply_trans2(connection_struct
*conn
,
3847 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3850 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
3851 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
3853 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
3854 unsigned int max_data_reply
= SVAL(inbuf
, smb_mdrcnt
);
3855 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
3856 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
3857 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
3858 int32 timeout
= IVALS(inbuf
,smb_timeout
);
3860 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
3861 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
3862 char *params
= NULL
, *data
= NULL
;
3863 unsigned int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
3864 START_PROFILE(SMBtrans2
);
3866 if(global_oplock_break
&& (tran_call
== TRANSACT2_OPEN
)) {
3867 /* Queue this open message as we are the process of an
3870 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3871 DEBUGADD(2,( "in oplock break state.\n"));
3873 push_oplock_pending_smb_message(inbuf
, length
);
3874 END_PROFILE(SMBtrans2
);
3878 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
3879 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
3880 END_PROFILE(SMBtrans2
);
3881 return ERROR_DOS(ERRSRV
,ERRaccess
);
3884 outsize
= set_message(outbuf
,0,0,True
);
3886 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3887 is so as a sanity check */
3890 * Need to have rc=0 for ioctl to get job id for OS/2.
3891 * Network printing will fail if function is not successful.
3892 * Similar function in reply.c will be used if protocol
3893 * is LANMAN1.0 instead of LM1.2X002.
3894 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3895 * outbuf doesn't have to be set(only job id is used).
3897 if ( (suwcnt
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
3898 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3899 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3900 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3902 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt
));
3903 DEBUG(2,("Transaction is %d\n",tran_call
));
3904 END_PROFILE(SMBtrans2
);
3905 ERROR_DOS(ERRDOS
,ERRinvalidparam
);
3909 /* Allocate the space for the maximum needed parameters and data */
3910 if (total_params
> 0)
3911 params
= (char *)malloc(total_params
);
3913 data
= (char *)malloc(total_data
);
3915 if ((total_params
&& !params
) || (total_data
&& !data
)) {
3916 DEBUG(2,("Out of memory in reply_trans2\n"));
3919 END_PROFILE(SMBtrans2
);
3920 return ERROR_DOS(ERRDOS
,ERRnomem
);
3923 /* Copy the param and data bytes sent with this request into
3924 the params buffer */
3925 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
3926 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
3928 if (num_params
> total_params
|| num_data
> total_data
)
3929 exit_server("invalid params in reply_trans2");
3932 unsigned int psoff
= SVAL(inbuf
, smb_psoff
);
3933 if ((psoff
+ num_params
< psoff
) || (psoff
+ num_params
< num_params
))
3935 if ((smb_base(inbuf
) + psoff
+ num_params
> inbuf
+ length
) ||
3936 (smb_base(inbuf
) + psoff
+ num_params
< smb_base(inbuf
)))
3938 memcpy( params
, smb_base(inbuf
) + psoff
, num_params
);
3941 unsigned int dsoff
= SVAL(inbuf
, smb_dsoff
);
3942 if ((dsoff
+ num_data
< dsoff
) || (dsoff
+ num_data
< num_data
))
3944 if ((smb_base(inbuf
) + dsoff
+ num_data
> inbuf
+ length
) ||
3945 (smb_base(inbuf
) + dsoff
+ num_data
< smb_base(inbuf
)))
3947 memcpy( data
, smb_base(inbuf
) + dsoff
, num_data
);
3950 srv_signing_trans_start(SVAL(inbuf
,smb_mid
));
3952 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
) {
3953 /* We need to send an interim response then receive the rest
3954 of the parameter/data bytes */
3955 outsize
= set_message(outbuf
,0,0,True
);
3956 srv_signing_trans_stop();
3957 if (!send_smb(smbd_server_fd(),outbuf
))
3958 exit_server("reply_trans2: send_smb failed.");
3960 while (num_data_sofar
< total_data
||
3961 num_params_sofar
< total_params
) {
3963 unsigned int param_disp
;
3964 unsigned int param_off
;
3965 unsigned int data_disp
;
3966 unsigned int data_off
;
3968 ret
= receive_next_smb(inbuf
,bufsize
,SMB_SECONDARY_WAIT
);
3971 * The sequence number for the trans reply is always
3972 * based on the last secondary received.
3975 srv_signing_trans_start(SVAL(inbuf
,smb_mid
));
3978 (CVAL(inbuf
, smb_com
) != SMBtranss2
)) || !ret
) {
3979 outsize
= set_message(outbuf
,0,0,True
);
3981 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3983 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3984 (smb_read_error
== READ_ERROR
) ? "error" : "timeout" ));
3988 /* Revise total_params and total_data in case
3989 they have changed downwards */
3990 if (SVAL(inbuf
, smb_tpscnt
) < total_params
)
3991 total_params
= SVAL(inbuf
, smb_tpscnt
);
3992 if (SVAL(inbuf
, smb_tdscnt
) < total_data
)
3993 total_data
= SVAL(inbuf
, smb_tdscnt
);
3995 num_params
= SVAL(inbuf
,smb_spscnt
);
3996 param_off
= SVAL(inbuf
, smb_spsoff
);
3997 param_disp
= SVAL(inbuf
, smb_spsdisp
);
3998 num_params_sofar
+= num_params
;
4000 num_data
= SVAL(inbuf
, smb_sdscnt
);
4001 data_off
= SVAL(inbuf
, smb_sdsoff
);
4002 data_disp
= SVAL(inbuf
, smb_sdsdisp
);
4003 num_data_sofar
+= num_data
;
4005 if (num_params_sofar
> total_params
|| num_data_sofar
> total_data
)
4009 if (param_disp
+ num_params
>= total_params
)
4011 if ((param_disp
+ num_params
< param_disp
) ||
4012 (param_disp
+ num_params
< num_params
))
4014 if (param_disp
> total_params
)
4016 if ((smb_base(inbuf
) + param_off
+ num_params
>= inbuf
+ bufsize
) ||
4017 (smb_base(inbuf
) + param_off
+ num_params
< smb_base(inbuf
)))
4019 if (params
+ param_disp
< params
)
4022 memcpy( ¶ms
[param_disp
], smb_base(inbuf
) + param_off
, num_params
);
4025 if (data_disp
+ num_data
>= total_data
)
4027 if ((data_disp
+ num_data
< data_disp
) ||
4028 (data_disp
+ num_data
< num_data
))
4030 if (data_disp
> total_data
)
4032 if ((smb_base(inbuf
) + data_off
+ num_data
>= inbuf
+ bufsize
) ||
4033 (smb_base(inbuf
) + data_off
+ num_data
< smb_base(inbuf
)))
4035 if (data
+ data_disp
< data
)
4038 memcpy( &data
[data_disp
], smb_base(inbuf
) + data_off
, num_data
);
4043 if (Protocol
>= PROTOCOL_NT1
) {
4044 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | 0x40); /* IS_LONG_NAME */
4047 /* Now we must call the relevant TRANS2 function */
4049 case TRANSACT2_OPEN
:
4050 START_PROFILE_NESTED(Trans2_open
);
4051 outsize
= call_trans2open(conn
, inbuf
, outbuf
, bufsize
,
4052 ¶ms
, total_params
, &data
, total_data
);
4053 END_PROFILE_NESTED(Trans2_open
);
4056 case TRANSACT2_FINDFIRST
:
4057 START_PROFILE_NESTED(Trans2_findfirst
);
4058 outsize
= call_trans2findfirst(conn
, inbuf
, outbuf
, bufsize
,
4059 ¶ms
, total_params
, &data
, total_data
);
4060 END_PROFILE_NESTED(Trans2_findfirst
);
4063 case TRANSACT2_FINDNEXT
:
4064 START_PROFILE_NESTED(Trans2_findnext
);
4065 outsize
= call_trans2findnext(conn
, inbuf
, outbuf
, length
, bufsize
,
4066 ¶ms
, total_params
, &data
, total_data
);
4067 END_PROFILE_NESTED(Trans2_findnext
);
4070 case TRANSACT2_QFSINFO
:
4071 START_PROFILE_NESTED(Trans2_qfsinfo
);
4072 outsize
= call_trans2qfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4073 ¶ms
, total_params
, &data
, total_data
);
4074 END_PROFILE_NESTED(Trans2_qfsinfo
);
4077 #ifdef HAVE_SYS_QUOTAS
4078 case TRANSACT2_SETFSINFO
:
4079 START_PROFILE_NESTED(Trans2_setfsinfo
);
4080 outsize
= call_trans2setfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4081 ¶ms
, total_params
, &data
, total_data
);
4082 END_PROFILE_NESTED(Trans2_setfsinfo
);
4085 case TRANSACT2_QPATHINFO
:
4086 case TRANSACT2_QFILEINFO
:
4087 START_PROFILE_NESTED(Trans2_qpathinfo
);
4088 outsize
= call_trans2qfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4089 ¶ms
, total_params
, &data
, total_data
);
4090 END_PROFILE_NESTED(Trans2_qpathinfo
);
4092 case TRANSACT2_SETPATHINFO
:
4093 case TRANSACT2_SETFILEINFO
:
4094 START_PROFILE_NESTED(Trans2_setpathinfo
);
4095 outsize
= call_trans2setfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
4096 ¶ms
, total_params
, &data
, total_data
);
4097 END_PROFILE_NESTED(Trans2_setpathinfo
);
4100 case TRANSACT2_FINDNOTIFYFIRST
:
4101 START_PROFILE_NESTED(Trans2_findnotifyfirst
);
4102 outsize
= call_trans2findnotifyfirst(conn
, inbuf
, outbuf
, length
, bufsize
,
4103 ¶ms
, total_params
, &data
, total_data
);
4104 END_PROFILE_NESTED(Trans2_findnotifyfirst
);
4107 case TRANSACT2_FINDNOTIFYNEXT
:
4108 START_PROFILE_NESTED(Trans2_findnotifynext
);
4109 outsize
= call_trans2findnotifynext(conn
, inbuf
, outbuf
, length
, bufsize
,
4110 ¶ms
, total_params
, &data
, total_data
);
4111 END_PROFILE_NESTED(Trans2_findnotifynext
);
4113 case TRANSACT2_MKDIR
:
4114 START_PROFILE_NESTED(Trans2_mkdir
);
4115 outsize
= call_trans2mkdir(conn
, inbuf
, outbuf
, length
, bufsize
,
4116 ¶ms
, total_params
, &data
, total_data
);
4117 END_PROFILE_NESTED(Trans2_mkdir
);
4120 case TRANSACT2_GET_DFS_REFERRAL
:
4121 START_PROFILE_NESTED(Trans2_get_dfs_referral
);
4122 outsize
= call_trans2getdfsreferral(conn
,inbuf
,outbuf
,length
, bufsize
,
4123 ¶ms
, total_params
, &data
, total_data
);
4124 END_PROFILE_NESTED(Trans2_get_dfs_referral
);
4126 case TRANSACT2_IOCTL
:
4127 START_PROFILE_NESTED(Trans2_ioctl
);
4128 outsize
= call_trans2ioctl(conn
,inbuf
,outbuf
,length
, bufsize
,
4129 ¶ms
, total_params
, &data
, total_data
);
4130 END_PROFILE_NESTED(Trans2_ioctl
);
4133 /* Error in request */
4134 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call
));
4137 END_PROFILE(SMBtrans2
);
4138 srv_signing_trans_stop();
4139 return ERROR_DOS(ERRSRV
,ERRerror
);
4142 /* As we do not know how many data packets will need to be
4143 returned here the various call_trans2xxxx calls
4144 must send their own. Thus a call_trans2xxx routine only
4145 returns a value other than -1 when it wants to send
4149 srv_signing_trans_stop();
4153 END_PROFILE(SMBtrans2
);
4154 return outsize
; /* If a correct response was needed the
4155 call_trans2xxx calls have already sent
4156 it. If outsize != -1 then it is returning */
4160 srv_signing_trans_stop();
4163 END_PROFILE(SMBtrans2
);
4164 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);