2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Extensively modified by Andrew Tridgell, 1995
6 Copyright (C) Jeremy Allison 1994-2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern BOOL case_sensitive
;
27 extern int smb_read_error
;
28 extern fstring local_machine
;
29 extern int global_oplock_break
;
30 extern uint32 global_client_caps
;
31 extern pstring global_myname
;
33 #define get_file_size(sbuf) ((sbuf).st_size)
35 /* given a stat buffer return the allocated size on disk, taking into
36 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 Send the required number of replies back.
54 We assume all fields other than the data fields are
55 set correctly for the type of call.
56 HACK ! Always assumes smb_setup field is zero.
57 ****************************************************************************/
59 static int send_trans2_replies(char *outbuf
, int bufsize
, char *params
, int paramsize
, char *pdata
, int datasize
)
61 /* As we are using a protocol > LANMAN1 then the max_send
62 variable must have been set in the sessetupX call.
63 This takes precedence over the max_xmit field in the
64 global struct. These different max_xmit variables should
65 be merged as this is now too confusing */
68 int data_to_send
= datasize
;
69 int params_to_send
= paramsize
;
73 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
74 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
75 int data_alignment_offset
= 0;
77 /* Initially set the wcnt area to be 10 - this is true for all
79 set_message(outbuf
,10,0,True
);
81 /* If there genuinely are no parameters or data to send just send
84 if(params_to_send
== 0 && data_to_send
== 0) {
85 if (!send_smb(smbd_server_fd(),outbuf
))
86 exit_server("send_trans2_replies: send_smb failed.");
90 /* When sending params and data ensure that both are nicely aligned */
91 /* Only do this alignment when there is also data to send - else
92 can cause NT redirector problems. */
94 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
95 data_alignment_offset
= 4 - (params_to_send
% 4);
97 /* Space is bufsize minus Netbios over TCP header minus SMB header */
98 /* The alignment_offset is to align the param bytes on an even byte
99 boundary. NT 4.0 Beta needs this to work correctly. */
101 useable_space
= bufsize
- ((smb_buf(outbuf
)+ alignment_offset
+data_alignment_offset
) - outbuf
);
103 /* useable_space can never be more than max_send minus the alignment offset. */
105 useable_space
= MIN(useable_space
, max_send
- (alignment_offset
+data_alignment_offset
));
108 while (params_to_send
|| data_to_send
) {
109 /* Calculate whether we will totally or partially fill this packet */
111 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
+ data_alignment_offset
;
113 /* We can never send more than useable_space */
115 * Note that 'useable_space' does not include the alignment offsets,
116 * but we must include the alignment offsets in the calculation of
117 * the length of the data we send over the wire, as the alignment offsets
118 * are sent here. Fix from Marc_Jacobsen@hp.com.
121 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
+ alignment_offset
+ data_alignment_offset
);
123 set_message(outbuf
, 10, total_sent_thistime
, True
);
125 /* Set total params and data to be sent */
126 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
127 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
129 /* Calculate how many parameters and data we can fit into
130 this packet. Parameters get precedence */
132 params_sent_thistime
= MIN(params_to_send
,useable_space
);
133 data_sent_thistime
= useable_space
- params_sent_thistime
;
134 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
136 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
138 /* smb_proff is the offset from the start of the SMB header to the
139 parameter bytes, however the first 4 bytes of outbuf are
140 the Netbios over TCP header. Thus use smb_base() to subtract
141 them from the calculation */
143 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
145 if(params_sent_thistime
== 0)
146 SSVAL(outbuf
,smb_prdisp
,0);
148 /* Absolute displacement of param bytes sent in this packet */
149 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
151 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
152 if(data_sent_thistime
== 0) {
153 SSVAL(outbuf
,smb_droff
,0);
154 SSVAL(outbuf
,smb_drdisp
, 0);
156 /* The offset of the data bytes is the offset of the
157 parameter bytes plus the number of parameters being sent this time */
158 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
159 smb_base(outbuf
)) + params_sent_thistime
+ data_alignment_offset
);
160 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
163 /* Copy the param bytes into the packet */
165 if(params_sent_thistime
)
166 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
168 /* Copy in the data bytes */
170 if(data_sent_thistime
)
171 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
+
172 data_alignment_offset
,pd
,data_sent_thistime
);
174 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
175 params_sent_thistime
, data_sent_thistime
, useable_space
));
176 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
177 params_to_send
, data_to_send
, paramsize
, datasize
));
179 /* Send the packet */
180 if (!send_smb(smbd_server_fd(),outbuf
))
181 exit_server("send_trans2_replies: send_smb failed.");
183 pp
+= params_sent_thistime
;
184 pd
+= data_sent_thistime
;
186 params_to_send
-= params_sent_thistime
;
187 data_to_send
-= data_sent_thistime
;
191 if(params_to_send
< 0 || data_to_send
< 0) {
192 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
193 params_to_send
, data_to_send
));
201 /****************************************************************************
202 Reply to a TRANSACT2_OPEN.
203 ****************************************************************************/
205 static int call_trans2open(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
206 char **pparams
, int total_params
, char **ppdata
, int total_data
)
208 char *params
= *pparams
;
213 BOOL return_additional_info
;
224 int fmode
=0,mtime
=0,rmode
;
226 SMB_STRUCT_STAT sbuf
;
228 BOOL bad_path
= False
;
232 * Ensure we have enough parameters to perform the operation.
235 if (total_params
< 29)
236 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
238 open_mode
= SVAL(params
, 2);
239 open_attr
= SVAL(params
,6);
240 oplock_request
= (((SVAL(params
,0)|(1<<1))>>1) | ((SVAL(params
,0)|(1<<2))>>1));
242 return_additional_info
= BITSETW(params
,0);
243 open_sattr
= SVAL(params
, 4);
244 open_time
= make_unix_date3(params
+8);
246 open_ofun
= SVAL(params
,12);
247 open_size
= IVAL(params
,14);
250 pstrcpy(fname
, pname
);
252 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
253 fname
,open_mode
, open_attr
, open_ofun
, open_size
));
256 return(ERROR_DOS(ERRSRV
,ERRaccess
));
258 /* XXXX we need to handle passed times, sattr and flags */
260 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
262 if (!check_name(fname
,conn
)) {
263 set_bad_path_error(errno
, bad_path
);
264 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
267 unixmode
= unix_mode(conn
,open_attr
| aARCH
, fname
);
269 fsp
= open_file_shared(conn
,fname
,&sbuf
,open_mode
,open_ofun
,unixmode
,
270 oplock_request
, &rmode
,&smb_action
);
273 set_bad_path_error(errno
, bad_path
);
274 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
277 size
= get_file_size(sbuf
);
278 fmode
= dos_mode(conn
,fname
,&sbuf
);
279 mtime
= sbuf
.st_mtime
;
282 close_file(fsp
,False
);
283 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
286 /* Realloc the size of parameters and data we will return */
287 params
= Realloc(*pparams
, 28);
289 return(ERROR_DOS(ERRDOS
,ERRnomem
));
292 memset((char *)params
,'\0',28);
293 SSVAL(params
,0,fsp
->fnum
);
294 SSVAL(params
,2,fmode
);
295 put_dos_date2(params
,4, mtime
);
296 SIVAL(params
,8, (uint32
)size
);
297 SSVAL(params
,12,rmode
);
299 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
300 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
302 SSVAL(params
,18,smb_action
);
305 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
307 SIVAL(params
,20,inode
);
309 /* Send the required number of replies */
310 send_trans2_replies(outbuf
, bufsize
, params
, 28, *ppdata
, 0);
315 /*********************************************************
316 Routine to check if a given string matches exactly.
317 as a special case a mask of "." does NOT match. That
318 is required for correct wildcard semantics
319 Case can be significant or not.
320 **********************************************************/
322 static BOOL
exact_match(char *str
,char *mask
, BOOL case_sig
)
324 if (mask
[0] == '.' && mask
[1] == 0)
327 return strcmp(str
,mask
)==0;
328 return strcasecmp(str
,mask
) == 0;
331 /****************************************************************************
332 Return the filetype for UNIX extensions.
333 ****************************************************************************/
335 static uint32
unix_filetype(mode_t mode
)
338 return UNIX_TYPE_FILE
;
339 else if(S_ISDIR(mode
))
340 return UNIX_TYPE_DIR
;
342 else if(S_ISLNK(mode
))
343 return UNIX_TYPE_SYMLINK
;
346 else if(S_ISCHR(mode
))
347 return UNIX_TYPE_CHARDEV
;
350 else if(S_ISBLK(mode
))
351 return UNIX_TYPE_BLKDEV
;
354 else if(S_ISFIFO(mode
))
355 return UNIX_TYPE_FIFO
;
358 else if(S_ISSOCK(mode
))
359 return UNIX_TYPE_SOCKET
;
362 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode
));
363 return UNIX_TYPE_UNKNOWN
;
366 /****************************************************************************
367 Return the major devicenumber for UNIX extensions.
368 ****************************************************************************/
370 static uint32
unix_dev_major(SMB_DEV_T dev
)
372 #if defined(HAVE_DEVICE_MAJOR_FN)
373 return (uint32
)major(dev
);
375 return (uint32
)(dev
>> 8);
379 /****************************************************************************
380 Return the minor devicenumber for UNIX extensions.
381 ****************************************************************************/
383 static uint32
unix_dev_minor(SMB_DEV_T dev
)
385 #if defined(HAVE_DEVICE_MINOR_FN)
386 return (uint32
)minor(dev
);
388 return (uint32
)(dev
& 0xff);
392 /****************************************************************************
393 Map wire perms onto standard UNIX permissions. Obey share restrictions.
394 ****************************************************************************/
396 static mode_t
unix_perms_from_wire( connection_struct
*conn
, SMB_STRUCT_STAT
*pst
, uint32 perms
)
400 if (perms
== SMB_MODE_NO_CHANGE
)
403 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
404 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
405 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
406 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
407 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
408 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
409 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
410 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
411 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
413 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
416 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
419 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
422 if (VALID_STAT(*pst
) && S_ISDIR(pst
->st_mode
)) {
423 ret
&= lp_dir_mask(SNUM(conn
));
424 /* Add in force bits */
425 ret
|= lp_force_dir_mode(SNUM(conn
));
427 /* Apply mode mask */
428 ret
&= lp_create_mask(SNUM(conn
));
429 /* Add in force bits */
430 ret
|= lp_force_create_mode(SNUM(conn
));
436 /****************************************************************************
437 checks for SMB_TIME_NO_CHANGE and if not found
438 calls interpret_long_date
439 ****************************************************************************/
440 time_t interpret_long_unix_date(char *p
)
442 DEBUG(1,("interpret_long_unix_date\n"));
443 if(IVAL(p
,0) == SMB_TIME_NO_CHANGE_LO
&&
444 IVAL(p
,4) == SMB_TIME_NO_CHANGE_HI
) {
447 return interpret_long_date(p
);
451 /****************************************************************************
452 Get a level dependent lanman2 dir entry.
453 ****************************************************************************/
455 static BOOL
get_lanman2_dir_entry(connection_struct
*conn
,
456 char *path_mask
,int dirtype
,int info_level
,
457 int requires_resume_key
,
458 BOOL dont_descend
,char **ppdata
,
459 char *base_data
, int space_remaining
,
460 BOOL
*out_of_space
, BOOL
*got_exact_match
,
465 SMB_STRUCT_STAT sbuf
;
469 char *p
, *pdata
= *ppdata
;
474 SMB_BIG_UINT allocation_size
= 0;
476 time_t mdate
=0, adate
=0, cdate
=0;
479 int nt_extmode
; /* Used for NT connections instead of mode */
480 BOOL needslash
= ( conn
->dirpath
[strlen(conn
->dirpath
) -1] != '/');
483 *out_of_space
= False
;
484 *got_exact_match
= False
;
489 p
= strrchr(path_mask
,'/');
496 pstrcpy(mask
, path_mask
);
501 /* Needed if we run out of space */
502 prev_dirpos
= TellDir(conn
->dirptr
);
503 dname
= ReadDirName(conn
->dirptr
);
506 * Due to bugs in NT client redirectors we are not using
507 * resume keys any more - set them to zero.
508 * Check out the related comments in findfirst/findnext.
514 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
515 (long)conn
->dirptr
,TellDir(conn
->dirptr
)));
520 pstrcpy(fname
,dname
);
522 if(!(got_match
= *got_exact_match
= exact_match(fname
, mask
, case_sensitive
)))
523 got_match
= mask_match(fname
, mask
, case_sensitive
);
525 if(!got_match
&& !mangle_is_8_3(fname
, False
)) {
528 * It turns out that NT matches wildcards against
529 * both long *and* short names. This may explain some
530 * of the wildcard wierdness from old DOS clients
531 * that some people have been seeing.... JRA.
535 pstrcpy( newname
, fname
);
536 mangle_map( newname
, True
, False
, SNUM(conn
));
537 if(!(got_match
= *got_exact_match
= exact_match(newname
, mask
, case_sensitive
)))
538 got_match
= mask_match(newname
, mask
, case_sensitive
);
542 BOOL isdots
= (strequal(fname
,"..") || strequal(fname
,"."));
543 if (dont_descend
&& !isdots
)
546 pstrcpy(pathreal
,conn
->dirpath
);
548 pstrcat(pathreal
,"/");
549 pstrcat(pathreal
,dname
);
551 if (INFO_LEVEL_IS_UNIX(info_level
)) {
552 if (vfs_lstat(conn
,pathreal
,&sbuf
) != 0) {
553 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
554 pathreal
,strerror(errno
)));
557 } else if (vfs_stat(conn
,pathreal
,&sbuf
) != 0) {
559 /* Needed to show the msdfs symlinks as
562 if(lp_host_msdfs() &&
563 lp_msdfs_root(SNUM(conn
)) &&
564 is_msdfs_link(conn
, pathreal
, NULL
, NULL
,
567 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal
));
568 sbuf
.st_mode
= (sbuf
.st_mode
& 0xFFF) | S_IFDIR
;
572 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
573 pathreal
,strerror(errno
)));
578 mode
= dos_mode(conn
,pathreal
,&sbuf
);
580 if (!dir_check_ftype(conn
,mode
,&sbuf
,dirtype
)) {
581 DEBUG(5,("[%s] attribs didn't match %x\n",fname
,dirtype
));
585 size
= get_file_size(sbuf
);
586 allocation_size
= get_allocation_size(NULL
,&sbuf
);
587 mdate
= sbuf
.st_mtime
;
588 adate
= sbuf
.st_atime
;
589 cdate
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
591 if (lp_dos_filetime_resolution(SNUM(conn
))) {
600 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal
,fname
));
606 mangle_map(fname
,False
,True
,SNUM(conn
));
611 nt_extmode
= mode
? mode
: FILE_ATTRIBUTE_NORMAL
;
613 switch (info_level
) {
615 if(requires_resume_key
) {
619 put_dos_date2(p
,l1_fdateCreation
,cdate
);
620 put_dos_date2(p
,l1_fdateLastAccess
,adate
);
621 put_dos_date2(p
,l1_fdateLastWrite
,mdate
);
622 SIVAL(p
,l1_cbFile
,(uint32
)size
);
623 SIVAL(p
,l1_cbFileAlloc
,(uint32
)allocation_size
);
624 SSVAL(p
,l1_attrFile
,mode
);
625 SCVAL(p
,l1_cchName
,strlen(fname
));
626 pstrcpy(p
+ l1_achName
, fname
);
627 nameptr
= p
+ l1_achName
;
628 p
+= l1_achName
+ strlen(fname
) + 1;
632 if(requires_resume_key
) {
636 put_dos_date2(p
,l2_fdateCreation
,cdate
);
637 put_dos_date2(p
,l2_fdateLastAccess
,adate
);
638 put_dos_date2(p
,l2_fdateLastWrite
,mdate
);
639 SIVAL(p
,l2_cbFile
,(uint32
)size
);
640 SIVAL(p
,l2_cbFileAlloc
,(uint32
)allocation_size
);
641 SSVAL(p
,l2_attrFile
,mode
);
642 SIVAL(p
,l2_cbList
,0); /* No extended attributes */
643 SCVAL(p
,l2_cchName
,strlen(fname
));
644 pstrcpy(p
+ l2_achName
, fname
);
645 nameptr
= p
+ l2_achName
;
646 p
+= l2_achName
+ strlen(fname
) + 1;
651 put_dos_date2(p
,4,cdate
);
652 put_dos_date2(p
,8,adate
);
653 put_dos_date2(p
,12,mdate
);
654 SIVAL(p
,16,(uint32
)size
);
655 SIVAL(p
,20,(uint32
)allocation_size
);
658 SCVAL(p
,30,strlen(fname
));
659 pstrcpy(p
+31, fname
);
661 p
+= 31 + strlen(fname
) + 1;
665 if(requires_resume_key
) {
669 SIVAL(p
,0,33+strlen(fname
)+1);
670 put_dos_date2(p
,4,cdate
);
671 put_dos_date2(p
,8,adate
);
672 put_dos_date2(p
,12,mdate
);
673 SIVAL(p
,16,(uint32
)size
);
674 SIVAL(p
,20,(uint32
)allocation_size
);
676 SCVAL(p
,32,strlen(fname
));
677 pstrcpy(p
+ 33, fname
);
679 p
+= 33 + strlen(fname
) + 1;
682 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
683 was_8_3
= mangle_is_8_3(fname
, True
);
684 len
= 94+strlen(fname
);
685 len
= (len
+ 3) & ~3;
686 SIVAL(p
,0,len
); p
+= 4;
687 SIVAL(p
,0,reskey
); p
+= 4;
688 put_long_date(p
,cdate
); p
+= 8;
689 put_long_date(p
,adate
); p
+= 8;
690 put_long_date(p
,mdate
); p
+= 8;
691 put_long_date(p
,mdate
); p
+= 8;
693 SOFF_T(p
,8,allocation_size
);
695 SIVAL(p
,0,nt_extmode
); p
+= 4;
696 SIVAL(p
,0,strlen(fname
)); p
+= 4;
697 SIVAL(p
,0,0); p
+= 4;
698 /* Clear the short name buffer. This is
699 * IMPORTANT as not doing so will trigger
700 * a Win2k client bug. JRA.
705 fstrcpy(tmpname
,fname
);
706 mangle_map(tmpname
,True
,True
,SNUM(conn
));
708 fstrcpy(p
+2,tmpname
);
709 SSVAL(p
, 0, strlen(tmpname
));
716 pstrcpy(p
,fname
); p
+= strlen(p
);
720 case SMB_FIND_FILE_DIRECTORY_INFO
:
721 len
= 64+strlen(fname
);
722 len
= (len
+ 3) & ~3;
723 SIVAL(p
,0,len
); p
+= 4;
724 SIVAL(p
,0,reskey
); p
+= 4;
725 put_long_date(p
,cdate
); p
+= 8;
726 put_long_date(p
,adate
); p
+= 8;
727 put_long_date(p
,mdate
); p
+= 8;
728 put_long_date(p
,mdate
); p
+= 8;
730 SOFF_T(p
,8,allocation_size
);
732 SIVAL(p
,0,nt_extmode
); p
+= 4;
733 SIVAL(p
,0,strlen(fname
)); p
+= 4;
738 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
739 len
= 68+strlen(fname
);
740 len
= (len
+ 3) & ~3;
741 SIVAL(p
,0,len
); p
+= 4;
742 SIVAL(p
,0,reskey
); p
+= 4;
743 put_long_date(p
,cdate
); p
+= 8;
744 put_long_date(p
,adate
); p
+= 8;
745 put_long_date(p
,mdate
); p
+= 8;
746 put_long_date(p
,mdate
); p
+= 8;
748 SOFF_T(p
,8,allocation_size
);
750 SIVAL(p
,0,nt_extmode
); p
+= 4;
751 SIVAL(p
,0,strlen(fname
)); p
+= 4;
752 SIVAL(p
,0,0); p
+= 4;
757 case SMB_FIND_FILE_NAMES_INFO
:
758 len
= 12+strlen(fname
);
759 len
= (len
+ 3) & ~3;
760 SIVAL(p
,0,len
); p
+= 4;
761 SIVAL(p
,0,reskey
); p
+= 4;
762 SIVAL(p
,0,strlen(fname
)); p
+= 4;
767 /* CIFS UNIX Extension. */
769 case SMB_FIND_FILE_UNIX
:
770 len
= 108+strlen(fname
)+1; /* (length of SMB_QUERY_FILE_UNIX_BASIC = 100)+4+4+strlen(fname)*/
771 /* +1 to be sure to transmit the termination of fname */
772 len
= (len
+ 3) & ~3;
774 SIVAL(p
,0,len
); p
+= 4; /* Offset from this structure to the beginning of the next one */
775 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
777 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
778 SOFF_T(p
,0,get_file_size(sbuf
)); /* File size 64 Bit */
781 SOFF_T(p
,0,get_allocation_size(NULL
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
784 put_long_date(p
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
785 put_long_date(p
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
786 put_long_date(p
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
789 SIVAL(p
,0,sbuf
.st_uid
); /* user id for the owner */
793 SIVAL(p
,0,sbuf
.st_gid
); /* group id of owner */
797 SIVAL(p
,0,unix_filetype(sbuf
.st_mode
));
800 SIVAL(p
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
804 SIVAL(p
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
808 SINO_T(p
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
811 SIVAL(p
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
815 SIVAL(p
,0,sbuf
.st_nlink
); /* number of hard links */
819 /* End of SMB_QUERY_FILE_UNIX_BASIC */
830 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
831 /* Move the dirptr back to prev_dirpos */
832 SeekDir(conn
->dirptr
, prev_dirpos
);
833 *out_of_space
= True
;
834 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
835 return False
; /* Not finished - just out of space */
838 /* Setup the last_filename pointer, as an offset from base_data */
839 *last_name_off
= PTR_DIFF(nameptr
,base_data
);
840 /* Advance the data pointer to the next slot */
846 /****************************************************************************
847 Reply to a TRANS2_FINDFIRST.
848 ****************************************************************************/
850 static int call_trans2findfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
851 char **pparams
, int total_params
, char **ppdata
, int total_data
)
853 /* We must be careful here that we don't return more than the
854 allowed number of data bytes. If this means returning fewer than
855 maxentries then so be it. We assume that the redirector has
856 enough room for the fixed number of parameter bytes it has
858 uint32 max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
859 char *params
= *pparams
;
860 char *pdata
= *ppdata
;
863 BOOL close_after_first
;
865 BOOL requires_resume_key
;
874 BOOL finished
= False
;
875 BOOL dont_descend
= False
;
876 BOOL out_of_space
= False
;
878 BOOL bad_path
= False
;
879 SMB_STRUCT_STAT sbuf
;
881 if (total_params
< 12)
882 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
884 *directory
= *mask
= 0;
886 dirtype
= SVAL(params
,0);
887 maxentries
= SVAL(params
,2);
888 close_after_first
= BITSETW(params
+4,0);
889 close_if_end
= BITSETW(params
+4,1);
890 requires_resume_key
= BITSETW(params
+4,2);
891 info_level
= SVAL(params
,6);
893 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
894 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
895 dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
896 info_level
, max_data_bytes
));
898 switch (info_level
) {
903 case SMB_FIND_FILE_DIRECTORY_INFO
:
904 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
905 case SMB_FIND_FILE_NAMES_INFO
:
906 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
908 case SMB_FIND_FILE_UNIX
:
909 if (!lp_unix_extensions())
910 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
913 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
916 pstrcpy(directory
, params
+ 12); /* Complete directory path with wildcard mask appended */
918 RESOLVE_FINDFIRST_DFSPATH(directory
, conn
, inbuf
, outbuf
);
920 DEBUG(5,("path=%s\n",directory
));
922 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
923 if(!check_name(directory
,conn
)) {
924 set_bad_path_error(errno
, bad_path
);
927 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
928 if((errno
== ENOTDIR
) && (Protocol
>= PROTOCOL_NT1
) && (get_remote_arch() == RA_WINNT
)) {
929 unix_ERR_class
= ERRDOS
;
930 unix_ERR_code
= ERRbaddirectory
;
934 return(UNIXERROR(ERRDOS
,ERRbadpath
));
937 p
= strrchr(directory
,'/');
939 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
940 if((directory
[0] == '.') && (directory
[1] == '\0'))
943 pstrcpy(mask
,directory
);
944 pstrcpy(directory
,"./");
950 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
952 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
954 return(ERROR_DOS(ERRDOS
,ERRnomem
));
956 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
958 /* Realloc the params space */
959 params
= Realloc(*pparams
, 10);
961 return ERROR_DOS(ERRDOS
,ERRnomem
);
964 dptr_num
= dptr_create(conn
,directory
, False
, True
,SVAL(inbuf
,smb_pid
));
966 return(UNIXERROR(ERRDOS
,ERRbadfile
));
968 /* Save the wildcard match and attribs we are using on this directory -
969 needed as lanman2 assumes these are being saved between calls */
971 if(!(wcard
= strdup(mask
))) {
972 dptr_close(&dptr_num
);
973 return ERROR_DOS(ERRDOS
,ERRnomem
);
976 dptr_set_wcard(dptr_num
, wcard
);
977 dptr_set_attr(dptr_num
, dirtype
);
979 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num
, wcard
, dirtype
));
981 /* We don't need to check for VOL here as this is returned by
982 a different TRANS2 call. */
984 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
986 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
990 space_remaining
= max_data_bytes
;
991 out_of_space
= False
;
993 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
994 BOOL got_exact_match
= False
;
996 /* this is a heuristic to avoid seeking the dirptr except when
997 absolutely necessary. It allows for a filename of about 40 chars */
999 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1000 out_of_space
= True
;
1003 finished
= !get_lanman2_dir_entry(conn
,mask
,dirtype
,info_level
,
1004 requires_resume_key
,dont_descend
,
1005 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1009 if (finished
&& out_of_space
)
1012 if (!finished
&& !out_of_space
)
1016 * As an optimisation if we know we aren't looking
1017 * for a wildcard name (ie. the name matches the wildcard exactly)
1018 * then we can finish on any (first) match.
1019 * This speeds up large directory searches. JRA.
1025 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1028 /* Check if we can close the dirptr */
1030 if(close_after_first
|| (finished
&& close_if_end
)) {
1031 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
1032 dptr_close(&dptr_num
);
1036 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1037 * from observation of NT.
1040 if(numentries
== 0) {
1041 dptr_close(&dptr_num
);
1042 return ERROR_DOS(ERRDOS
,ERRbadfile
);
1045 /* At this point pdata points to numentries directory entries. */
1047 /* Set up the return parameter block */
1048 SSVAL(params
,0,dptr_num
);
1049 SSVAL(params
,2,numentries
);
1050 SSVAL(params
,4,finished
);
1051 SSVAL(params
,6,0); /* Never an EA error */
1052 SSVAL(params
,8,last_name_off
);
1054 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
));
1056 if ((! *directory
) && dptr_path(dptr_num
))
1057 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1059 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1060 smb_fn_name(CVAL(inbuf
,smb_com
)),
1061 mask
, directory
, dirtype
, numentries
) );
1064 * Force a name mangle here to ensure that the
1065 * mask as an 8.3 name is top of the mangled cache.
1066 * The reasons for this are subtle. Don't remove
1067 * this code unless you know what you are doing
1068 * (see PR#13758). JRA.
1071 if(!mangle_is_8_3_wildcards( mask
, False
))
1072 mangle_map(mask
, True
, True
, SNUM(conn
));
1077 /****************************************************************************
1078 Reply to a TRANS2_FINDNEXT.
1079 ****************************************************************************/
1081 static int call_trans2findnext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1082 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1084 /* We must be careful here that we don't return more than the
1085 allowed number of data bytes. If this means returning fewer than
1086 maxentries then so be it. We assume that the redirector has
1087 enough room for the fixed number of parameter bytes it has
1089 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1090 char *params
= *pparams
;
1091 char *pdata
= *ppdata
;
1096 BOOL close_after_request
;
1098 BOOL requires_resume_key
;
1100 pstring resume_name
;
1106 int i
, last_name_off
=0;
1107 BOOL finished
= False
;
1108 BOOL dont_descend
= False
;
1109 BOOL out_of_space
= False
;
1110 int space_remaining
;
1112 if (total_params
< 12)
1113 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1115 dptr_num
= SVAL(params
,0);
1116 maxentries
= SVAL(params
,2);
1117 info_level
= SVAL(params
,4);
1118 resume_key
= IVAL(params
,6);
1119 close_after_request
= BITSETW(params
+10,0);
1120 close_if_end
= BITSETW(params
+10,1);
1121 requires_resume_key
= BITSETW(params
+10,2);
1122 continue_bit
= BITSETW(params
+10,3);
1124 *mask
= *directory
= *resume_name
= 0;
1126 pstrcpy( resume_name
, params
+12);
1128 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1129 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1130 resume_key = %d resume name = %s continue=%d level = %d\n",
1131 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
1132 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
1134 switch (info_level
) {
1139 case SMB_FIND_FILE_DIRECTORY_INFO
:
1140 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1141 case SMB_FIND_FILE_NAMES_INFO
:
1142 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1144 case SMB_FIND_FILE_UNIX
:
1145 if (!lp_unix_extensions())
1146 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1149 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1152 pdata
= Realloc( *ppdata
, max_data_bytes
+ 1024);
1154 return ERROR_DOS(ERRDOS
,ERRnomem
);
1157 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1159 /* Realloc the params space */
1160 params
= Realloc(*pparams
, 6*SIZEOFWORD
);
1161 if( params
== NULL
)
1162 return ERROR_DOS(ERRDOS
,ERRnomem
);
1165 /* Check that the dptr is valid */
1166 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
)))
1167 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1169 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1171 /* Get the wildcard mask from the dptr */
1172 if((p
= dptr_wcard(dptr_num
))== NULL
) {
1173 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
1174 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1177 pstrcpy(directory
,conn
->dirpath
);
1179 /* Get the attr mask from the dptr */
1180 dirtype
= dptr_attr(dptr_num
);
1182 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1183 dptr_num
, mask
, dirtype
, (long)conn
->dirptr
, TellDir(conn
->dirptr
)));
1185 /* We don't need to check for VOL here as this is returned by
1186 a different TRANS2 call. */
1188 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1189 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
1190 dont_descend
= True
;
1193 space_remaining
= max_data_bytes
;
1194 out_of_space
= False
;
1197 * Seek to the correct position. We no longer use the resume key but
1198 * depend on the last file name instead.
1201 if(requires_resume_key
&& *resume_name
&& !continue_bit
) {
1204 * Fix for NT redirector problem triggered by resume key indexes
1205 * changing between directory scans. We now return a resume key of 0
1206 * and instead look for the filename to continue from (also given
1207 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1208 * findfirst/findnext (as is usual) then the directory pointer
1209 * should already be at the correct place. Check this by scanning
1210 * backwards looking for an exact (ie. case sensitive) filename match.
1211 * If we get to the beginning of the directory and haven't found it then scan
1212 * forwards again looking for a match. JRA.
1215 int current_pos
, start_pos
;
1217 void *dirptr
= conn
->dirptr
;
1218 start_pos
= TellDir(dirptr
);
1220 for(current_pos
= start_pos
; current_pos
>= 0; current_pos
--) {
1221 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos
));
1223 SeekDir(dirptr
, current_pos
);
1224 dname
= ReadDirName(dirptr
);
1227 * Remember, name_map_mangle is called by
1228 * get_lanman2_dir_entry(), so the resume name
1229 * could be mangled. Ensure we do the same
1234 mangle_map( dname
, False
, True
, SNUM(conn
));
1236 if(dname
&& strcsequal( resume_name
, dname
)) {
1237 SeekDir(dirptr
, current_pos
+1);
1238 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1244 * Scan forward from start if not found going backwards.
1247 if(current_pos
< 0) {
1248 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos
));
1249 SeekDir(dirptr
, start_pos
);
1250 for(current_pos
= start_pos
; (dname
= ReadDirName(dirptr
)) != NULL
; SeekDir(dirptr
,++current_pos
)) {
1253 * Remember, name_map_mangle is called by
1254 * get_lanman2_dir_entry(), so the resume name
1255 * could be mangled. Ensure we do the same
1260 mangle_map( dname
, False
, True
, SNUM(conn
));
1262 if(dname
&& strcsequal( resume_name
, dname
)) {
1263 SeekDir(dirptr
, current_pos
+1);
1264 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1268 } /* end if current_pos */
1269 } /* end if requires_resume_key && !continue_bit */
1271 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
1272 BOOL got_exact_match
= False
;
1274 /* this is a heuristic to avoid seeking the dirptr except when
1275 absolutely necessary. It allows for a filename of about 40 chars */
1277 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1278 out_of_space
= True
;
1281 finished
= !get_lanman2_dir_entry(conn
,mask
,dirtype
,info_level
,
1282 requires_resume_key
,dont_descend
,
1283 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1287 if (finished
&& out_of_space
)
1290 if (!finished
&& !out_of_space
)
1294 * As an optimisation if we know we aren't looking
1295 * for a wildcard name (ie. the name matches the wildcard exactly)
1296 * then we can finish on any (first) match.
1297 * This speeds up large directory searches. JRA.
1303 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1306 /* Check if we can close the dirptr */
1307 if(close_after_request
|| (finished
&& close_if_end
)) {
1308 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
1309 dptr_close(&dptr_num
); /* This frees up the saved mask */
1313 /* Set up the return parameter block */
1314 SSVAL(params
,0,numentries
);
1315 SSVAL(params
,2,finished
);
1316 SSVAL(params
,4,0); /* Never an EA error */
1317 SSVAL(params
,6,last_name_off
);
1319 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
1321 if ((! *directory
) && dptr_path(dptr_num
))
1322 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1324 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1325 smb_fn_name(CVAL(inbuf
,smb_com
)),
1326 mask
, directory
, dirtype
, numentries
) );
1331 /****************************************************************************
1332 Reply to a TRANS2_QFSINFO (query filesystem info).
1333 ****************************************************************************/
1335 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1336 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1338 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1339 char *pdata
= *ppdata
;
1340 char *params
= *pparams
;
1344 char *vname
= volume_label(SNUM(conn
));
1345 int snum
= SNUM(conn
);
1346 char *fstype
= lp_fstype(SNUM(conn
));
1348 if (total_params
< 2)
1349 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1351 info_level
= SVAL(params
,0);
1352 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
1354 if(vfs_stat(conn
,".",&st
)!=0) {
1355 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
1356 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
1359 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
1360 if ( pdata
== NULL
)
1361 return ERROR_DOS(ERRDOS
,ERRnomem
);
1364 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1366 switch (info_level
) {
1369 SMB_BIG_UINT dfree
,dsize
,bsize
;
1371 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1372 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
1373 SIVAL(pdata
,l1_cSectorUnit
,bsize
/512);
1374 SIVAL(pdata
,l1_cUnit
,dsize
);
1375 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
1376 SSVAL(pdata
,l1_cbSector
,512);
1377 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1378 (unsigned int)bsize
, (unsigned int)st
.st_dev
, ((unsigned int)bsize
)/512, (unsigned int)dsize
,
1379 (unsigned int)dfree
, 512));
1385 /* Return volume name */
1386 int volname_len
= MIN(strlen(vname
),11);
1387 data_len
= l2_vol_szVolLabel
+ volname_len
+ 1;
1389 * Add volume serial number - hash of a combination of
1390 * the called hostname and the service name.
1392 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(local_machine
)<<16) );
1393 SCVAL(pdata
,l2_vol_cch
,volname_len
);
1394 StrnCpy(pdata
+l2_vol_szVolLabel
,vname
,volname_len
);
1395 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1396 (unsigned)st
.st_ctime
, volname_len
,
1397 pdata
+l2_vol_szVolLabel
));
1401 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
1402 case SMB_FS_ATTRIBUTE_INFORMATION
:
1405 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
1406 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)); /* FS ATTRIBUTES */
1407 #if 0 /* Old code. JRA. */
1408 SIVAL(pdata
,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1409 SIVAL(pdata
,0,0x700FF);
1410 #endif /* Old code. */
1412 SIVAL(pdata
,4,255); /* Max filename component length */
1413 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1414 and will think we can't do long filenames */
1415 fstype_len
= dos_PutUniCode(pdata
+12,unix_to_dos_static(fstype
),sizeof(pstring
), False
);
1416 SIVAL(pdata
,8,fstype_len
);
1417 data_len
= 12 + fstype_len
;
1418 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1422 case SMB_QUERY_FS_LABEL_INFO
:
1423 case SMB_FS_LABEL_INFORMATION
:
1424 data_len
= 4 + strlen(vname
);
1425 SIVAL(pdata
,0,strlen(vname
));
1426 pstrcpy(pdata
+4,vname
);
1429 case SMB_QUERY_FS_VOLUME_INFO
:
1430 case SMB_FS_VOLUME_INFORMATION
:
1432 * Add volume serial number - hash of a combination of
1433 * the called hostname and the service name.
1435 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
1436 (str_checksum(local_machine
)<<16));
1438 /* NT4 always serves this up as unicode but expects it to be
1439 * delivered as ascii! (tridge && JRA)
1441 if ((get_remote_arch() != RA_WIN2K
) && (global_client_caps
& CAP_NT_SMBS
)) {
1442 data_len
= 18 + strlen(vname
);
1443 SIVAL(pdata
,12,strlen(vname
));
1444 pstrcpy(pdata
+18,vname
);
1448 vnamelen
= dos_PutUniCode(pdata
+18, vname
, sizeof(pstring
), False
);
1449 data_len
= 18 + vnamelen
;
1450 SIVAL(pdata
,12,vnamelen
);
1451 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1454 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1455 (int)strlen(vname
),vname
));
1458 case SMB_QUERY_FS_SIZE_INFO
:
1459 case SMB_FS_SIZE_INFORMATION
:
1461 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1463 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1464 block_size
= lp_block_size(snum
);
1465 if (bsize
< block_size
) {
1466 SMB_BIG_UINT factor
= block_size
/bsize
;
1471 if (bsize
> block_size
) {
1472 SMB_BIG_UINT factor
= bsize
/block_size
;
1477 bytes_per_sector
= 512;
1478 sectors_per_unit
= bsize
/bytes_per_sector
;
1479 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1480 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1481 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1482 SBIG_UINT(pdata
,0,dsize
);
1483 SBIG_UINT(pdata
,8,dfree
);
1484 SIVAL(pdata
,16,sectors_per_unit
);
1485 SIVAL(pdata
,20,bytes_per_sector
);
1489 case SMB_FS_FULL_SIZE_INFORMATION
:
1491 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1493 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1494 block_size
= lp_block_size(snum
);
1495 if (bsize
< block_size
) {
1496 SMB_BIG_UINT factor
= block_size
/bsize
;
1501 if (bsize
> block_size
) {
1502 SMB_BIG_UINT factor
= bsize
/block_size
;
1507 bytes_per_sector
= 512;
1508 sectors_per_unit
= bsize
/bytes_per_sector
;
1509 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1510 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1511 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1512 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
1513 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
1514 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
1515 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
1516 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
1520 case SMB_QUERY_FS_DEVICE_INFO
:
1521 case SMB_FS_DEVICE_INFORMATION
:
1523 SIVAL(pdata
,0,0); /* dev type */
1524 SIVAL(pdata
,4,0); /* characteristics */
1527 case SMB_FS_OBJECTID_INFORMATION
:
1532 * Query the version and capabilities of the CIFS UNIX extensions
1536 case SMB_QUERY_CIFS_UNIX_INFO
:
1538 if (!lp_unix_extensions())
1539 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1542 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
1543 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
1544 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)0)); /* No capabilities for now... */
1547 case SMB_MAC_QUERY_FS_INFO
:
1549 * Thursby MAC extension... ONLY on NTFS filesystems
1550 * once we do streams then we don't need this
1552 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
1554 SIVAL(pdata
,84,0x100); /* Don't support mac... */
1559 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1562 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
1564 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
1569 /****************************************************************************
1570 Reply to a TRANS2_SETFSINFO (set filesystem info).
1571 ****************************************************************************/
1573 static int call_trans2setfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1574 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1576 /* Just say yes we did it - there is nothing that
1577 can be set here so it doesn't matter. */
1579 DEBUG(3,("call_trans2setfsinfo\n"));
1581 if (!CAN_WRITE(conn
))
1582 return(ERROR_DOS(ERRSRV
,ERRaccess
));
1584 outsize
= set_message(outbuf
,10,0,True
);
1589 /****************************************************************************
1590 Utility function to set bad path error.
1591 ****************************************************************************/
1593 NTSTATUS
set_bad_path_error(int err
, BOOL bad_path
)
1595 if((err
== ENOENT
) && bad_path
) {
1596 unix_ERR_class
= ERRDOS
;
1597 unix_ERR_code
= ERRbadpath
;
1598 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1600 return NT_STATUS_OK
;
1603 /****************************************************************************
1604 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1605 file name or file id).
1606 ****************************************************************************/
1608 static int call_trans2qfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1609 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1611 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1612 char *params
= *pparams
;
1613 char *pdata
= *ppdata
;
1614 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
1618 SMB_BIG_UINT allocation_size
= 0;
1619 unsigned int data_size
;
1620 SMB_STRUCT_STAT sbuf
;
1628 BOOL bad_path
= False
;
1629 BOOL delete_pending
= False
;
1631 files_struct
*fsp
= NULL
;
1634 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1636 if (tran_call
== TRANSACT2_QFILEINFO
) {
1637 if (total_params
< 4)
1638 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1640 fsp
= file_fsp(params
,0);
1641 info_level
= SVAL(params
,2);
1643 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
1645 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
1647 * This is actually a QFILEINFO on a directory
1648 * handle (returned from an NT SMB). NT5.0 seems
1649 * to do this call. JRA.
1651 fname
= fsp
->fsp_name
;
1652 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1653 if (!check_name(fname
,conn
)) {
1654 DEBUG(3,("call_trans2qfilepathinfo: check_name of %s failed (%s)\n",fname
,strerror(errno
)));
1655 set_bad_path_error(errno
, bad_path
);
1656 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1659 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1660 /* Always do lstat for UNIX calls. */
1661 if (vfs_lstat(conn
,fname
,&sbuf
)) {
1662 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname
,strerror(errno
)));
1663 set_bad_path_error(errno
, bad_path
);
1664 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1666 } else if (!VALID_STAT(sbuf
) && vfs_stat(conn
,fname
,&sbuf
)) {
1667 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname
,strerror(errno
)));
1668 set_bad_path_error(errno
, bad_path
);
1669 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1672 delete_pending
= fsp
->directory_delete_on_close
;
1676 * Original code - this is an open file.
1678 CHECK_FSP(fsp
,conn
);
1680 fname
= fsp
->fsp_name
;
1681 if (vfs_fstat(fsp
,fsp
->fd
,&sbuf
) != 0) {
1682 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
1683 return(UNIXERROR(ERRDOS
,ERRbadfid
));
1686 if((pos
= fsp
->conn
->vfs_ops
.lseek(fsp
,fsp
->fd
,0,SEEK_CUR
)) == -1)
1687 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
1689 delete_pending
= fsp
->delete_on_close
;
1693 if (total_params
< 6)
1694 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1696 info_level
= SVAL(params
,0);
1698 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
1701 pstrcpy(fname
,¶ms
[6]);
1703 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1705 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1706 if (!check_name(fname
,conn
)) {
1707 DEBUG(3,("call_trans2qfilepathinfo: check_name of %s failed (%s)\n",fname
,strerror(errno
)));
1708 set_bad_path_error(errno
, bad_path
);
1709 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1711 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1712 /* Always do lstat for UNIX calls. */
1713 if (vfs_lstat(conn
,fname
,&sbuf
)) {
1714 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname
,strerror(errno
)));
1715 set_bad_path_error(errno
, bad_path
);
1716 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1718 } else if (!VALID_STAT(sbuf
) && vfs_stat(conn
,fname
,&sbuf
)) {
1719 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname
,strerror(errno
)));
1720 set_bad_path_error(errno
, bad_path
);
1721 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1726 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
1727 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1729 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1730 fname
,info_level
,tran_call
,total_data
));
1732 p
= strrchr(fname
,'/');
1738 mode
= dos_mode(conn
,fname
,&sbuf
);
1739 fullpathname
= fname
;
1740 size
= get_file_size(sbuf
);
1741 allocation_size
= get_allocation_size(fsp
,&sbuf
);
1745 /* from now on we only want the part after the / */
1748 params
= Realloc(*pparams
,2);
1749 if ( params
== NULL
)
1750 return ERROR_DOS(ERRDOS
,ERRnomem
);
1752 memset((char *)params
,'\0',2);
1753 data_size
= max_data_bytes
+ 1024;
1754 pdata
= Realloc(*ppdata
, data_size
);
1755 if ( pdata
== NULL
)
1756 return ERROR_DOS(ERRDOS
,ERRnomem
);
1759 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
1760 /* uggh, EAs for OS2 */
1761 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
1762 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
1765 memset((char *)pdata
,'\0',data_size
);
1767 c_time
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
1769 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1771 sbuf
.st_atime
&= ~1;
1772 sbuf
.st_mtime
&= ~1;
1773 sbuf
.st_mtime
&= ~1;
1776 /* NT expects the name to be in an exact form */
1777 if (strequal(fname
,"."))
1778 pstrcpy(dos_fname
, "\\");
1780 snprintf(dos_fname
, sizeof(dos_fname
), "\\%s", fname
);
1781 string_replace( dos_fname
, '/','\\');
1784 switch (info_level
) {
1785 case SMB_INFO_STANDARD
:
1786 case SMB_INFO_QUERY_EA_SIZE
:
1787 data_size
= (info_level
==1?22:26);
1788 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
1789 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
1790 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
1791 SIVAL(pdata
,l1_cbFile
,(uint32
)size
);
1792 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
1793 SSVAL(pdata
,l1_attrFile
,mode
);
1794 SIVAL(pdata
,l1_attrFile
+2,4); /* this is what OS2 does */
1797 case SMB_INFO_QUERY_EAS_FROM_LIST
:
1799 put_dos_date2(pdata
,0,c_time
);
1800 put_dos_date2(pdata
,4,sbuf
.st_atime
);
1801 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
1802 SIVAL(pdata
,12,(uint32
)size
);
1803 SIVAL(pdata
,16,(uint32
)allocation_size
);
1804 SIVAL(pdata
,20,mode
);
1807 case SMB_INFO_QUERY_ALL_EAS
:
1809 SIVAL(pdata
,0,data_size
);
1813 return ERROR_DOS(ERRDOS
,ERRbadfunc
); /* os/2 needs this */
1815 case SMB_FILE_BASIC_INFORMATION
:
1816 case SMB_QUERY_FILE_BASIC_INFO
:
1818 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
)
1819 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
1824 put_long_date(pdata
,c_time
);
1825 put_long_date(pdata
+8,sbuf
.st_atime
);
1826 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1827 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1828 SIVAL(pdata
,32,mode
);
1830 DEBUG(5,("SMB_QFBI - "));
1833 time_t create_time
= c_time
;
1834 DEBUG(5,("create: %s ", ctime(&create_time
)));
1837 DEBUG(5,("access: %s ", ctime(&sbuf
.st_atime
)));
1838 DEBUG(5,("write: %s ", ctime(&sbuf
.st_mtime
)));
1839 DEBUG(5,("change: %s ", ctime(&sbuf
.st_mtime
)));
1840 DEBUG(5,("mode: %x\n", mode
));
1844 case SMB_FILE_STANDARD_INFORMATION
:
1845 case SMB_QUERY_FILE_STANDARD_INFO
:
1848 /* Fake up allocation size. */
1849 SOFF_T(pdata
,0,allocation_size
);
1850 SOFF_T(pdata
,8,size
);
1851 SIVAL(pdata
,16,sbuf
.st_nlink
);
1853 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
1856 case SMB_FILE_EA_INFORMATION
:
1857 case SMB_QUERY_FILE_EA_INFO
:
1862 /* Get the 8.3 name - used if NT SMB was negotiated. */
1864 case SMB_QUERY_FILE_ALT_NAME_INFO
:
1867 pstrcpy(short_name
,p
);
1868 /* Mangle if not already 8.3 */
1869 if(!mangle_is_8_3(short_name
, True
)) {
1870 mangle_map(short_name
,True
,True
,SNUM(conn
));
1872 strupper(short_name
);
1873 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1874 l
= dos_PutUniCode(pdata
+ 4, short_name
, sizeof(pstring
), False
);
1880 case SMB_QUERY_FILE_NAME_INFO
:
1882 * The first part of this code is essential
1883 * to get security descriptors to work on mapped
1884 * drives. Don't ask how I discovered this unless
1885 * you like hearing about me suffering.... :-). JRA.
1888 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1889 l
= dos_PutUniCode(pdata
+ 4, dos_fname
,sizeof(pstring
), False
);
1894 case SMB_FILE_ALLOCATION_INFORMATION
:
1895 case SMB_QUERY_FILE_ALLOCATION_INFO
:
1897 SOFF_T(pdata
,0,allocation_size
);
1900 case SMB_QUERY_FILE_END_OF_FILEINFO
:
1901 case SMB_FILE_END_OF_FILE_INFORMATION
:
1903 SOFF_T(pdata
,0,size
);
1906 case SMB_QUERY_FILE_ALL_INFO
:
1907 put_long_date(pdata
,c_time
);
1908 put_long_date(pdata
+8,sbuf
.st_atime
);
1909 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1910 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1911 SIVAL(pdata
,32,mode
);
1913 SOFF_T(pdata
,0,allocation_size
);
1914 SOFF_T(pdata
,8,size
);
1915 SIVAL(pdata
,16,sbuf
.st_nlink
);
1916 SCVAL(pdata
,20,delete_pending
);
1917 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
1919 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
);
1920 pdata
+= 8; /* index number */
1921 pdata
+= 4; /* EA info */
1923 SIVAL(pdata
,0,0xA9);
1925 SIVAL(pdata
,0,0xd01BF);
1927 SOFF_T(pdata
,0,pos
); /* current offset */
1929 SIVAL(pdata
,0,mode
); /* is this the right sort of mode info? */
1931 pdata
+= 4; /* alignment */
1933 pstrcpy(pdata
+4,dos_fname
);
1935 data_size
= PTR_DIFF(pdata
,(*ppdata
));
1938 case SMB_FILE_INTERNAL_INFORMATION
:
1939 /* This should be an index number - looks like dev/ino to me :-) */
1940 SIVAL(pdata
,0,sbuf
.st_dev
);
1941 SIVAL(pdata
,4,sbuf
.st_ino
);
1945 case SMB_FILE_ACCESS_INFORMATION
:
1946 SIVAL(pdata
,0,0x12019F); /* ??? */
1950 case SMB_FILE_NAME_INFORMATION
:
1951 /* Pathname with leading '\'. */
1955 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1956 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
1957 SIVAL(pdata
,0,byte_len
);
1958 data_size
= 4 + byte_len
;
1962 case SMB_FILE_DISPOSITION_INFORMATION
:
1964 SCVAL(pdata
,0,delete_pending
);
1967 case SMB_FILE_POSITION_INFORMATION
:
1969 SOFF_T(pdata
,0,pos
);
1972 case SMB_FILE_MODE_INFORMATION
:
1973 SIVAL(pdata
,0,mode
);
1977 case SMB_FILE_ALIGNMENT_INFORMATION
:
1978 SIVAL(pdata
,0,0); /* No alignment needed. */
1983 /* Not yet finished... JRA */
1988 put_long_date(pdata
,c_time
);
1989 put_long_date(pdata
+8,sbuf
.st_atime
);
1990 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1991 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1992 SIVAL(pdata
,32,mode
);
1993 SIVAL(pdata
,36,0); /* ??? */
1994 SIVAL(pdata
,40,0x20); /* ??? */
1995 SIVAL(pdata
,44,0); /* ??? */
1996 SOFF_T(pdata
,48,size
);
1997 SIVAL(pdata
,56,0x1); /* ??? */
1998 SIVAL(pdata
,60,0); /* ??? */
1999 SIVAL(pdata
,64,0); /* ??? */
2000 SIVAL(pdata
,68,length
); /* Following string length in bytes. */
2001 dos_PutUniCode(pdata
+72,,False
);
2006 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
2007 /* Last component of pathname. */
2009 size_t byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
2010 SIVAL(pdata
,0,byte_len
);
2011 data_size
= 4 + byte_len
;
2017 * NT4 server just returns "invalid query" to this - if we try to answer
2018 * it then NTws gets a BSOD! (tridge).
2019 * W2K seems to want this. JRA.
2021 case SMB_QUERY_FILE_STREAM_INFO
:
2023 case SMB_FILE_STREAM_INFORMATION
:
2027 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", 14, False
);
2028 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
2029 SIVAL(pdata
,0,0); /* Next stream (none). */
2030 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
2031 SOFF_T(pdata
,8,size
);
2032 SOFF_T(pdata
,16,allocation_size
);
2033 data_size
= 24 + byte_len
;
2037 case SMB_FILE_COMPRESSION_INFORMATION
:
2038 SOFF_T(pdata
,0,size
);
2039 SIVAL(pdata
,8,0); /* ??? */
2040 SIVAL(pdata
,12,0); /* ??? */
2044 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
2045 put_long_date(pdata
,c_time
);
2046 put_long_date(pdata
+8,sbuf
.st_atime
);
2047 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2048 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2049 SOFF_T(pdata
,32,allocation_size
); /* Allocation size. */
2050 SOFF_T(pdata
,40,size
);
2051 SIVAL(pdata
,48,mode
);
2052 SIVAL(pdata
,52,0); /* ??? */
2056 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
2057 SIVAL(pdata
,0,mode
);
2063 * CIFS UNIX Extensions.
2066 case SMB_QUERY_FILE_UNIX_BASIC
:
2068 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf
.st_mode
));
2070 SOFF_T(pdata
,0,get_file_size(sbuf
)); /* File size 64 Bit */
2073 SOFF_T(pdata
,0,get_allocation_size(fsp
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
2076 put_long_date(pdata
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
2077 put_long_date(pdata
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
2078 put_long_date(pdata
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
2081 SIVAL(pdata
,0,sbuf
.st_uid
); /* user id for the owner */
2085 SIVAL(pdata
,0,sbuf
.st_gid
); /* group id of owner */
2089 SIVAL(pdata
,0,unix_filetype(sbuf
.st_mode
));
2092 SIVAL(pdata
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
2096 SIVAL(pdata
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
2100 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
2103 SIVAL(pdata
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
2107 SIVAL(pdata
,0,sbuf
.st_nlink
); /* number of hard links */
2110 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2114 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2116 for (i
=0; i
<100; i
++)
2117 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
2123 case SMB_QUERY_FILE_UNIX_LINK
:
2129 if(!S_ISLNK(sbuf
.st_mode
))
2130 return(UNIXERROR(ERRSRV
,ERRbadlink
));
2132 return(UNIXERROR(ERRDOS
,ERRbadlink
));
2134 len
= conn
->vfs_ops
.readlink(conn
,dos_to_unix_static(fullpathname
), buffer
, sizeof(pstring
)-1); /* read link */
2136 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2138 unix_to_dos(buffer
);
2139 pstrcpy(pdata
,buffer
); /* write '\0' terminated string */
2140 pdata
+= strlen(buffer
)+1;
2141 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2147 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2150 send_trans2_replies( outbuf
, bufsize
, params
, 2, *ppdata
, data_size
);
2155 /****************************************************************************
2156 Deal with the internal needs of setting the delete on close flag. Note that
2157 as the tdb locking is recursive, it is safe to call this from within
2158 open_file_shared. JRA.
2159 ****************************************************************************/
2161 NTSTATUS
set_delete_on_close_internal(files_struct
*fsp
, BOOL delete_on_close
)
2164 * Only allow delete on close for writable shares.
2167 if (delete_on_close
&& !CAN_WRITE(fsp
->conn
)) {
2168 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2170 return NT_STATUS_ACCESS_DENIED
;
2173 * Only allow delete on close for files/directories opened with delete intent.
2176 if (delete_on_close
&& !(fsp
->desired_access
& DELETE_ACCESS
)) {
2177 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2179 return NT_STATUS_ACCESS_DENIED
;
2182 if(fsp
->is_directory
) {
2183 fsp
->directory_delete_on_close
= delete_on_close
;
2184 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2185 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2187 fsp
->delete_on_close
= delete_on_close
;
2188 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2189 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2192 return NT_STATUS_OK
;
2195 /****************************************************************************
2196 Sets the delete on close flag over all share modes on this file.
2197 Modify the share mode entry for all files open
2198 on this device and inode to tell other smbds we have
2199 changed the delete on close flag. This will be noticed
2200 in the close code, the last closer will delete the file
2202 ****************************************************************************/
2204 NTSTATUS
set_delete_on_close_over_all(files_struct
*fsp
, BOOL delete_on_close
)
2206 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2207 delete_on_close
? "Adding" : "Removing", fsp
->fnum
, fsp
->fsp_name
));
2209 if (fsp
->is_directory
|| fsp
->is_stat
)
2210 return NT_STATUS_OK
;
2212 if (lock_share_entry_fsp(fsp
) == False
)
2213 return NT_STATUS_ACCESS_DENIED
;
2215 if (!modify_delete_flag(fsp
->dev
, fsp
->inode
, delete_on_close
)) {
2216 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2218 unlock_share_entry_fsp(fsp
);
2219 return NT_STATUS_ACCESS_DENIED
;
2222 unlock_share_entry_fsp(fsp
);
2223 return NT_STATUS_OK
;
2226 /****************************************************************************
2227 Returns true if this pathname is within the share, and thus safe.
2228 ****************************************************************************/
2230 static int ensure_link_is_safe(connection_struct
*conn
, const char *link_dest_in
, char *link_dest_out
)
2233 char resolved_name
[PATH_MAX
+1];
2235 pstring resolved_name
;
2237 fstring last_component
;
2241 BOOL bad_path
= False
;
2242 SMB_STRUCT_STAT sbuf
;
2244 pstrcpy(link_dest
, link_dest_in
);
2245 unix_convert(link_dest
,conn
,0,&bad_path
,&sbuf
);
2247 /* Store the UNIX converted path. */
2248 pstrcpy(link_dest_out
, link_dest
);
2250 p
= strrchr(link_dest
, '/');
2252 fstrcpy(last_component
, p
+1);
2255 fstrcpy(last_component
, link_dest
);
2256 pstrcpy(link_dest
, "./");
2259 if (conn
->vfs_ops
.realpath(conn
,dos_to_unix_static(link_dest
),resolved_name
) == NULL
)
2262 pstrcpy(link_dest
, unix_to_dos_static(resolved_name
));
2263 pstrcat(link_dest
, "/");
2264 pstrcat(link_dest
, last_component
);
2266 if (*link_dest
!= '/') {
2267 /* Relative path. */
2268 pstrcpy(link_test
, conn
->connectpath
);
2269 pstrcat(link_test
, "/");
2270 pstrcat(link_test
, link_dest
);
2272 pstrcpy(link_test
, link_dest
);
2276 * Check if the link is within the share.
2279 if (strncmp(conn
->connectpath
, link_test
, strlen(conn
->connectpath
))) {
2286 /****************************************************************************
2287 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2288 ****************************************************************************/
2290 static int call_trans2setfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2291 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2293 char *params
= *pparams
;
2294 char *pdata
= *ppdata
;
2295 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2300 SMB_STRUCT_STAT sbuf
;
2304 BOOL bad_path
= False
;
2305 files_struct
*fsp
= NULL
;
2306 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
2307 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
2308 mode_t unixmode
= 0;
2310 if (tran_call
== TRANSACT2_SETFILEINFO
) {
2312 if (total_params
< 4)
2313 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2315 fsp
= file_fsp(params
,0);
2316 info_level
= SVAL(params
,2);
2318 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2320 * This is actually a SETFILEINFO on a directory
2321 * handle (returned from an NT SMB). NT5.0 seems
2322 * to do this call. JRA.
2324 fname
= fsp
->fsp_name
;
2325 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2326 if (!check_name(fname
,conn
) || (!VALID_STAT(sbuf
))) {
2327 DEBUG(3,("fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2328 set_bad_path_error(errno
, bad_path
);
2329 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2331 } else if (fsp
&& fsp
->print_file
) {
2333 * Doing a DELETE_ON_CLOSE should cancel a print job.
2335 if (((info_level
== SMB_SET_FILE_DISPOSITION_INFO
)||(info_level
== SMB_FILE_DISPOSITION_INFORMATION
)) &&
2337 fsp
->share_mode
= FILE_DELETE_ON_CLOSE
;
2339 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
2343 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2346 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2349 * Original code - this is an open file.
2351 CHECK_FSP(fsp
,conn
);
2353 fname
= fsp
->fsp_name
;
2356 if (vfs_fstat(fsp
,fd
,&sbuf
) != 0) {
2357 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
2358 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2363 if (total_params
< 6)
2364 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2366 info_level
= SVAL(params
,0);
2368 pstrcpy(fname
,¶ms
[6]);
2369 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2370 if(!check_name(fname
, conn
)) {
2371 set_bad_path_error(errno
, bad_path
);
2372 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2376 * For CIFS UNIX extensions the target name may not exist.
2379 if(!VALID_STAT(sbuf
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
2381 DEBUG(3,("stat of %s failed (%s)\n", fname
, strerror(errno
)));
2382 set_bad_path_error(errno
, bad_path
);
2383 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2387 if (!CAN_WRITE(conn
))
2388 return ERROR_DOS(ERRSRV
,ERRaccess
);
2390 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2391 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2393 if (VALID_STAT(sbuf
))
2394 unixmode
= sbuf
.st_mode
;
2396 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2397 tran_call
,fname
,info_level
,total_data
));
2399 /* Realloc the parameter and data sizes */
2400 params
= Realloc(*pparams
,2);
2402 return ERROR_DOS(ERRDOS
,ERRnomem
);
2408 /* the pending modtime overrides the current modtime */
2409 sbuf
.st_mtime
= fsp
->pending_modtime
;
2412 size
= get_file_size(sbuf
);
2413 tvs
.modtime
= sbuf
.st_mtime
;
2414 tvs
.actime
= sbuf
.st_atime
;
2415 dosmode
= dos_mode(conn
,fname
,&sbuf
);
2416 unixmode
= sbuf
.st_mode
;
2418 set_owner
= VALID_STAT(sbuf
) ? sbuf
.st_uid
: (uid_t
)SMB_UID_NO_CHANGE
;
2419 set_grp
= VALID_STAT(sbuf
) ? sbuf
.st_gid
: (gid_t
)SMB_GID_NO_CHANGE
;
2421 switch (info_level
) {
2422 case SMB_INFO_STANDARD
:
2424 if (total_data
< l1_cbFile
+4)
2425 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2428 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
2431 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
2433 dosmode
= SVAL(pdata
,l1_attrFile
);
2434 size
= IVAL(pdata
,l1_cbFile
);
2438 case SMB_INFO_SET_EA
:
2439 return(ERROR_DOS(ERRDOS
,ERReasnotsupported
));
2441 /* XXXX um, i don't think this is right.
2442 it's also not in the cifs6.txt spec.
2444 case SMB_INFO_QUERY_EAS_FROM_LIST
:
2445 if (total_data
< 28)
2446 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2448 tvs
.actime
= make_unix_date2(pdata
+8);
2449 tvs
.modtime
= make_unix_date2(pdata
+12);
2450 size
= IVAL(pdata
,16);
2451 dosmode
= IVAL(pdata
,24);
2454 /* XXXX nor this. not in cifs6.txt, either. */
2455 case SMB_INFO_QUERY_ALL_EAS
:
2456 if (total_data
< 28)
2457 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2459 tvs
.actime
= make_unix_date2(pdata
+8);
2460 tvs
.modtime
= make_unix_date2(pdata
+12);
2461 size
= IVAL(pdata
,16);
2462 dosmode
= IVAL(pdata
,24);
2465 case SMB_SET_FILE_BASIC_INFO
:
2466 case SMB_FILE_BASIC_INFORMATION
:
2468 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2470 time_t changed_time
;
2472 if (total_data
< 36)
2473 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2475 /* Ignore create time at offset pdata. */
2478 tvs
.actime
= interpret_long_date(pdata
+8);
2480 write_time
= interpret_long_date(pdata
+16);
2481 changed_time
= interpret_long_date(pdata
+24);
2483 tvs
.modtime
= MIN(write_time
, changed_time
);
2485 if (write_time
> tvs
.modtime
&& write_time
!= 0xffffffff) {
2486 tvs
.modtime
= write_time
;
2489 /* Prefer a defined time to an undefined one. */
2490 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
2491 tvs
.modtime
= (write_time
== (time_t)0 || write_time
== (time_t)-1
2496 dosmode
= IVAL(pdata
,32);
2500 case SMB_FILE_ALLOCATION_INFORMATION
:
2501 case SMB_SET_FILE_ALLOCATION_INFO
:
2504 SMB_BIG_UINT allocation_size
;
2507 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2509 allocation_size
= (SMB_BIG_UINT
)IVAL(pdata
,0);
2510 #ifdef LARGE_SMB_OFF_T
2511 allocation_size
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
2512 #else /* LARGE_SMB_OFF_T */
2513 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2514 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2515 #endif /* LARGE_SMB_OFF_T */
2516 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2517 fname
, (double)allocation_size
));
2519 if (allocation_size
)
2520 allocation_size
= SMB_ROUNDUP(allocation_size
,SMB_ROUNDUP_ALLOCATION_SIZE
);
2522 if(allocation_size
!= get_file_size(sbuf
)) {
2523 SMB_STRUCT_STAT new_sbuf
;
2525 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2526 fname
, (double)allocation_size
));
2529 files_struct
*new_fsp
= NULL
;
2530 int access_mode
= 0;
2533 if(global_oplock_break
) {
2534 /* Queue this file modify as we are the process of an oplock break. */
2536 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2537 DEBUGADD(2,( "in oplock break state.\n"));
2539 push_oplock_pending_smb_message(inbuf
, length
);
2543 new_fsp
= open_file_shared1(conn
, fname
, &sbuf
,FILE_WRITE_DATA
,
2544 SET_OPEN_MODE(DOS_OPEN_RDWR
),
2545 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
2546 0, 0, &access_mode
, &action
);
2548 if (new_fsp
== NULL
)
2549 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2550 ret
= vfs_allocate_file_space(new_fsp
, allocation_size
);
2551 if (vfs_fstat(new_fsp
,new_fsp
->fd
,&new_sbuf
) != 0) {
2552 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp
->fnum
, strerror(errno
)));
2555 close_file(new_fsp
,True
);
2557 ret
= vfs_allocate_file_space(fsp
, allocation_size
);
2558 if (vfs_fstat(fsp
,fd
,&new_sbuf
) != 0) {
2559 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
2564 return ERROR_NT(NT_STATUS_DISK_FULL
);
2566 /* Allocate can trucate size... */
2567 size
= get_file_size(new_sbuf
);
2573 case SMB_FILE_END_OF_FILE_INFORMATION
:
2574 case SMB_SET_FILE_END_OF_FILE_INFO
:
2577 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2579 size
= IVAL(pdata
,0);
2580 #ifdef LARGE_SMB_OFF_T
2581 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2582 #else /* LARGE_SMB_OFF_T */
2583 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2584 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2585 #endif /* LARGE_SMB_OFF_T */
2586 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname
, (double)size
));
2590 case SMB_FILE_DISPOSITION_INFORMATION
:
2591 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
2593 BOOL delete_on_close
;
2597 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2599 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
2601 if (tran_call
!= TRANSACT2_SETFILEINFO
)
2602 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
2605 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2607 status
= set_delete_on_close_internal(fsp
, delete_on_close
);
2608 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
2609 return ERROR_NT(status
);
2611 /* The set is across all open files on this dev/inode pair. */
2612 status
=set_delete_on_close_over_all(fsp
, delete_on_close
);
2613 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
2614 return ERROR_NT(status
);
2620 * CIFS UNIX extensions.
2623 case SMB_SET_FILE_UNIX_BASIC
:
2625 uint32 raw_unixmode
;
2627 if (total_data
< 100)
2628 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2630 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
2631 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
2632 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
2633 #ifdef LARGE_SMB_OFF_T
2634 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2635 #else /* LARGE_SMB_OFF_T */
2636 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2637 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2638 #endif /* LARGE_SMB_OFF_T */
2640 pdata
+=24; /* ctime & st_blocks are not changed */
2641 tvs
.actime
= interpret_long_unix_date(pdata
); /* access_time */
2642 tvs
.modtime
= interpret_long_unix_date(pdata
+8); /* modification_time */
2644 set_owner
= (uid_t
)IVAL(pdata
,0);
2646 set_grp
= (gid_t
)IVAL(pdata
,0);
2648 raw_unixmode
= IVAL(pdata
,28);
2649 unixmode
= unix_perms_from_wire(conn
, &sbuf
, raw_unixmode
);
2650 dosmode
= 0; /* Ensure dos mode change doesn't override this. */
2652 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2653 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2654 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
2656 if (!VALID_STAT(sbuf
)) {
2659 * The only valid use of this is to create character and block
2660 * devices, and named pipes. This is deprecated (IMHO) and
2661 * a new info level should be used for mknod. JRA.
2664 #if !defined(HAVE_MAKEDEV_FN)
2665 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2666 #else /* HAVE_MAKEDEV_FN */
2667 uint32 file_type
= IVAL(pdata
,0);
2668 uint32 dev_major
= IVAL(pdata
,4);
2669 uint32 dev_minor
= IVAL(pdata
,12);
2671 uid_t myuid
= geteuid();
2672 gid_t mygid
= getegid();
2675 if (tran_call
== TRANSACT2_SETFILEINFO
)
2676 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2678 if (raw_unixmode
== SMB_MODE_NO_CHANGE
)
2679 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2681 dev
= makedev(dev_major
, dev_minor
);
2683 /* We can only create as the owner/group we are. */
2685 if ((set_owner
!= myuid
) && (set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
))
2686 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2687 if ((set_grp
!= mygid
) && (set_grp
!= (gid_t
)SMB_GID_NO_CHANGE
))
2688 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2690 if (file_type
!= UNIX_TYPE_CHARDEV
&& file_type
!= UNIX_TYPE_BLKDEV
&&
2691 file_type
!= UNIX_TYPE_FIFO
)
2692 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2694 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2695 0%o for file %s\n", (double)dev
, unixmode
, fname
));
2697 /* Ok - do the mknod. */
2698 if (conn
->vfs_ops
.mknod(conn
,dos_to_unix_static(fname
), unixmode
, dev
) != 0)
2699 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2702 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2704 #endif /* HAVE_MAKEDEV_FN */
2709 * Deal with the UNIX specific mode set.
2712 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
2713 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
2714 (unsigned int)unixmode
, fname
));
2715 if (vfs_chmod(conn
,fname
,unixmode
) != 0)
2716 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2720 * Deal with the UNIX specific uid set.
2723 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) && (sbuf
.st_uid
!= set_owner
)) {
2724 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
2725 (unsigned int)set_owner
, fname
));
2726 if (vfs_chown(conn
,fname
,set_owner
, (gid_t
)-1) != 0)
2727 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2731 * Deal with the UNIX specific gid set.
2734 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) && (sbuf
.st_gid
!= set_grp
)) {
2735 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
2736 (unsigned int)set_owner
, fname
));
2737 if (vfs_chown(conn
,fname
,(uid_t
)-1, set_grp
) != 0)
2738 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2743 case SMB_SET_FILE_UNIX_LINK
:
2746 /* Set a symbolic link. */
2747 /* Don't allow this if follow links is false. */
2749 if (!lp_symlinks(SNUM(conn
)))
2750 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2752 /* Disallow if already exists. */
2753 if (VALID_STAT(sbuf
))
2754 return(ERROR_DOS(ERRDOS
,ERRbadpath
));
2756 pstrcpy(link_dest
, pdata
);
2758 if (ensure_link_is_safe(conn
, link_dest
, link_dest
) != 0)
2759 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2760 dos_to_unix(link_dest
);
2763 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
2764 fname
, link_dest
));
2766 if (conn
->vfs_ops
.symlink(conn
,link_dest
,fname
) != 0)
2767 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2769 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2773 case SMB_SET_FILE_UNIX_HLINK
:
2777 /* Set a hard link. */
2779 /* Disallow if already exists. */
2780 if (VALID_STAT(sbuf
))
2781 return(ERROR_DOS(ERRDOS
,ERRbadpath
));
2783 pstrcpy(link_dest
, pdata
);
2785 if (ensure_link_is_safe(conn
, link_dest
, link_dest
) != 0)
2786 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2788 dos_to_unix(link_dest
);
2791 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
2792 fname
, link_dest
));
2794 if (conn
->vfs_ops
.link(conn
,link_dest
,fname
) != 0)
2795 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2797 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2802 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2805 /* get some defaults (no modifications) if any info is zero or -1. */
2806 if (tvs
.actime
== (time_t)0 || tvs
.actime
== (time_t)-1)
2807 tvs
.actime
= sbuf
.st_atime
;
2809 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
2810 tvs
.modtime
= sbuf
.st_mtime
;
2812 DEBUG(6,("actime: %s " , ctime(&tvs
.actime
)));
2813 DEBUG(6,("modtime: %s ", ctime(&tvs
.modtime
)));
2814 DEBUG(6,("size: %.0f ", (double)size
));
2815 if (S_ISDIR(sbuf
.st_mode
))
2820 DEBUG(6,("dosmode: %x\n" , dosmode
));
2822 if(!((info_level
== SMB_SET_FILE_END_OF_FILE_INFO
) ||
2823 (info_level
== SMB_SET_FILE_ALLOCATION_INFO
) ||
2824 (info_level
== SMB_FILE_ALLOCATION_INFORMATION
) ||
2825 (info_level
== SMB_FILE_END_OF_FILE_INFORMATION
))) {
2827 * Only do this test if we are not explicitly
2828 * changing the size of a file.
2831 size
= get_file_size(sbuf
);
2835 * Try and set the times, size and mode of this file -
2836 * if they are different from the current values
2839 if (sbuf
.st_mtime
!= tvs
.modtime
|| sbuf
.st_atime
!= tvs
.actime
) {
2842 * This was a setfileinfo on an open file.
2843 * NT does this a lot. It's actually pointless
2844 * setting the time here, as it will be overwritten
2845 * on the next write, so we save the request
2846 * away and will set it on file close. JRA.
2849 if (tvs
.modtime
!= (time_t)0 && tvs
.modtime
!= (time_t)-1) {
2850 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2851 ctime(&tvs
.modtime
) ));
2852 fsp
->pending_modtime
= tvs
.modtime
;
2857 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2859 if(file_utime(conn
, fname
, &tvs
)!=0)
2860 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2864 /* check the mode isn't different, before changing it */
2865 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, fname
, &sbuf
))) {
2867 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2870 if(file_chmod(conn
, fname
, dosmode
, NULL
)) {
2871 DEBUG(2,("chmod of %s failed (%s)\n", fname
, strerror(errno
)));
2872 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2876 if(size
!= get_file_size(sbuf
)) {
2880 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2881 fname
, (double)size
));
2884 files_struct
*new_fsp
= NULL
;
2885 int access_mode
= 0;
2888 if(global_oplock_break
) {
2889 /* Queue this file modify as we are the process of an oplock break. */
2891 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2892 DEBUGADD(2,( "in oplock break state.\n"));
2894 push_oplock_pending_smb_message(inbuf
, length
);
2898 new_fsp
= open_file_shared(conn
, fname
, &sbuf
,
2899 SET_OPEN_MODE(DOS_OPEN_RDWR
),
2900 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
2901 0, 0, &access_mode
, &action
);
2903 if (new_fsp
== NULL
)
2904 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2905 ret
= vfs_set_filelen(new_fsp
, size
);
2906 close_file(new_fsp
,True
);
2908 ret
= vfs_set_filelen(fsp
, size
);
2912 return (UNIXERROR(ERRHRD
,ERRdiskfull
));
2916 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2920 /****************************************************************************
2921 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2922 ****************************************************************************/
2924 static int call_trans2mkdir(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2925 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2927 char *params
= *pparams
;
2930 SMB_STRUCT_STAT sbuf
;
2931 BOOL bad_path
= False
;
2933 if (!CAN_WRITE(conn
))
2934 return ERROR_DOS(ERRSRV
,ERRaccess
);
2936 if (total_params
< 4)
2937 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2939 pstrcpy(directory
, ¶ms
[4]);
2941 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
2943 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
2944 if (check_name(directory
,conn
))
2945 ret
= vfs_mkdir(conn
,directory
,unix_mode(conn
,aDIR
,directory
));
2948 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno
)));
2949 set_bad_path_error(errno
, bad_path
);
2950 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2953 /* Realloc the parameter and data sizes */
2954 params
= Realloc(*pparams
,2);
2956 return ERROR_DOS(ERRDOS
,ERRnomem
);
2961 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2966 /****************************************************************************
2967 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2968 We don't actually do this - we just send a null response.
2969 ****************************************************************************/
2971 static int call_trans2findnotifyfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2972 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2974 static uint16 fnf_handle
= 257;
2975 char *params
= *pparams
;
2978 if (total_params
< 6)
2979 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2981 info_level
= SVAL(params
,4);
2982 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
2984 switch (info_level
) {
2989 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2992 /* Realloc the parameter and data sizes */
2993 params
= Realloc(*pparams
,6);
2995 return ERROR_DOS(ERRDOS
,ERRnomem
);
2998 SSVAL(params
,0,fnf_handle
);
2999 SSVAL(params
,2,0); /* No changes */
3000 SSVAL(params
,4,0); /* No EA errors */
3007 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0);
3012 /****************************************************************************
3013 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3014 changes). Currently this does nothing.
3015 ****************************************************************************/
3017 static int call_trans2findnotifynext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
3018 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3020 char *params
= *pparams
;
3022 DEBUG(3,("call_trans2findnotifynext\n"));
3024 /* Realloc the parameter and data sizes */
3025 params
= Realloc(*pparams
,4);
3027 return ERROR_DOS(ERRDOS
,ERRnomem
);
3030 SSVAL(params
,0,0); /* No changes */
3031 SSVAL(params
,2,0); /* No EA errors */
3033 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0);
3038 /****************************************************************************
3039 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3040 ****************************************************************************/
3042 static int call_trans2getdfsreferral(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
3043 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3045 char *params
= *pparams
;
3046 enum remote_arch_types ra_type
= get_remote_arch();
3047 BOOL NT_arch
= ((ra_type
== RA_WINNT
) || (ra_type
== RA_WIN2K
) || (ra_type
== RA_WINXP
) || (ra_type
== RA_WIN2K3
));
3050 int max_referral_level
;
3052 DEBUG(10,("call_trans2getdfsreferral\n"));
3054 if (total_params
< 2)
3055 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3057 max_referral_level
= SVAL(params
,0);
3059 if(!lp_host_msdfs())
3060 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
3062 /* if pathname is in UNICODE, convert to DOS */
3063 /* NT always sends in UNICODE, may not set UNICODE flag */
3064 if(NT_arch
|| (SVAL(inbuf
,smb_flg2
) & FLAGS2_UNICODE_STRINGS
)) {
3065 unistr_to_dos(pathname
, ¶ms
[2], sizeof(pathname
));
3066 DEBUG(10,("UNICODE referral for %s\n",pathname
));
3068 pstrcpy(pathname
,¶ms
[2]);
3070 if((reply_size
= setup_dfs_referral(pathname
,max_referral_level
,ppdata
)) < 0)
3071 return ERROR_DOS(ERRDOS
,ERRbadfile
);
3073 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_UNICODE_STRINGS
| FLAGS2_DFS_PATHNAMES
);
3074 send_trans2_replies(outbuf
,bufsize
,0,0,*ppdata
,reply_size
);
3079 #define LMCAT_SPL 0x53
3080 #define LMFUNC_GETJOBID 0x60
3082 /****************************************************************************
3083 reply to a TRANS2_IOCTL - used for OS/2 printing.
3084 ****************************************************************************/
3086 static int call_trans2ioctl(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
3087 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3089 char *pdata
= *ppdata
;
3090 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv15
);
3092 if ((SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3093 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3094 pdata
= Realloc(*ppdata
, 32);
3096 return ERROR_DOS(ERRDOS
,ERRnomem
);
3099 SSVAL(pdata
,0,fsp
->print_jobid
); /* Job number */
3100 StrnCpy(pdata
+2, global_myname
, 15); /* Our NetBIOS name */
3101 StrnCpy(pdata
+18, lp_servicename(SNUM(conn
)), 13); /* Service name */
3102 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32);
3105 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3106 return ERROR_DOS(ERRSRV
,ERRerror
);
3110 /****************************************************************************
3111 Reply to a SMBfindclose (stop trans2 directory search).
3112 ****************************************************************************/
3114 int reply_findclose(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3117 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
3118 START_PROFILE(SMBfindclose
);
3120 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
3122 dptr_close(&dptr_num
);
3124 outsize
= set_message(outbuf
,0,0,True
);
3126 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
3128 END_PROFILE(SMBfindclose
);
3132 /****************************************************************************
3133 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3134 ****************************************************************************/
3136 int reply_findnclose(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3140 START_PROFILE(SMBfindnclose
);
3142 dptr_num
= SVAL(inbuf
,smb_vwv0
);
3144 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
3146 /* We never give out valid handles for a
3147 findnotifyfirst - so any dptr_num is ok here.
3150 outsize
= set_message(outbuf
,0,0,True
);
3152 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
3154 END_PROFILE(SMBfindnclose
);
3158 /****************************************************************************
3159 Reply to a SMBtranss2 - just ignore it!
3160 ****************************************************************************/
3162 int reply_transs2(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3164 START_PROFILE(SMBtranss2
);
3165 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
3166 END_PROFILE(SMBtranss2
);
3170 /****************************************************************************
3171 Reply to a SMBtrans2.
3172 ****************************************************************************/
3174 int reply_trans2(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3177 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
3178 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
3180 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
3181 unsigned int max_data_reply
= SVAL(inbuf
, smb_mdrcnt
);
3182 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
3183 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
3184 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
3185 int32 timeout
= IVALS(inbuf
,smb_timeout
);
3187 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
3188 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
3189 char *params
= NULL
, *data
= NULL
;
3190 unsigned int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
3191 START_PROFILE(SMBtrans2
);
3193 if(global_oplock_break
&& (tran_call
== TRANSACT2_OPEN
)) {
3194 /* Queue this open message as we are the process of an
3197 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3198 DEBUGADD(2,( "in oplock break state.\n"));
3200 push_oplock_pending_smb_message(inbuf
, length
);
3201 END_PROFILE(SMBtrans2
);
3205 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
3206 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
3207 END_PROFILE(SMBtrans2
);
3208 return ERROR_DOS(ERRSRV
,ERRaccess
);
3211 outsize
= set_message(outbuf
,0,0,True
);
3213 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3214 is so as a sanity check */
3217 * Need to have rc=0 for ioctl to get job id for OS/2.
3218 * Network printing will fail if function is not successful.
3219 * Similar function in reply.c will be used if protocol
3220 * is LANMAN1.0 instead of LM1.2X002.
3221 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3222 * outbuf doesn't have to be set(only job id is used).
3224 if ( (suwcnt
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
3225 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3226 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3227 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3229 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt
));
3230 DEBUG(2,("Transaction is %d\n",tran_call
));
3231 END_PROFILE(SMBtrans2
);
3232 ERROR_DOS(ERRDOS
,ERRinvalidparam
);
3236 /* Allocate the space for the maximum needed parameters and data */
3237 if (total_params
> 0)
3238 params
= (char *)malloc(total_params
);
3240 data
= (char *)malloc(total_data
);
3242 if ((total_params
&& !params
) || (total_data
&& !data
)) {
3243 DEBUG(2,("Out of memory in reply_trans2\n"));
3246 END_PROFILE(SMBtrans2
);
3247 return ERROR_DOS(ERRDOS
,ERRnomem
);
3250 /* Copy the param and data bytes sent with this request into
3251 the params buffer */
3252 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
3253 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
3255 if (num_params
> total_params
|| num_data
> total_data
)
3256 exit_server("invalid params in reply_trans2");
3259 unsigned int psoff
= SVAL(inbuf
, smb_psoff
);
3260 if ((psoff
+ num_params
< psoff
) || (psoff
+ num_params
< num_params
))
3262 if (smb_base(inbuf
) + psoff
+ num_params
> inbuf
+ length
)
3264 memcpy( params
, smb_base(inbuf
) + psoff
, num_params
);
3267 unsigned int dsoff
= SVAL(inbuf
, smb_dsoff
);
3268 if ((dsoff
+ num_data
< dsoff
) || (dsoff
+ num_data
< num_data
))
3270 if (smb_base(inbuf
) + dsoff
+ num_data
> inbuf
+ length
)
3272 memcpy( data
, smb_base(inbuf
) + dsoff
, num_data
);
3275 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
) {
3276 /* We need to send an interim response then receive the rest
3277 of the parameter/data bytes */
3278 outsize
= set_message(outbuf
,0,0,True
);
3279 if (!send_smb(smbd_server_fd(),outbuf
))
3280 exit_server("reply_trans2: send_smb failed.");
3282 while (num_data_sofar
< total_data
||
3283 num_params_sofar
< total_params
) {
3285 unsigned int param_disp
;
3286 unsigned int param_off
;
3287 unsigned int data_disp
;
3288 unsigned int data_off
;
3290 ret
= receive_next_smb(inbuf
,bufsize
,SMB_SECONDARY_WAIT
);
3293 (CVAL(inbuf
, smb_com
) != SMBtranss2
)) || !ret
) {
3294 outsize
= set_message(outbuf
,0,0,True
);
3296 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3298 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3299 (smb_read_error
== READ_ERROR
) ? "error" : "timeout" ));
3303 /* Revise total_params and total_data in case
3304 they have changed downwards */
3305 if (SVAL(inbuf
, smb_tpscnt
) < total_params
)
3306 total_params
= SVAL(inbuf
, smb_tpscnt
);
3307 if (SVAL(inbuf
, smb_tdscnt
) < total_data
)
3308 total_data
= SVAL(inbuf
, smb_tdscnt
);
3310 num_params
= SVAL(inbuf
,smb_spscnt
);
3311 param_off
= SVAL(inbuf
, smb_spsoff
);
3312 param_disp
= SVAL(inbuf
, smb_spsdisp
);
3313 num_params_sofar
+= num_params
;
3315 num_data
= SVAL(inbuf
, smb_sdscnt
);
3316 data_off
= SVAL(inbuf
, smb_sdsoff
);
3317 data_disp
= SVAL(inbuf
, smb_sdsdisp
);
3318 num_data_sofar
+= num_data
;
3320 if (num_params_sofar
> total_params
|| num_data_sofar
> total_data
)
3324 if (param_disp
+ num_params
>= total_params
)
3326 if ((param_disp
+ num_params
< param_disp
) ||
3327 (param_disp
+ num_params
< num_params
))
3329 if (smb_base(inbuf
) + param_off
+ num_params
>= inbuf
+ bufsize
)
3331 if (params
+ param_disp
< params
)
3334 memcpy( ¶ms
[param_disp
], smb_base(inbuf
) + param_off
, num_params
);
3337 if (data_disp
+ num_data
>= total_data
)
3339 if ((data_disp
+ num_data
< data_disp
) ||
3340 (data_disp
+ num_data
< num_data
))
3342 if (smb_base(inbuf
) + data_off
+ num_data
>= inbuf
+ bufsize
)
3344 if (data
+ data_disp
< data
)
3347 memcpy( &data
[data_disp
], smb_base(inbuf
) + data_off
, num_data
);
3352 if (Protocol
>= PROTOCOL_NT1
)
3353 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_IS_LONG_NAME
);
3355 /* Now we must call the relevant TRANS2 function */
3357 case TRANSACT2_OPEN
:
3358 START_PROFILE_NESTED(Trans2_open
);
3359 outsize
= call_trans2open(conn
, inbuf
, outbuf
, bufsize
,
3360 ¶ms
, total_params
, &data
, total_data
);
3361 END_PROFILE_NESTED(Trans2_open
);
3364 case TRANSACT2_FINDFIRST
:
3365 START_PROFILE_NESTED(Trans2_findfirst
);
3366 outsize
= call_trans2findfirst(conn
, inbuf
, outbuf
, bufsize
,
3367 ¶ms
, total_params
, &data
, total_data
);
3368 END_PROFILE_NESTED(Trans2_findfirst
);
3371 case TRANSACT2_FINDNEXT
:
3372 START_PROFILE_NESTED(Trans2_findnext
);
3373 outsize
= call_trans2findnext(conn
, inbuf
, outbuf
, length
, bufsize
,
3374 ¶ms
, total_params
, &data
, total_data
);
3375 END_PROFILE_NESTED(Trans2_findnext
);
3378 case TRANSACT2_QFSINFO
:
3379 START_PROFILE_NESTED(Trans2_qfsinfo
);
3380 outsize
= call_trans2qfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3381 ¶ms
, total_params
, &data
, total_data
);
3382 END_PROFILE_NESTED(Trans2_qfsinfo
);
3385 case TRANSACT2_SETFSINFO
:
3386 START_PROFILE_NESTED(Trans2_setfsinfo
);
3387 outsize
= call_trans2setfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3388 ¶ms
, total_params
, &data
, total_data
);
3389 END_PROFILE_NESTED(Trans2_setfsinfo
);
3392 case TRANSACT2_QPATHINFO
:
3393 case TRANSACT2_QFILEINFO
:
3394 START_PROFILE_NESTED(Trans2_qpathinfo
);
3395 outsize
= call_trans2qfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3396 ¶ms
, total_params
, &data
, total_data
);
3397 END_PROFILE_NESTED(Trans2_qpathinfo
);
3399 case TRANSACT2_SETPATHINFO
:
3400 case TRANSACT2_SETFILEINFO
:
3401 START_PROFILE_NESTED(Trans2_setpathinfo
);
3402 outsize
= call_trans2setfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3403 ¶ms
, total_params
, &data
, total_data
);
3404 END_PROFILE_NESTED(Trans2_setpathinfo
);
3407 case TRANSACT2_FINDNOTIFYFIRST
:
3408 START_PROFILE_NESTED(Trans2_findnotifyfirst
);
3409 outsize
= call_trans2findnotifyfirst(conn
, inbuf
, outbuf
, length
, bufsize
,
3410 ¶ms
, total_params
, &data
, total_data
);
3411 END_PROFILE_NESTED(Trans2_findnotifyfirst
);
3414 case TRANSACT2_FINDNOTIFYNEXT
:
3415 START_PROFILE_NESTED(Trans2_findnotifynext
);
3416 outsize
= call_trans2findnotifynext(conn
, inbuf
, outbuf
, length
, bufsize
,
3417 ¶ms
, total_params
, &data
, total_data
);
3418 END_PROFILE_NESTED(Trans2_findnotifynext
);
3420 case TRANSACT2_MKDIR
:
3421 START_PROFILE_NESTED(Trans2_mkdir
);
3422 outsize
= call_trans2mkdir(conn
, inbuf
, outbuf
, length
, bufsize
,
3423 ¶ms
, total_params
, &data
, total_data
);
3424 END_PROFILE_NESTED(Trans2_mkdir
);
3427 case TRANSACT2_GET_DFS_REFERRAL
:
3428 START_PROFILE_NESTED(Trans2_get_dfs_referral
);
3429 outsize
= call_trans2getdfsreferral(conn
,inbuf
,outbuf
,length
, bufsize
,
3430 ¶ms
, total_params
, &data
, total_data
);
3431 END_PROFILE_NESTED(Trans2_get_dfs_referral
);
3433 case TRANSACT2_IOCTL
:
3434 START_PROFILE_NESTED(Trans2_ioctl
);
3435 outsize
= call_trans2ioctl(conn
,inbuf
,outbuf
,length
, bufsize
,
3436 ¶ms
, total_params
, &data
, total_data
);
3437 END_PROFILE_NESTED(Trans2_ioctl
);
3440 /* Error in request */
3441 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call
));
3444 END_PROFILE(SMBtrans2
);
3445 return ERROR_DOS(ERRSRV
,ERRerror
);
3448 /* As we do not know how many data packets will need to be
3449 returned here the various call_trans2xxxx calls
3450 must send their own. Thus a call_trans2xxx routine only
3451 returns a value other than -1 when it wants to send
3457 END_PROFILE(SMBtrans2
);
3458 return outsize
; /* If a correct response was needed the
3459 call_trans2xxx calls have already sent
3460 it. If outsize != -1 then it is returning */
3466 END_PROFILE(SMBtrans2
);
3467 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);