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
;
31 extern pstring global_myname
;
33 #define get_file_size(sbuf) (sbuf.st_size)
35 /* given a stat buffer return the allocated size on disk, taking into
36 account sparse files */
37 SMB_OFF_T
get_allocation_size(files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
40 #if defined(HAVE_STAT_ST_BLKSIZE) && defined(HAVE_STAT_ST_BLOCKS)
41 ret
= sbuf
->st_blksize
* (SMB_OFF_T
)sbuf
->st_blocks
;
42 #elif defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
43 ret
= (SMB_OFF_T
)STAT_ST_BLOCKSIZE
* (SMB_OFF_T
)sbuf
->st_blocks
;
45 ret
= get_file_size(*sbuf
);
47 if (!ret
&& fsp
&& fsp
->initial_allocation_size
)
48 ret
= fsp
->initial_allocation_size
;
49 ret
= SMB_ROUNDUP(ret
,SMB_ROUNDUP_ALLOCATION_SIZE
);
53 /****************************************************************************
54 Send the required number of replies back.
55 We assume all fields other than the data fields are
56 set correctly for the type of call.
57 HACK ! Always assumes smb_setup field is zero.
58 ****************************************************************************/
60 static int send_trans2_replies(char *outbuf
,
67 /* As we are using a protocol > LANMAN1 then the max_send
68 variable must have been set in the sessetupX call.
69 This takes precedence over the max_xmit field in the
70 global struct. These different max_xmit variables should
71 be merged as this is now too confusing */
74 int data_to_send
= datasize
;
75 int params_to_send
= paramsize
;
79 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
80 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
81 int data_alignment_offset
= 0;
83 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
85 set_message(outbuf
,10,0,True
);
87 /* If there genuinely are no parameters or data to send just send the empty packet */
89 if(params_to_send
== 0 && data_to_send
== 0) {
90 if (!send_smb(smbd_server_fd(),outbuf
))
91 exit_server("send_trans2_replies: send_smb failed.");
95 /* When sending params and data ensure that both are nicely aligned */
96 /* Only do this alignment when there is also data to send - else
97 can cause NT redirector problems. */
99 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
100 data_alignment_offset
= 4 - (params_to_send
% 4);
102 /* Space is bufsize minus Netbios over TCP header minus SMB header */
103 /* The alignment_offset is to align the param bytes on an even byte
104 boundary. NT 4.0 Beta needs this to work correctly. */
106 useable_space
= bufsize
- ((smb_buf(outbuf
)+ alignment_offset
+data_alignment_offset
) - outbuf
);
108 /* useable_space can never be more than max_send minus the alignment offset. */
110 useable_space
= MIN(useable_space
, max_send
- (alignment_offset
+data_alignment_offset
));
112 while (params_to_send
|| data_to_send
) {
113 /* Calculate whether we will totally or partially fill this packet */
115 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
+ data_alignment_offset
;
117 /* We can never send more than useable_space */
119 * Note that 'useable_space' does not include the alignment offsets,
120 * but we must include the alignment offsets in the calculation of
121 * the length of the data we send over the wire, as the alignment offsets
122 * are sent here. Fix from Marc_Jacobsen@hp.com.
125 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
+ alignment_offset
+ data_alignment_offset
);
127 set_message(outbuf
, 10, total_sent_thistime
, True
);
129 /* Set total params and data to be sent */
130 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
131 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
133 /* Calculate how many parameters and data we can fit into
134 * this packet. Parameters get precedence
137 params_sent_thistime
= MIN(params_to_send
,useable_space
);
138 data_sent_thistime
= useable_space
- params_sent_thistime
;
139 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
141 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
143 /* smb_proff is the offset from the start of the SMB header to the
144 parameter bytes, however the first 4 bytes of outbuf are
145 the Netbios over TCP header. Thus use smb_base() to subtract
146 them from the calculation */
148 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
150 if(params_sent_thistime
== 0)
151 SSVAL(outbuf
,smb_prdisp
,0);
153 /* Absolute displacement of param bytes sent in this packet */
154 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
156 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
157 if(data_sent_thistime
== 0) {
158 SSVAL(outbuf
,smb_droff
,0);
159 SSVAL(outbuf
,smb_drdisp
, 0);
161 /* The offset of the data bytes is the offset of the
162 parameter bytes plus the number of parameters being sent this time */
163 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
164 smb_base(outbuf
)) + params_sent_thistime
+ data_alignment_offset
);
165 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
168 /* Copy the param bytes into the packet */
170 if(params_sent_thistime
)
171 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
173 /* Copy in the data bytes */
174 if(data_sent_thistime
)
175 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
+
176 data_alignment_offset
,pd
,data_sent_thistime
);
178 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
179 params_sent_thistime
, data_sent_thistime
, useable_space
));
180 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
181 params_to_send
, data_to_send
, paramsize
, datasize
));
183 /* Send the packet */
184 if (!send_smb(smbd_server_fd(),outbuf
))
185 exit_server("send_trans2_replies: send_smb failed.");
187 pp
+= params_sent_thistime
;
188 pd
+= data_sent_thistime
;
190 params_to_send
-= params_sent_thistime
;
191 data_to_send
-= data_sent_thistime
;
194 if(params_to_send
< 0 || data_to_send
< 0) {
195 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
196 params_to_send
, data_to_send
));
204 /****************************************************************************
205 Reply to a TRANSACT2_OPEN.
206 ****************************************************************************/
208 static int call_trans2open(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
209 char **pparams
, int total_params
, char **ppdata
, int total_data
)
211 char *params
= *pparams
;
216 BOOL return_additional_info
;
226 int fmode
=0,mtime
=0,rmode
;
228 SMB_STRUCT_STAT sbuf
;
230 BOOL bad_path
= False
;
234 * Ensure we have enough parameters to perform the operation.
237 if (total_params
< 29)
238 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
240 open_mode
= SVAL(params
, 2);
241 open_attr
= SVAL(params
,6);
242 oplock_request
= (((SVAL(params
,0)|(1<<1))>>1) | ((SVAL(params
,0)|(1<<2))>>1));
244 return_additional_info
= BITSETW(params
,0);
245 open_sattr
= SVAL(params
, 4);
246 open_time
= make_unix_date3(params
+8);
248 open_ofun
= SVAL(params
,12);
249 open_size
= IVAL(params
,14);
252 srvstr_pull(inbuf
, fname
, pname
, sizeof(fname
), -1, STR_TERMINATE
);
254 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
255 fname
,open_mode
, open_attr
, open_ofun
, open_size
));
258 return(ERROR_DOS(ERRSRV
,ERRaccess
));
260 /* XXXX we need to handle passed times, sattr and flags */
262 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
264 if (!check_name(fname
,conn
)) {
265 set_bad_path_error(errno
, bad_path
);
266 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
269 unixmode
= unix_mode(conn
,open_attr
| aARCH
, fname
);
271 fsp
= open_file_shared(conn
,fname
,&sbuf
,open_mode
,open_ofun
,unixmode
,
272 oplock_request
, &rmode
,&smb_action
);
275 set_bad_path_error(errno
, bad_path
);
276 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
279 size
= get_file_size(sbuf
);
280 fmode
= dos_mode(conn
,fname
,&sbuf
);
281 mtime
= sbuf
.st_mtime
;
284 close_file(fsp
,False
);
285 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
288 /* Realloc the size of parameters and data we will return */
289 params
= Realloc(*pparams
, 28);
291 return(ERROR_DOS(ERRDOS
,ERRnomem
));
294 memset((char *)params
,'\0',28);
295 SSVAL(params
,0,fsp
->fnum
);
296 SSVAL(params
,2,fmode
);
297 put_dos_date2(params
,4, mtime
);
298 SIVAL(params
,8, (uint32
)size
);
299 SSVAL(params
,12,rmode
);
301 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
302 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
304 SSVAL(params
,18,smb_action
);
307 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
309 SIVAL(params
,20,inode
);
311 /* Send the required number of replies */
312 send_trans2_replies(outbuf
, bufsize
, params
, 28, *ppdata
, 0);
317 /*********************************************************
318 Routine to check if a given string matches exactly.
319 as a special case a mask of "." does NOT match. That
320 is required for correct wildcard semantics
321 Case can be significant or not.
322 **********************************************************/
324 static BOOL
exact_match(char *str
,char *mask
, BOOL case_sig
)
326 if (mask
[0] == '.' && mask
[1] == 0)
329 return strcmp(str
,mask
)==0;
330 return strcasecmp(str
,mask
) == 0;
333 /****************************************************************************
334 Return the filetype for UNIX extensions.
335 ****************************************************************************/
337 static uint32
unix_filetype(mode_t mode
)
340 return UNIX_TYPE_FILE
;
341 else if(S_ISDIR(mode
))
342 return UNIX_TYPE_DIR
;
344 else if(S_ISLNK(mode
))
345 return UNIX_TYPE_SYMLINK
;
348 else if(S_ISCHR(mode
))
349 return UNIX_TYPE_CHARDEV
;
352 else if(S_ISBLK(mode
))
353 return UNIX_TYPE_BLKDEV
;
356 else if(S_ISFIFO(mode
))
357 return UNIX_TYPE_FIFO
;
360 else if(S_ISSOCK(mode
))
361 return UNIX_TYPE_SOCKET
;
364 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode
));
365 return UNIX_TYPE_UNKNOWN
;
368 /****************************************************************************
369 Return the major devicenumber for UNIX extensions.
370 ****************************************************************************/
372 static uint32
unix_dev_major(SMB_DEV_T dev
)
374 #if defined(HAVE_DEVICE_MAJOR_FN)
375 return (uint32
)major(dev
);
377 return (uint32
)(dev
>> 8);
381 /****************************************************************************
382 Return the minor devicenumber for UNIX extensions.
383 ****************************************************************************/
385 static uint32
unix_dev_minor(SMB_DEV_T dev
)
387 #if defined(HAVE_DEVICE_MINOR_FN)
388 return (uint32
)minor(dev
);
390 return (uint32
)(dev
& 0xff);
394 /****************************************************************************
395 Map wire perms onto standard UNIX permissions. Obey share restrictions.
396 ****************************************************************************/
398 static mode_t
unix_perms_from_wire( connection_struct
*conn
, SMB_STRUCT_STAT
*pst
, uint32 perms
)
402 if (perms
== SMB_MODE_NO_CHANGE
)
405 ret
|= ((perms
& UNIX_X_OTH
) ? S_IXOTH
: 0);
406 ret
|= ((perms
& UNIX_W_OTH
) ? S_IWOTH
: 0);
407 ret
|= ((perms
& UNIX_R_OTH
) ? S_IROTH
: 0);
408 ret
|= ((perms
& UNIX_X_GRP
) ? S_IXGRP
: 0);
409 ret
|= ((perms
& UNIX_W_GRP
) ? S_IWGRP
: 0);
410 ret
|= ((perms
& UNIX_R_GRP
) ? S_IRGRP
: 0);
411 ret
|= ((perms
& UNIX_X_USR
) ? S_IXUSR
: 0);
412 ret
|= ((perms
& UNIX_W_USR
) ? S_IWUSR
: 0);
413 ret
|= ((perms
& UNIX_R_USR
) ? S_IRUSR
: 0);
415 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
418 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
421 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
424 if (VALID_STAT(*pst
) && S_ISDIR(pst
->st_mode
)) {
425 ret
&= lp_dir_mask(SNUM(conn
));
426 /* Add in force bits */
427 ret
|= lp_force_dir_mode(SNUM(conn
));
429 /* Apply mode mask */
430 ret
&= lp_create_mask(SNUM(conn
));
431 /* Add in force bits */
432 ret
|= lp_force_create_mode(SNUM(conn
));
438 /****************************************************************************
439 checks for SMB_TIME_NO_CHANGE and if not found
440 calls interpret_long_date
441 ****************************************************************************/
442 time_t interpret_long_unix_date(char *p
)
444 DEBUG(1,("interpret_long_unix_date\n"));
445 if(IVAL(p
,0) == SMB_TIME_NO_CHANGE_LO
&&
446 IVAL(p
,4) == SMB_TIME_NO_CHANGE_HI
) {
449 return interpret_long_date(p
);
453 /****************************************************************************
454 Get a level dependent lanman2 dir entry.
455 ****************************************************************************/
457 static BOOL
get_lanman2_dir_entry(connection_struct
*conn
,
458 void *inbuf
, void *outbuf
,
459 char *path_mask
,int dirtype
,int info_level
,
460 int requires_resume_key
,
461 BOOL dont_descend
,char **ppdata
,
462 char *base_data
, int space_remaining
,
463 BOOL
*out_of_space
, BOOL
*got_exact_match
,
468 SMB_STRUCT_STAT sbuf
;
472 char *p
, *q
, *pdata
= *ppdata
;
476 SMB_OFF_T file_size
= 0;
477 SMB_OFF_T allocation_size
= 0;
479 time_t mdate
=0, adate
=0, cdate
=0;
482 int nt_extmode
; /* Used for NT connections instead of mode */
483 BOOL needslash
= ( conn
->dirpath
[strlen(conn
->dirpath
) -1] != '/');
486 *out_of_space
= False
;
487 *got_exact_match
= False
;
492 p
= strrchr_m(path_mask
,'/');
499 pstrcpy(mask
, path_mask
);
504 /* Needed if we run out of space */
505 prev_dirpos
= TellDir(conn
->dirptr
);
506 dname
= ReadDirName(conn
->dirptr
);
509 * Due to bugs in NT client redirectors we are not using
510 * resume keys any more - set them to zero.
511 * Check out the related comments in findfirst/findnext.
517 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
518 (long)conn
->dirptr
,TellDir(conn
->dirptr
)));
523 pstrcpy(fname
,dname
);
525 if(!(got_match
= *got_exact_match
= exact_match(fname
, mask
, case_sensitive
)))
526 got_match
= mask_match(fname
, mask
, case_sensitive
);
528 if(!got_match
&& !mangle_is_8_3(fname
, False
)) {
531 * It turns out that NT matches wildcards against
532 * both long *and* short names. This may explain some
533 * of the wildcard wierdness from old DOS clients
534 * that some people have been seeing.... JRA.
538 pstrcpy( newname
, fname
);
539 mangle_map( newname
, True
, False
, SNUM(conn
));
540 if(!(got_match
= *got_exact_match
= exact_match(newname
, mask
, case_sensitive
)))
541 got_match
= mask_match(newname
, mask
, case_sensitive
);
545 BOOL isdots
= (strequal(fname
,"..") || strequal(fname
,"."));
546 if (dont_descend
&& !isdots
)
549 pstrcpy(pathreal
,conn
->dirpath
);
551 pstrcat(pathreal
,"/");
552 pstrcat(pathreal
,dname
);
554 if (INFO_LEVEL_IS_UNIX(info_level
)) {
555 if (vfs_lstat(conn
,pathreal
,&sbuf
) != 0) {
556 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
557 pathreal
,strerror(errno
)));
560 } else if (vfs_stat(conn
,pathreal
,&sbuf
) != 0) {
562 /* Needed to show the msdfs symlinks as
565 if(lp_host_msdfs() &&
566 lp_msdfs_root(SNUM(conn
)) &&
567 is_msdfs_link(conn
, pathreal
, NULL
, NULL
,
570 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal
));
571 sbuf
.st_mode
= (sbuf
.st_mode
& 0xFFF) | S_IFDIR
;
575 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
576 pathreal
,strerror(errno
)));
581 mode
= dos_mode(conn
,pathreal
,&sbuf
);
583 if (!dir_check_ftype(conn
,mode
,&sbuf
,dirtype
)) {
584 DEBUG(5,("[%s] attribs didn't match %x\n",fname
,dirtype
));
588 file_size
= get_file_size(sbuf
);
589 allocation_size
= get_allocation_size(NULL
,&sbuf
);
590 mdate
= sbuf
.st_mtime
;
591 adate
= sbuf
.st_atime
;
592 cdate
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
594 if (lp_dos_filetime_resolution(SNUM(conn
))) {
603 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal
,fname
));
609 mangle_map(fname
,False
,True
,SNUM(conn
));
614 nt_extmode
= mode
? mode
: FILE_ATTRIBUTE_NORMAL
;
616 switch (info_level
) {
617 case SMB_INFO_STANDARD
:
618 if(requires_resume_key
) {
622 put_dos_date2(p
,l1_fdateCreation
,cdate
);
623 put_dos_date2(p
,l1_fdateLastAccess
,adate
);
624 put_dos_date2(p
,l1_fdateLastWrite
,mdate
);
625 SIVAL(p
,l1_cbFile
,(uint32
)file_size
);
626 SIVAL(p
,l1_cbFileAlloc
,(uint32
)allocation_size
);
627 SSVAL(p
,l1_attrFile
,mode
);
630 p
+= align_string(outbuf
, p
, 0);
631 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
632 SCVAL(nameptr
, -1, len
);
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 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_NOALIGN
);
653 *p
++ = 0; /* craig from unisys pointed out we need this */
656 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
657 was_8_3
= mangle_is_8_3(fname
, True
);
659 SIVAL(p
,0,reskey
); p
+= 4;
660 put_long_date(p
,cdate
); p
+= 8;
661 put_long_date(p
,adate
); p
+= 8;
662 put_long_date(p
,mdate
); p
+= 8;
663 put_long_date(p
,mdate
); p
+= 8;
664 SOFF_T(p
,0,file_size
);
665 SOFF_T(p
,8,allocation_size
);
667 SIVAL(p
,0,nt_extmode
); p
+= 4;
669 SIVAL(p
,0,0); p
+= 4;
670 /* Clear the short name buffer. This is
671 * IMPORTANT as not doing so will trigger
672 * a Win2k client bug. JRA.
676 pstring mangled_name
;
677 pstrcpy(mangled_name
, fname
);
678 mangle_map(mangled_name
,True
,True
,SNUM(conn
));
679 mangled_name
[12] = 0;
680 len
= srvstr_push(outbuf
, p
+2, mangled_name
, 24, STR_UPPER
);
687 len
= srvstr_push(outbuf
, p
, fname
, -1, 0);
690 len
= PTR_DIFF(p
, pdata
);
691 len
= (len
+ 3) & ~3;
696 case SMB_FIND_FILE_DIRECTORY_INFO
:
698 SIVAL(p
,0,reskey
); p
+= 4;
699 put_long_date(p
,cdate
); p
+= 8;
700 put_long_date(p
,adate
); p
+= 8;
701 put_long_date(p
,mdate
); p
+= 8;
702 put_long_date(p
,mdate
); p
+= 8;
703 SOFF_T(p
,0,file_size
);
704 SOFF_T(p
,8,allocation_size
);
706 SIVAL(p
,0,nt_extmode
); p
+= 4;
708 len
= srvstr_push(outbuf
, p
, fname
, -1, 0);
711 len
= PTR_DIFF(p
, pdata
);
712 len
= (len
+ 3) & ~3;
717 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
719 SIVAL(p
,0,reskey
); p
+= 4;
720 put_long_date(p
,cdate
); p
+= 8;
721 put_long_date(p
,adate
); p
+= 8;
722 put_long_date(p
,mdate
); p
+= 8;
723 put_long_date(p
,mdate
); p
+= 8;
724 SOFF_T(p
,0,file_size
);
725 SOFF_T(p
,8,allocation_size
);
727 SIVAL(p
,0,nt_extmode
); p
+= 4;
729 SIVAL(p
,0,0); p
+= 4;
731 len
= srvstr_push(outbuf
, p
, fname
, -1, 0);
735 len
= PTR_DIFF(p
, pdata
);
736 len
= (len
+ 3) & ~3;
741 case SMB_FIND_FILE_NAMES_INFO
:
743 SIVAL(p
,0,reskey
); p
+= 4;
745 /* this must *not* be null terminated or w2k gets in a loop trying to set an
746 acl on a dir (tridge) */
747 len
= srvstr_push(outbuf
, p
, fname
, -1, 0);
750 len
= PTR_DIFF(p
, pdata
);
751 len
= (len
+ 3) & ~3;
756 /* CIFS UNIX Extension. */
758 case SMB_FIND_FILE_UNIX
:
760 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
762 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
763 SOFF_T(p
,0,get_file_size(sbuf
)); /* File size 64 Bit */
766 SOFF_T(p
,0,get_allocation_size(NULL
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
769 put_long_date(p
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
770 put_long_date(p
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
771 put_long_date(p
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
774 SIVAL(p
,0,sbuf
.st_uid
); /* user id for the owner */
778 SIVAL(p
,0,sbuf
.st_gid
); /* group id of owner */
782 SIVAL(p
,0,unix_filetype(sbuf
.st_mode
));
785 SIVAL(p
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
789 SIVAL(p
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
793 SINO_T(p
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
796 SIVAL(p
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
800 SIVAL(p
,0,sbuf
.st_nlink
); /* number of hard links */
804 len
= srvstr_push(outbuf
, p
, fname
, -1, STR_TERMINATE
);
807 len
= PTR_DIFF(p
, pdata
);
808 len
= (len
+ 3) & ~3;
809 SIVAL(pdata
,0,len
); /* Offset from this structure to the beginning of the next one */
811 /* End of SMB_QUERY_FILE_UNIX_BASIC */
820 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
821 /* Move the dirptr back to prev_dirpos */
822 SeekDir(conn
->dirptr
, prev_dirpos
);
823 *out_of_space
= True
;
824 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
825 return False
; /* Not finished - just out of space */
828 /* Setup the last_filename pointer, as an offset from base_data */
829 *last_name_off
= PTR_DIFF(nameptr
,base_data
);
830 /* Advance the data pointer to the next slot */
836 /****************************************************************************
837 Reply to a TRANS2_FINDFIRST.
838 ****************************************************************************/
840 static int call_trans2findfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
841 char **pparams
, int total_params
, char **ppdata
, int total_data
)
843 /* We must be careful here that we don't return more than the
844 allowed number of data bytes. If this means returning fewer than
845 maxentries then so be it. We assume that the redirector has
846 enough room for the fixed number of parameter bytes it has
848 uint32 max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
849 char *params
= *pparams
;
850 char *pdata
= *ppdata
;
851 int dirtype
= SVAL(params
,0);
852 int maxentries
= SVAL(params
,2);
853 BOOL close_after_first
= BITSETW(params
+4,0);
854 BOOL close_if_end
= BITSETW(params
+4,1);
855 BOOL requires_resume_key
= BITSETW(params
+4,2);
856 int info_level
= SVAL(params
,6);
864 BOOL finished
= False
;
865 BOOL dont_descend
= False
;
866 BOOL out_of_space
= False
;
868 BOOL bad_path
= False
;
869 SMB_STRUCT_STAT sbuf
;
871 if (total_params
< 12)
872 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
874 *directory
= *mask
= 0;
876 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
877 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
878 dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
879 info_level
, max_data_bytes
));
881 switch (info_level
) {
882 case SMB_INFO_STANDARD
:
883 case SMB_INFO_QUERY_EA_SIZE
:
884 case SMB_FIND_FILE_DIRECTORY_INFO
:
885 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
886 case SMB_FIND_FILE_NAMES_INFO
:
887 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
889 case SMB_FIND_FILE_UNIX
:
890 if (!lp_unix_extensions())
891 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
894 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
897 srvstr_pull(inbuf
, directory
, params
+12, sizeof(directory
), -1, STR_TERMINATE
);
899 RESOLVE_FINDFIRST_DFSPATH(directory
, conn
, inbuf
, outbuf
);
901 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
902 if(!check_name(directory
,conn
)) {
903 set_bad_path_error(errno
, bad_path
);
904 return(UNIXERROR(ERRDOS
,ERRbadpath
));
907 p
= strrchr_m(directory
,'/');
909 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
910 if((directory
[0] == '.') && (directory
[1] == '\0'))
913 pstrcpy(mask
,directory
);
914 pstrcpy(directory
,"./");
920 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
922 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
924 return(ERROR_DOS(ERRDOS
,ERRnomem
));
927 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
929 /* Realloc the params space */
930 params
= Realloc(*pparams
, 10);
932 return ERROR_DOS(ERRDOS
,ERRnomem
);
935 dptr_num
= dptr_create(conn
,directory
, False
, True
,SVAL(inbuf
,smb_pid
));
937 return(UNIXERROR(ERRDOS
,ERRbadfile
));
939 /* Save the wildcard match and attribs we are using on this directory -
940 needed as lanman2 assumes these are being saved between calls */
942 if(!(wcard
= strdup(mask
))) {
943 dptr_close(&dptr_num
);
944 return ERROR_DOS(ERRDOS
,ERRnomem
);
947 dptr_set_wcard(dptr_num
, wcard
);
948 dptr_set_attr(dptr_num
, dirtype
);
950 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num
, wcard
, dirtype
));
952 /* We don't need to check for VOL here as this is returned by
953 a different TRANS2 call. */
955 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
956 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
960 space_remaining
= max_data_bytes
;
961 out_of_space
= False
;
963 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
964 BOOL got_exact_match
= False
;
966 /* this is a heuristic to avoid seeking the dirptr except when
967 absolutely necessary. It allows for a filename of about 40 chars */
968 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
972 finished
= !get_lanman2_dir_entry(conn
,
974 mask
,dirtype
,info_level
,
975 requires_resume_key
,dont_descend
,
976 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
980 if (finished
&& out_of_space
)
983 if (!finished
&& !out_of_space
)
987 * As an optimisation if we know we aren't looking
988 * for a wildcard name (ie. the name matches the wildcard exactly)
989 * then we can finish on any (first) match.
990 * This speeds up large directory searches. JRA.
996 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
999 /* Check if we can close the dirptr */
1000 if(close_after_first
|| (finished
&& close_if_end
)) {
1001 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
1002 dptr_close(&dptr_num
);
1006 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1007 * from observation of NT.
1010 if(numentries
== 0) {
1011 dptr_close(&dptr_num
);
1012 return ERROR_DOS(ERRDOS
,ERRbadfile
);
1015 /* At this point pdata points to numentries directory entries. */
1017 /* Set up the return parameter block */
1018 SSVAL(params
,0,dptr_num
);
1019 SSVAL(params
,2,numentries
);
1020 SSVAL(params
,4,finished
);
1021 SSVAL(params
,6,0); /* Never an EA error */
1022 SSVAL(params
,8,last_name_off
);
1024 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
));
1026 if ((! *directory
) && dptr_path(dptr_num
))
1027 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1029 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1030 smb_fn_name(CVAL(inbuf
,smb_com
)),
1031 mask
, directory
, dirtype
, numentries
) );
1034 * Force a name mangle here to ensure that the
1035 * mask as an 8.3 name is top of the mangled cache.
1036 * The reasons for this are subtle. Don't remove
1037 * this code unless you know what you are doing
1038 * (see PR#13758). JRA.
1041 if(!mangle_is_8_3_wildcards( mask
, False
))
1042 mangle_map(mask
, True
, True
, SNUM(conn
));
1047 /****************************************************************************
1048 Reply to a TRANS2_FINDNEXT.
1049 ****************************************************************************/
1051 static int call_trans2findnext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1052 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1054 /* We must be careful here that we don't return more than the
1055 allowed number of data bytes. If this means returning fewer than
1056 maxentries then so be it. We assume that the redirector has
1057 enough room for the fixed number of parameter bytes it has
1059 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1060 char *params
= *pparams
;
1061 char *pdata
= *ppdata
;
1062 int dptr_num
= SVAL(params
,0);
1063 int maxentries
= SVAL(params
,2);
1064 uint16 info_level
= SVAL(params
,4);
1065 uint32 resume_key
= IVAL(params
,6);
1066 BOOL close_after_request
= BITSETW(params
+10,0);
1067 BOOL close_if_end
= BITSETW(params
+10,1);
1068 BOOL requires_resume_key
= BITSETW(params
+10,2);
1069 BOOL continue_bit
= BITSETW(params
+10,3);
1070 pstring resume_name
;
1076 int i
, last_name_off
=0;
1077 BOOL finished
= False
;
1078 BOOL dont_descend
= False
;
1079 BOOL out_of_space
= False
;
1080 int space_remaining
;
1082 if (total_params
< 12)
1083 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1085 *mask
= *directory
= *resume_name
= 0;
1087 srvstr_pull(inbuf
, resume_name
, params
+12, sizeof(resume_name
), -1, STR_TERMINATE
);
1089 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1090 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1091 resume_key = %d resume name = %s continue=%d level = %d\n",
1092 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
1093 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
1095 switch (info_level
) {
1096 case SMB_INFO_STANDARD
:
1097 case SMB_INFO_QUERY_EA_SIZE
:
1098 case SMB_FIND_FILE_DIRECTORY_INFO
:
1099 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1100 case SMB_FIND_FILE_NAMES_INFO
:
1101 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1103 case SMB_FIND_FILE_UNIX
:
1104 if (!lp_unix_extensions())
1105 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1108 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1111 pdata
= Realloc( *ppdata
, max_data_bytes
+ 1024);
1113 return ERROR_DOS(ERRDOS
,ERRnomem
);
1116 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1118 /* Realloc the params space */
1119 params
= Realloc(*pparams
, 6*SIZEOFWORD
);
1120 if( params
== NULL
)
1121 return ERROR_DOS(ERRDOS
,ERRnomem
);
1125 /* Check that the dptr is valid */
1126 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
)))
1127 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1129 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1131 /* Get the wildcard mask from the dptr */
1132 if((p
= dptr_wcard(dptr_num
))== NULL
) {
1133 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
1134 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1138 pstrcpy(directory
,conn
->dirpath
);
1140 /* Get the attr mask from the dptr */
1141 dirtype
= dptr_attr(dptr_num
);
1143 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1144 dptr_num
, mask
, dirtype
,
1146 TellDir(conn
->dirptr
)));
1148 /* We don't need to check for VOL here as this is returned by
1149 a different TRANS2 call. */
1151 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1152 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
1153 dont_descend
= True
;
1156 space_remaining
= max_data_bytes
;
1157 out_of_space
= False
;
1160 * Seek to the correct position. We no longer use the resume key but
1161 * depend on the last file name instead.
1164 if(requires_resume_key
&& *resume_name
&& !continue_bit
) {
1167 * Fix for NT redirector problem triggered by resume key indexes
1168 * changing between directory scans. We now return a resume key of 0
1169 * and instead look for the filename to continue from (also given
1170 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1171 * findfirst/findnext (as is usual) then the directory pointer
1172 * should already be at the correct place. Check this by scanning
1173 * backwards looking for an exact (ie. case sensitive) filename match.
1174 * If we get to the beginning of the directory and haven't found it then scan
1175 * forwards again looking for a match. JRA.
1178 int current_pos
, start_pos
;
1180 void *dirptr
= conn
->dirptr
;
1181 start_pos
= TellDir(dirptr
);
1182 for(current_pos
= start_pos
; current_pos
>= 0; current_pos
--) {
1183 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos
));
1185 SeekDir(dirptr
, current_pos
);
1186 dname
= ReadDirName(dirptr
);
1189 * Remember, mangle_map is called by
1190 * get_lanman2_dir_entry(), so the resume name
1191 * could be mangled. Ensure we do the same
1196 mangle_map( dname
, False
, True
, SNUM(conn
));
1198 if(dname
&& strcsequal( resume_name
, dname
)) {
1199 SeekDir(dirptr
, current_pos
+1);
1200 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1206 * Scan forward from start if not found going backwards.
1209 if(current_pos
< 0) {
1210 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos
));
1211 SeekDir(dirptr
, start_pos
);
1212 for(current_pos
= start_pos
; (dname
= ReadDirName(dirptr
)) != NULL
; SeekDir(dirptr
,++current_pos
)) {
1215 * Remember, mangle_map is called by
1216 * get_lanman2_dir_entry(), so the resume name
1217 * could be mangled. Ensure we do the same
1222 mangle_map( dname
, False
, True
, SNUM(conn
));
1224 if(dname
&& strcsequal( resume_name
, dname
)) {
1225 SeekDir(dirptr
, current_pos
+1);
1226 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1230 } /* end if current_pos */
1231 } /* end if requires_resume_key && !continue_bit */
1233 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
1234 BOOL got_exact_match
= False
;
1236 /* this is a heuristic to avoid seeking the dirptr except when
1237 absolutely necessary. It allows for a filename of about 40 chars */
1238 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1239 out_of_space
= True
;
1242 finished
= !get_lanman2_dir_entry(conn
,
1244 mask
,dirtype
,info_level
,
1245 requires_resume_key
,dont_descend
,
1246 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1250 if (finished
&& out_of_space
)
1253 if (!finished
&& !out_of_space
)
1257 * As an optimisation if we know we aren't looking
1258 * for a wildcard name (ie. the name matches the wildcard exactly)
1259 * then we can finish on any (first) match.
1260 * This speeds up large directory searches. JRA.
1266 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1269 /* Check if we can close the dirptr */
1270 if(close_after_request
|| (finished
&& close_if_end
)) {
1271 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
1272 dptr_close(&dptr_num
); /* This frees up the saved mask */
1276 /* Set up the return parameter block */
1277 SSVAL(params
,0,numentries
);
1278 SSVAL(params
,2,finished
);
1279 SSVAL(params
,4,0); /* Never an EA error */
1280 SSVAL(params
,6,last_name_off
);
1282 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
1284 if ((! *directory
) && dptr_path(dptr_num
))
1285 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1287 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1288 smb_fn_name(CVAL(inbuf
,smb_com
)),
1289 mask
, directory
, dirtype
, numentries
) );
1294 /****************************************************************************
1295 Reply to a TRANS2_QFSINFO (query filesystem info).
1296 ****************************************************************************/
1298 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
,
1299 int length
, int bufsize
,
1300 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1302 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1303 char *pdata
= *ppdata
;
1304 char *params
= *pparams
;
1305 uint16 info_level
= SVAL(params
,0);
1308 char *vname
= volume_label(SNUM(conn
));
1309 int snum
= SNUM(conn
);
1310 char *fstype
= lp_fstype(SNUM(conn
));
1312 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
1314 if(vfs_stat(conn
,".",&st
)!=0) {
1315 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
1316 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
1319 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
1320 if ( pdata
== NULL
)
1321 return ERROR_DOS(ERRDOS
,ERRnomem
);
1324 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1326 switch (info_level
) {
1327 case SMB_INFO_ALLOCATION
:
1329 SMB_BIG_UINT dfree
,dsize
,bsize
;
1331 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1332 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
1333 SIVAL(pdata
,l1_cSectorUnit
,bsize
/512);
1334 SIVAL(pdata
,l1_cUnit
,dsize
);
1335 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
1336 SSVAL(pdata
,l1_cbSector
,512);
1337 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1338 (unsigned int)bsize
, (unsigned int)st
.st_dev
, ((unsigned int)bsize
)/512, (unsigned int)dsize
,
1339 (unsigned int)dfree
, 512));
1343 case SMB_INFO_VOLUME
:
1344 /* Return volume name */
1346 * Add volume serial number - hash of a combination of
1347 * the called hostname and the service name.
1349 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(local_machine
)<<16) );
1350 len
= srvstr_push(outbuf
, pdata
+l2_vol_szVolLabel
, vname
, -1, STR_TERMINATE
);
1351 SCVAL(pdata
,l2_vol_cch
,len
);
1352 data_len
= l2_vol_szVolLabel
+ len
;
1353 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1354 (unsigned)st
.st_ctime
, len
, vname
));
1357 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
1358 case SMB_FS_ATTRIBUTE_INFORMATION
:
1360 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
1361 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)); /* FS ATTRIBUTES */
1362 SIVAL(pdata
,4,255); /* Max filename component length */
1363 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1364 and will think we can't do long filenames */
1365 len
= srvstr_push(outbuf
, pdata
+12, fstype
, -1, 0);
1367 data_len
= 12 + len
;
1370 case SMB_QUERY_FS_LABEL_INFO
:
1371 case SMB_FS_LABEL_INFORMATION
:
1372 len
= srvstr_push(outbuf
, pdata
+4, vname
, -1, STR_TERMINATE
);
1377 case SMB_QUERY_FS_VOLUME_INFO
:
1378 case SMB_FS_VOLUME_INFORMATION
:
1381 * Add volume serial number - hash of a combination of
1382 * the called hostname and the service name.
1384 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
1385 (str_checksum(local_machine
)<<16));
1387 len
= srvstr_push(outbuf
, pdata
+18, vname
, -1, STR_TERMINATE
);
1388 SIVAL(pdata
,12,len
);
1390 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1391 (int)strlen(vname
),vname
, lp_servicename(snum
)));
1394 case SMB_QUERY_FS_SIZE_INFO
:
1395 case SMB_FS_SIZE_INFORMATION
:
1397 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1399 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1400 block_size
= lp_block_size(snum
);
1401 if (bsize
< block_size
) {
1402 SMB_BIG_UINT factor
= block_size
/bsize
;
1407 if (bsize
> block_size
) {
1408 SMB_BIG_UINT factor
= bsize
/block_size
;
1413 bytes_per_sector
= 512;
1414 sectors_per_unit
= bsize
/bytes_per_sector
;
1415 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1416 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1417 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1418 SBIG_UINT(pdata
,0,dsize
);
1419 SBIG_UINT(pdata
,8,dfree
);
1420 SIVAL(pdata
,16,sectors_per_unit
);
1421 SIVAL(pdata
,20,bytes_per_sector
);
1425 case SMB_FS_FULL_SIZE_INFORMATION
:
1427 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1429 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1430 block_size
= lp_block_size(snum
);
1431 if (bsize
< block_size
) {
1432 SMB_BIG_UINT factor
= block_size
/bsize
;
1437 if (bsize
> block_size
) {
1438 SMB_BIG_UINT factor
= bsize
/block_size
;
1443 bytes_per_sector
= 512;
1444 sectors_per_unit
= bsize
/bytes_per_sector
;
1445 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1446 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1447 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1448 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
1449 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
1450 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
1451 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
1452 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
1456 case SMB_QUERY_FS_DEVICE_INFO
:
1457 case SMB_FS_DEVICE_INFORMATION
:
1459 SIVAL(pdata
,0,0); /* dev type */
1460 SIVAL(pdata
,4,0); /* characteristics */
1463 case SMB_FS_OBJECTID_INFORMATION
:
1468 * Query the version and capabilities of the CIFS UNIX extensions
1472 case SMB_QUERY_CIFS_UNIX_INFO
:
1473 if (!lp_unix_extensions())
1474 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1476 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
1477 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
1478 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)0)); /* No capabilities for now... */
1481 case SMB_MAC_QUERY_FS_INFO
:
1483 * Thursby MAC extension... ONLY on NTFS filesystems
1484 * once we do streams then we don't need this
1486 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
1488 SIVAL(pdata
,84,0x100); /* Don't support mac... */
1493 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1497 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
1499 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
1504 /****************************************************************************
1505 Reply to a TRANS2_SETFSINFO (set filesystem info).
1506 ****************************************************************************/
1508 static int call_trans2setfsinfo(connection_struct
*conn
,
1509 char *inbuf
, char *outbuf
, int length
, int bufsize
,
1510 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1512 /* Just say yes we did it - there is nothing that
1513 can be set here so it doesn't matter. */
1515 DEBUG(3,("call_trans2setfsinfo\n"));
1517 if (!CAN_WRITE(conn
))
1518 return ERROR_DOS(ERRSRV
,ERRaccess
);
1520 outsize
= set_message(outbuf
,10,0,True
);
1525 /****************************************************************************
1526 * Utility function to set bad path error.
1527 ****************************************************************************/
1529 NTSTATUS
set_bad_path_error(int err
, BOOL bad_path
)
1531 if((err
== ENOENT
) && bad_path
) {
1532 unix_ERR_class
= ERRDOS
;
1533 unix_ERR_code
= ERRbadpath
;
1534 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1536 return NT_STATUS_OK
;
1539 /****************************************************************************
1540 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1541 file name or file id).
1542 ****************************************************************************/
1544 static int call_trans2qfilepathinfo(connection_struct
*conn
,
1545 char *inbuf
, char *outbuf
, int length
,
1547 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1549 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1550 char *params
= *pparams
;
1551 char *pdata
= *ppdata
;
1552 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
1555 SMB_OFF_T file_size
=0;
1556 SMB_OFF_T allocation_size
=0;
1557 unsigned int data_size
;
1558 SMB_STRUCT_STAT sbuf
;
1559 pstring fname
, dos_fname
;
1564 BOOL bad_path
= False
;
1565 BOOL delete_pending
= False
;
1568 files_struct
*fsp
= NULL
;
1571 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1573 if (tran_call
== TRANSACT2_QFILEINFO
) {
1574 if (total_params
< 4)
1575 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1577 fsp
= file_fsp(params
,0);
1578 info_level
= SVAL(params
,2);
1580 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
1582 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
1584 * This is actually a QFILEINFO on a directory
1585 * handle (returned from an NT SMB). NT5.0 seems
1586 * to do this call. JRA.
1588 pstrcpy(fname
, fsp
->fsp_name
);
1589 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1590 if (!check_name(fname
,conn
)) {
1591 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
1592 set_bad_path_error(errno
, bad_path
);
1593 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1596 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1597 /* Always do lstat for UNIX calls. */
1598 if (vfs_lstat(conn
,fname
,&sbuf
)) {
1599 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname
,strerror(errno
)));
1600 set_bad_path_error(errno
, bad_path
);
1601 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1603 } else if (!VALID_STAT(sbuf
) && vfs_stat(conn
,fname
,&sbuf
)) {
1604 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname
,strerror(errno
)));
1605 set_bad_path_error(errno
, bad_path
);
1606 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1609 delete_pending
= fsp
->directory_delete_on_close
;
1612 * Original code - this is an open file.
1614 CHECK_FSP(fsp
,conn
);
1616 pstrcpy(fname
, fsp
->fsp_name
);
1617 if (vfs_fstat(fsp
,fsp
->fd
,&sbuf
) != 0) {
1618 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp
->fnum
, strerror(errno
)));
1619 return(UNIXERROR(ERRDOS
,ERRbadfid
));
1621 if((pos
= fsp
->conn
->vfs_ops
.lseek(fsp
,fsp
->fd
,0,SEEK_CUR
)) == -1)
1622 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
1624 delete_pending
= fsp
->delete_on_close
;
1628 if (total_params
< 6)
1629 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1631 info_level
= SVAL(params
,0);
1633 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
1635 srvstr_pull(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
);
1637 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1639 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1640 if (!check_name(fname
,conn
)) {
1641 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
1642 set_bad_path_error(errno
, bad_path
);
1643 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1646 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1647 /* Always do lstat for UNIX calls. */
1648 if (vfs_lstat(conn
,fname
,&sbuf
)) {
1649 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname
,strerror(errno
)));
1650 set_bad_path_error(errno
, bad_path
);
1651 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1653 } else if (!VALID_STAT(sbuf
) && vfs_stat(conn
,fname
,&sbuf
)) {
1654 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname
,strerror(errno
)));
1655 set_bad_path_error(errno
, bad_path
);
1656 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1660 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
1661 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1663 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1664 fname
,info_level
,tran_call
,total_data
));
1666 p
= strrchr_m(fname
,'/');
1672 mode
= dos_mode(conn
,fname
,&sbuf
);
1673 fullpathname
= fname
;
1674 file_size
= get_file_size(sbuf
);
1675 allocation_size
= get_allocation_size(fsp
,&sbuf
);
1679 params
= Realloc(*pparams
,2);
1681 return ERROR_DOS(ERRDOS
,ERRnomem
);
1683 memset((char *)params
,'\0',2);
1684 data_size
= max_data_bytes
+ 1024;
1685 pdata
= Realloc(*ppdata
, data_size
);
1686 if ( pdata
== NULL
)
1687 return ERROR_DOS(ERRDOS
,ERRnomem
);
1690 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
1691 /* uggh, EAs for OS2 */
1692 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
1693 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
1696 memset((char *)pdata
,'\0',data_size
);
1698 c_time
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
1700 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1702 sbuf
.st_atime
&= ~1;
1703 sbuf
.st_mtime
&= ~1;
1704 sbuf
.st_mtime
&= ~1;
1707 /* NT expects the name to be in an exact form of the *full*
1708 filename. See the trans2 torture test */
1709 if (strequal(base_name
,".")) {
1710 pstrcpy(dos_fname
, "\\");
1712 snprintf(dos_fname
, sizeof(dos_fname
), "\\%s", fname
);
1713 string_replace(dos_fname
, '/', '\\');
1716 switch (info_level
) {
1717 case SMB_INFO_STANDARD
:
1718 case SMB_INFO_QUERY_EA_SIZE
:
1719 data_size
= (info_level
==1?22:26);
1720 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
1721 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
1722 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
1723 SIVAL(pdata
,l1_cbFile
,(uint32
)file_size
);
1724 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
1725 SSVAL(pdata
,l1_attrFile
,mode
);
1726 SIVAL(pdata
,l1_attrFile
+2,4); /* this is what OS2 does */
1729 case SMB_INFO_QUERY_EAS_FROM_LIST
:
1731 put_dos_date2(pdata
,0,c_time
);
1732 put_dos_date2(pdata
,4,sbuf
.st_atime
);
1733 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
1734 SIVAL(pdata
,12,(uint32
)file_size
);
1735 SIVAL(pdata
,16,(uint32
)allocation_size
);
1736 SIVAL(pdata
,20,mode
);
1739 case SMB_INFO_QUERY_ALL_EAS
:
1741 SIVAL(pdata
,0,data_size
);
1745 return ERROR_DOS(ERRDOS
,ERRbadfunc
); /* os/2 needs this */
1747 case SMB_FILE_BASIC_INFORMATION
:
1748 case SMB_QUERY_FILE_BASIC_INFO
:
1750 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
)
1751 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
1756 put_long_date(pdata
,c_time
);
1757 put_long_date(pdata
+8,sbuf
.st_atime
);
1758 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1759 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1760 SIVAL(pdata
,32,mode
);
1762 DEBUG(5,("SMB_QFBI - "));
1764 time_t create_time
= c_time
;
1765 DEBUG(5,("create: %s ", ctime(&create_time
)));
1767 DEBUG(5,("access: %s ", ctime(&sbuf
.st_atime
)));
1768 DEBUG(5,("write: %s ", ctime(&sbuf
.st_mtime
)));
1769 DEBUG(5,("change: %s ", ctime(&sbuf
.st_mtime
)));
1770 DEBUG(5,("mode: %x\n", mode
));
1774 case SMB_FILE_STANDARD_INFORMATION
:
1775 case SMB_QUERY_FILE_STANDARD_INFO
:
1778 SOFF_T(pdata
,0,allocation_size
);
1779 SOFF_T(pdata
,8,file_size
);
1780 SIVAL(pdata
,16,sbuf
.st_nlink
);
1782 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
1785 case SMB_FILE_EA_INFORMATION
:
1786 case SMB_QUERY_FILE_EA_INFO
:
1790 /* Get the 8.3 name - used if NT SMB was negotiated. */
1791 case SMB_QUERY_FILE_ALT_NAME_INFO
:
1795 pstrcpy(short_name
,base_name
);
1796 /* Mangle if not already 8.3 */
1797 if(!mangle_is_8_3(short_name
, True
)) {
1798 mangle_map(short_name
,True
,True
,SNUM(conn
));
1800 len
= srvstr_push(outbuf
, pdata
+4, short_name
, -1, STR_TERMINATE
|STR_UPPER
);
1801 data_size
= 4 + len
;
1806 case SMB_QUERY_FILE_NAME_INFO
:
1808 this must be *exactly* right for ACLs on mapped drives to work
1810 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_UNICODE
);
1811 data_size
= 4 + len
;
1815 case SMB_FILE_ALLOCATION_INFORMATION
:
1816 case SMB_QUERY_FILE_ALLOCATION_INFO
:
1818 SOFF_T(pdata
,0,allocation_size
);
1821 case SMB_FILE_END_OF_FILE_INFORMATION
:
1822 case SMB_QUERY_FILE_END_OF_FILEINFO
:
1824 SOFF_T(pdata
,0,file_size
);
1827 case SMB_QUERY_FILE_ALL_INFO
:
1828 put_long_date(pdata
,c_time
);
1829 put_long_date(pdata
+8,sbuf
.st_atime
);
1830 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1831 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1832 SIVAL(pdata
,32,mode
);
1834 SOFF_T(pdata
,0,allocation_size
);
1835 SOFF_T(pdata
,8,file_size
);
1836 SIVAL(pdata
,16,sbuf
.st_nlink
);
1837 SCVAL(pdata
,20,delete_pending
);
1838 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
1840 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
);
1841 pdata
+= 8; /* index number */
1842 pdata
+= 4; /* EA info */
1844 SIVAL(pdata
,0,0xA9);
1846 SIVAL(pdata
,0,0xd01BF);
1848 SOFF_T(pdata
,0,pos
); /* current offset */
1850 SIVAL(pdata
,0,mode
); /* is this the right sort of mode info? */
1852 pdata
+= 4; /* alignment */
1853 len
= srvstr_push(outbuf
, pdata
+4, dos_fname
, -1, STR_TERMINATE
);
1856 data_size
= PTR_DIFF(pdata
,(*ppdata
));
1859 case SMB_FILE_INTERNAL_INFORMATION
:
1860 /* This should be an index number - looks like
1863 I think this causes us to fail the IFSKIT
1864 BasicFileInformationTest. -tpot */
1866 SIVAL(pdata
,0,sbuf
.st_dev
);
1867 SIVAL(pdata
,4,sbuf
.st_ino
);
1871 case SMB_FILE_ACCESS_INFORMATION
:
1872 SIVAL(pdata
,0,0x12019F); /* ??? */
1876 case SMB_FILE_NAME_INFORMATION
:
1877 /* Pathname with leading '\'. */
1880 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
1881 SIVAL(pdata
,0,byte_len
);
1882 data_size
= 4 + byte_len
;
1886 case SMB_FILE_DISPOSITION_INFORMATION
:
1888 SCVAL(pdata
,0,delete_pending
);
1891 case SMB_FILE_POSITION_INFORMATION
:
1893 SOFF_T(pdata
,0,pos
);
1896 case SMB_FILE_MODE_INFORMATION
:
1897 SIVAL(pdata
,0,mode
);
1901 case SMB_FILE_ALIGNMENT_INFORMATION
:
1902 SIVAL(pdata
,0,0); /* No alignment needed. */
1907 /* Not yet finished... JRA */
1910 put_long_date(pdata
,c_time
);
1911 put_long_date(pdata
+8,sbuf
.st_atime
);
1912 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1913 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1914 SIVAL(pdata
,32,mode
);
1915 SIVAL(pdata
,36,0); /* ??? */
1916 SIVAL(pdata
,40,0x20); /* ??? */
1917 SIVAL(pdata
,44,0); /* ??? */
1918 SOFF_T(pdata
,48,size
);
1919 SIVAL(pdata
,56,0x1); /* ??? */
1920 SIVAL(pdata
,60,0); /* ??? */
1921 SIVAL(pdata
,64,0); /* ??? */
1922 SIVAL(pdata
,68,length
); /* Following string length in bytes. */
1923 dos_PutUniCode(pdata
+72,,False
);
1928 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
1929 /* Last component of pathname. */
1931 size_t byte_len
= dos_PutUniCode(pdata
+4,fname
,max_data_bytes
,False
);
1932 SIVAL(pdata
,0,byte_len
);
1933 data_size
= 4 + byte_len
;
1939 * NT4 server just returns "invalid query" to this - if we try to answer
1940 * it then NTws gets a BSOD! (tridge).
1941 * W2K seems to want this. JRA.
1943 case SMB_QUERY_FILE_STREAM_INFO
:
1945 case SMB_FILE_STREAM_INFORMATION
:
1949 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", 0xE, False
);
1950 SIVAL(pdata
,0,0); /* ??? */
1951 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
1952 SOFF_T(pdata
,8,file_size
);
1953 SIVAL(pdata
,16,allocation_size
);
1954 SIVAL(pdata
,20,0); /* ??? */
1955 data_size
= 24 + byte_len
;
1959 case SMB_FILE_COMPRESSION_INFORMATION
:
1960 SOFF_T(pdata
,0,allocation_size
);
1961 SIVAL(pdata
,8,0); /* ??? */
1962 SIVAL(pdata
,12,0); /* ??? */
1966 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
1967 put_long_date(pdata
,c_time
);
1968 put_long_date(pdata
+8,sbuf
.st_atime
);
1969 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1970 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1971 SIVAL(pdata
,32,allocation_size
);
1972 SOFF_T(pdata
,40,file_size
);
1973 SIVAL(pdata
,48,mode
);
1974 SIVAL(pdata
,52,0); /* ??? */
1978 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
1979 SIVAL(pdata
,0,mode
);
1985 * CIFS UNIX Extensions.
1988 case SMB_QUERY_FILE_UNIX_BASIC
:
1990 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf
.st_mode
));
1992 SOFF_T(pdata
,0,get_file_size(sbuf
)); /* File size 64 Bit */
1995 SOFF_T(pdata
,0,get_allocation_size(fsp
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
1998 put_long_date(pdata
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
1999 put_long_date(pdata
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
2000 put_long_date(pdata
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
2003 SIVAL(pdata
,0,sbuf
.st_uid
); /* user id for the owner */
2007 SIVAL(pdata
,0,sbuf
.st_gid
); /* group id of owner */
2011 SIVAL(pdata
,0,unix_filetype(sbuf
.st_mode
));
2014 SIVAL(pdata
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
2018 SIVAL(pdata
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
2022 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
2025 SIVAL(pdata
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
2029 SIVAL(pdata
,0,sbuf
.st_nlink
); /* number of hard links */
2032 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2036 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2038 for (i
=0; i
<100; i
++)
2039 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
2045 case SMB_QUERY_FILE_UNIX_LINK
:
2050 if(!S_ISLNK(sbuf
.st_mode
))
2051 return(UNIXERROR(ERRSRV
,ERRbadlink
));
2053 return(UNIXERROR(ERRDOS
,ERRbadlink
));
2055 len
= conn
->vfs_ops
.readlink(conn
,fullpathname
, buffer
, sizeof(pstring
)-1); /* read link */
2057 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2059 len
= srvstr_push(outbuf
, pdata
, buffer
, -1, STR_TERMINATE
);
2061 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2067 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2070 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, data_size
);
2075 /****************************************************************************
2076 Deal with the internal needs of setting the delete on close flag. Note that
2077 as the tdb locking is recursive, it is safe to call this from within
2078 open_file_shared. JRA.
2079 ****************************************************************************/
2081 NTSTATUS
set_delete_on_close_internal(files_struct
*fsp
, BOOL delete_on_close
)
2084 * Only allow delete on close for writable shares.
2087 if (delete_on_close
&& !CAN_WRITE(fsp
->conn
)) {
2088 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2090 return NT_STATUS_ACCESS_DENIED
;
2093 * Only allow delete on close for files/directories opened with delete intent.
2096 if (delete_on_close
&& !(fsp
->desired_access
& DELETE_ACCESS
)) {
2097 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2099 return NT_STATUS_ACCESS_DENIED
;
2102 if(fsp
->is_directory
) {
2103 fsp
->directory_delete_on_close
= delete_on_close
;
2104 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2105 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2108 files_struct
*iterate_fsp
;
2111 * Modify the share mode entry for all files open
2112 * on this device and inode to tell other smbds we have
2113 * changed the delete on close flag. This will be noticed
2114 * in the close code, the last closer will delete the file
2118 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2119 delete_on_close
? "Adding" : "Removing", fsp
->fnum
, fsp
->fsp_name
));
2121 if (lock_share_entry_fsp(fsp
) == False
)
2122 return NT_STATUS_ACCESS_DENIED
;
2124 if (!modify_delete_flag(fsp
->dev
, fsp
->inode
, delete_on_close
)) {
2125 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2127 unlock_share_entry_fsp(fsp
);
2128 return NT_STATUS_ACCESS_DENIED
;
2135 unlock_share_entry_fsp(fsp
);
2138 * Go through all files we have open on the same device and
2139 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
2140 * Other smbd's that have this file open will look in the share_mode on close.
2141 * take care of this (rare) case in close_file(). See the comment there.
2142 * NB. JRA. We don't really need to do this anymore - all should be taken
2143 * care of in the share_mode changes in the tdb.
2146 for(iterate_fsp
= file_find_di_first(fsp
->dev
, fsp
->inode
);
2147 iterate_fsp
; iterate_fsp
= file_find_di_next(iterate_fsp
))
2148 fsp
->delete_on_close
= delete_on_close
;
2151 * Set the delete on close flag in the fsp.
2153 fsp
->delete_on_close
= delete_on_close
;
2155 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2156 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2160 return NT_STATUS_OK
;
2163 /****************************************************************************
2164 Returns true if this pathname is within the share, and thus safe.
2165 ****************************************************************************/
2167 static int ensure_link_is_safe(connection_struct
*conn
, const char *link_dest_in
, char *link_dest_out
)
2170 char resolved_name
[PATH_MAX
+1];
2172 pstring resolved_name
;
2174 fstring last_component
;
2178 BOOL bad_path
= False
;
2179 SMB_STRUCT_STAT sbuf
;
2181 pstrcpy(link_dest
, link_dest_in
);
2182 unix_convert(link_dest
,conn
,0,&bad_path
,&sbuf
);
2184 /* Store the UNIX converted path. */
2185 pstrcpy(link_dest_out
, link_dest
);
2187 p
= strrchr(link_dest
, '/');
2189 fstrcpy(last_component
, p
+1);
2192 fstrcpy(last_component
, link_dest
);
2193 pstrcpy(link_dest
, "./");
2196 if (conn
->vfs_ops
.realpath(conn
,link_dest
,resolved_name
) == NULL
)
2199 pstrcpy(link_dest
, resolved_name
);
2200 pstrcat(link_dest
, "/");
2201 pstrcat(link_dest
, last_component
);
2203 if (*link_dest
!= '/') {
2204 /* Relative path. */
2205 pstrcpy(link_test
, conn
->connectpath
);
2206 pstrcat(link_test
, "/");
2207 pstrcat(link_test
, link_dest
);
2209 pstrcpy(link_test
, link_dest
);
2213 * Check if the link is within the share.
2216 if (strncmp(conn
->connectpath
, link_test
, strlen(conn
->connectpath
))) {
2223 /****************************************************************************
2224 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2225 ****************************************************************************/
2227 static int call_trans2setfilepathinfo(connection_struct
*conn
,
2228 char *inbuf
, char *outbuf
, int length
, int bufsize
,
2229 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2231 char *params
= *pparams
;
2232 char *pdata
= *ppdata
;
2233 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2238 SMB_STRUCT_STAT sbuf
;
2241 BOOL bad_path
= False
;
2242 files_struct
*fsp
= NULL
;
2243 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
2244 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
2245 mode_t unixmode
= 0;
2247 if (tran_call
== TRANSACT2_SETFILEINFO
) {
2248 fsp
= file_fsp(params
,0);
2249 info_level
= SVAL(params
,2);
2251 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2253 * This is actually a SETFILEINFO on a directory
2254 * handle (returned from an NT SMB). NT5.0 seems
2255 * to do this call. JRA.
2257 pstrcpy(fname
, fsp
->fsp_name
);
2258 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2259 if (!check_name(fname
,conn
) || (!VALID_STAT(sbuf
))) {
2260 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2261 set_bad_path_error(errno
, bad_path
);
2262 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2264 } else if (fsp
&& fsp
->print_file
) {
2266 * Doing a DELETE_ON_CLOSE should cancel a print job.
2268 if ((info_level
== SMB_SET_FILE_DISPOSITION_INFO
) && CVAL(pdata
,0)) {
2269 fsp
->share_mode
= FILE_DELETE_ON_CLOSE
;
2271 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp
->fsp_name
));
2274 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2277 return (UNIXERROR(ERRDOS
,ERRbadpath
));
2280 * Original code - this is an open file.
2282 CHECK_FSP(fsp
,conn
);
2284 pstrcpy(fname
, fsp
->fsp_name
);
2287 if (vfs_fstat(fsp
,fd
,&sbuf
) != 0) {
2288 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
2289 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2294 if (total_params
< 6)
2295 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2297 info_level
= SVAL(params
,0);
2298 srvstr_pull(inbuf
, fname
, ¶ms
[6], sizeof(fname
), -1, STR_TERMINATE
);
2299 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2300 if(!check_name(fname
, conn
)) {
2301 set_bad_path_error(errno
, bad_path
);
2302 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2306 * For CIFS UNIX extensions the target name may not exist.
2309 if(!VALID_STAT(sbuf
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
2310 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname
, strerror(errno
)));
2311 set_bad_path_error(errno
, bad_path
);
2312 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2316 if (!CAN_WRITE(conn
))
2317 return ERROR_DOS(ERRSRV
,ERRaccess
);
2319 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2320 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2322 if (VALID_STAT(sbuf
))
2323 unixmode
= sbuf
.st_mode
;
2325 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2326 tran_call
,fname
,info_level
,total_data
));
2328 /* Realloc the parameter and data sizes */
2329 params
= Realloc(*pparams
,2);
2331 return ERROR_DOS(ERRDOS
,ERRnomem
);
2337 /* the pending modtime overrides the current modtime */
2338 sbuf
.st_mtime
= fsp
->pending_modtime
;
2341 size
= get_file_size(sbuf
);
2342 tvs
.modtime
= sbuf
.st_mtime
;
2343 tvs
.actime
= sbuf
.st_atime
;
2344 dosmode
= dos_mode(conn
,fname
,&sbuf
);
2345 unixmode
= sbuf
.st_mode
;
2347 set_owner
= VALID_STAT(sbuf
) ? sbuf
.st_uid
: (uid_t
)SMB_UID_NO_CHANGE
;
2348 set_grp
= VALID_STAT(sbuf
) ? sbuf
.st_gid
: (gid_t
)SMB_GID_NO_CHANGE
;
2350 switch (info_level
) {
2351 case SMB_INFO_STANDARD
:
2353 if (total_data
< l1_cbFile
+4)
2354 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2357 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
2360 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
2362 dosmode
= SVAL(pdata
,l1_attrFile
);
2363 size
= IVAL(pdata
,l1_cbFile
);
2368 case SMB_INFO_SET_EA
:
2369 return(ERROR_DOS(ERRDOS
,ERReasnotsupported
));
2371 /* XXXX um, i don't think this is right.
2372 it's also not in the cifs6.txt spec.
2374 case SMB_INFO_QUERY_EAS_FROM_LIST
:
2375 if (total_data
< 28)
2376 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2378 tvs
.actime
= make_unix_date2(pdata
+8);
2379 tvs
.modtime
= make_unix_date2(pdata
+12);
2380 size
= IVAL(pdata
,16);
2381 dosmode
= IVAL(pdata
,24);
2384 /* XXXX nor this. not in cifs6.txt, either. */
2385 case SMB_INFO_QUERY_ALL_EAS
:
2386 if (total_data
< 28)
2387 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2389 tvs
.actime
= make_unix_date2(pdata
+8);
2390 tvs
.modtime
= make_unix_date2(pdata
+12);
2391 size
= IVAL(pdata
,16);
2392 dosmode
= IVAL(pdata
,24);
2395 case SMB_SET_FILE_BASIC_INFO
:
2396 case SMB_FILE_BASIC_INFORMATION
:
2398 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2400 time_t changed_time
;
2402 if (total_data
< 36)
2403 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2405 /* Ignore create time at offset pdata. */
2408 tvs
.actime
= interpret_long_date(pdata
+8);
2410 write_time
= interpret_long_date(pdata
+16);
2411 changed_time
= interpret_long_date(pdata
+24);
2413 tvs
.modtime
= MIN(write_time
, changed_time
);
2415 if (write_time
> tvs
.modtime
&& write_time
!= 0xffffffff) {
2416 tvs
.modtime
= write_time
;
2418 /* Prefer a defined time to an undefined one. */
2419 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
2420 tvs
.modtime
= (write_time
== (time_t)0 || write_time
== (time_t)-1
2421 ? changed_time
: write_time
);
2424 dosmode
= IVAL(pdata
,32);
2428 case SMB_FILE_ALLOCATION_INFORMATION
:
2429 case SMB_SET_FILE_ALLOCATION_INFO
:
2432 SMB_OFF_T allocation_size
;
2435 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2437 allocation_size
= IVAL(pdata
,0);
2438 #ifdef LARGE_SMB_OFF_T
2439 allocation_size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2440 #else /* LARGE_SMB_OFF_T */
2441 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2442 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2443 #endif /* LARGE_SMB_OFF_T */
2444 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2445 fname
, (double)allocation_size
));
2447 if (allocation_size
)
2448 allocation_size
= SMB_ROUNDUP(allocation_size
,SMB_ROUNDUP_ALLOCATION_SIZE
);
2450 if(allocation_size
!= get_file_size(sbuf
)) {
2451 SMB_STRUCT_STAT new_sbuf
;
2453 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2454 fname
, (double)allocation_size
));
2457 files_struct
*new_fsp
= NULL
;
2458 int access_mode
= 0;
2461 if(global_oplock_break
) {
2462 /* Queue this file modify as we are the process of an oplock break. */
2464 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2465 DEBUGADD(2,( "in oplock break state.\n"));
2467 push_oplock_pending_smb_message(inbuf
, length
);
2471 new_fsp
= open_file_shared1(conn
, fname
, &sbuf
,FILE_WRITE_DATA
,
2472 SET_OPEN_MODE(DOS_OPEN_RDWR
),
2473 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
2474 0, 0, &access_mode
, &action
);
2476 if (new_fsp
== NULL
)
2477 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2478 ret
= vfs_allocate_file_space(new_fsp
, allocation_size
);
2479 if (vfs_fstat(new_fsp
,new_fsp
->fd
,&new_sbuf
) != 0) {
2480 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2481 new_fsp
->fnum
, strerror(errno
)));
2484 close_file(new_fsp
,True
);
2486 ret
= vfs_allocate_file_space(fsp
, allocation_size
);
2487 if (vfs_fstat(fsp
,fd
,&new_sbuf
) != 0) {
2488 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2489 fsp
->fnum
, strerror(errno
)));
2494 return ERROR_NT(NT_STATUS_DISK_FULL
);
2496 /* Allocate can truncate size... */
2497 size
= get_file_size(new_sbuf
);
2503 case SMB_FILE_END_OF_FILE_INFORMATION
:
2504 case SMB_SET_FILE_END_OF_FILE_INFO
:
2507 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2509 size
= IVAL(pdata
,0);
2510 #ifdef LARGE_SMB_OFF_T
2511 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2512 #else /* LARGE_SMB_OFF_T */
2513 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2514 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2515 #endif /* LARGE_SMB_OFF_T */
2516 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname
, (double)size
));
2520 case SMB_FILE_DISPOSITION_INFORMATION
:
2521 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
2523 BOOL delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
2527 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2529 if (tran_call
!= TRANSACT2_SETFILEINFO
)
2530 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2533 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2535 status
= set_delete_on_close_internal(fsp
, delete_on_close
);
2537 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
2538 return ERROR_NT(status
);
2544 * CIFS UNIX extensions.
2547 case SMB_SET_FILE_UNIX_BASIC
:
2549 uint32 raw_unixmode
;
2551 if (total_data
< 100)
2552 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2554 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
2555 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
2556 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
2557 #ifdef LARGE_SMB_OFF_T
2558 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2559 #else /* LARGE_SMB_OFF_T */
2560 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2561 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2562 #endif /* LARGE_SMB_OFF_T */
2564 pdata
+=24; /* ctime & st_blocks are not changed */
2565 tvs
.actime
= interpret_long_unix_date(pdata
); /* access_time */
2566 tvs
.modtime
= interpret_long_unix_date(pdata
+8); /* modification_time */
2568 set_owner
= (uid_t
)IVAL(pdata
,0);
2570 set_grp
= (gid_t
)IVAL(pdata
,0);
2572 raw_unixmode
= IVAL(pdata
,28);
2573 unixmode
= unix_perms_from_wire(conn
, &sbuf
, raw_unixmode
);
2574 dosmode
= 0; /* Ensure dos mode change doesn't override this. */
2576 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2577 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2578 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
2580 if (!VALID_STAT(sbuf
)) {
2583 * The only valid use of this is to create character and block
2584 * devices, and named pipes. This is deprecated (IMHO) and
2585 * a new info level should be used for mknod. JRA.
2588 #if !defined(HAVE_MAKEDEV_FN)
2589 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2590 #else /* HAVE_MAKEDEV_FN */
2591 uint32 file_type
= IVAL(pdata
,0);
2592 uint32 dev_major
= IVAL(pdata
,4);
2593 uint32 dev_minor
= IVAL(pdata
,12);
2595 uid_t myuid
= geteuid();
2596 gid_t mygid
= getegid();
2599 if (tran_call
== TRANSACT2_SETFILEINFO
)
2600 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2602 if (raw_unixmode
== SMB_MODE_NO_CHANGE
)
2603 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2605 dev
= makedev(dev_major
, dev_minor
);
2607 /* We can only create as the owner/group we are. */
2609 if ((set_owner
!= myuid
) && (set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
))
2610 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2611 if ((set_grp
!= mygid
) && (set_grp
!= (gid_t
)SMB_GID_NO_CHANGE
))
2612 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2614 if (file_type
!= UNIX_TYPE_CHARDEV
&& file_type
!= UNIX_TYPE_BLKDEV
&&
2615 file_type
!= UNIX_TYPE_FIFO
)
2616 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2618 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2619 0%o for file %s\n", (double)dev
, unixmode
, fname
));
2621 /* Ok - do the mknod. */
2622 if (conn
->vfs_ops
.mknod(conn
,dos_to_unix_static(fname
), unixmode
, dev
) != 0)
2623 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
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
)) {
3012 pdata
= Realloc(*ppdata
, 32);
3014 return ERROR_DOS(ERRDOS
,ERRnomem
);
3017 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3018 CAN ACCEPT THIS IN UNICODE. JRA. */
3020 rap_jobid
= pjobid_to_rap(SNUM(fsp
->conn
), fsp
->print_jobid
); /* Job number */
3021 SSVAL(pdata
,0,rap_jobid
); /* Job number */
3022 srvstr_push( outbuf
, pdata
+ 2, global_myname
, 15, STR_ASCII
|STR_TERMINATE
); /* Our NetBIOS name */
3023 srvstr_push( outbuf
, pdata
+18, lp_servicename(SNUM(conn
)), 13, STR_ASCII
|STR_TERMINATE
); /* Service name */
3024 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32);
3027 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3028 return ERROR_DOS(ERRSRV
,ERRerror
);
3032 /****************************************************************************
3033 Reply to a SMBfindclose (stop trans2 directory search).
3034 ****************************************************************************/
3036 int reply_findclose(connection_struct
*conn
,
3037 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3040 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
3041 START_PROFILE(SMBfindclose
);
3043 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
3045 dptr_close(&dptr_num
);
3047 outsize
= set_message(outbuf
,0,0,True
);
3049 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
3051 END_PROFILE(SMBfindclose
);
3055 /****************************************************************************
3056 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3057 ****************************************************************************/
3059 int reply_findnclose(connection_struct
*conn
,
3060 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3064 START_PROFILE(SMBfindnclose
);
3066 dptr_num
= SVAL(inbuf
,smb_vwv0
);
3068 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
3070 /* We never give out valid handles for a
3071 findnotifyfirst - so any dptr_num is ok here.
3074 outsize
= set_message(outbuf
,0,0,True
);
3076 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
3078 END_PROFILE(SMBfindnclose
);
3082 /****************************************************************************
3083 Reply to a SMBtranss2 - just ignore it!
3084 ****************************************************************************/
3086 int reply_transs2(connection_struct
*conn
,
3087 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3089 START_PROFILE(SMBtranss2
);
3090 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
3091 END_PROFILE(SMBtranss2
);
3095 /****************************************************************************
3096 Reply to a SMBtrans2.
3097 ****************************************************************************/
3099 int reply_trans2(connection_struct
*conn
,
3100 char *inbuf
,char *outbuf
,int length
,int bufsize
)
3103 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
3104 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
3106 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
3107 unsigned int max_data_reply
= SVAL(inbuf
, smb_mdrcnt
);
3108 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
3109 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
3110 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
3111 int32 timeout
= IVALS(inbuf
,smb_timeout
);
3113 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
3114 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
3115 char *params
= NULL
, *data
= NULL
;
3116 int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
3117 START_PROFILE(SMBtrans2
);
3119 if(global_oplock_break
&& (tran_call
== TRANSACT2_OPEN
)) {
3120 /* Queue this open message as we are the process of an
3123 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3124 DEBUGADD(2,( "in oplock break state.\n"));
3126 push_oplock_pending_smb_message(inbuf
, length
);
3127 END_PROFILE(SMBtrans2
);
3131 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
3132 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
3133 END_PROFILE(SMBtrans2
);
3134 return ERROR_DOS(ERRSRV
,ERRaccess
);
3137 outsize
= set_message(outbuf
,0,0,True
);
3139 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3140 is so as a sanity check */
3143 * Need to have rc=0 for ioctl to get job id for OS/2.
3144 * Network printing will fail if function is not successful.
3145 * Similar function in reply.c will be used if protocol
3146 * is LANMAN1.0 instead of LM1.2X002.
3147 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3148 * outbuf doesn't have to be set(only job id is used).
3150 if ( (suwcnt
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
3151 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3152 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3153 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3155 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt
));
3156 DEBUG(2,("Transaction is %d\n",tran_call
));
3157 END_PROFILE(SMBtrans2
);
3158 return ERROR_DOS(ERRSRV
,ERRerror
);
3162 /* Allocate the space for the maximum needed parameters and data */
3163 if (total_params
> 0)
3164 params
= (char *)malloc(total_params
);
3166 data
= (char *)malloc(total_data
);
3168 if ((total_params
&& !params
) || (total_data
&& !data
)) {
3169 DEBUG(2,("Out of memory in reply_trans2\n"));
3172 END_PROFILE(SMBtrans2
);
3173 return ERROR_DOS(ERRDOS
,ERRnomem
);
3176 /* Copy the param and data bytes sent with this request into
3177 the params buffer */
3178 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
3179 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
3181 if (num_params
> total_params
|| num_data
> total_data
)
3182 exit_server("invalid params in reply_trans2");
3185 memcpy( params
, smb_base(inbuf
) + SVAL(inbuf
, smb_psoff
), num_params
);
3187 memcpy( data
, smb_base(inbuf
) + SVAL(inbuf
, smb_dsoff
), num_data
);
3189 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
) {
3190 /* We need to send an interim response then receive the rest
3191 of the parameter/data bytes */
3192 outsize
= set_message(outbuf
,0,0,True
);
3193 if (!send_smb(smbd_server_fd(),outbuf
))
3194 exit_server("reply_trans2: send_smb failed.");
3196 while (num_data_sofar
< total_data
||
3197 num_params_sofar
< total_params
) {
3200 ret
= receive_next_smb(inbuf
,bufsize
,SMB_SECONDARY_WAIT
);
3203 (CVAL(inbuf
, smb_com
) != SMBtranss2
)) || !ret
) {
3204 outsize
= set_message(outbuf
,0,0,True
);
3206 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3208 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3209 (smb_read_error
== READ_ERROR
) ? "error" : "timeout" ));
3212 END_PROFILE(SMBtrans2
);
3213 return ERROR_DOS(ERRSRV
,ERRerror
);
3216 /* Revise total_params and total_data in case
3217 they have changed downwards */
3218 total_params
= SVAL(inbuf
, smb_tpscnt
);
3219 total_data
= SVAL(inbuf
, smb_tdscnt
);
3220 num_params_sofar
+= (num_params
= SVAL(inbuf
,smb_spscnt
));
3221 num_data_sofar
+= ( num_data
= SVAL(inbuf
, smb_sdscnt
));
3222 if (num_params_sofar
> total_params
|| num_data_sofar
> total_data
)
3223 exit_server("data overflow in trans2");
3225 memcpy( ¶ms
[ SVAL(inbuf
, smb_spsdisp
)],
3226 smb_base(inbuf
) + SVAL(inbuf
, smb_spsoff
), num_params
);
3227 memcpy( &data
[SVAL(inbuf
, smb_sdsdisp
)],
3228 smb_base(inbuf
)+ SVAL(inbuf
, smb_sdsoff
), num_data
);
3232 if (Protocol
>= PROTOCOL_NT1
) {
3233 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | 0x40); /* IS_LONG_NAME */
3236 /* Now we must call the relevant TRANS2 function */
3238 case TRANSACT2_OPEN
:
3239 START_PROFILE_NESTED(Trans2_open
);
3240 outsize
= call_trans2open(conn
, inbuf
, outbuf
, bufsize
,
3241 ¶ms
, total_params
, &data
, total_data
);
3242 END_PROFILE_NESTED(Trans2_open
);
3245 case TRANSACT2_FINDFIRST
:
3246 START_PROFILE_NESTED(Trans2_findfirst
);
3247 outsize
= call_trans2findfirst(conn
, inbuf
, outbuf
, bufsize
,
3248 ¶ms
, total_params
, &data
, total_data
);
3249 END_PROFILE_NESTED(Trans2_findfirst
);
3252 case TRANSACT2_FINDNEXT
:
3253 START_PROFILE_NESTED(Trans2_findnext
);
3254 outsize
= call_trans2findnext(conn
, inbuf
, outbuf
, length
, bufsize
,
3255 ¶ms
, total_params
, &data
, total_data
);
3256 END_PROFILE_NESTED(Trans2_findnext
);
3259 case TRANSACT2_QFSINFO
:
3260 START_PROFILE_NESTED(Trans2_qfsinfo
);
3261 outsize
= call_trans2qfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3262 ¶ms
, total_params
, &data
, total_data
);
3263 END_PROFILE_NESTED(Trans2_qfsinfo
);
3266 case TRANSACT2_SETFSINFO
:
3267 START_PROFILE_NESTED(Trans2_setfsinfo
);
3268 outsize
= call_trans2setfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3269 ¶ms
, total_params
, &data
, total_data
);
3270 END_PROFILE_NESTED(Trans2_setfsinfo
);
3273 case TRANSACT2_QPATHINFO
:
3274 case TRANSACT2_QFILEINFO
:
3275 START_PROFILE_NESTED(Trans2_qpathinfo
);
3276 outsize
= call_trans2qfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3277 ¶ms
, total_params
, &data
, total_data
);
3278 END_PROFILE_NESTED(Trans2_qpathinfo
);
3280 case TRANSACT2_SETPATHINFO
:
3281 case TRANSACT2_SETFILEINFO
:
3282 START_PROFILE_NESTED(Trans2_setpathinfo
);
3283 outsize
= call_trans2setfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3284 ¶ms
, total_params
, &data
, total_data
);
3285 END_PROFILE_NESTED(Trans2_setpathinfo
);
3288 case TRANSACT2_FINDNOTIFYFIRST
:
3289 START_PROFILE_NESTED(Trans2_findnotifyfirst
);
3290 outsize
= call_trans2findnotifyfirst(conn
, inbuf
, outbuf
, length
, bufsize
,
3291 ¶ms
, total_params
, &data
, total_data
);
3292 END_PROFILE_NESTED(Trans2_findnotifyfirst
);
3295 case TRANSACT2_FINDNOTIFYNEXT
:
3296 START_PROFILE_NESTED(Trans2_findnotifynext
);
3297 outsize
= call_trans2findnotifynext(conn
, inbuf
, outbuf
, length
, bufsize
,
3298 ¶ms
, total_params
, &data
, total_data
);
3299 END_PROFILE_NESTED(Trans2_findnotifynext
);
3301 case TRANSACT2_MKDIR
:
3302 START_PROFILE_NESTED(Trans2_mkdir
);
3303 outsize
= call_trans2mkdir(conn
, inbuf
, outbuf
, length
, bufsize
,
3304 ¶ms
, total_params
, &data
, total_data
);
3305 END_PROFILE_NESTED(Trans2_mkdir
);
3308 case TRANSACT2_GET_DFS_REFERRAL
:
3309 START_PROFILE_NESTED(Trans2_get_dfs_referral
);
3310 outsize
= call_trans2getdfsreferral(conn
,inbuf
,outbuf
,length
, bufsize
,
3311 ¶ms
, total_params
, &data
, total_data
);
3312 END_PROFILE_NESTED(Trans2_get_dfs_referral
);
3314 case TRANSACT2_IOCTL
:
3315 START_PROFILE_NESTED(Trans2_ioctl
);
3316 outsize
= call_trans2ioctl(conn
,inbuf
,outbuf
,length
, bufsize
,
3317 ¶ms
, total_params
, &data
, total_data
);
3318 END_PROFILE_NESTED(Trans2_ioctl
);
3321 /* Error in request */
3322 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call
));
3325 END_PROFILE(SMBtrans2
);
3326 return ERROR_DOS(ERRSRV
,ERRerror
);
3329 /* As we do not know how many data packets will need to be
3330 returned here the various call_trans2xxxx calls
3331 must send their own. Thus a call_trans2xxx routine only
3332 returns a value other than -1 when it wants to send
3338 END_PROFILE(SMBtrans2
);
3339 return outsize
; /* If a correct response was needed the
3340 call_trans2xxx calls have already sent
3341 it. If outsize != -1 then it is returning */