2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2001
6 Extensively modified by Andrew Tridgell, 1995
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
;
32 #define get_file_size(sbuf) ((sbuf).st_size)
34 /* given a stat buffer return the allocated size on disk, taking into
35 account sparse files */
36 SMB_BIG_UINT
get_allocation_size(files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
39 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
40 ret
= (SMB_BIG_UINT
)STAT_ST_BLOCKSIZE
* (SMB_BIG_UINT
)sbuf
->st_blocks
;
42 ret
= (SMB_BIG_UINT
)get_file_size(*sbuf
);
44 if (!ret
&& fsp
&& fsp
->initial_allocation_size
)
45 ret
= fsp
->initial_allocation_size
;
46 ret
= SMB_ROUNDUP(ret
,SMB_ROUNDUP_ALLOCATION_SIZE
);
50 /****************************************************************************
51 Send the required number of replies back.
52 We assume all fields other than the data fields are
53 set correctly for the type of call.
54 HACK ! Always assumes smb_setup field is zero.
55 ****************************************************************************/
57 static int send_trans2_replies(char *outbuf
,
64 /* As we are using a protocol > LANMAN1 then the max_send
65 variable must have been set in the sessetupX call.
66 This takes precedence over the max_xmit field in the
67 global struct. These different max_xmit variables should
68 be merged as this is now too confusing */
71 int data_to_send
= datasize
;
72 int params_to_send
= paramsize
;
76 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
77 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
78 int data_alignment_offset
= 0;
80 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
82 set_message(outbuf
,10,0,True
);
84 /* If there genuinely are no parameters or data to send just send the empty packet */
86 if(params_to_send
== 0 && data_to_send
== 0) {
87 if (!send_smb(smbd_server_fd(),outbuf
))
88 exit_server("send_trans2_replies: send_smb failed.");
92 /* When sending params and data ensure that both are nicely aligned */
93 /* Only do this alignment when there is also data to send - else
94 can cause NT redirector problems. */
96 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
97 data_alignment_offset
= 4 - (params_to_send
% 4);
99 /* Space is bufsize minus Netbios over TCP header minus SMB header */
100 /* The alignment_offset is to align the param bytes on an even byte
101 boundary. NT 4.0 Beta needs this to work correctly. */
103 useable_space
= bufsize
- ((smb_buf(outbuf
)+ alignment_offset
+data_alignment_offset
) - outbuf
);
105 /* useable_space can never be more than max_send minus the alignment offset. */
107 useable_space
= MIN(useable_space
, max_send
- (alignment_offset
+data_alignment_offset
));
109 while (params_to_send
|| data_to_send
) {
110 /* Calculate whether we will totally or partially fill this packet */
112 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
+ data_alignment_offset
;
114 /* We can never send more than useable_space */
116 * Note that 'useable_space' does not include the alignment offsets,
117 * but we must include the alignment offsets in the calculation of
118 * the length of the data we send over the wire, as the alignment offsets
119 * are sent here. Fix from Marc_Jacobsen@hp.com.
122 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
+ alignment_offset
+ data_alignment_offset
);
124 set_message(outbuf
, 10, total_sent_thistime
, True
);
126 /* Set total params and data to be sent */
127 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
128 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
130 /* Calculate how many parameters and data we can fit into
131 * this packet. Parameters get precedence
134 params_sent_thistime
= MIN(params_to_send
,useable_space
);
135 data_sent_thistime
= useable_space
- params_sent_thistime
;
136 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
138 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
140 /* smb_proff is the offset from the start of the SMB header to the
141 parameter bytes, however the first 4 bytes of outbuf are
142 the Netbios over TCP header. Thus use smb_base() to subtract
143 them from the calculation */
145 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
147 if(params_sent_thistime
== 0)
148 SSVAL(outbuf
,smb_prdisp
,0);
150 /* Absolute displacement of param bytes sent in this packet */
151 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
153 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
154 if(data_sent_thistime
== 0) {
155 SSVAL(outbuf
,smb_droff
,0);
156 SSVAL(outbuf
,smb_drdisp
, 0);
158 /* The offset of the data bytes is the offset of the
159 parameter bytes plus the number of parameters being sent this time */
160 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
161 smb_base(outbuf
)) + params_sent_thistime
+ data_alignment_offset
);
162 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
165 /* Copy the param bytes into the packet */
167 if(params_sent_thistime
)
168 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
170 /* Copy in the data bytes */
171 if(data_sent_thistime
)
172 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
+
173 data_alignment_offset
,pd
,data_sent_thistime
);
175 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
176 params_sent_thistime
, data_sent_thistime
, useable_space
));
177 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
178 params_to_send
, data_to_send
, paramsize
, datasize
));
180 /* Send the packet */
181 if (!send_smb(smbd_server_fd(),outbuf
))
182 exit_server("send_trans2_replies: send_smb failed.");
184 pp
+= params_sent_thistime
;
185 pd
+= data_sent_thistime
;
187 params_to_send
-= params_sent_thistime
;
188 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
;
223 int fmode
=0,mtime
=0,rmode
;
225 SMB_STRUCT_STAT sbuf
;
227 BOOL bad_path
= False
;
231 * Ensure we have enough parameters to perform the operation.
234 if (total_params
< 29)
235 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
237 open_mode
= SVAL(params
, 2);
238 open_attr
= SVAL(params
,6);
239 oplock_request
= (((SVAL(params
,0)|(1<<1))>>1) | ((SVAL(params
,0)|(1<<2))>>1));
241 return_additional_info
= BITSETW(params
,0);
242 open_sattr
= SVAL(params
, 4);
243 open_time
= make_unix_date3(params
+8);
245 open_ofun
= SVAL(params
,12);
246 open_size
= IVAL(params
,14);
249 srvstr_pull(inbuf
, fname
, pname
, sizeof(fname
), -1, STR_TERMINATE
);
251 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
252 fname
,open_mode
, open_attr
, open_ofun
, open_size
));
255 return(ERROR_DOS(ERRSRV
,ERRaccess
));
257 /* XXXX we need to handle passed times, sattr and flags */
259 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
261 if (!check_name(fname
,conn
)) {
262 set_bad_path_error(errno
, bad_path
);
263 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
266 unixmode
= unix_mode(conn
,open_attr
| aARCH
, fname
);
268 fsp
= open_file_shared(conn
,fname
,&sbuf
,open_mode
,open_ofun
,unixmode
,
269 oplock_request
, &rmode
,&smb_action
);
272 set_bad_path_error(errno
, bad_path
);
273 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
276 size
= get_file_size(sbuf
);
277 fmode
= dos_mode(conn
,fname
,&sbuf
);
278 mtime
= sbuf
.st_mtime
;
281 close_file(fsp
,False
);
282 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
285 /* Realloc the size of parameters and data we will return */
286 params
= Realloc(*pparams
, 28);
288 return(ERROR_DOS(ERRDOS
,ERRnomem
));
291 memset((char *)params
,'\0',28);
292 SSVAL(params
,0,fsp
->fnum
);
293 SSVAL(params
,2,fmode
);
294 put_dos_date2(params
,4, mtime
);
295 SIVAL(params
,8, (uint32
)size
);
296 SSVAL(params
,12,rmode
);
298 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
299 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
301 SSVAL(params
,18,smb_action
);
304 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
306 SIVAL(params
,20,inode
);
308 /* Send the required number of replies */
309 send_trans2_replies(outbuf
, bufsize
, params
, 28, *ppdata
, 0);
314 /*********************************************************
315 Routine to check if a given string matches exactly.
316 as a special case a mask of "." does NOT match. That
317 is required for correct wildcard semantics
318 Case can be significant or not.
319 **********************************************************/
321 static BOOL
exact_match(char *str
,char *mask
, BOOL case_sig
)
323 if (mask
[0] == '.' && mask
[1] == 0)
326 return strcmp(str
,mask
)==0;
327 return strcasecmp(str
,mask
) == 0;
330 /****************************************************************************
331 Return the filetype for UNIX extensions.
332 ****************************************************************************/
334 static uint32
unix_filetype(mode_t mode
)
337 return UNIX_TYPE_FILE
;
338 else if(S_ISDIR(mode
))
339 return UNIX_TYPE_DIR
;
341 else if(S_ISLNK(mode
))
342 return UNIX_TYPE_SYMLINK
;
345 else if(S_ISCHR(mode
))
346 return UNIX_TYPE_CHARDEV
;
349 else if(S_ISBLK(mode
))
350 return UNIX_TYPE_BLKDEV
;
353 else if(S_ISFIFO(mode
))
354 return UNIX_TYPE_FIFO
;
357 else if(S_ISSOCK(mode
))
358 return UNIX_TYPE_SOCKET
;
361 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode
));
362 return UNIX_TYPE_UNKNOWN
;
365 /****************************************************************************
366 Return the major devicenumber for UNIX extensions.
367 ****************************************************************************/
369 static uint32
unix_dev_major(SMB_DEV_T dev
)
371 #if defined(HAVE_DEVICE_MAJOR_FN)
372 return (uint32
)major(dev
);
374 return (uint32
)(dev
>> 8);
378 /****************************************************************************
379 Return the minor devicenumber for UNIX extensions.
380 ****************************************************************************/
382 static uint32
unix_dev_minor(SMB_DEV_T dev
)
384 #if defined(HAVE_DEVICE_MINOR_FN)
385 return (uint32
)minor(dev
);
387 return (uint32
)(dev
& 0xff);
391 /****************************************************************************
392 Map wire perms onto standard UNIX permissions. Obey share restrictions.
393 ****************************************************************************/
395 static mode_t
unix_perms_from_wire( connection_struct
*conn
, SMB_STRUCT_STAT
*pst
, uint32 perms
)
399 if (perms
== SMB_MODE_NO_CHANGE
)
402 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
403 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
404 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
405 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
406 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
407 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
408 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
409 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
410 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
412 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
415 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
418 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
421 if (VALID_STAT(*pst
) && S_ISDIR(pst
->st_mode
)) {
422 ret
&= lp_dir_mask(SNUM(conn
));
423 /* Add in force bits */
424 ret
|= lp_force_dir_mode(SNUM(conn
));
426 /* Apply mode mask */
427 ret
&= lp_create_mask(SNUM(conn
));
428 /* Add in force bits */
429 ret
|= lp_force_create_mode(SNUM(conn
));
435 /****************************************************************************
436 checks for SMB_TIME_NO_CHANGE and if not found
437 calls interpret_long_date
438 ****************************************************************************/
439 time_t interpret_long_unix_date(char *p
)
441 DEBUG(1,("interpret_long_unix_date\n"));
442 if(IVAL(p
,0) == SMB_TIME_NO_CHANGE_LO
&&
443 IVAL(p
,4) == SMB_TIME_NO_CHANGE_HI
) {
446 return interpret_long_date(p
);
450 /****************************************************************************
451 Get a level dependent lanman2 dir entry.
452 ****************************************************************************/
454 static BOOL
get_lanman2_dir_entry(connection_struct
*conn
,
455 void *inbuf
, void *outbuf
,
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
, *q
, *pdata
= *ppdata
;
473 SMB_OFF_T file_size
= 0;
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_m(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 file_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
) {
614 case SMB_INFO_STANDARD
:
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
)file_size
);
623 SIVAL(p
,l1_cbFileAlloc
,(uint32
)allocation_size
);
624 SSVAL(p
,l1_attrFile
,mode
);
627 p
+= align_string(outbuf
, p
, 0);
628 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
629 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)
630 SCVAL(nameptr
, -1, len
-2);
632 SCVAL(nameptr
, -1, len
-1);
636 case SMB_INFO_QUERY_EA_SIZE
:
637 if(requires_resume_key
) {
641 put_dos_date2(p
,l2_fdateCreation
,cdate
);
642 put_dos_date2(p
,l2_fdateLastAccess
,adate
);
643 put_dos_date2(p
,l2_fdateLastWrite
,mdate
);
644 SIVAL(p
,l2_cbFile
,(uint32
)file_size
);
645 SIVAL(p
,l2_cbFileAlloc
,(uint32
)allocation_size
);
646 SSVAL(p
,l2_attrFile
,mode
);
647 SIVAL(p
,l2_cbList
,0); /* No extended attributes */
650 p
+= align_string(outbuf
, p
, 0);
651 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
652 if (SVAL(outbuf
, smb_flg2
) & FLAGS2_UNICODE_STRINGS
)
653 SCVAL(nameptr
, -1, len
-2);
655 SCVAL(nameptr
, -1, len
-1);
659 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
660 was_8_3
= mangle_is_8_3(fname
, True
);
662 SIVAL(p
,0,reskey
); p
+= 4;
663 put_long_date(p
,cdate
); p
+= 8;
664 put_long_date(p
,adate
); p
+= 8;
665 put_long_date(p
,mdate
); p
+= 8;
666 put_long_date(p
,mdate
); p
+= 8;
667 SOFF_T(p
,0,file_size
);
668 SOFF_T(p
,8,allocation_size
);
670 SIVAL(p
,0,nt_extmode
); p
+= 4;
672 SIVAL(p
,0,0); p
+= 4;
673 /* Clear the short name buffer. This is
674 * IMPORTANT as not doing so will trigger
675 * a Win2k client bug. JRA.
679 pstring mangled_name
;
680 pstrcpy(mangled_name
, fname
);
681 mangle_map(mangled_name
,True
,True
,SNUM(conn
));
682 mangled_name
[12] = 0;
683 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
);
690 len
= srvstr_push(outbuf
, p
, fname
, -1, 0);
693 len
= PTR_DIFF(p
, pdata
);
694 len
= (len
+ 3) & ~3;
699 case SMB_FIND_FILE_DIRECTORY_INFO
:
701 SIVAL(p
,0,reskey
); p
+= 4;
702 put_long_date(p
,cdate
); p
+= 8;
703 put_long_date(p
,adate
); p
+= 8;
704 put_long_date(p
,mdate
); p
+= 8;
705 put_long_date(p
,mdate
); p
+= 8;
706 SOFF_T(p
,0,file_size
);
707 SOFF_T(p
,8,allocation_size
);
709 SIVAL(p
,0,nt_extmode
); p
+= 4;
711 len
= srvstr_push(outbuf
, p
, fname
, -1, 0);
714 len
= PTR_DIFF(p
, pdata
);
715 len
= (len
+ 3) & ~3;
720 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
722 SIVAL(p
,0,reskey
); p
+= 4;
723 put_long_date(p
,cdate
); p
+= 8;
724 put_long_date(p
,adate
); p
+= 8;
725 put_long_date(p
,mdate
); p
+= 8;
726 put_long_date(p
,mdate
); p
+= 8;
727 SOFF_T(p
,0,file_size
);
728 SOFF_T(p
,8,allocation_size
);
730 SIVAL(p
,0,nt_extmode
); p
+= 4;
732 SIVAL(p
,0,0); p
+= 4;
734 len
= srvstr_push(outbuf
, p
, fname
, -1, 0);
738 len
= PTR_DIFF(p
, pdata
);
739 len
= (len
+ 3) & ~3;
744 case SMB_FIND_FILE_NAMES_INFO
:
746 SIVAL(p
,0,reskey
); p
+= 4;
748 /* this must *not* be null terminated or w2k gets in a loop trying to set an
749 acl on a dir (tridge) */
750 len
= srvstr_push(outbuf
, p
, fname
, -1, 0);
753 len
= PTR_DIFF(p
, pdata
);
754 len
= (len
+ 3) & ~3;
759 /* CIFS UNIX Extension. */
761 case SMB_FIND_FILE_UNIX
:
763 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
765 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
766 SOFF_T(p
,0,get_file_size(sbuf
)); /* File size 64 Bit */
769 SOFF_T(p
,0,get_allocation_size(NULL
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
772 put_long_date(p
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
773 put_long_date(p
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
774 put_long_date(p
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
777 SIVAL(p
,0,sbuf
.st_uid
); /* user id for the owner */
781 SIVAL(p
,0,sbuf
.st_gid
); /* group id of owner */
785 SIVAL(p
,0,unix_filetype(sbuf
.st_mode
));
788 SIVAL(p
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
792 SIVAL(p
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
796 SINO_T(p
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
799 SIVAL(p
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
803 SIVAL(p
,0,sbuf
.st_nlink
); /* number of hard links */
807 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
810 len
= PTR_DIFF(p
, pdata
);
811 len
= (len
+ 3) & ~3;
812 SIVAL(pdata
,0,len
); /* Offset from this structure to the beginning of the next one */
814 /* End of SMB_QUERY_FILE_UNIX_BASIC */
823 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
824 /* Move the dirptr back to prev_dirpos */
825 SeekDir(conn
->dirptr
, prev_dirpos
);
826 *out_of_space
= True
;
827 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
828 return False
; /* Not finished - just out of space */
831 /* Setup the last_filename pointer, as an offset from base_data */
832 *last_name_off
= PTR_DIFF(nameptr
,base_data
);
833 /* Advance the data pointer to the next slot */
839 /****************************************************************************
840 Reply to a TRANS2_FINDFIRST.
841 ****************************************************************************/
843 static int call_trans2findfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
844 char **pparams
, int total_params
, char **ppdata
, int total_data
)
846 /* We must be careful here that we don't return more than the
847 allowed number of data bytes. If this means returning fewer than
848 maxentries then so be it. We assume that the redirector has
849 enough room for the fixed number of parameter bytes it has
851 uint32 max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
852 char *params
= *pparams
;
853 char *pdata
= *ppdata
;
854 int dirtype
= SVAL(params
,0);
855 int maxentries
= SVAL(params
,2);
856 BOOL close_after_first
= BITSETW(params
+4,0);
857 BOOL close_if_end
= BITSETW(params
+4,1);
858 BOOL requires_resume_key
= BITSETW(params
+4,2);
859 int info_level
= SVAL(params
,6);
867 BOOL finished
= False
;
868 BOOL dont_descend
= False
;
869 BOOL out_of_space
= False
;
871 BOOL bad_path
= False
;
872 SMB_STRUCT_STAT sbuf
;
874 if (total_params
< 12)
875 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
877 *directory
= *mask
= 0;
879 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
880 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
881 dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
882 info_level
, max_data_bytes
));
884 switch (info_level
) {
885 case SMB_INFO_STANDARD
:
886 case SMB_INFO_QUERY_EA_SIZE
:
887 case SMB_FIND_FILE_DIRECTORY_INFO
:
888 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
889 case SMB_FIND_FILE_NAMES_INFO
:
890 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
892 case SMB_FIND_FILE_UNIX
:
893 if (!lp_unix_extensions())
894 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
897 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
900 srvstr_pull(inbuf
, directory
, params
+12, sizeof(directory
), -1, STR_TERMINATE
);
902 RESOLVE_FINDFIRST_DFSPATH(directory
, conn
, inbuf
, outbuf
);
904 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
905 if(!check_name(directory
,conn
)) {
906 set_bad_path_error(errno
, bad_path
);
907 return(UNIXERROR(ERRDOS
,ERRbadpath
));
910 p
= strrchr_m(directory
,'/');
912 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
913 if((directory
[0] == '.') && (directory
[1] == '\0'))
916 pstrcpy(mask
,directory
);
917 pstrcpy(directory
,"./");
923 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
925 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
927 return(ERROR_DOS(ERRDOS
,ERRnomem
));
930 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
932 /* Realloc the params space */
933 params
= Realloc(*pparams
, 10);
935 return ERROR_DOS(ERRDOS
,ERRnomem
);
938 dptr_num
= dptr_create(conn
,directory
, False
, True
,SVAL(inbuf
,smb_pid
));
940 return(UNIXERROR(ERRDOS
,ERRbadfile
));
942 /* Save the wildcard match and attribs we are using on this directory -
943 needed as lanman2 assumes these are being saved between calls */
945 if(!(wcard
= strdup(mask
))) {
946 dptr_close(&dptr_num
);
947 return ERROR_DOS(ERRDOS
,ERRnomem
);
950 dptr_set_wcard(dptr_num
, wcard
);
951 dptr_set_attr(dptr_num
, dirtype
);
953 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num
, wcard
, dirtype
));
955 /* We don't need to check for VOL here as this is returned by
956 a different TRANS2 call. */
958 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
959 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
963 space_remaining
= max_data_bytes
;
964 out_of_space
= False
;
966 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
967 BOOL got_exact_match
= False
;
969 /* this is a heuristic to avoid seeking the dirptr except when
970 absolutely necessary. It allows for a filename of about 40 chars */
971 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
975 finished
= !get_lanman2_dir_entry(conn
,
977 mask
,dirtype
,info_level
,
978 requires_resume_key
,dont_descend
,
979 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
983 if (finished
&& out_of_space
)
986 if (!finished
&& !out_of_space
)
990 * As an optimisation if we know we aren't looking
991 * for a wildcard name (ie. the name matches the wildcard exactly)
992 * then we can finish on any (first) match.
993 * This speeds up large directory searches. JRA.
999 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1002 /* Check if we can close the dirptr */
1003 if(close_after_first
|| (finished
&& close_if_end
)) {
1004 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
1005 dptr_close(&dptr_num
);
1009 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1010 * from observation of NT.
1013 if(numentries
== 0) {
1014 dptr_close(&dptr_num
);
1015 return ERROR_DOS(ERRDOS
,ERRbadfile
);
1018 /* At this point pdata points to numentries directory entries. */
1020 /* Set up the return parameter block */
1021 SSVAL(params
,0,dptr_num
);
1022 SSVAL(params
,2,numentries
);
1023 SSVAL(params
,4,finished
);
1024 SSVAL(params
,6,0); /* Never an EA error */
1025 SSVAL(params
,8,last_name_off
);
1027 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
));
1029 if ((! *directory
) && dptr_path(dptr_num
))
1030 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1032 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1033 smb_fn_name(CVAL(inbuf
,smb_com
)),
1034 mask
, directory
, dirtype
, numentries
) );
1037 * Force a name mangle here to ensure that the
1038 * mask as an 8.3 name is top of the mangled cache.
1039 * The reasons for this are subtle. Don't remove
1040 * this code unless you know what you are doing
1041 * (see PR#13758). JRA.
1044 if(!mangle_is_8_3_wildcards( mask
, False
))
1045 mangle_map(mask
, True
, True
, SNUM(conn
));
1050 /****************************************************************************
1051 Reply to a TRANS2_FINDNEXT.
1052 ****************************************************************************/
1054 static int call_trans2findnext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1055 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1057 /* We must be careful here that we don't return more than the
1058 allowed number of data bytes. If this means returning fewer than
1059 maxentries then so be it. We assume that the redirector has
1060 enough room for the fixed number of parameter bytes it has
1062 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1063 char *params
= *pparams
;
1064 char *pdata
= *ppdata
;
1065 int dptr_num
= SVAL(params
,0);
1066 int maxentries
= SVAL(params
,2);
1067 uint16 info_level
= SVAL(params
,4);
1068 uint32 resume_key
= IVAL(params
,6);
1069 BOOL close_after_request
= BITSETW(params
+10,0);
1070 BOOL close_if_end
= BITSETW(params
+10,1);
1071 BOOL requires_resume_key
= BITSETW(params
+10,2);
1072 BOOL continue_bit
= BITSETW(params
+10,3);
1073 pstring resume_name
;
1079 int i
, last_name_off
=0;
1080 BOOL finished
= False
;
1081 BOOL dont_descend
= False
;
1082 BOOL out_of_space
= False
;
1083 int space_remaining
;
1085 if (total_params
< 12)
1086 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1088 *mask
= *directory
= *resume_name
= 0;
1090 srvstr_pull(inbuf
, resume_name
, params
+12, sizeof(resume_name
), -1, STR_TERMINATE
);
1092 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1093 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1094 resume_key = %d resume name = %s continue=%d level = %d\n",
1095 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
1096 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
1098 switch (info_level
) {
1099 case SMB_INFO_STANDARD
:
1100 case SMB_INFO_QUERY_EA_SIZE
:
1101 case SMB_FIND_FILE_DIRECTORY_INFO
:
1102 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1103 case SMB_FIND_FILE_NAMES_INFO
:
1104 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1106 case SMB_FIND_FILE_UNIX
:
1107 if (!lp_unix_extensions())
1108 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1111 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1114 pdata
= Realloc( *ppdata
, max_data_bytes
+ 1024);
1116 return ERROR_DOS(ERRDOS
,ERRnomem
);
1119 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1121 /* Realloc the params space */
1122 params
= Realloc(*pparams
, 6*SIZEOFWORD
);
1123 if( params
== NULL
)
1124 return ERROR_DOS(ERRDOS
,ERRnomem
);
1128 /* Check that the dptr is valid */
1129 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
)))
1130 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1132 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1134 /* Get the wildcard mask from the dptr */
1135 if((p
= dptr_wcard(dptr_num
))== NULL
) {
1136 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
1137 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1141 pstrcpy(directory
,conn
->dirpath
);
1143 /* Get the attr mask from the dptr */
1144 dirtype
= dptr_attr(dptr_num
);
1146 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1147 dptr_num
, mask
, dirtype
,
1149 TellDir(conn
->dirptr
)));
1151 /* We don't need to check for VOL here as this is returned by
1152 a different TRANS2 call. */
1154 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1155 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
1156 dont_descend
= True
;
1159 space_remaining
= max_data_bytes
;
1160 out_of_space
= False
;
1163 * Seek to the correct position. We no longer use the resume key but
1164 * depend on the last file name instead.
1167 if(requires_resume_key
&& *resume_name
&& !continue_bit
) {
1170 * Fix for NT redirector problem triggered by resume key indexes
1171 * changing between directory scans. We now return a resume key of 0
1172 * and instead look for the filename to continue from (also given
1173 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1174 * findfirst/findnext (as is usual) then the directory pointer
1175 * should already be at the correct place. Check this by scanning
1176 * backwards looking for an exact (ie. case sensitive) filename match.
1177 * If we get to the beginning of the directory and haven't found it then scan
1178 * forwards again looking for a match. JRA.
1181 int current_pos
, start_pos
;
1182 const char *dname
= NULL
;
1183 pstring dname_pstring
;
1184 void *dirptr
= conn
->dirptr
;
1185 start_pos
= TellDir(dirptr
);
1186 for(current_pos
= start_pos
; current_pos
>= 0; current_pos
--) {
1187 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos
));
1189 SeekDir(dirptr
, current_pos
);
1190 dname
= ReadDirName(dirptr
);
1193 * Remember, mangle_map is called by
1194 * get_lanman2_dir_entry(), so the resume name
1195 * could be mangled. Ensure we do the same
1199 /* make sure we get a copy that mangle_map can modify */
1201 pstrcpy(dname_pstring
, dname
);
1202 mangle_map( dname_pstring
, False
, True
, SNUM(conn
));
1204 if(strcsequal( resume_name
, dname_pstring
)) {
1205 SeekDir(dirptr
, current_pos
+1);
1206 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1213 * Scan forward from start if not found going backwards.
1216 if(current_pos
< 0) {
1217 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos
));
1218 SeekDir(dirptr
, start_pos
);
1219 for(current_pos
= start_pos
; (dname
= ReadDirName(dirptr
)) != NULL
; SeekDir(dirptr
,++current_pos
)) {
1222 * Remember, mangle_map is called by
1223 * get_lanman2_dir_entry(), so the resume name
1224 * could be mangled. Ensure we do the same
1229 /* make sure we get a copy that mangle_map can modify */
1231 pstrcpy(dname_pstring
, dname
);
1232 mangle_map(dname_pstring
, False
, True
, SNUM(conn
));
1234 if(strcsequal( resume_name
, dname_pstring
)) {
1235 SeekDir(dirptr
, current_pos
+1);
1236 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1241 } /* end if current_pos */
1242 } /* end if requires_resume_key && !continue_bit */
1244 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
1245 BOOL got_exact_match
= False
;
1247 /* this is a heuristic to avoid seeking the dirptr except when
1248 absolutely necessary. It allows for a filename of about 40 chars */
1249 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1250 out_of_space
= True
;
1253 finished
= !get_lanman2_dir_entry(conn
,
1255 mask
,dirtype
,info_level
,
1256 requires_resume_key
,dont_descend
,
1257 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1261 if (finished
&& out_of_space
)
1264 if (!finished
&& !out_of_space
)
1268 * As an optimisation if we know we aren't looking
1269 * for a wildcard name (ie. the name matches the wildcard exactly)
1270 * then we can finish on any (first) match.
1271 * This speeds up large directory searches. JRA.
1277 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1280 /* Check if we can close the dirptr */
1281 if(close_after_request
|| (finished
&& close_if_end
)) {
1282 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
1283 dptr_close(&dptr_num
); /* This frees up the saved mask */
1286 /* Set up the return parameter block */
1287 SSVAL(params
,0,numentries
);
1288 SSVAL(params
,2,finished
);
1289 SSVAL(params
,4,0); /* Never an EA error */
1290 SSVAL(params
,6,last_name_off
);
1292 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
1294 if ((! *directory
) && dptr_path(dptr_num
))
1295 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1297 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1298 smb_fn_name(CVAL(inbuf
,smb_com
)),
1299 mask
, directory
, dirtype
, numentries
) );
1304 /****************************************************************************
1305 Reply to a TRANS2_QFSINFO (query filesystem info).
1306 ****************************************************************************/
1308 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
,
1309 int length
, int bufsize
,
1310 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1312 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1313 char *pdata
= *ppdata
;
1314 char *params
= *pparams
;
1315 uint16 info_level
= SVAL(params
,0);
1318 char *vname
= volume_label(SNUM(conn
));
1319 int snum
= SNUM(conn
);
1320 char *fstype
= lp_fstype(SNUM(conn
));
1322 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
1324 if(vfs_stat(conn
,".",&st
)!=0) {
1325 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
1326 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
1329 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
1330 if ( pdata
== NULL
)
1331 return ERROR_DOS(ERRDOS
,ERRnomem
);
1334 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1336 switch (info_level
) {
1337 case SMB_INFO_ALLOCATION
:
1339 SMB_BIG_UINT dfree
,dsize
,bsize
;
1341 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1342 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
1343 SIVAL(pdata
,l1_cSectorUnit
,bsize
/512);
1344 SIVAL(pdata
,l1_cUnit
,dsize
);
1345 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
1346 SSVAL(pdata
,l1_cbSector
,512);
1347 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1348 (unsigned int)bsize
, (unsigned int)st
.st_dev
, ((unsigned int)bsize
)/512, (unsigned int)dsize
,
1349 (unsigned int)dfree
, 512));
1353 case SMB_INFO_VOLUME
:
1354 /* Return volume name */
1356 * Add volume serial number - hash of a combination of
1357 * the called hostname and the service name.
1359 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(local_machine
)<<16) );
1360 len
= srvstr_push(outbuf
, pdata
+l2_vol_szVolLabel
, vname
, -1, STR_TERMINATE
);
1361 SCVAL(pdata
,l2_vol_cch
,len
);
1362 data_len
= l2_vol_szVolLabel
+ len
;
1363 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1364 (unsigned)st
.st_ctime
, len
, vname
));
1367 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
1368 case SMB_FS_ATTRIBUTE_INFORMATION
:
1370 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
1371 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)); /* FS ATTRIBUTES */
1372 SIVAL(pdata
,4,255); /* Max filename component length */
1373 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1374 and will think we can't do long filenames */
1375 len
= srvstr_push(outbuf
, pdata
+12, fstype
, -1, 0);
1377 data_len
= 12 + len
;
1380 case SMB_QUERY_FS_LABEL_INFO
:
1381 case SMB_FS_LABEL_INFORMATION
:
1382 len
= srvstr_push(outbuf
, pdata
+4, vname
, -1, STR_TERMINATE
);
1387 case SMB_QUERY_FS_VOLUME_INFO
:
1388 case SMB_FS_VOLUME_INFORMATION
:
1391 * Add volume serial number - hash of a combination of
1392 * the called hostname and the service name.
1394 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
1395 (str_checksum(local_machine
)<<16));
1397 len
= srvstr_push(outbuf
, pdata
+18, vname
, -1, STR_TERMINATE
);
1398 SIVAL(pdata
,12,len
);
1400 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1401 (int)strlen(vname
),vname
, lp_servicename(snum
)));
1404 case SMB_QUERY_FS_SIZE_INFO
:
1405 case SMB_FS_SIZE_INFORMATION
:
1407 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1409 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1410 block_size
= lp_block_size(snum
);
1411 if (bsize
< block_size
) {
1412 SMB_BIG_UINT factor
= block_size
/bsize
;
1417 if (bsize
> block_size
) {
1418 SMB_BIG_UINT factor
= bsize
/block_size
;
1423 bytes_per_sector
= 512;
1424 sectors_per_unit
= bsize
/bytes_per_sector
;
1425 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1426 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1427 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1428 SBIG_UINT(pdata
,0,dsize
);
1429 SBIG_UINT(pdata
,8,dfree
);
1430 SIVAL(pdata
,16,sectors_per_unit
);
1431 SIVAL(pdata
,20,bytes_per_sector
);
1435 case SMB_FS_FULL_SIZE_INFORMATION
:
1437 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1439 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1440 block_size
= lp_block_size(snum
);
1441 if (bsize
< block_size
) {
1442 SMB_BIG_UINT factor
= block_size
/bsize
;
1447 if (bsize
> block_size
) {
1448 SMB_BIG_UINT factor
= bsize
/block_size
;
1453 bytes_per_sector
= 512;
1454 sectors_per_unit
= bsize
/bytes_per_sector
;
1455 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1456 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1457 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1458 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
1459 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
1460 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
1461 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
1462 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
1466 case SMB_QUERY_FS_DEVICE_INFO
:
1467 case SMB_FS_DEVICE_INFORMATION
:
1469 SIVAL(pdata
,0,0); /* dev type */
1470 SIVAL(pdata
,4,0); /* characteristics */
1473 case SMB_FS_OBJECTID_INFORMATION
:
1478 * Query the version and capabilities of the CIFS UNIX extensions
1482 case SMB_QUERY_CIFS_UNIX_INFO
:
1483 if (!lp_unix_extensions())
1484 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1486 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
1487 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
1488 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)0)); /* No capabilities for now... */
1491 case SMB_MAC_QUERY_FS_INFO
:
1493 * Thursby MAC extension... ONLY on NTFS filesystems
1494 * once we do streams then we don't need this
1496 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
1498 SIVAL(pdata
,84,0x100); /* Don't support mac... */
1503 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1507 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
1509 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
1514 /****************************************************************************
1515 Reply to a TRANS2_SETFSINFO (set filesystem info).
1516 ****************************************************************************/
1518 static int call_trans2setfsinfo(connection_struct
*conn
,
1519 char *inbuf
, char *outbuf
, int length
, int bufsize
,
1520 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1522 /* Just say yes we did it - there is nothing that
1523 can be set here so it doesn't matter. */
1525 DEBUG(3,("call_trans2setfsinfo\n"));
1527 if (!CAN_WRITE(conn
))
1528 return ERROR_DOS(ERRSRV
,ERRaccess
);
1530 outsize
= set_message(outbuf
,10,0,True
);
1535 /****************************************************************************
1536 * Utility function to set bad path error.
1537 ****************************************************************************/
1539 NTSTATUS
set_bad_path_error(int err
, BOOL bad_path
)
1541 if((err
== ENOENT
) && bad_path
) {
1542 unix_ERR_class
= ERRDOS
;
1543 unix_ERR_code
= ERRbadpath
;
1544 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1546 return NT_STATUS_OK
;
1549 /****************************************************************************
1550 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1551 file name or file id).
1552 ****************************************************************************/
1554 static int call_trans2qfilepathinfo(connection_struct
*conn
,
1555 char *inbuf
, char *outbuf
, int length
,
1557 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1559 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1560 char *params
= *pparams
;
1561 char *pdata
= *ppdata
;
1562 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
1565 SMB_OFF_T file_size
=0;
1566 SMB_BIG_UINT allocation_size
=0;
1567 unsigned int data_size
;
1568 SMB_STRUCT_STAT sbuf
;
1569 pstring fname
, dos_fname
;
1574 BOOL bad_path
= False
;
1575 BOOL delete_pending
= False
;
1578 files_struct
*fsp
= NULL
;
1581 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1583 if (tran_call
== TRANSACT2_QFILEINFO
) {
1584 if (total_params
< 4)
1585 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1587 fsp
= file_fsp(params
,0);
1588 info_level
= SVAL(params
,2);
1590 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
1592 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
1594 * This is actually a QFILEINFO on a directory
1595 * handle (returned from an NT SMB). NT5.0 seems
1596 * to do this call. JRA.
1598 pstrcpy(fname
, fsp
->fsp_name
);
1599 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1600 if (!check_name(fname
,conn
)) {
1601 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
1602 set_bad_path_error(errno
, bad_path
);
1603 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1606 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1607 /* Always do lstat for UNIX calls. */
1608 if (vfs_lstat(conn
,fname
,&sbuf
)) {
1609 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname
,strerror(errno
)));
1610 set_bad_path_error(errno
, bad_path
);
1611 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1613 } else if (!VALID_STAT(sbuf
) && vfs_stat(conn
,fname
,&sbuf
)) {
1614 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname
,strerror(errno
)));
1615 set_bad_path_error(errno
, bad_path
);
1616 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1619 delete_pending
= fsp
->directory_delete_on_close
;
1622 * Original code - this is an open file.
1624 CHECK_FSP(fsp
,conn
);
1626 pstrcpy(fname
, fsp
->fsp_name
);
1627 if (vfs_fstat(fsp
,fsp
->fd
,&sbuf
) != 0) {
1628 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp
->fnum
, strerror(errno
)));
1629 return(UNIXERROR(ERRDOS
,ERRbadfid
));
1631 if((pos
= fsp
->conn
->vfs_ops
.lseek(fsp
,fsp
->fd
,0,SEEK_CUR
)) == -1)
1632 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
1634 delete_pending
= fsp
->delete_on_close
;
1638 if (total_params
< 6)
1639 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1641 info_level
= SVAL(params
,0);
1643 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
1645 srvstr_pull(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
);
1647 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1649 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1650 if (!check_name(fname
,conn
)) {
1651 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
1652 set_bad_path_error(errno
, bad_path
);
1653 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1656 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1657 /* Always do lstat for UNIX calls. */
1658 if (vfs_lstat(conn
,fname
,&sbuf
)) {
1659 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname
,strerror(errno
)));
1660 set_bad_path_error(errno
, bad_path
);
1661 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1663 } else if (!VALID_STAT(sbuf
) && vfs_stat(conn
,fname
,&sbuf
)) {
1664 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname
,strerror(errno
)));
1665 set_bad_path_error(errno
, bad_path
);
1666 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1670 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
1671 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1673 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1674 fname
,info_level
,tran_call
,total_data
));
1676 p
= strrchr_m(fname
,'/');
1682 mode
= dos_mode(conn
,fname
,&sbuf
);
1683 fullpathname
= fname
;
1684 file_size
= get_file_size(sbuf
);
1685 allocation_size
= get_allocation_size(fsp
,&sbuf
);
1689 params
= Realloc(*pparams
,2);
1691 return ERROR_DOS(ERRDOS
,ERRnomem
);
1693 memset((char *)params
,'\0',2);
1694 data_size
= max_data_bytes
+ 1024;
1695 pdata
= Realloc(*ppdata
, data_size
);
1696 if ( pdata
== NULL
)
1697 return ERROR_DOS(ERRDOS
,ERRnomem
);
1700 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
1701 /* uggh, EAs for OS2 */
1702 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
1703 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
1706 memset((char *)pdata
,'\0',data_size
);
1708 c_time
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
1710 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1712 sbuf
.st_atime
&= ~1;
1713 sbuf
.st_mtime
&= ~1;
1714 sbuf
.st_mtime
&= ~1;
1717 /* NT expects the name to be in an exact form of the *full*
1718 filename. See the trans2 torture test */
1719 if (strequal(base_name
,".")) {
1720 pstrcpy(dos_fname
, "\\");
1722 snprintf(dos_fname
, sizeof(dos_fname
), "\\%s", fname
);
1723 string_replace(dos_fname
, '/', '\\');
1726 switch (info_level
) {
1727 case SMB_INFO_STANDARD
:
1728 case SMB_INFO_QUERY_EA_SIZE
:
1729 data_size
= (info_level
==1?22:26);
1730 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
1731 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
1732 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
1733 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
1734 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
1735 SSVAL(pdata
,l1_attrFile
,mode
);
1736 SIVAL(pdata
,l1_attrFile
+2,4); /* this is what OS2 does */
1739 case SMB_INFO_QUERY_EAS_FROM_LIST
:
1741 put_dos_date2(pdata
,0,c_time
);
1742 put_dos_date2(pdata
,4,sbuf
.st_atime
);
1743 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
1744 SIVAL(pdata
,12,(uint32
)file_size
);
1745 SIVAL(pdata
,16,(uint32
)allocation_size
);
1746 SIVAL(pdata
,20,mode
);
1749 case SMB_INFO_QUERY_ALL_EAS
:
1751 SIVAL(pdata
,0,data_size
);
1755 return ERROR_DOS(ERRDOS
,ERRbadfunc
); /* os/2 needs this */
1757 case SMB_FILE_BASIC_INFORMATION
:
1758 case SMB_QUERY_FILE_BASIC_INFO
:
1760 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
)
1761 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
1766 put_long_date(pdata
,c_time
);
1767 put_long_date(pdata
+8,sbuf
.st_atime
);
1768 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1769 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1770 SIVAL(pdata
,32,mode
);
1772 DEBUG(5,("SMB_QFBI - "));
1774 time_t create_time
= c_time
;
1775 DEBUG(5,("create: %s ", ctime(&create_time
)));
1777 DEBUG(5,("access: %s ", ctime(&sbuf
.st_atime
)));
1778 DEBUG(5,("write: %s ", ctime(&sbuf
.st_mtime
)));
1779 DEBUG(5,("change: %s ", ctime(&sbuf
.st_mtime
)));
1780 DEBUG(5,("mode: %x\n", mode
));
1784 case SMB_FILE_STANDARD_INFORMATION
:
1785 case SMB_QUERY_FILE_STANDARD_INFO
:
1788 SOFF_T(pdata
,0,allocation_size
);
1789 SOFF_T(pdata
,8,file_size
);
1790 SIVAL(pdata
,16,sbuf
.st_nlink
);
1792 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
1795 case SMB_FILE_EA_INFORMATION
:
1796 case SMB_QUERY_FILE_EA_INFO
:
1800 /* Get the 8.3 name - used if NT SMB was negotiated. */
1801 case SMB_QUERY_FILE_ALT_NAME_INFO
:
1805 pstrcpy(short_name
,base_name
);
1806 /* Mangle if not already 8.3 */
1807 if(!mangle_is_8_3(short_name
, True
)) {
1808 mangle_map(short_name
,True
,True
,SNUM(conn
));
1810 len
= srvstr_push(outbuf
, pdata
+4, short_name
, -1, STR_UNICODE
);
1811 data_size
= 4 + len
;
1816 case SMB_QUERY_FILE_NAME_INFO
:
1818 this must be *exactly* right for ACLs on mapped drives to work
1820 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
1821 data_size
= 4 + len
;
1825 case SMB_FILE_ALLOCATION_INFORMATION
:
1826 case SMB_QUERY_FILE_ALLOCATION_INFO
:
1828 SOFF_T(pdata
,0,allocation_size
);
1831 case SMB_FILE_END_OF_FILE_INFORMATION
:
1832 case SMB_QUERY_FILE_END_OF_FILEINFO
:
1834 SOFF_T(pdata
,0,file_size
);
1837 case SMB_QUERY_FILE_ALL_INFO
:
1838 put_long_date(pdata
,c_time
);
1839 put_long_date(pdata
+8,sbuf
.st_atime
);
1840 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1841 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1842 SIVAL(pdata
,32,mode
);
1844 SOFF_T(pdata
,0,allocation_size
);
1845 SOFF_T(pdata
,8,file_size
);
1846 SIVAL(pdata
,16,sbuf
.st_nlink
);
1847 SCVAL(pdata
,20,delete_pending
);
1848 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
1850 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
);
1851 pdata
+= 8; /* index number */
1852 pdata
+= 4; /* EA info */
1854 SIVAL(pdata
,0,0xA9);
1856 SIVAL(pdata
,0,0xd01BF);
1858 SOFF_T(pdata
,0,pos
); /* current offset */
1860 SIVAL(pdata
,0,mode
); /* is this the right sort of mode info? */
1862 pdata
+= 4; /* alignment */
1863 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_TERMINATE
);
1866 data_size
= PTR_DIFF(pdata
,(*ppdata
));
1869 case SMB_FILE_INTERNAL_INFORMATION
:
1870 /* This should be an index number - looks like
1873 I think this causes us to fail the IFSKIT
1874 BasicFileInformationTest. -tpot */
1876 SIVAL(pdata
,0,sbuf
.st_dev
);
1877 SIVAL(pdata
,4,sbuf
.st_ino
);
1881 case SMB_FILE_ACCESS_INFORMATION
:
1882 SIVAL(pdata
,0,0x12019F); /* ??? */
1886 case SMB_FILE_NAME_INFORMATION
:
1887 /* Pathname with leading '\'. */
1890 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
1891 SIVAL(pdata
,0,byte_len
);
1892 data_size
= 4 + byte_len
;
1896 case SMB_FILE_DISPOSITION_INFORMATION
:
1898 SCVAL(pdata
,0,delete_pending
);
1901 case SMB_FILE_POSITION_INFORMATION
:
1903 SOFF_T(pdata
,0,pos
);
1906 case SMB_FILE_MODE_INFORMATION
:
1907 SIVAL(pdata
,0,mode
);
1911 case SMB_FILE_ALIGNMENT_INFORMATION
:
1912 SIVAL(pdata
,0,0); /* No alignment needed. */
1917 /* Not yet finished... JRA */
1920 put_long_date(pdata
,c_time
);
1921 put_long_date(pdata
+8,sbuf
.st_atime
);
1922 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1923 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1924 SIVAL(pdata
,32,mode
);
1925 SIVAL(pdata
,36,0); /* ??? */
1926 SIVAL(pdata
,40,0x20); /* ??? */
1927 SIVAL(pdata
,44,0); /* ??? */
1928 SOFF_T(pdata
,48,size
);
1929 SIVAL(pdata
,56,0x1); /* ??? */
1930 SIVAL(pdata
,60,0); /* ??? */
1931 SIVAL(pdata
,64,0); /* ??? */
1932 SIVAL(pdata
,68,length
); /* Following string length in bytes. */
1933 dos_PutUniCode(pdata
+72,,False
);
1938 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
1939 /* Last component of pathname. */
1941 size_t byte_len
= dos_PutUniCode(pdata
+4,fname
,max_data_bytes
,False
);
1942 SIVAL(pdata
,0,byte_len
);
1943 data_size
= 4 + byte_len
;
1949 * NT4 server just returns "invalid query" to this - if we try to answer
1950 * it then NTws gets a BSOD! (tridge).
1951 * W2K seems to want this. JRA.
1953 case SMB_QUERY_FILE_STREAM_INFO
:
1955 case SMB_FILE_STREAM_INFORMATION
:
1959 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", 0xE, False
);
1960 SIVAL(pdata
,0,0); /* ??? */
1961 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
1962 SOFF_T(pdata
,8,file_size
);
1963 SIVAL(pdata
,16,allocation_size
);
1964 SIVAL(pdata
,20,0); /* ??? */
1965 data_size
= 24 + byte_len
;
1969 case SMB_FILE_COMPRESSION_INFORMATION
:
1970 SOFF_T(pdata
,0,allocation_size
);
1971 SIVAL(pdata
,8,0); /* ??? */
1972 SIVAL(pdata
,12,0); /* ??? */
1976 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
1977 put_long_date(pdata
,c_time
);
1978 put_long_date(pdata
+8,sbuf
.st_atime
);
1979 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1980 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1981 SIVAL(pdata
,32,allocation_size
);
1982 SOFF_T(pdata
,40,file_size
);
1983 SIVAL(pdata
,48,mode
);
1984 SIVAL(pdata
,52,0); /* ??? */
1988 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
1989 SIVAL(pdata
,0,mode
);
1995 * CIFS UNIX Extensions.
1998 case SMB_QUERY_FILE_UNIX_BASIC
:
2000 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf
.st_mode
));
2002 SOFF_T(pdata
,0,get_file_size(sbuf
)); /* File size 64 Bit */
2005 SOFF_T(pdata
,0,get_allocation_size(fsp
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
2008 put_long_date(pdata
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
2009 put_long_date(pdata
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
2010 put_long_date(pdata
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
2013 SIVAL(pdata
,0,sbuf
.st_uid
); /* user id for the owner */
2017 SIVAL(pdata
,0,sbuf
.st_gid
); /* group id of owner */
2021 SIVAL(pdata
,0,unix_filetype(sbuf
.st_mode
));
2024 SIVAL(pdata
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
2028 SIVAL(pdata
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
2032 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
2035 SIVAL(pdata
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
2039 SIVAL(pdata
,0,sbuf
.st_nlink
); /* number of hard links */
2042 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2046 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2048 for (i
=0; i
<100; i
++)
2049 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
2055 case SMB_QUERY_FILE_UNIX_LINK
:
2060 if(!S_ISLNK(sbuf
.st_mode
))
2061 return(UNIXERROR(ERRSRV
,ERRbadlink
));
2063 return(UNIXERROR(ERRDOS
,ERRbadlink
));
2065 len
= conn
->vfs_ops
.readlink(conn
,fullpathname
, buffer
, sizeof(pstring
)-1); /* read link */
2067 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2069 len
= srvstr_push(outbuf
, pdata
, buffer
, -1, STR_TERMINATE
);
2071 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2077 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2080 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, data_size
);
2085 /****************************************************************************
2086 Deal with the internal needs of setting the delete on close flag. Note that
2087 as the tdb locking is recursive, it is safe to call this from within
2088 open_file_shared. JRA.
2089 ****************************************************************************/
2091 NTSTATUS
set_delete_on_close_internal(files_struct
*fsp
, BOOL delete_on_close
)
2094 * Only allow delete on close for writable shares.
2097 if (delete_on_close
&& !CAN_WRITE(fsp
->conn
)) {
2098 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2100 return NT_STATUS_ACCESS_DENIED
;
2103 * Only allow delete on close for files/directories opened with delete intent.
2106 if (delete_on_close
&& !(fsp
->desired_access
& DELETE_ACCESS
)) {
2107 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2109 return NT_STATUS_ACCESS_DENIED
;
2112 if(fsp
->is_directory
) {
2113 fsp
->directory_delete_on_close
= delete_on_close
;
2114 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2115 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2117 fsp
->delete_on_close
= delete_on_close
;
2118 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2119 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2122 return NT_STATUS_OK
;
2125 /****************************************************************************
2126 Sets the delete on close flag over all share modes on this file.
2127 Modify the share mode entry for all files open
2128 on this device and inode to tell other smbds we have
2129 changed the delete on close flag. This will be noticed
2130 in the close code, the last closer will delete the file
2132 ****************************************************************************/
2134 NTSTATUS
set_delete_on_close_over_all(files_struct
*fsp
, BOOL delete_on_close
)
2136 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2137 delete_on_close
? "Adding" : "Removing", fsp
->fnum
, fsp
->fsp_name
));
2139 if (fsp
->is_directory
|| fsp
->is_stat
)
2140 return NT_STATUS_OK
;
2142 if (lock_share_entry_fsp(fsp
) == False
)
2143 return NT_STATUS_ACCESS_DENIED
;
2145 if (!modify_delete_flag(fsp
->dev
, fsp
->inode
, delete_on_close
)) {
2146 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2148 unlock_share_entry_fsp(fsp
);
2149 return NT_STATUS_ACCESS_DENIED
;
2152 unlock_share_entry_fsp(fsp
);
2153 return NT_STATUS_OK
;
2156 /****************************************************************************
2157 Returns true if this pathname is within the share, and thus safe.
2158 ****************************************************************************/
2160 static int ensure_link_is_safe(connection_struct
*conn
, const char *link_dest_in
, char *link_dest_out
)
2163 char resolved_name
[PATH_MAX
+1];
2165 pstring resolved_name
;
2167 fstring last_component
;
2171 BOOL bad_path
= False
;
2172 SMB_STRUCT_STAT sbuf
;
2174 pstrcpy(link_dest
, link_dest_in
);
2175 unix_convert(link_dest
,conn
,0,&bad_path
,&sbuf
);
2177 /* Store the UNIX converted path. */
2178 pstrcpy(link_dest_out
, link_dest
);
2180 p
= strrchr(link_dest
, '/');
2182 fstrcpy(last_component
, p
+1);
2185 fstrcpy(last_component
, link_dest
);
2186 pstrcpy(link_dest
, "./");
2189 if (conn
->vfs_ops
.realpath(conn
,link_dest
,resolved_name
) == NULL
)
2192 pstrcpy(link_dest
, resolved_name
);
2193 pstrcat(link_dest
, "/");
2194 pstrcat(link_dest
, last_component
);
2196 if (*link_dest
!= '/') {
2197 /* Relative path. */
2198 pstrcpy(link_test
, conn
->connectpath
);
2199 pstrcat(link_test
, "/");
2200 pstrcat(link_test
, link_dest
);
2202 pstrcpy(link_test
, link_dest
);
2206 * Check if the link is within the share.
2209 if (strncmp(conn
->connectpath
, link_test
, strlen(conn
->connectpath
))) {
2216 /****************************************************************************
2217 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2218 ****************************************************************************/
2220 static int call_trans2setfilepathinfo(connection_struct
*conn
,
2221 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2222 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2224 char *params
= *pparams
;
2225 char *pdata
= *ppdata
;
2226 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2231 SMB_STRUCT_STAT sbuf
;
2234 BOOL bad_path
= False
;
2235 files_struct
*fsp
= NULL
;
2236 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
2237 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
2238 mode_t unixmode
= 0;
2240 if (tran_call
== TRANSACT2_SETFILEINFO
) {
2241 fsp
= file_fsp(params
,0);
2242 info_level
= SVAL(params
,2);
2244 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2246 * This is actually a SETFILEINFO on a directory
2247 * handle (returned from an NT SMB). NT5.0 seems
2248 * to do this call. JRA.
2250 pstrcpy(fname
, fsp
->fsp_name
);
2251 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2252 if (!check_name(fname
,conn
) || (!VALID_STAT(sbuf
))) {
2253 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2254 set_bad_path_error(errno
, bad_path
);
2255 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2257 } else if (fsp
&& fsp
->print_file
) {
2259 * Doing a DELETE_ON_CLOSE should cancel a print job.
2261 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
2262 fsp
->share_mode
= FILE_DELETE_ON_CLOSE
;
2264 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp
->fsp_name
));
2267 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2270 return (UNIXERROR(ERRDOS
,ERRbadpath
));
2273 * Original code - this is an open file.
2275 CHECK_FSP(fsp
,conn
);
2277 pstrcpy(fname
, fsp
->fsp_name
);
2280 if (vfs_fstat(fsp
,fd
,&sbuf
) != 0) {
2281 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
2282 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2287 if (total_params
< 6)
2288 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2290 info_level
= SVAL(params
,0);
2291 srvstr_pull(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
);
2292 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2293 if(!check_name(fname
, conn
)) {
2294 set_bad_path_error(errno
, bad_path
);
2295 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2299 * For CIFS UNIX extensions the target name may not exist.
2302 if(!VALID_STAT(sbuf
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
2303 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname
, strerror(errno
)));
2304 set_bad_path_error(errno
, bad_path
);
2305 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2309 if (!CAN_WRITE(conn
))
2310 return ERROR_DOS(ERRSRV
,ERRaccess
);
2312 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2313 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2315 if (VALID_STAT(sbuf
))
2316 unixmode
= sbuf
.st_mode
;
2318 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2319 tran_call
,fname
,info_level
,total_data
));
2321 /* Realloc the parameter and data sizes */
2322 params
= Realloc(*pparams
,2);
2324 return ERROR_DOS(ERRDOS
,ERRnomem
);
2330 /* the pending modtime overrides the current modtime */
2331 sbuf
.st_mtime
= fsp
->pending_modtime
;
2334 size
= get_file_size(sbuf
);
2335 tvs
.modtime
= sbuf
.st_mtime
;
2336 tvs
.actime
= sbuf
.st_atime
;
2337 dosmode
= dos_mode(conn
,fname
,&sbuf
);
2338 unixmode
= sbuf
.st_mode
;
2340 set_owner
= VALID_STAT(sbuf
) ? sbuf
.st_uid
: (uid_t
)SMB_UID_NO_CHANGE
;
2341 set_grp
= VALID_STAT(sbuf
) ? sbuf
.st_gid
: (gid_t
)SMB_GID_NO_CHANGE
;
2343 switch (info_level
) {
2344 case SMB_INFO_STANDARD
:
2346 if (total_data
< l1_cbFile
+4)
2347 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2350 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
2353 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
2355 dosmode
= SVAL(pdata
,l1_attrFile
);
2356 size
= IVAL(pdata
,l1_cbFile
);
2361 case SMB_INFO_SET_EA
:
2362 return(ERROR_DOS(ERRDOS
,ERReasnotsupported
));
2364 /* XXXX um, i don't think this is right.
2365 it's also not in the cifs6.txt spec.
2367 case SMB_INFO_QUERY_EAS_FROM_LIST
:
2368 if (total_data
< 28)
2369 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2371 tvs
.actime
= make_unix_date2(pdata
+8);
2372 tvs
.modtime
= make_unix_date2(pdata
+12);
2373 size
= IVAL(pdata
,16);
2374 dosmode
= IVAL(pdata
,24);
2377 /* XXXX nor this. not in cifs6.txt, either. */
2378 case SMB_INFO_QUERY_ALL_EAS
:
2379 if (total_data
< 28)
2380 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2382 tvs
.actime
= make_unix_date2(pdata
+8);
2383 tvs
.modtime
= make_unix_date2(pdata
+12);
2384 size
= IVAL(pdata
,16);
2385 dosmode
= IVAL(pdata
,24);
2388 case SMB_SET_FILE_BASIC_INFO
:
2389 case SMB_FILE_BASIC_INFORMATION
:
2391 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2393 time_t changed_time
;
2395 if (total_data
< 36)
2396 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2398 /* Ignore create time at offset pdata. */
2401 tvs
.actime
= interpret_long_date(pdata
+8);
2403 write_time
= interpret_long_date(pdata
+16);
2404 changed_time
= interpret_long_date(pdata
+24);
2406 tvs
.modtime
= MIN(write_time
, changed_time
);
2408 if (write_time
> tvs
.modtime
&& write_time
!= 0xffffffff) {
2409 tvs
.modtime
= write_time
;
2411 /* Prefer a defined time to an undefined one. */
2412 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
2413 tvs
.modtime
= (write_time
== (time_t)0 || write_time
== (time_t)-1
2414 ? changed_time
: write_time
);
2417 dosmode
= IVAL(pdata
,32);
2421 case SMB_FILE_ALLOCATION_INFORMATION
:
2422 case SMB_SET_FILE_ALLOCATION_INFO
:
2425 SMB_BIG_UINT allocation_size
;
2428 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2430 allocation_size
= (SMB_BIG_UINT
)IVAL(pdata
,0);
2431 #ifdef LARGE_SMB_OFF_T
2432 allocation_size
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
2433 #else /* LARGE_SMB_OFF_T */
2434 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2435 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2436 #endif /* LARGE_SMB_OFF_T */
2437 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2438 fname
, (double)allocation_size
));
2440 if (allocation_size
)
2441 allocation_size
= SMB_ROUNDUP(allocation_size
,SMB_ROUNDUP_ALLOCATION_SIZE
);
2443 if(allocation_size
!= get_file_size(sbuf
)) {
2444 SMB_STRUCT_STAT new_sbuf
;
2446 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2447 fname
, (double)allocation_size
));
2450 files_struct
*new_fsp
= NULL
;
2451 int access_mode
= 0;
2454 if(global_oplock_break
) {
2455 /* Queue this file modify as we are the process of an oplock break. */
2457 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2458 DEBUGADD(2,( "in oplock break state.\n"));
2460 push_oplock_pending_smb_message(inbuf
, length
);
2464 new_fsp
= open_file_shared1(conn
, fname
, &sbuf
,FILE_WRITE_DATA
,
2465 SET_OPEN_MODE(DOS_OPEN_RDWR
),
2466 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
2467 0, 0, &access_mode
, &action
);
2469 if (new_fsp
== NULL
)
2470 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2471 ret
= vfs_allocate_file_space(new_fsp
, allocation_size
);
2472 if (vfs_fstat(new_fsp
,new_fsp
->fd
,&new_sbuf
) != 0) {
2473 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2474 new_fsp
->fnum
, strerror(errno
)));
2477 close_file(new_fsp
,True
);
2479 ret
= vfs_allocate_file_space(fsp
, allocation_size
);
2480 if (vfs_fstat(fsp
,fd
,&new_sbuf
) != 0) {
2481 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2482 fsp
->fnum
, strerror(errno
)));
2487 return ERROR_NT(NT_STATUS_DISK_FULL
);
2489 /* Allocate can truncate size... */
2490 size
= get_file_size(new_sbuf
);
2496 case SMB_FILE_END_OF_FILE_INFORMATION
:
2497 case SMB_SET_FILE_END_OF_FILE_INFO
:
2500 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2502 size
= IVAL(pdata
,0);
2503 #ifdef LARGE_SMB_OFF_T
2504 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2505 #else /* LARGE_SMB_OFF_T */
2506 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2507 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2508 #endif /* LARGE_SMB_OFF_T */
2509 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname
, (double)size
));
2513 case SMB_FILE_DISPOSITION_INFORMATION
:
2514 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
2516 BOOL delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
2520 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2522 if (tran_call
!= TRANSACT2_SETFILEINFO
)
2523 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2526 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2528 status
= set_delete_on_close_internal(fsp
, delete_on_close
);
2530 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
2531 return ERROR_NT(status
);
2533 /* The set is across all open files on this dev/inode pair. */
2534 status
=set_delete_on_close_over_all(fsp
, delete_on_close
);
2535 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
2536 return ERROR_NT(status
);
2542 * CIFS UNIX extensions.
2545 case SMB_SET_FILE_UNIX_BASIC
:
2547 uint32 raw_unixmode
;
2549 if (total_data
< 100)
2550 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2552 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
2553 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
2554 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
2555 #ifdef LARGE_SMB_OFF_T
2556 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2557 #else /* LARGE_SMB_OFF_T */
2558 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2559 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2560 #endif /* LARGE_SMB_OFF_T */
2562 pdata
+=24; /* ctime & st_blocks are not changed */
2563 tvs
.actime
= interpret_long_unix_date(pdata
); /* access_time */
2564 tvs
.modtime
= interpret_long_unix_date(pdata
+8); /* modification_time */
2566 set_owner
= (uid_t
)IVAL(pdata
,0);
2568 set_grp
= (gid_t
)IVAL(pdata
,0);
2570 raw_unixmode
= IVAL(pdata
,28);
2571 unixmode
= unix_perms_from_wire(conn
, &sbuf
, raw_unixmode
);
2572 dosmode
= 0; /* Ensure dos mode change doesn't override this. */
2574 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2575 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2576 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
2578 if (!VALID_STAT(sbuf
)) {
2581 * The only valid use of this is to create character and block
2582 * devices, and named pipes. This is deprecated (IMHO) and
2583 * a new info level should be used for mknod. JRA.
2586 #if !defined(HAVE_MAKEDEV_FN)
2587 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2588 #else /* HAVE_MAKEDEV_FN */
2589 uint32 file_type
= IVAL(pdata
,0);
2590 uint32 dev_major
= IVAL(pdata
,4);
2591 uint32 dev_minor
= IVAL(pdata
,12);
2593 uid_t myuid
= geteuid();
2594 gid_t mygid
= getegid();
2597 if (tran_call
== TRANSACT2_SETFILEINFO
)
2598 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2600 if (raw_unixmode
== SMB_MODE_NO_CHANGE
)
2601 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2603 dev
= makedev(dev_major
, dev_minor
);
2605 /* We can only create as the owner/group we are. */
2607 if ((set_owner
!= myuid
) && (set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
))
2608 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2609 if ((set_grp
!= mygid
) && (set_grp
!= (gid_t
)SMB_GID_NO_CHANGE
))
2610 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2612 if (file_type
!= UNIX_TYPE_CHARDEV
&& file_type
!= UNIX_TYPE_BLKDEV
&&
2613 file_type
!= UNIX_TYPE_FIFO
)
2614 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2616 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2617 0%o for file %s\n", (double)dev
, unixmode
, fname
));
2619 /* Ok - do the mknod. */
2620 if (conn
->vfs_ops
.mknod(conn
,dos_to_unix_static(fname
), unixmode
, dev
) != 0)
2621 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2623 inherit_access_acl(conn
, fname
, unixmode
);
2626 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2628 #endif /* HAVE_MAKEDEV_FN */
2633 * Deal with the UNIX specific mode set.
2636 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
2637 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
2638 (unsigned int)unixmode
, fname
));
2639 if (vfs_chmod(conn
,fname
,unixmode
) != 0)
2640 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2644 * Deal with the UNIX specific uid set.
2647 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) && (sbuf
.st_uid
!= set_owner
)) {
2648 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
2649 (unsigned int)set_owner
, fname
));
2650 if (vfs_chown(conn
,fname
,set_owner
, (gid_t
)-1) != 0)
2651 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2655 * Deal with the UNIX specific gid set.
2658 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) && (sbuf
.st_gid
!= set_grp
)) {
2659 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
2660 (unsigned int)set_owner
, fname
));
2661 if (vfs_chown(conn
,fname
,(uid_t
)-1, set_grp
) != 0)
2662 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2667 case SMB_SET_FILE_UNIX_LINK
:
2670 /* Set a symbolic link. */
2671 /* Don't allow this if follow links is false. */
2673 if (!lp_symlinks(SNUM(conn
)))
2674 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2676 /* Disallow if already exists. */
2677 if (VALID_STAT(sbuf
))
2678 return(ERROR_DOS(ERRDOS
,ERRbadpath
));
2680 srvstr_pull(inbuf
, link_dest
, pdata
, sizeof(link_dest
), -1, STR_TERMINATE
);
2682 if (ensure_link_is_safe(conn
, link_dest
, link_dest
) != 0)
2683 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2685 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
2686 fname
, link_dest
));
2688 if (conn
->vfs_ops
.symlink(conn
,link_dest
,fname
) != 0)
2689 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2691 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2695 case SMB_SET_FILE_UNIX_HLINK
:
2699 /* Set a hard link. */
2701 /* Disallow if already exists. */
2702 if (VALID_STAT(sbuf
))
2703 return(ERROR_DOS(ERRDOS
,ERRbadpath
));
2705 srvstr_pull(inbuf
, link_dest
, pdata
, sizeof(link_dest
), -1, STR_TERMINATE
);
2707 if (ensure_link_is_safe(conn
, link_dest
, link_dest
) != 0)
2708 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2710 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
2711 fname
, link_dest
));
2713 if (conn
->vfs_ops
.link(conn
,link_dest
,fname
) != 0)
2714 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2716 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2721 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2724 /* get some defaults (no modifications) if any info is zero or -1. */
2725 if (tvs
.actime
== (time_t)0 || tvs
.actime
== (time_t)-1)
2726 tvs
.actime
= sbuf
.st_atime
;
2728 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
2729 tvs
.modtime
= sbuf
.st_mtime
;
2731 DEBUG(6,("actime: %s " , ctime(&tvs
.actime
)));
2732 DEBUG(6,("modtime: %s ", ctime(&tvs
.modtime
)));
2733 DEBUG(6,("size: %.0f ", (double)size
));
2735 if (S_ISDIR(sbuf
.st_mode
))
2740 DEBUG(6,("dosmode: %x\n" , dosmode
));
2742 if(!((info_level
== SMB_SET_FILE_END_OF_FILE_INFO
) ||
2743 (info_level
== SMB_SET_FILE_ALLOCATION_INFO
) ||
2744 (info_level
== SMB_FILE_ALLOCATION_INFORMATION
) ||
2745 (info_level
== SMB_FILE_END_OF_FILE_INFORMATION
))) {
2748 * Only do this test if we are not explicitly
2749 * changing the size of a file.
2752 size
= get_file_size(sbuf
);
2756 * Try and set the times, size and mode of this file -
2757 * if they are different from the current values
2759 if (sbuf
.st_mtime
!= tvs
.modtime
|| sbuf
.st_atime
!= tvs
.actime
) {
2762 * This was a setfileinfo on an open file.
2763 * NT does this a lot. It's actually pointless
2764 * setting the time here, as it will be overwritten
2765 * on the next write, so we save the request
2766 * away and will set it on file close. JRA.
2769 if (tvs
.modtime
!= (time_t)0 && tvs
.modtime
!= (time_t)-1) {
2770 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs
.modtime
) ));
2771 fsp
->pending_modtime
= tvs
.modtime
;
2776 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2778 if(file_utime(conn
, fname
, &tvs
)!=0)
2779 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2783 /* check the mode isn't different, before changing it */
2784 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, fname
, &sbuf
))) {
2786 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname
, dosmode
));
2788 if(file_chmod(conn
, fname
, dosmode
, NULL
)) {
2789 DEBUG(2,("chmod of %s failed (%s)\n", fname
, strerror(errno
)));
2790 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2794 if (size
!= get_file_size(sbuf
)) {
2798 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2799 fname
, (double)size
));
2802 files_struct
*new_fsp
= NULL
;
2803 int access_mode
= 0;
2806 if(global_oplock_break
) {
2807 /* Queue this file modify as we are the process of an oplock break. */
2809 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2810 DEBUGADD(2,( "in oplock break state.\n"));
2812 push_oplock_pending_smb_message(inbuf
, length
);
2816 new_fsp
= open_file_shared(conn
, fname
, &sbuf
,
2817 SET_OPEN_MODE(DOS_OPEN_RDWR
),
2818 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
2819 0, 0, &access_mode
, &action
);
2821 if (new_fsp
== NULL
)
2822 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2823 ret
= vfs_set_filelen(new_fsp
, size
);
2824 close_file(new_fsp
,True
);
2826 ret
= vfs_set_filelen(fsp
, size
);
2830 return (UNIXERROR(ERRHRD
,ERRdiskfull
));
2834 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2839 /****************************************************************************
2840 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2841 ****************************************************************************/
2843 static int call_trans2mkdir(connection_struct
*conn
,
2844 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2845 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2847 char *params
= *pparams
;
2850 SMB_STRUCT_STAT sbuf
;
2851 BOOL bad_path
= False
;
2853 if (!CAN_WRITE(conn
))
2854 return ERROR_DOS(ERRSRV
,ERRaccess
);
2856 if (total_params
< 4)
2857 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2859 srvstr_pull(inbuf
, directory
, ¶ms
[4], sizeof(directory
), -1, STR_TERMINATE
);
2861 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
2863 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
2864 if (check_name(directory
,conn
))
2865 ret
= vfs_mkdir(conn
,directory
,unix_mode(conn
,aDIR
,directory
));
2868 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno
)));
2869 set_bad_path_error(errno
, bad_path
);
2870 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2873 /* Realloc the parameter and data sizes */
2874 params
= Realloc(*pparams
,2);
2876 return ERROR_DOS(ERRDOS
,ERRnomem
);
2881 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2886 /****************************************************************************
2887 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2888 We don't actually do this - we just send a null response.
2889 ****************************************************************************/
2891 static int call_trans2findnotifyfirst(connection_struct
*conn
,
2892 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2893 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2895 static uint16 fnf_handle
= 257;
2896 char *params
= *pparams
;
2899 if (total_params
< 6)
2900 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2902 info_level
= SVAL(params
,4);
2903 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
2905 switch (info_level
) {
2910 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2913 /* Realloc the parameter and data sizes */
2914 params
= Realloc(*pparams
,6);
2916 return ERROR_DOS(ERRDOS
,ERRnomem
);
2919 SSVAL(params
,0,fnf_handle
);
2920 SSVAL(params
,2,0); /* No changes */
2921 SSVAL(params
,4,0); /* No EA errors */
2928 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0);
2933 /****************************************************************************
2934 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2935 changes). Currently this does nothing.
2936 ****************************************************************************/
2938 static int call_trans2findnotifynext(connection_struct
*conn
,
2939 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2940 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2942 char *params
= *pparams
;
2944 DEBUG(3,("call_trans2findnotifynext\n"));
2946 /* Realloc the parameter and data sizes */
2947 params
= Realloc(*pparams
,4);
2949 return ERROR_DOS(ERRDOS
,ERRnomem
);
2952 SSVAL(params
,0,0); /* No changes */
2953 SSVAL(params
,2,0); /* No EA errors */
2955 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0);
2960 /****************************************************************************
2961 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2962 ****************************************************************************/
2964 static int call_trans2getdfsreferral(connection_struct
*conn
, char* inbuf
,
2965 char* outbuf
, int length
, int bufsize
,
2966 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2968 char *params
= *pparams
;
2971 int max_referral_level
;
2973 DEBUG(10,("call_trans2getdfsreferral\n"));
2975 if (total_params
< 2)
2976 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2978 max_referral_level
= SVAL(params
,0);
2980 if(!lp_host_msdfs())
2981 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
2983 srvstr_pull(inbuf
, pathname
, ¶ms
[2], sizeof(pathname
), -1, STR_TERMINATE
);
2985 if((reply_size
= setup_dfs_referral(pathname
,max_referral_level
,ppdata
)) < 0)
2986 return ERROR_DOS(ERRDOS
,ERRbadfile
);
2988 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_DFS_PATHNAMES
);
2989 send_trans2_replies(outbuf
,bufsize
,0,0,*ppdata
,reply_size
);
2994 #define LMCAT_SPL 0x53
2995 #define LMFUNC_GETJOBID 0x60
2997 /****************************************************************************
2998 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2999 ****************************************************************************/
3001 static int call_trans2ioctl(connection_struct
*conn
, char* inbuf
,
3002 char* outbuf
, int length
, int bufsize
,
3003 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3005 char *pdata
= *ppdata
;
3006 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv15
);
3008 if ((SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3009 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3010 pdata
= Realloc(*ppdata
, 32);
3012 return ERROR_DOS(ERRDOS
,ERRnomem
);
3015 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3016 CAN ACCEPT THIS IN UNICODE. JRA. */
3018 SSVAL(pdata
,0,fsp
->rap_print_jobid
); /* Job number */
3019 srvstr_push( outbuf
, pdata
+ 2, global_myname(), 15, STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
3020 srvstr_push( outbuf
, pdata
+18, lp_servicename(SNUM(conn
)), 13, STR_ASCII
|STR_TERMINATE
); /* Service name */
3021 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32);
3024 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3025 return ERROR_DOS(ERRSRV
,ERRerror
);
3029 /****************************************************************************
3030 Reply to a SMBfindclose (stop trans2 directory search).
3031 ****************************************************************************/
3033 int reply_findclose(connection_struct
*conn
,
3034 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3037 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
3038 START_PROFILE(SMBfindclose
);
3040 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
3042 dptr_close(&dptr_num
);
3044 outsize
= set_message(outbuf
,0,0,True
);
3046 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
3048 END_PROFILE(SMBfindclose
);
3052 /****************************************************************************
3053 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3054 ****************************************************************************/
3056 int reply_findnclose(connection_struct
*conn
,
3057 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3061 START_PROFILE(SMBfindnclose
);
3063 dptr_num
= SVAL(inbuf
,smb_vwv0
);
3065 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
3067 /* We never give out valid handles for a
3068 findnotifyfirst - so any dptr_num is ok here.
3071 outsize
= set_message(outbuf
,0,0,True
);
3073 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
3075 END_PROFILE(SMBfindnclose
);
3079 /****************************************************************************
3080 Reply to a SMBtranss2 - just ignore it!
3081 ****************************************************************************/
3083 int reply_transs2(connection_struct
*conn
,
3084 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3086 START_PROFILE(SMBtranss2
);
3087 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
3088 END_PROFILE(SMBtranss2
);
3092 /****************************************************************************
3093 Reply to a SMBtrans2.
3094 ****************************************************************************/
3096 int reply_trans2(connection_struct
*conn
,
3097 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3100 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
3101 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
3103 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
3104 unsigned int max_data_reply
= SVAL(inbuf
, smb_mdrcnt
);
3105 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
3106 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
3107 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
3108 int32 timeout
= IVALS(inbuf
,smb_timeout
);
3110 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
3111 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
3112 char *params
= NULL
, *data
= NULL
;
3113 unsigned int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
3114 START_PROFILE(SMBtrans2
);
3116 if(global_oplock_break
&& (tran_call
== TRANSACT2_OPEN
)) {
3117 /* Queue this open message as we are the process of an
3120 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3121 DEBUGADD(2,( "in oplock break state.\n"));
3123 push_oplock_pending_smb_message(inbuf
, length
);
3124 END_PROFILE(SMBtrans2
);
3128 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
3129 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
3130 END_PROFILE(SMBtrans2
);
3131 return ERROR_DOS(ERRSRV
,ERRaccess
);
3134 outsize
= set_message(outbuf
,0,0,True
);
3136 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3137 is so as a sanity check */
3140 * Need to have rc=0 for ioctl to get job id for OS/2.
3141 * Network printing will fail if function is not successful.
3142 * Similar function in reply.c will be used if protocol
3143 * is LANMAN1.0 instead of LM1.2X002.
3144 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3145 * outbuf doesn't have to be set(only job id is used).
3147 if ( (suwcnt
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
3148 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3149 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3150 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3152 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt
));
3153 DEBUG(2,("Transaction is %d\n",tran_call
));
3154 END_PROFILE(SMBtrans2
);
3155 ERROR_DOS(ERRDOS
,ERRinvalidparam
);
3159 /* Allocate the space for the maximum needed parameters and data */
3160 if (total_params
> 0)
3161 params
= (char *)malloc(total_params
);
3163 data
= (char *)malloc(total_data
);
3165 if ((total_params
&& !params
) || (total_data
&& !data
)) {
3166 DEBUG(2,("Out of memory in reply_trans2\n"));
3169 END_PROFILE(SMBtrans2
);
3170 return ERROR_DOS(ERRDOS
,ERRnomem
);
3173 /* Copy the param and data bytes sent with this request into
3174 the params buffer */
3175 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
3176 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
3178 if (num_params
> total_params
|| num_data
> total_data
)
3179 exit_server("invalid params in reply_trans2");
3182 unsigned int psoff
= SVAL(inbuf
, smb_psoff
);
3183 if ((psoff
+ num_params
< psoff
) || (psoff
+ num_params
< num_params
))
3185 if (smb_base(inbuf
) + psoff
+ num_params
> inbuf
+ length
)
3187 memcpy( params
, smb_base(inbuf
) + psoff
, num_params
);
3190 unsigned int dsoff
= SVAL(inbuf
, smb_dsoff
);
3191 if ((dsoff
+ num_data
< dsoff
) || (dsoff
+ num_data
< num_data
))
3193 if (smb_base(inbuf
) + dsoff
+ num_data
> inbuf
+ length
)
3195 memcpy( data
, smb_base(inbuf
) + dsoff
, num_data
);
3198 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
) {
3199 /* We need to send an interim response then receive the rest
3200 of the parameter/data bytes */
3201 outsize
= set_message(outbuf
,0,0,True
);
3202 if (!send_smb(smbd_server_fd(),outbuf
))
3203 exit_server("reply_trans2: send_smb failed.");
3205 while (num_data_sofar
< total_data
||
3206 num_params_sofar
< total_params
) {
3208 unsigned int param_disp
;
3209 unsigned int param_off
;
3210 unsigned int data_disp
;
3211 unsigned int data_off
;
3213 ret
= receive_next_smb(inbuf
,bufsize
,SMB_SECONDARY_WAIT
);
3216 (CVAL(inbuf
, smb_com
) != SMBtranss2
)) || !ret
) {
3217 outsize
= set_message(outbuf
,0,0,True
);
3219 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3221 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3222 (smb_read_error
== READ_ERROR
) ? "error" : "timeout" ));
3226 /* Revise total_params and total_data in case
3227 they have changed downwards */
3228 if (SVAL(inbuf
, smb_tpscnt
) < total_params
)
3229 total_params
= SVAL(inbuf
, smb_tpscnt
);
3230 if (SVAL(inbuf
, smb_tdscnt
) < total_data
)
3231 total_data
= SVAL(inbuf
, smb_tdscnt
);
3233 num_params
= SVAL(inbuf
,smb_spscnt
);
3234 param_off
= SVAL(inbuf
, smb_spsoff
);
3235 param_disp
= SVAL(inbuf
, smb_spsdisp
);
3236 num_params_sofar
+= num_params
;
3238 num_data
= SVAL(inbuf
, smb_sdscnt
);
3239 data_off
= SVAL(inbuf
, smb_sdsoff
);
3240 data_disp
= SVAL(inbuf
, smb_sdsdisp
);
3241 num_data_sofar
+= num_data
;
3243 if (num_params_sofar
> total_params
|| num_data_sofar
> total_data
)
3247 if (param_disp
+ num_params
>= total_params
)
3249 if ((param_disp
+ num_params
< param_disp
) ||
3250 (param_disp
+ num_params
< num_params
))
3252 if (smb_base(inbuf
) + param_off
+ num_params
>= inbuf
+ bufsize
)
3254 if (params
+ param_disp
< params
)
3257 memcpy( ¶ms
[param_disp
], smb_base(inbuf
) + param_off
, num_params
);
3260 if (data_disp
+ num_data
>= total_data
)
3262 if ((data_disp
+ num_data
< data_disp
) ||
3263 (data_disp
+ num_data
< num_data
))
3265 if (smb_base(inbuf
) + data_off
+ num_data
>= inbuf
+ bufsize
)
3267 if (data
+ data_disp
< data
)
3270 memcpy( &data
[data_disp
], smb_base(inbuf
) + data_off
, num_data
);
3275 if (Protocol
>= PROTOCOL_NT1
) {
3276 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | 0x40); /* IS_LONG_NAME */
3279 /* Now we must call the relevant TRANS2 function */
3281 case TRANSACT2_OPEN
:
3282 START_PROFILE_NESTED(Trans2_open
);
3283 outsize
= call_trans2open(conn
, inbuf
, outbuf
, bufsize
,
3284 ¶ms
, total_params
, &data
, total_data
);
3285 END_PROFILE_NESTED(Trans2_open
);
3288 case TRANSACT2_FINDFIRST
:
3289 START_PROFILE_NESTED(Trans2_findfirst
);
3290 outsize
= call_trans2findfirst(conn
, inbuf
, outbuf
, bufsize
,
3291 ¶ms
, total_params
, &data
, total_data
);
3292 END_PROFILE_NESTED(Trans2_findfirst
);
3295 case TRANSACT2_FINDNEXT
:
3296 START_PROFILE_NESTED(Trans2_findnext
);
3297 outsize
= call_trans2findnext(conn
, inbuf
, outbuf
, length
, bufsize
,
3298 ¶ms
, total_params
, &data
, total_data
);
3299 END_PROFILE_NESTED(Trans2_findnext
);
3302 case TRANSACT2_QFSINFO
:
3303 START_PROFILE_NESTED(Trans2_qfsinfo
);
3304 outsize
= call_trans2qfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3305 ¶ms
, total_params
, &data
, total_data
);
3306 END_PROFILE_NESTED(Trans2_qfsinfo
);
3309 case TRANSACT2_SETFSINFO
:
3310 START_PROFILE_NESTED(Trans2_setfsinfo
);
3311 outsize
= call_trans2setfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3312 ¶ms
, total_params
, &data
, total_data
);
3313 END_PROFILE_NESTED(Trans2_setfsinfo
);
3316 case TRANSACT2_QPATHINFO
:
3317 case TRANSACT2_QFILEINFO
:
3318 START_PROFILE_NESTED(Trans2_qpathinfo
);
3319 outsize
= call_trans2qfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3320 ¶ms
, total_params
, &data
, total_data
);
3321 END_PROFILE_NESTED(Trans2_qpathinfo
);
3323 case TRANSACT2_SETPATHINFO
:
3324 case TRANSACT2_SETFILEINFO
:
3325 START_PROFILE_NESTED(Trans2_setpathinfo
);
3326 outsize
= call_trans2setfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3327 ¶ms
, total_params
, &data
, total_data
);
3328 END_PROFILE_NESTED(Trans2_setpathinfo
);
3331 case TRANSACT2_FINDNOTIFYFIRST
:
3332 START_PROFILE_NESTED(Trans2_findnotifyfirst
);
3333 outsize
= call_trans2findnotifyfirst(conn
, inbuf
, outbuf
, length
, bufsize
,
3334 ¶ms
, total_params
, &data
, total_data
);
3335 END_PROFILE_NESTED(Trans2_findnotifyfirst
);
3338 case TRANSACT2_FINDNOTIFYNEXT
:
3339 START_PROFILE_NESTED(Trans2_findnotifynext
);
3340 outsize
= call_trans2findnotifynext(conn
, inbuf
, outbuf
, length
, bufsize
,
3341 ¶ms
, total_params
, &data
, total_data
);
3342 END_PROFILE_NESTED(Trans2_findnotifynext
);
3344 case TRANSACT2_MKDIR
:
3345 START_PROFILE_NESTED(Trans2_mkdir
);
3346 outsize
= call_trans2mkdir(conn
, inbuf
, outbuf
, length
, bufsize
,
3347 ¶ms
, total_params
, &data
, total_data
);
3348 END_PROFILE_NESTED(Trans2_mkdir
);
3351 case TRANSACT2_GET_DFS_REFERRAL
:
3352 START_PROFILE_NESTED(Trans2_get_dfs_referral
);
3353 outsize
= call_trans2getdfsreferral(conn
,inbuf
,outbuf
,length
, bufsize
,
3354 ¶ms
, total_params
, &data
, total_data
);
3355 END_PROFILE_NESTED(Trans2_get_dfs_referral
);
3357 case TRANSACT2_IOCTL
:
3358 START_PROFILE_NESTED(Trans2_ioctl
);
3359 outsize
= call_trans2ioctl(conn
,inbuf
,outbuf
,length
, bufsize
,
3360 ¶ms
, total_params
, &data
, total_data
);
3361 END_PROFILE_NESTED(Trans2_ioctl
);
3364 /* Error in request */
3365 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call
));
3368 END_PROFILE(SMBtrans2
);
3369 return ERROR_DOS(ERRSRV
,ERRerror
);
3372 /* As we do not know how many data packets will need to be
3373 returned here the various call_trans2xxxx calls
3374 must send their own. Thus a call_trans2xxx routine only
3375 returns a value other than -1 when it wants to send
3381 END_PROFILE(SMBtrans2
);
3382 return outsize
; /* If a correct response was needed the
3383 call_trans2xxx calls have already sent
3384 it. If outsize != -1 then it is returning */
3390 END_PROFILE(SMBtrans2
);
3391 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);