2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Extensively modified by Andrew Tridgell, 1995
6 Copyright (C) Jeremy Allison 1994-2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern BOOL case_sensitive
;
27 extern int smb_read_error
;
28 extern fstring local_machine
;
29 extern int global_oplock_break
;
30 extern uint32 global_client_caps
;
31 extern pstring global_myname
;
33 #define get_file_size(sbuf) ((sbuf).st_size)
35 /* given a stat buffer return the allocated size on disk, taking into
36 account sparse files */
38 SMB_BIG_UINT
get_allocation_size(files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
41 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
42 ret
= (SMB_BIG_UINT
)STAT_ST_BLOCKSIZE
* (SMB_BIG_UINT
)sbuf
->st_blocks
;
44 ret
= (SMB_BIG_UINT
)get_file_size(*sbuf
);
46 if (!ret
&& fsp
&& fsp
->initial_allocation_size
)
47 ret
= fsp
->initial_allocation_size
;
48 ret
= SMB_ROUNDUP(ret
,SMB_ROUNDUP_ALLOCATION_SIZE
);
52 /****************************************************************************
53 Send the required number of replies back.
54 We assume all fields other than the data fields are
55 set correctly for the type of call.
56 HACK ! Always assumes smb_setup field is zero.
57 ****************************************************************************/
59 static int send_trans2_replies(char *outbuf
, int bufsize
, char *params
, int paramsize
, char *pdata
, int datasize
)
61 /* As we are using a protocol > LANMAN1 then the max_send
62 variable must have been set in the sessetupX call.
63 This takes precedence over the max_xmit field in the
64 global struct. These different max_xmit variables should
65 be merged as this is now too confusing */
68 int data_to_send
= datasize
;
69 int params_to_send
= paramsize
;
73 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
74 int alignment_offset
= 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
75 int data_alignment_offset
= 0;
77 /* Initially set the wcnt area to be 10 - this is true for all
79 set_message(outbuf
,10,0,True
);
81 /* If there genuinely are no parameters or data to send just send
84 if(params_to_send
== 0 && data_to_send
== 0) {
85 if (!send_smb(smbd_server_fd(),outbuf
))
86 exit_server("send_trans2_replies: send_smb failed.");
90 /* When sending params and data ensure that both are nicely aligned */
91 /* Only do this alignment when there is also data to send - else
92 can cause NT redirector problems. */
94 if (((params_to_send
% 4) != 0) && (data_to_send
!= 0))
95 data_alignment_offset
= 4 - (params_to_send
% 4);
97 /* Space is bufsize minus Netbios over TCP header minus SMB header */
98 /* The alignment_offset is to align the param bytes on an even byte
99 boundary. NT 4.0 Beta needs this to work correctly. */
101 useable_space
= bufsize
- ((smb_buf(outbuf
)+ alignment_offset
+data_alignment_offset
) - outbuf
);
103 /* useable_space can never be more than max_send minus the alignment offset. */
105 useable_space
= MIN(useable_space
, max_send
- (alignment_offset
+data_alignment_offset
));
108 while (params_to_send
|| data_to_send
) {
109 /* Calculate whether we will totally or partially fill this packet */
111 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
+ data_alignment_offset
;
113 /* We can never send more than useable_space */
115 * Note that 'useable_space' does not include the alignment offsets,
116 * but we must include the alignment offsets in the calculation of
117 * the length of the data we send over the wire, as the alignment offsets
118 * are sent here. Fix from Marc_Jacobsen@hp.com.
121 total_sent_thistime
= MIN(total_sent_thistime
, useable_space
+ alignment_offset
+ data_alignment_offset
);
123 set_message(outbuf
, 10, total_sent_thistime
, True
);
125 /* Set total params and data to be sent */
126 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
127 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
129 /* Calculate how many parameters and data we can fit into
130 this packet. Parameters get precedence */
132 params_sent_thistime
= MIN(params_to_send
,useable_space
);
133 data_sent_thistime
= useable_space
- params_sent_thistime
;
134 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
136 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
138 /* smb_proff is the offset from the start of the SMB header to the
139 parameter bytes, however the first 4 bytes of outbuf are
140 the Netbios over TCP header. Thus use smb_base() to subtract
141 them from the calculation */
143 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
145 if(params_sent_thistime
== 0)
146 SSVAL(outbuf
,smb_prdisp
,0);
148 /* Absolute displacement of param bytes sent in this packet */
149 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
151 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
152 if(data_sent_thistime
== 0) {
153 SSVAL(outbuf
,smb_droff
,0);
154 SSVAL(outbuf
,smb_drdisp
, 0);
156 /* The offset of the data bytes is the offset of the
157 parameter bytes plus the number of parameters being sent this time */
158 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
159 smb_base(outbuf
)) + params_sent_thistime
+ data_alignment_offset
);
160 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
163 /* Copy the param bytes into the packet */
165 if(params_sent_thistime
)
166 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
168 /* Copy in the data bytes */
170 if(data_sent_thistime
)
171 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
+
172 data_alignment_offset
,pd
,data_sent_thistime
);
174 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
175 params_sent_thistime
, data_sent_thistime
, useable_space
));
176 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
177 params_to_send
, data_to_send
, paramsize
, datasize
));
179 /* Send the packet */
180 if (!send_smb(smbd_server_fd(),outbuf
))
181 exit_server("send_trans2_replies: send_smb failed.");
183 pp
+= params_sent_thistime
;
184 pd
+= data_sent_thistime
;
186 params_to_send
-= params_sent_thistime
;
187 data_to_send
-= data_sent_thistime
;
191 if(params_to_send
< 0 || data_to_send
< 0) {
192 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
193 params_to_send
, data_to_send
));
201 /****************************************************************************
202 Reply to a TRANSACT2_OPEN.
203 ****************************************************************************/
205 static int call_trans2open(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
206 char **pparams
, int total_params
, char **ppdata
, int total_data
)
208 char *params
= *pparams
;
213 BOOL return_additional_info
;
225 int fmode
=0,mtime
=0,rmode
;
227 SMB_STRUCT_STAT sbuf
;
229 BOOL bad_path
= False
;
233 * Ensure we have enough parameters to perform the operation.
236 if (total_params
< 29)
237 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
239 open_mode
= SVAL(params
, 2);
240 open_attr
= SVAL(params
,6);
241 oplock_request
= (((SVAL(params
,0)|(1<<1))>>1) | ((SVAL(params
,0)|(1<<2))>>1));
243 return_additional_info
= BITSETW(params
,0);
244 open_sattr
= SVAL(params
, 4);
245 open_time
= make_unix_date3(params
+8);
247 open_ofun
= SVAL(params
,12);
248 open_size
= IVAL(params
,14);
250 namelen
= strlen(pname
)+1;
252 StrnCpy(fname
,pname
,namelen
);
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 char *path_mask
,int dirtype
,int info_level
,
459 int requires_resume_key
,
460 BOOL dont_descend
,char **ppdata
,
461 char *base_data
, int space_remaining
,
462 BOOL
*out_of_space
, BOOL
*got_exact_match
,
467 SMB_STRUCT_STAT sbuf
;
471 char *p
, *pdata
= *ppdata
;
476 SMB_BIG_UINT allocation_size
= 0;
478 time_t mdate
=0, adate
=0, cdate
=0;
481 int nt_extmode
; /* Used for NT connections instead of mode */
482 BOOL needslash
= ( conn
->dirpath
[strlen(conn
->dirpath
) -1] != '/');
485 *out_of_space
= False
;
486 *got_exact_match
= False
;
491 p
= strrchr(path_mask
,'/');
498 pstrcpy(mask
, path_mask
);
503 /* Needed if we run out of space */
504 prev_dirpos
= TellDir(conn
->dirptr
);
505 dname
= ReadDirName(conn
->dirptr
);
508 * Due to bugs in NT client redirectors we are not using
509 * resume keys any more - set them to zero.
510 * Check out the related comments in findfirst/findnext.
516 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
517 (long)conn
->dirptr
,TellDir(conn
->dirptr
)));
522 pstrcpy(fname
,dname
);
524 if(!(got_match
= *got_exact_match
= exact_match(fname
, mask
, case_sensitive
)))
525 got_match
= mask_match(fname
, mask
, case_sensitive
);
527 if(!got_match
&& !mangle_is_8_3(fname
, False
)) {
530 * It turns out that NT matches wildcards against
531 * both long *and* short names. This may explain some
532 * of the wildcard wierdness from old DOS clients
533 * that some people have been seeing.... JRA.
537 pstrcpy( newname
, fname
);
538 mangle_map( newname
, True
, False
, SNUM(conn
));
539 if(!(got_match
= *got_exact_match
= exact_match(newname
, mask
, case_sensitive
)))
540 got_match
= mask_match(newname
, mask
, case_sensitive
);
544 BOOL isdots
= (strequal(fname
,"..") || strequal(fname
,"."));
545 if (dont_descend
&& !isdots
)
548 pstrcpy(pathreal
,conn
->dirpath
);
550 pstrcat(pathreal
,"/");
551 pstrcat(pathreal
,dname
);
553 if (INFO_LEVEL_IS_UNIX(info_level
)) {
554 if (vfs_lstat(conn
,pathreal
,&sbuf
) != 0) {
555 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
556 pathreal
,strerror(errno
)));
559 } else if (vfs_stat(conn
,pathreal
,&sbuf
) != 0) {
561 /* Needed to show the msdfs symlinks as
564 if(lp_host_msdfs() &&
565 lp_msdfs_root(SNUM(conn
)) &&
566 is_msdfs_link(conn
, pathreal
, NULL
, NULL
,
569 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal
));
570 sbuf
.st_mode
= (sbuf
.st_mode
& 0xFFF) | S_IFDIR
;
574 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
575 pathreal
,strerror(errno
)));
580 mode
= dos_mode(conn
,pathreal
,&sbuf
);
582 if (!dir_check_ftype(conn
,mode
,&sbuf
,dirtype
)) {
583 DEBUG(5,("[%s] attribs didn't match %x\n",fname
,dirtype
));
587 size
= get_file_size(sbuf
);
588 allocation_size
= get_allocation_size(NULL
,&sbuf
);
589 mdate
= sbuf
.st_mtime
;
590 adate
= sbuf
.st_atime
;
591 cdate
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
593 if (lp_dos_filetime_resolution(SNUM(conn
))) {
602 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal
,fname
));
608 mangle_map(fname
,False
,True
,SNUM(conn
));
613 nt_extmode
= mode
? mode
: FILE_ATTRIBUTE_NORMAL
;
615 switch (info_level
) {
617 if(requires_resume_key
) {
621 put_dos_date2(p
,l1_fdateCreation
,cdate
);
622 put_dos_date2(p
,l1_fdateLastAccess
,adate
);
623 put_dos_date2(p
,l1_fdateLastWrite
,mdate
);
624 SIVAL(p
,l1_cbFile
,(uint32
)size
);
625 SIVAL(p
,l1_cbFileAlloc
,(uint32
)allocation_size
);
626 SSVAL(p
,l1_attrFile
,mode
);
627 SCVAL(p
,l1_cchName
,strlen(fname
));
628 pstrcpy(p
+ l1_achName
, fname
);
629 nameptr
= p
+ l1_achName
;
630 p
+= l1_achName
+ strlen(fname
) + 1;
634 if(requires_resume_key
) {
638 put_dos_date2(p
,l2_fdateCreation
,cdate
);
639 put_dos_date2(p
,l2_fdateLastAccess
,adate
);
640 put_dos_date2(p
,l2_fdateLastWrite
,mdate
);
641 SIVAL(p
,l2_cbFile
,(uint32
)size
);
642 SIVAL(p
,l2_cbFileAlloc
,(uint32
)allocation_size
);
643 SSVAL(p
,l2_attrFile
,mode
);
644 SIVAL(p
,l2_cbList
,0); /* No extended attributes */
645 SCVAL(p
,l2_cchName
,strlen(fname
));
646 pstrcpy(p
+ l2_achName
, fname
);
647 nameptr
= p
+ l2_achName
;
648 p
+= l2_achName
+ strlen(fname
) + 1;
653 put_dos_date2(p
,4,cdate
);
654 put_dos_date2(p
,8,adate
);
655 put_dos_date2(p
,12,mdate
);
656 SIVAL(p
,16,(uint32
)size
);
657 SIVAL(p
,20,(uint32
)allocation_size
);
660 SCVAL(p
,30,strlen(fname
));
661 pstrcpy(p
+31, fname
);
663 p
+= 31 + strlen(fname
) + 1;
667 if(requires_resume_key
) {
671 SIVAL(p
,0,33+strlen(fname
)+1);
672 put_dos_date2(p
,4,cdate
);
673 put_dos_date2(p
,8,adate
);
674 put_dos_date2(p
,12,mdate
);
675 SIVAL(p
,16,(uint32
)size
);
676 SIVAL(p
,20,(uint32
)allocation_size
);
678 SCVAL(p
,32,strlen(fname
));
679 pstrcpy(p
+ 33, fname
);
681 p
+= 33 + strlen(fname
) + 1;
684 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
685 was_8_3
= mangle_is_8_3(fname
, True
);
686 len
= 94+strlen(fname
);
687 len
= (len
+ 3) & ~3;
688 SIVAL(p
,0,len
); p
+= 4;
689 SIVAL(p
,0,reskey
); p
+= 4;
690 put_long_date(p
,cdate
); p
+= 8;
691 put_long_date(p
,adate
); p
+= 8;
692 put_long_date(p
,mdate
); p
+= 8;
693 put_long_date(p
,mdate
); p
+= 8;
695 SOFF_T(p
,8,allocation_size
);
697 SIVAL(p
,0,nt_extmode
); p
+= 4;
698 SIVAL(p
,0,strlen(fname
)); p
+= 4;
699 SIVAL(p
,0,0); p
+= 4;
700 /* Clear the short name buffer. This is
701 * IMPORTANT as not doing so will trigger
702 * a Win2k client bug. JRA.
707 fstrcpy(tmpname
,fname
);
708 mangle_map(tmpname
,True
,True
,SNUM(conn
));
710 fstrcpy(p
+2,tmpname
);
711 SSVAL(p
, 0, strlen(tmpname
));
718 pstrcpy(p
,fname
); p
+= strlen(p
);
722 case SMB_FIND_FILE_DIRECTORY_INFO
:
723 len
= 64+strlen(fname
);
724 len
= (len
+ 3) & ~3;
725 SIVAL(p
,0,len
); p
+= 4;
726 SIVAL(p
,0,reskey
); p
+= 4;
727 put_long_date(p
,cdate
); p
+= 8;
728 put_long_date(p
,adate
); p
+= 8;
729 put_long_date(p
,mdate
); p
+= 8;
730 put_long_date(p
,mdate
); p
+= 8;
732 SOFF_T(p
,8,allocation_size
);
734 SIVAL(p
,0,nt_extmode
); p
+= 4;
735 SIVAL(p
,0,strlen(fname
)); p
+= 4;
740 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
741 len
= 68+strlen(fname
);
742 len
= (len
+ 3) & ~3;
743 SIVAL(p
,0,len
); p
+= 4;
744 SIVAL(p
,0,reskey
); p
+= 4;
745 put_long_date(p
,cdate
); p
+= 8;
746 put_long_date(p
,adate
); p
+= 8;
747 put_long_date(p
,mdate
); p
+= 8;
748 put_long_date(p
,mdate
); p
+= 8;
750 SOFF_T(p
,8,allocation_size
);
752 SIVAL(p
,0,nt_extmode
); p
+= 4;
753 SIVAL(p
,0,strlen(fname
)); p
+= 4;
754 SIVAL(p
,0,0); p
+= 4;
759 case SMB_FIND_FILE_NAMES_INFO
:
760 len
= 12+strlen(fname
);
761 len
= (len
+ 3) & ~3;
762 SIVAL(p
,0,len
); p
+= 4;
763 SIVAL(p
,0,reskey
); p
+= 4;
764 SIVAL(p
,0,strlen(fname
)); p
+= 4;
769 /* CIFS UNIX Extension. */
771 case SMB_FIND_FILE_UNIX
:
772 len
= 108+strlen(fname
)+1; /* (length of SMB_QUERY_FILE_UNIX_BASIC = 100)+4+4+strlen(fname)*/
773 /* +1 to be sure to transmit the termination of fname */
774 len
= (len
+ 3) & ~3;
776 SIVAL(p
,0,len
); p
+= 4; /* Offset from this structure to the beginning of the next one */
777 SIVAL(p
,0,reskey
); p
+= 4; /* Used for continuing search. */
779 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
780 SOFF_T(p
,0,get_file_size(sbuf
)); /* File size 64 Bit */
783 SOFF_T(p
,0,get_allocation_size(NULL
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
786 put_long_date(p
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
787 put_long_date(p
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
788 put_long_date(p
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
791 SIVAL(p
,0,sbuf
.st_uid
); /* user id for the owner */
795 SIVAL(p
,0,sbuf
.st_gid
); /* group id of owner */
799 SIVAL(p
,0,unix_filetype(sbuf
.st_mode
));
802 SIVAL(p
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
806 SIVAL(p
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
810 SINO_T(p
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
813 SIVAL(p
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
817 SIVAL(p
,0,sbuf
.st_nlink
); /* number of hard links */
821 /* End of SMB_QUERY_FILE_UNIX_BASIC */
832 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
833 /* Move the dirptr back to prev_dirpos */
834 SeekDir(conn
->dirptr
, prev_dirpos
);
835 *out_of_space
= True
;
836 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
837 return False
; /* Not finished - just out of space */
840 /* Setup the last_filename pointer, as an offset from base_data */
841 *last_name_off
= PTR_DIFF(nameptr
,base_data
);
842 /* Advance the data pointer to the next slot */
848 /****************************************************************************
849 Reply to a TRANS2_FINDFIRST.
850 ****************************************************************************/
852 static int call_trans2findfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int bufsize
,
853 char **pparams
, int total_params
, char **ppdata
, int total_data
)
855 /* We must be careful here that we don't return more than the
856 allowed number of data bytes. If this means returning fewer than
857 maxentries then so be it. We assume that the redirector has
858 enough room for the fixed number of parameter bytes it has
860 uint32 max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
861 char *params
= *pparams
;
862 char *pdata
= *ppdata
;
865 BOOL close_after_first
;
867 BOOL requires_resume_key
;
876 BOOL finished
= False
;
877 BOOL dont_descend
= False
;
878 BOOL out_of_space
= False
;
880 BOOL bad_path
= False
;
881 SMB_STRUCT_STAT sbuf
;
883 if (total_params
< 12)
884 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
886 *directory
= *mask
= 0;
888 dirtype
= SVAL(params
,0);
889 maxentries
= SVAL(params
,2);
890 close_after_first
= BITSETW(params
+4,0);
891 close_if_end
= BITSETW(params
+4,1);
892 requires_resume_key
= BITSETW(params
+4,2);
893 info_level
= SVAL(params
,6);
895 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
896 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
897 dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
898 info_level
, max_data_bytes
));
900 switch (info_level
) {
905 case SMB_FIND_FILE_DIRECTORY_INFO
:
906 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
907 case SMB_FIND_FILE_NAMES_INFO
:
908 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
910 case SMB_FIND_FILE_UNIX
:
911 if (!lp_unix_extensions())
912 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
915 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
918 pstrcpy(directory
, params
+ 12); /* Complete directory path with wildcard mask appended */
920 RESOLVE_FINDFIRST_DFSPATH(directory
, conn
, inbuf
, outbuf
);
922 DEBUG(5,("path=%s\n",directory
));
924 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
925 if(!check_name(directory
,conn
)) {
926 set_bad_path_error(errno
, bad_path
);
929 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
930 if((errno
== ENOTDIR
) && (Protocol
>= PROTOCOL_NT1
) && (get_remote_arch() == RA_WINNT
)) {
931 unix_ERR_class
= ERRDOS
;
932 unix_ERR_code
= ERRbaddirectory
;
936 return(UNIXERROR(ERRDOS
,ERRbadpath
));
939 p
= strrchr(directory
,'/');
941 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
942 if((directory
[0] == '.') && (directory
[1] == '\0'))
945 pstrcpy(mask
,directory
);
946 pstrcpy(directory
,"./");
952 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
954 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
956 return(ERROR_DOS(ERRDOS
,ERRnomem
));
958 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
960 /* Realloc the params space */
961 params
= Realloc(*pparams
, 10);
963 return ERROR_DOS(ERRDOS
,ERRnomem
);
966 dptr_num
= dptr_create(conn
,directory
, False
, True
,SVAL(inbuf
,smb_pid
));
968 return(UNIXERROR(ERRDOS
,ERRbadfile
));
970 /* Save the wildcard match and attribs we are using on this directory -
971 needed as lanman2 assumes these are being saved between calls */
973 if(!(wcard
= strdup(mask
))) {
974 dptr_close(&dptr_num
);
975 return ERROR_DOS(ERRDOS
,ERRnomem
);
978 dptr_set_wcard(dptr_num
, wcard
);
979 dptr_set_attr(dptr_num
, dirtype
);
981 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num
, wcard
, dirtype
));
983 /* We don't need to check for VOL here as this is returned by
984 a different TRANS2 call. */
986 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
988 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
992 space_remaining
= max_data_bytes
;
993 out_of_space
= False
;
995 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++) {
996 BOOL got_exact_match
= False
;
998 /* this is a heuristic to avoid seeking the dirptr except when
999 absolutely necessary. It allows for a filename of about 40 chars */
1001 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1002 out_of_space
= True
;
1005 finished
= !get_lanman2_dir_entry(conn
,mask
,dirtype
,info_level
,
1006 requires_resume_key
,dont_descend
,
1007 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1011 if (finished
&& out_of_space
)
1014 if (!finished
&& !out_of_space
)
1018 * As an optimisation if we know we aren't looking
1019 * for a wildcard name (ie. the name matches the wildcard exactly)
1020 * then we can finish on any (first) match.
1021 * This speeds up large directory searches. JRA.
1027 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1030 /* Check if we can close the dirptr */
1032 if(close_after_first
|| (finished
&& close_if_end
)) {
1033 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
1034 dptr_close(&dptr_num
);
1038 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1039 * from observation of NT.
1042 if(numentries
== 0) {
1043 dptr_close(&dptr_num
);
1044 return ERROR_DOS(ERRDOS
,ERRbadfile
);
1047 /* At this point pdata points to numentries directory entries. */
1049 /* Set up the return parameter block */
1050 SSVAL(params
,0,dptr_num
);
1051 SSVAL(params
,2,numentries
);
1052 SSVAL(params
,4,finished
);
1053 SSVAL(params
,6,0); /* Never an EA error */
1054 SSVAL(params
,8,last_name_off
);
1056 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
));
1058 if ((! *directory
) && dptr_path(dptr_num
))
1059 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1061 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1062 smb_fn_name(CVAL(inbuf
,smb_com
)),
1063 mask
, directory
, dirtype
, numentries
) );
1066 * Force a name mangle here to ensure that the
1067 * mask as an 8.3 name is top of the mangled cache.
1068 * The reasons for this are subtle. Don't remove
1069 * this code unless you know what you are doing
1070 * (see PR#13758). JRA.
1073 if(!mangle_is_8_3_wildcards( mask
, False
))
1074 mangle_map(mask
, True
, True
, SNUM(conn
));
1079 /****************************************************************************
1080 Reply to a TRANS2_FINDNEXT.
1081 ****************************************************************************/
1083 static int call_trans2findnext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1084 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1086 /* We must be careful here that we don't return more than the
1087 allowed number of data bytes. If this means returning fewer than
1088 maxentries then so be it. We assume that the redirector has
1089 enough room for the fixed number of parameter bytes it has
1091 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1092 char *params
= *pparams
;
1093 char *pdata
= *ppdata
;
1098 BOOL close_after_request
;
1100 BOOL requires_resume_key
;
1102 pstring resume_name
;
1108 int i
, last_name_off
=0;
1109 BOOL finished
= False
;
1110 BOOL dont_descend
= False
;
1111 BOOL out_of_space
= False
;
1112 int space_remaining
;
1114 if (total_params
< 12)
1115 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1117 dptr_num
= SVAL(params
,0);
1118 maxentries
= SVAL(params
,2);
1119 info_level
= SVAL(params
,4);
1120 resume_key
= IVAL(params
,6);
1121 close_after_request
= BITSETW(params
+10,0);
1122 close_if_end
= BITSETW(params
+10,1);
1123 requires_resume_key
= BITSETW(params
+10,2);
1124 continue_bit
= BITSETW(params
+10,3);
1126 *mask
= *directory
= *resume_name
= 0;
1128 pstrcpy( resume_name
, params
+12);
1130 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1131 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1132 resume_key = %d resume name = %s continue=%d level = %d\n",
1133 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
1134 requires_resume_key
, resume_key
, resume_name
, continue_bit
, info_level
));
1136 switch (info_level
) {
1141 case SMB_FIND_FILE_DIRECTORY_INFO
:
1142 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
1143 case SMB_FIND_FILE_NAMES_INFO
:
1144 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
1146 case SMB_FIND_FILE_UNIX
:
1147 if (!lp_unix_extensions())
1148 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
1151 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1154 pdata
= Realloc( *ppdata
, max_data_bytes
+ 1024);
1156 return ERROR_DOS(ERRDOS
,ERRnomem
);
1159 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1161 /* Realloc the params space */
1162 params
= Realloc(*pparams
, 6*SIZEOFWORD
);
1163 if( params
== NULL
)
1164 return ERROR_DOS(ERRDOS
,ERRnomem
);
1167 /* Check that the dptr is valid */
1168 if(!(conn
->dirptr
= dptr_fetch_lanman2(dptr_num
)))
1169 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1171 string_set(&conn
->dirpath
,dptr_path(dptr_num
));
1173 /* Get the wildcard mask from the dptr */
1174 if((p
= dptr_wcard(dptr_num
))== NULL
) {
1175 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
1176 return ERROR_DOS(ERRDOS
,ERRnofiles
);
1179 pstrcpy(directory
,conn
->dirpath
);
1181 /* Get the attr mask from the dptr */
1182 dirtype
= dptr_attr(dptr_num
);
1184 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1185 dptr_num
, mask
, dirtype
, (long)conn
->dirptr
, TellDir(conn
->dirptr
)));
1187 /* We don't need to check for VOL here as this is returned by
1188 a different TRANS2 call. */
1190 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn
->dirpath
,lp_dontdescend(SNUM(conn
))));
1191 if (in_list(conn
->dirpath
,lp_dontdescend(SNUM(conn
)),case_sensitive
))
1192 dont_descend
= True
;
1195 space_remaining
= max_data_bytes
;
1196 out_of_space
= False
;
1199 * Seek to the correct position. We no longer use the resume key but
1200 * depend on the last file name instead.
1203 if(requires_resume_key
&& *resume_name
&& !continue_bit
) {
1206 * Fix for NT redirector problem triggered by resume key indexes
1207 * changing between directory scans. We now return a resume key of 0
1208 * and instead look for the filename to continue from (also given
1209 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1210 * findfirst/findnext (as is usual) then the directory pointer
1211 * should already be at the correct place. Check this by scanning
1212 * backwards looking for an exact (ie. case sensitive) filename match.
1213 * If we get to the beginning of the directory and haven't found it then scan
1214 * forwards again looking for a match. JRA.
1217 int current_pos
, start_pos
;
1219 void *dirptr
= conn
->dirptr
;
1220 start_pos
= TellDir(dirptr
);
1222 for(current_pos
= start_pos
; current_pos
>= 0; current_pos
--) {
1223 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos
));
1225 SeekDir(dirptr
, current_pos
);
1226 dname
= ReadDirName(dirptr
);
1229 * Remember, name_map_mangle is called by
1230 * get_lanman2_dir_entry(), so the resume name
1231 * could be mangled. Ensure we do the same
1236 mangle_map( dname
, False
, True
, SNUM(conn
));
1238 if(dname
&& strcsequal( resume_name
, dname
)) {
1239 SeekDir(dirptr
, current_pos
+1);
1240 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1246 * Scan forward from start if not found going backwards.
1249 if(current_pos
< 0) {
1250 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos
));
1251 SeekDir(dirptr
, start_pos
);
1252 for(current_pos
= start_pos
; (dname
= ReadDirName(dirptr
)) != NULL
; SeekDir(dirptr
,++current_pos
)) {
1255 * Remember, name_map_mangle is called by
1256 * get_lanman2_dir_entry(), so the resume name
1257 * could be mangled. Ensure we do the same
1262 mangle_map( dname
, False
, True
, SNUM(conn
));
1264 if(dname
&& strcsequal( resume_name
, dname
)) {
1265 SeekDir(dirptr
, current_pos
+1);
1266 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos
+1 ));
1270 } /* end if current_pos */
1271 } /* end if requires_resume_key && !continue_bit */
1273 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++) {
1274 BOOL got_exact_match
= False
;
1276 /* this is a heuristic to avoid seeking the dirptr except when
1277 absolutely necessary. It allows for a filename of about 40 chars */
1279 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0) {
1280 out_of_space
= True
;
1283 finished
= !get_lanman2_dir_entry(conn
,mask
,dirtype
,info_level
,
1284 requires_resume_key
,dont_descend
,
1285 &p
,pdata
,space_remaining
, &out_of_space
, &got_exact_match
,
1289 if (finished
&& out_of_space
)
1292 if (!finished
&& !out_of_space
)
1296 * As an optimisation if we know we aren't looking
1297 * for a wildcard name (ie. the name matches the wildcard exactly)
1298 * then we can finish on any (first) match.
1299 * This speeds up large directory searches. JRA.
1305 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
1308 /* Check if we can close the dirptr */
1309 if(close_after_request
|| (finished
&& close_if_end
)) {
1310 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
1311 dptr_close(&dptr_num
); /* This frees up the saved mask */
1315 /* Set up the return parameter block */
1316 SSVAL(params
,0,numentries
);
1317 SSVAL(params
,2,finished
);
1318 SSVAL(params
,4,0); /* Never an EA error */
1319 SSVAL(params
,6,last_name_off
);
1321 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
1323 if ((! *directory
) && dptr_path(dptr_num
))
1324 slprintf(directory
,sizeof(directory
)-1, "(%s)",dptr_path(dptr_num
));
1326 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1327 smb_fn_name(CVAL(inbuf
,smb_com
)),
1328 mask
, directory
, dirtype
, numentries
) );
1333 /****************************************************************************
1334 Reply to a TRANS2_QFSINFO (query filesystem info).
1335 ****************************************************************************/
1337 static int call_trans2qfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1338 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1340 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1341 char *pdata
= *ppdata
;
1342 char *params
= *pparams
;
1346 char *vname
= volume_label(SNUM(conn
));
1347 int snum
= SNUM(conn
);
1348 char *fstype
= lp_fstype(SNUM(conn
));
1350 if (total_params
< 2)
1351 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1353 info_level
= SVAL(params
,0);
1354 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level
));
1356 if(vfs_stat(conn
,".",&st
)!=0) {
1357 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
1358 return ERROR_DOS(ERRSRV
,ERRinvdevice
);
1361 pdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
1362 if ( pdata
== NULL
)
1363 return ERROR_DOS(ERRDOS
,ERRnomem
);
1366 memset((char *)pdata
,'\0',max_data_bytes
+ 1024);
1368 switch (info_level
) {
1371 SMB_BIG_UINT dfree
,dsize
,bsize
;
1373 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1374 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
1375 SIVAL(pdata
,l1_cSectorUnit
,bsize
/512);
1376 SIVAL(pdata
,l1_cUnit
,dsize
);
1377 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
1378 SSVAL(pdata
,l1_cbSector
,512);
1379 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1380 (unsigned int)bsize
, (unsigned int)st
.st_dev
, ((unsigned int)bsize
)/512, (unsigned int)dsize
,
1381 (unsigned int)dfree
, 512));
1387 /* Return volume name */
1388 int volname_len
= MIN(strlen(vname
),11);
1389 data_len
= l2_vol_szVolLabel
+ volname_len
+ 1;
1391 * Add volume serial number - hash of a combination of
1392 * the called hostname and the service name.
1394 SIVAL(pdata
,0,str_checksum(lp_servicename(snum
)) ^ (str_checksum(local_machine
)<<16) );
1395 SCVAL(pdata
,l2_vol_cch
,volname_len
);
1396 StrnCpy(pdata
+l2_vol_szVolLabel
,vname
,volname_len
);
1397 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1398 (unsigned)st
.st_ctime
, volname_len
,
1399 pdata
+l2_vol_szVolLabel
));
1403 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
1404 case SMB_FS_ATTRIBUTE_INFORMATION
:
1407 SIVAL(pdata
,0,FILE_CASE_PRESERVED_NAMES
|FILE_CASE_SENSITIVE_SEARCH
|
1408 (lp_nt_acl_support(SNUM(conn
)) ? FILE_PERSISTENT_ACLS
: 0)); /* FS ATTRIBUTES */
1409 #if 0 /* Old code. JRA. */
1410 SIVAL(pdata
,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1411 SIVAL(pdata
,0,0x700FF);
1412 #endif /* Old code. */
1414 SIVAL(pdata
,4,255); /* Max filename component length */
1415 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1416 and will think we can't do long filenames */
1417 fstype_len
= dos_PutUniCode(pdata
+12,unix_to_dos_static(fstype
),sizeof(pstring
), False
);
1418 SIVAL(pdata
,8,fstype_len
);
1419 data_len
= 12 + fstype_len
;
1420 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1424 case SMB_QUERY_FS_LABEL_INFO
:
1425 case SMB_FS_LABEL_INFORMATION
:
1426 data_len
= 4 + strlen(vname
);
1427 SIVAL(pdata
,0,strlen(vname
));
1428 pstrcpy(pdata
+4,vname
);
1431 case SMB_QUERY_FS_VOLUME_INFO
:
1432 case SMB_FS_VOLUME_INFORMATION
:
1434 * Add volume serial number - hash of a combination of
1435 * the called hostname and the service name.
1437 SIVAL(pdata
,8,str_checksum(lp_servicename(snum
)) ^
1438 (str_checksum(local_machine
)<<16));
1440 /* NT4 always serves this up as unicode but expects it to be
1441 * delivered as ascii! (tridge && JRA)
1443 if ((get_remote_arch() != RA_WIN2K
) && (global_client_caps
& CAP_NT_SMBS
)) {
1444 data_len
= 18 + strlen(vname
);
1445 SIVAL(pdata
,12,strlen(vname
));
1446 pstrcpy(pdata
+18,vname
);
1450 vnamelen
= dos_PutUniCode(pdata
+18, vname
, sizeof(pstring
), False
);
1451 data_len
= 18 + vnamelen
;
1452 SIVAL(pdata
,12,vnamelen
);
1453 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1456 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1457 (int)strlen(vname
),vname
));
1460 case SMB_QUERY_FS_SIZE_INFO
:
1461 case SMB_FS_SIZE_INFORMATION
:
1463 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1465 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1466 block_size
= lp_block_size(snum
);
1467 if (bsize
< block_size
) {
1468 SMB_BIG_UINT factor
= block_size
/bsize
;
1473 if (bsize
> block_size
) {
1474 SMB_BIG_UINT factor
= bsize
/block_size
;
1479 bytes_per_sector
= 512;
1480 sectors_per_unit
= bsize
/bytes_per_sector
;
1481 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1482 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1483 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1484 SBIG_UINT(pdata
,0,dsize
);
1485 SBIG_UINT(pdata
,8,dfree
);
1486 SIVAL(pdata
,16,sectors_per_unit
);
1487 SIVAL(pdata
,20,bytes_per_sector
);
1491 case SMB_FS_FULL_SIZE_INFORMATION
:
1493 SMB_BIG_UINT dfree
,dsize
,bsize
,block_size
,sectors_per_unit
,bytes_per_sector
;
1495 conn
->vfs_ops
.disk_free(conn
,".",False
,&bsize
,&dfree
,&dsize
);
1496 block_size
= lp_block_size(snum
);
1497 if (bsize
< block_size
) {
1498 SMB_BIG_UINT factor
= block_size
/bsize
;
1503 if (bsize
> block_size
) {
1504 SMB_BIG_UINT factor
= bsize
/block_size
;
1509 bytes_per_sector
= 512;
1510 sectors_per_unit
= bsize
/bytes_per_sector
;
1511 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1512 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize
, (unsigned int)sectors_per_unit
,
1513 (unsigned int)bytes_per_sector
, (unsigned int)dsize
, (unsigned int)dfree
));
1514 SBIG_UINT(pdata
,0,dsize
); /* Total Allocation units. */
1515 SBIG_UINT(pdata
,8,dfree
); /* Caller available allocation units. */
1516 SBIG_UINT(pdata
,16,dfree
); /* Actual available allocation units. */
1517 SIVAL(pdata
,24,sectors_per_unit
); /* Sectors per allocation unit. */
1518 SIVAL(pdata
,28,bytes_per_sector
); /* Bytes per sector. */
1522 case SMB_QUERY_FS_DEVICE_INFO
:
1523 case SMB_FS_DEVICE_INFORMATION
:
1525 SIVAL(pdata
,0,0); /* dev type */
1526 SIVAL(pdata
,4,0); /* characteristics */
1529 case SMB_FS_OBJECTID_INFORMATION
:
1534 * Query the version and capabilities of the CIFS UNIX extensions
1538 case SMB_QUERY_CIFS_UNIX_INFO
:
1540 if (!lp_unix_extensions())
1541 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1544 SSVAL(pdata
,0,CIFS_UNIX_MAJOR_VERSION
);
1545 SSVAL(pdata
,2,CIFS_UNIX_MINOR_VERSION
);
1546 SBIG_UINT(pdata
,4,((SMB_BIG_UINT
)0)); /* No capabilities for now... */
1549 case SMB_MAC_QUERY_FS_INFO
:
1551 * Thursby MAC extension... ONLY on NTFS filesystems
1552 * once we do streams then we don't need this
1554 if (strequal(lp_fstype(SNUM(conn
)),"NTFS")) {
1556 SIVAL(pdata
,84,0x100); /* Don't support mac... */
1561 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1564 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
1566 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
) );
1571 /****************************************************************************
1572 Reply to a TRANS2_SETFSINFO (set filesystem info).
1573 ****************************************************************************/
1575 static int call_trans2setfsinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1576 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1578 /* Just say yes we did it - there is nothing that
1579 can be set here so it doesn't matter. */
1581 DEBUG(3,("call_trans2setfsinfo\n"));
1583 if (!CAN_WRITE(conn
))
1584 return(ERROR_DOS(ERRSRV
,ERRaccess
));
1586 outsize
= set_message(outbuf
,10,0,True
);
1591 /****************************************************************************
1592 Utility function to set bad path error.
1593 ****************************************************************************/
1595 NTSTATUS
set_bad_path_error(int err
, BOOL bad_path
)
1597 if((err
== ENOENT
) && bad_path
) {
1598 unix_ERR_class
= ERRDOS
;
1599 unix_ERR_code
= ERRbadpath
;
1600 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1602 return NT_STATUS_OK
;
1605 /****************************************************************************
1606 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1607 file name or file id).
1608 ****************************************************************************/
1610 static int call_trans2qfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
1611 char **pparams
, int total_params
, char **ppdata
, int total_data
)
1613 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
1614 char *params
= *pparams
;
1615 char *pdata
= *ppdata
;
1616 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
1620 SMB_BIG_UINT allocation_size
= 0;
1621 unsigned int data_size
;
1622 SMB_STRUCT_STAT sbuf
;
1630 BOOL bad_path
= False
;
1631 BOOL delete_pending
= False
;
1633 files_struct
*fsp
= NULL
;
1636 return ERROR_NT(NT_STATUS_INVALID_PARAMETER
);
1638 if (tran_call
== TRANSACT2_QFILEINFO
) {
1639 if (total_params
< 4)
1640 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1642 fsp
= file_fsp(params
,0);
1643 info_level
= SVAL(params
,2);
1645 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level
));
1647 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
1649 * This is actually a QFILEINFO on a directory
1650 * handle (returned from an NT SMB). NT5.0 seems
1651 * to do this call. JRA.
1653 fname
= fsp
->fsp_name
;
1654 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1655 if (!check_name(fname
,conn
)) {
1656 DEBUG(3,("call_trans2qfilepathinfo: check_name of %s failed (%s)\n",fname
,strerror(errno
)));
1657 set_bad_path_error(errno
, bad_path
);
1658 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1661 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1662 /* Always do lstat for UNIX calls. */
1663 if (vfs_lstat(conn
,fname
,&sbuf
)) {
1664 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname
,strerror(errno
)));
1665 set_bad_path_error(errno
, bad_path
);
1666 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1668 } else if (!VALID_STAT(sbuf
) && vfs_stat(conn
,fname
,&sbuf
)) {
1669 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname
,strerror(errno
)));
1670 set_bad_path_error(errno
, bad_path
);
1671 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1674 delete_pending
= fsp
->directory_delete_on_close
;
1678 * Original code - this is an open file.
1680 CHECK_FSP(fsp
,conn
);
1682 fname
= fsp
->fsp_name
;
1683 if (vfs_fstat(fsp
,fsp
->fd
,&sbuf
) != 0) {
1684 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
1685 return(UNIXERROR(ERRDOS
,ERRbadfid
));
1688 if((pos
= fsp
->conn
->vfs_ops
.lseek(fsp
,fsp
->fd
,0,SEEK_CUR
)) == -1)
1689 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
1691 delete_pending
= fsp
->delete_on_close
;
1695 if (total_params
< 6)
1696 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
1698 info_level
= SVAL(params
,0);
1700 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level
));
1703 pstrcpy(fname
,¶ms
[6]);
1705 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1707 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
1708 if (!check_name(fname
,conn
)) {
1709 DEBUG(3,("call_trans2qfilepathinfo: check_name of %s failed (%s)\n",fname
,strerror(errno
)));
1710 set_bad_path_error(errno
, bad_path
);
1711 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1713 if (INFO_LEVEL_IS_UNIX(info_level
)) {
1714 /* Always do lstat for UNIX calls. */
1715 if (vfs_lstat(conn
,fname
,&sbuf
)) {
1716 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname
,strerror(errno
)));
1717 set_bad_path_error(errno
, bad_path
);
1718 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1720 } else if (!VALID_STAT(sbuf
) && vfs_stat(conn
,fname
,&sbuf
)) {
1721 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname
,strerror(errno
)));
1722 set_bad_path_error(errno
, bad_path
);
1723 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1728 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
1729 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
1731 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1732 fname
,info_level
,tran_call
,total_data
));
1734 p
= strrchr(fname
,'/');
1740 mode
= dos_mode(conn
,fname
,&sbuf
);
1741 fullpathname
= fname
;
1742 size
= get_file_size(sbuf
);
1743 allocation_size
= get_allocation_size(fsp
,&sbuf
);
1747 /* from now on we only want the part after the / */
1750 params
= Realloc(*pparams
,2);
1751 if ( params
== NULL
)
1752 return ERROR_DOS(ERRDOS
,ERRnomem
);
1754 memset((char *)params
,'\0',2);
1755 data_size
= max_data_bytes
+ 1024;
1756 pdata
= Realloc(*ppdata
, data_size
);
1757 if ( pdata
== NULL
)
1758 return ERROR_DOS(ERRDOS
,ERRnomem
);
1761 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
1762 /* uggh, EAs for OS2 */
1763 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
1764 return ERROR_DOS(ERRDOS
,ERReasnotsupported
);
1767 memset((char *)pdata
,'\0',data_size
);
1769 c_time
= get_create_time(&sbuf
,lp_fake_dir_create_times(SNUM(conn
)));
1771 if (lp_dos_filetime_resolution(SNUM(conn
))) {
1773 sbuf
.st_atime
&= ~1;
1774 sbuf
.st_mtime
&= ~1;
1775 sbuf
.st_mtime
&= ~1;
1778 /* NT expects the name to be in an exact form */
1779 if (strequal(fname
,"."))
1780 pstrcpy(dos_fname
, "\\");
1782 snprintf(dos_fname
, sizeof(dos_fname
), "\\%s", fname
);
1783 string_replace( dos_fname
, '/','\\');
1786 switch (info_level
) {
1787 case SMB_INFO_STANDARD
:
1788 case SMB_INFO_QUERY_EA_SIZE
:
1789 data_size
= (info_level
==1?22:26);
1790 put_dos_date2(pdata
,l1_fdateCreation
,c_time
);
1791 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
1792 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
); /* write time */
1793 SIVAL(pdata
,l1_cbFile
,(uint32
)size
);
1794 SIVAL(pdata
,l1_cbFileAlloc
,(uint32
)allocation_size
);
1795 SSVAL(pdata
,l1_attrFile
,mode
);
1796 SIVAL(pdata
,l1_attrFile
+2,4); /* this is what OS2 does */
1799 case SMB_INFO_QUERY_EAS_FROM_LIST
:
1801 put_dos_date2(pdata
,0,c_time
);
1802 put_dos_date2(pdata
,4,sbuf
.st_atime
);
1803 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
1804 SIVAL(pdata
,12,(uint32
)size
);
1805 SIVAL(pdata
,16,(uint32
)allocation_size
);
1806 SIVAL(pdata
,20,mode
);
1809 case SMB_INFO_QUERY_ALL_EAS
:
1811 SIVAL(pdata
,0,data_size
);
1815 return ERROR_DOS(ERRDOS
,ERRbadfunc
); /* os/2 needs this */
1817 case SMB_FILE_BASIC_INFORMATION
:
1818 case SMB_QUERY_FILE_BASIC_INFO
:
1820 if (info_level
== SMB_QUERY_FILE_BASIC_INFO
)
1821 data_size
= 36; /* w95 returns 40 bytes not 36 - why ?. */
1826 put_long_date(pdata
,c_time
);
1827 put_long_date(pdata
+8,sbuf
.st_atime
);
1828 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1829 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1830 SIVAL(pdata
,32,mode
);
1832 DEBUG(5,("SMB_QFBI - "));
1835 time_t create_time
= c_time
;
1836 DEBUG(5,("create: %s ", ctime(&create_time
)));
1839 DEBUG(5,("access: %s ", ctime(&sbuf
.st_atime
)));
1840 DEBUG(5,("write: %s ", ctime(&sbuf
.st_mtime
)));
1841 DEBUG(5,("change: %s ", ctime(&sbuf
.st_mtime
)));
1842 DEBUG(5,("mode: %x\n", mode
));
1846 case SMB_FILE_STANDARD_INFORMATION
:
1847 case SMB_QUERY_FILE_STANDARD_INFO
:
1850 /* Fake up allocation size. */
1851 SOFF_T(pdata
,0,allocation_size
);
1852 SOFF_T(pdata
,8,size
);
1853 SIVAL(pdata
,16,sbuf
.st_nlink
);
1855 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
1858 case SMB_FILE_EA_INFORMATION
:
1859 case SMB_QUERY_FILE_EA_INFO
:
1864 /* Get the 8.3 name - used if NT SMB was negotiated. */
1866 case SMB_QUERY_FILE_ALT_NAME_INFO
:
1869 pstrcpy(short_name
,p
);
1870 /* Mangle if not already 8.3 */
1871 if(!mangle_is_8_3(short_name
, True
)) {
1872 mangle_map(short_name
,True
,True
,SNUM(conn
));
1874 strupper(short_name
);
1875 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1876 l
= dos_PutUniCode(pdata
+ 4, short_name
, sizeof(pstring
), False
);
1882 case SMB_QUERY_FILE_NAME_INFO
:
1884 * The first part of this code is essential
1885 * to get security descriptors to work on mapped
1886 * drives. Don't ask how I discovered this unless
1887 * you like hearing about me suffering.... :-). JRA.
1890 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1891 l
= dos_PutUniCode(pdata
+ 4, dos_fname
,sizeof(pstring
), False
);
1896 case SMB_FILE_ALLOCATION_INFORMATION
:
1897 case SMB_QUERY_FILE_ALLOCATION_INFO
:
1899 SOFF_T(pdata
,0,allocation_size
);
1902 case SMB_QUERY_FILE_END_OF_FILEINFO
:
1903 case SMB_FILE_END_OF_FILE_INFORMATION
:
1905 SOFF_T(pdata
,0,size
);
1908 case SMB_QUERY_FILE_ALL_INFO
:
1909 put_long_date(pdata
,c_time
);
1910 put_long_date(pdata
+8,sbuf
.st_atime
);
1911 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1912 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1913 SIVAL(pdata
,32,mode
);
1915 SOFF_T(pdata
,0,allocation_size
);
1916 SOFF_T(pdata
,8,size
);
1917 SIVAL(pdata
,16,sbuf
.st_nlink
);
1918 SCVAL(pdata
,20,delete_pending
);
1919 SCVAL(pdata
,21,(mode
&aDIR
)?1:0);
1921 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
);
1922 pdata
+= 8; /* index number */
1923 pdata
+= 4; /* EA info */
1925 SIVAL(pdata
,0,0xA9);
1927 SIVAL(pdata
,0,0xd01BF);
1929 SOFF_T(pdata
,0,pos
); /* current offset */
1931 SIVAL(pdata
,0,mode
); /* is this the right sort of mode info? */
1933 pdata
+= 4; /* alignment */
1935 pstrcpy(pdata
+4,dos_fname
);
1937 data_size
= PTR_DIFF(pdata
,(*ppdata
));
1940 case SMB_FILE_INTERNAL_INFORMATION
:
1941 /* This should be an index number - looks like dev/ino to me :-) */
1942 SIVAL(pdata
,0,sbuf
.st_dev
);
1943 SIVAL(pdata
,4,sbuf
.st_ino
);
1947 case SMB_FILE_ACCESS_INFORMATION
:
1948 SIVAL(pdata
,0,0x12019F); /* ??? */
1952 case SMB_FILE_NAME_INFORMATION
:
1953 /* Pathname with leading '\'. */
1957 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
1958 byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
1959 SIVAL(pdata
,0,byte_len
);
1960 data_size
= 4 + byte_len
;
1964 case SMB_FILE_DISPOSITION_INFORMATION
:
1966 SCVAL(pdata
,0,delete_pending
);
1969 case SMB_FILE_POSITION_INFORMATION
:
1971 SOFF_T(pdata
,0,pos
);
1974 case SMB_FILE_MODE_INFORMATION
:
1975 SIVAL(pdata
,0,mode
);
1979 case SMB_FILE_ALIGNMENT_INFORMATION
:
1980 SIVAL(pdata
,0,0); /* No alignment needed. */
1985 /* Not yet finished... JRA */
1990 put_long_date(pdata
,c_time
);
1991 put_long_date(pdata
+8,sbuf
.st_atime
);
1992 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
1993 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
1994 SIVAL(pdata
,32,mode
);
1995 SIVAL(pdata
,36,0); /* ??? */
1996 SIVAL(pdata
,40,0x20); /* ??? */
1997 SIVAL(pdata
,44,0); /* ??? */
1998 SOFF_T(pdata
,48,size
);
1999 SIVAL(pdata
,56,0x1); /* ??? */
2000 SIVAL(pdata
,60,0); /* ??? */
2001 SIVAL(pdata
,64,0); /* ??? */
2002 SIVAL(pdata
,68,length
); /* Following string length in bytes. */
2003 dos_PutUniCode(pdata
+72,,False
);
2008 case SMB_FILE_ALTERNATE_NAME_INFORMATION
:
2009 /* Last component of pathname. */
2011 size_t byte_len
= dos_PutUniCode(pdata
+4,dos_fname
,max_data_bytes
,False
);
2012 SIVAL(pdata
,0,byte_len
);
2013 data_size
= 4 + byte_len
;
2019 * NT4 server just returns "invalid query" to this - if we try to answer
2020 * it then NTws gets a BSOD! (tridge).
2021 * W2K seems to want this. JRA.
2023 case SMB_QUERY_FILE_STREAM_INFO
:
2025 case SMB_FILE_STREAM_INFORMATION
:
2029 size_t byte_len
= dos_PutUniCode(pdata
+24,"::$DATA", 14, False
);
2030 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
)|FLAGS2_UNICODE_STRINGS
);
2031 SIVAL(pdata
,0,0); /* Next stream (none). */
2032 SIVAL(pdata
,4,byte_len
); /* Byte length of unicode string ::$DATA */
2033 SOFF_T(pdata
,8,size
);
2034 SOFF_T(pdata
,16,allocation_size
);
2035 data_size
= 24 + byte_len
;
2039 case SMB_FILE_COMPRESSION_INFORMATION
:
2040 SOFF_T(pdata
,0,size
);
2041 SIVAL(pdata
,8,0); /* ??? */
2042 SIVAL(pdata
,12,0); /* ??? */
2046 case SMB_FILE_NETWORK_OPEN_INFORMATION
:
2047 put_long_date(pdata
,c_time
);
2048 put_long_date(pdata
+8,sbuf
.st_atime
);
2049 put_long_date(pdata
+16,sbuf
.st_mtime
); /* write time */
2050 put_long_date(pdata
+24,sbuf
.st_mtime
); /* change time */
2051 SOFF_T(pdata
,32,allocation_size
); /* Allocation size. */
2052 SOFF_T(pdata
,40,size
);
2053 SIVAL(pdata
,48,mode
);
2054 SIVAL(pdata
,52,0); /* ??? */
2058 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION
:
2059 SIVAL(pdata
,0,mode
);
2065 * CIFS UNIX Extensions.
2068 case SMB_QUERY_FILE_UNIX_BASIC
:
2070 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf
.st_mode
));
2072 SOFF_T(pdata
,0,get_file_size(sbuf
)); /* File size 64 Bit */
2075 SOFF_T(pdata
,0,get_allocation_size(fsp
,&sbuf
)); /* Number of bytes used on disk - 64 Bit */
2078 put_long_date(pdata
,sbuf
.st_ctime
); /* Creation Time 64 Bit */
2079 put_long_date(pdata
+8,sbuf
.st_atime
); /* Last access time 64 Bit */
2080 put_long_date(pdata
+16,sbuf
.st_mtime
); /* Last modification time 64 Bit */
2083 SIVAL(pdata
,0,sbuf
.st_uid
); /* user id for the owner */
2087 SIVAL(pdata
,0,sbuf
.st_gid
); /* group id of owner */
2091 SIVAL(pdata
,0,unix_filetype(sbuf
.st_mode
));
2094 SIVAL(pdata
,0,unix_dev_major(sbuf
.st_rdev
)); /* Major device number if type is device */
2098 SIVAL(pdata
,0,unix_dev_minor(sbuf
.st_rdev
)); /* Minor device number if type is device */
2102 SINO_T(pdata
,0,(SMB_INO_T
)sbuf
.st_ino
); /* inode number */
2105 SIVAL(pdata
,0, unix_perms_to_wire(sbuf
.st_mode
)); /* Standard UNIX file permissions */
2109 SIVAL(pdata
,0,sbuf
.st_nlink
); /* number of hard links */
2112 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2116 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2118 for (i
=0; i
<100; i
++)
2119 DEBUG(4,("%d=%x, ",i
, (*ppdata
)[i
]));
2125 case SMB_QUERY_FILE_UNIX_LINK
:
2131 if(!S_ISLNK(sbuf
.st_mode
))
2132 return(UNIXERROR(ERRSRV
,ERRbadlink
));
2134 return(UNIXERROR(ERRDOS
,ERRbadlink
));
2136 len
= conn
->vfs_ops
.readlink(conn
,dos_to_unix_static(fullpathname
), buffer
, sizeof(pstring
)-1); /* read link */
2138 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2140 unix_to_dos(buffer
);
2141 pstrcpy(pdata
,buffer
); /* write '\0' terminated string */
2142 pdata
+= strlen(buffer
)+1;
2143 data_size
= PTR_DIFF(pdata
,(*ppdata
));
2149 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2152 send_trans2_replies( outbuf
, bufsize
, params
, 2, *ppdata
, data_size
);
2157 /****************************************************************************
2158 Deal with the internal needs of setting the delete on close flag. Note that
2159 as the tdb locking is recursive, it is safe to call this from within
2160 open_file_shared. JRA.
2161 ****************************************************************************/
2163 NTSTATUS
set_delete_on_close_internal(files_struct
*fsp
, BOOL delete_on_close
)
2166 * Only allow delete on close for writable shares.
2169 if (delete_on_close
&& !CAN_WRITE(fsp
->conn
)) {
2170 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2172 return NT_STATUS_ACCESS_DENIED
;
2175 * Only allow delete on close for files/directories opened with delete intent.
2178 if (delete_on_close
&& !(fsp
->desired_access
& DELETE_ACCESS
)) {
2179 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2181 return NT_STATUS_ACCESS_DENIED
;
2184 if(fsp
->is_directory
) {
2185 fsp
->directory_delete_on_close
= delete_on_close
;
2186 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2187 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2189 fsp
->delete_on_close
= delete_on_close
;
2190 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2191 delete_on_close
? "Added" : "Removed", fsp
->fnum
, fsp
->fsp_name
));
2194 return NT_STATUS_OK
;
2197 /****************************************************************************
2198 Sets the delete on close flag over all share modes on this file.
2199 Modify the share mode entry for all files open
2200 on this device and inode to tell other smbds we have
2201 changed the delete on close flag. This will be noticed
2202 in the close code, the last closer will delete the file
2204 ****************************************************************************/
2206 NTSTATUS
set_delete_on_close_over_all(files_struct
*fsp
, BOOL delete_on_close
)
2208 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2209 delete_on_close
? "Adding" : "Removing", fsp
->fnum
, fsp
->fsp_name
));
2211 if (lock_share_entry_fsp(fsp
) == False
)
2212 return NT_STATUS_ACCESS_DENIED
;
2214 if (!modify_delete_flag(fsp
->dev
, fsp
->inode
, delete_on_close
)) {
2215 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2217 unlock_share_entry_fsp(fsp
);
2218 return NT_STATUS_ACCESS_DENIED
;
2221 unlock_share_entry_fsp(fsp
);
2222 return NT_STATUS_OK
;
2225 /****************************************************************************
2226 Returns true if this pathname is within the share, and thus safe.
2227 ****************************************************************************/
2229 static int ensure_link_is_safe(connection_struct
*conn
, const char *link_dest_in
, char *link_dest_out
)
2232 char resolved_name
[PATH_MAX
+1];
2234 pstring resolved_name
;
2236 fstring last_component
;
2240 BOOL bad_path
= False
;
2241 SMB_STRUCT_STAT sbuf
;
2243 pstrcpy(link_dest
, link_dest_in
);
2244 unix_convert(link_dest
,conn
,0,&bad_path
,&sbuf
);
2246 /* Store the UNIX converted path. */
2247 pstrcpy(link_dest_out
, link_dest
);
2249 p
= strrchr(link_dest
, '/');
2251 fstrcpy(last_component
, p
+1);
2254 fstrcpy(last_component
, link_dest
);
2255 pstrcpy(link_dest
, "./");
2258 if (conn
->vfs_ops
.realpath(conn
,dos_to_unix_static(link_dest
),resolved_name
) == NULL
)
2261 pstrcpy(link_dest
, unix_to_dos_static(resolved_name
));
2262 pstrcat(link_dest
, "/");
2263 pstrcat(link_dest
, last_component
);
2265 if (*link_dest
!= '/') {
2266 /* Relative path. */
2267 pstrcpy(link_test
, conn
->connectpath
);
2268 pstrcat(link_test
, "/");
2269 pstrcat(link_test
, link_dest
);
2271 pstrcpy(link_test
, link_dest
);
2275 * Check if the link is within the share.
2278 if (strncmp(conn
->connectpath
, link_test
, strlen(conn
->connectpath
))) {
2285 /****************************************************************************
2286 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2287 ****************************************************************************/
2289 static int call_trans2setfilepathinfo(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2290 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2292 char *params
= *pparams
;
2293 char *pdata
= *ppdata
;
2294 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
2299 SMB_STRUCT_STAT sbuf
;
2303 BOOL bad_path
= False
;
2304 files_struct
*fsp
= NULL
;
2305 uid_t set_owner
= (uid_t
)SMB_UID_NO_CHANGE
;
2306 gid_t set_grp
= (uid_t
)SMB_GID_NO_CHANGE
;
2307 mode_t unixmode
= 0;
2309 if (tran_call
== TRANSACT2_SETFILEINFO
) {
2311 if (total_params
< 4)
2312 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2314 fsp
= file_fsp(params
,0);
2315 info_level
= SVAL(params
,2);
2317 if(fsp
&& (fsp
->is_directory
|| fsp
->fd
== -1)) {
2319 * This is actually a SETFILEINFO on a directory
2320 * handle (returned from an NT SMB). NT5.0 seems
2321 * to do this call. JRA.
2323 fname
= fsp
->fsp_name
;
2324 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2325 if (!check_name(fname
,conn
) || (!VALID_STAT(sbuf
))) {
2326 DEBUG(3,("fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
2327 set_bad_path_error(errno
, bad_path
);
2328 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2330 } else if (fsp
&& fsp
->print_file
) {
2332 * Doing a DELETE_ON_CLOSE should cancel a print job.
2334 if (((info_level
== SMB_SET_FILE_DISPOSITION_INFO
)||(info_level
== SMB_FILE_DISPOSITION_INFORMATION
)) &&
2336 fsp
->share_mode
= FILE_DELETE_ON_CLOSE
;
2338 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
2342 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2345 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2348 * Original code - this is an open file.
2350 CHECK_FSP(fsp
,conn
);
2352 fname
= fsp
->fsp_name
;
2355 if (vfs_fstat(fsp
,fd
,&sbuf
) != 0) {
2356 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
2357 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2362 if (total_params
< 6)
2363 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2365 info_level
= SVAL(params
,0);
2367 pstrcpy(fname
,¶ms
[6]);
2368 unix_convert(fname
,conn
,0,&bad_path
,&sbuf
);
2369 if(!check_name(fname
, conn
)) {
2370 set_bad_path_error(errno
, bad_path
);
2371 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2375 * For CIFS UNIX extensions the target name may not exist.
2378 if(!VALID_STAT(sbuf
) && !INFO_LEVEL_IS_UNIX(info_level
)) {
2380 DEBUG(3,("stat of %s failed (%s)\n", fname
, strerror(errno
)));
2381 set_bad_path_error(errno
, bad_path
);
2382 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2386 if (!CAN_WRITE(conn
))
2387 return ERROR_DOS(ERRSRV
,ERRaccess
);
2389 if (INFO_LEVEL_IS_UNIX(info_level
) && !lp_unix_extensions())
2390 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2392 if (VALID_STAT(sbuf
))
2393 unixmode
= sbuf
.st_mode
;
2395 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2396 tran_call
,fname
,info_level
,total_data
));
2398 /* Realloc the parameter and data sizes */
2399 params
= Realloc(*pparams
,2);
2401 return ERROR_DOS(ERRDOS
,ERRnomem
);
2407 /* the pending modtime overrides the current modtime */
2408 sbuf
.st_mtime
= fsp
->pending_modtime
;
2411 size
= get_file_size(sbuf
);
2412 tvs
.modtime
= sbuf
.st_mtime
;
2413 tvs
.actime
= sbuf
.st_atime
;
2414 dosmode
= dos_mode(conn
,fname
,&sbuf
);
2415 unixmode
= sbuf
.st_mode
;
2417 set_owner
= VALID_STAT(sbuf
) ? sbuf
.st_uid
: (uid_t
)SMB_UID_NO_CHANGE
;
2418 set_grp
= VALID_STAT(sbuf
) ? sbuf
.st_gid
: (gid_t
)SMB_GID_NO_CHANGE
;
2420 switch (info_level
) {
2421 case SMB_INFO_STANDARD
:
2423 if (total_data
< l1_cbFile
+4)
2424 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2427 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
2430 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
2432 dosmode
= SVAL(pdata
,l1_attrFile
);
2433 size
= IVAL(pdata
,l1_cbFile
);
2437 case SMB_INFO_SET_EA
:
2438 return(ERROR_DOS(ERRDOS
,ERReasnotsupported
));
2440 /* XXXX um, i don't think this is right.
2441 it's also not in the cifs6.txt spec.
2443 case SMB_INFO_QUERY_EAS_FROM_LIST
:
2444 if (total_data
< 28)
2445 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2447 tvs
.actime
= make_unix_date2(pdata
+8);
2448 tvs
.modtime
= make_unix_date2(pdata
+12);
2449 size
= IVAL(pdata
,16);
2450 dosmode
= IVAL(pdata
,24);
2453 /* XXXX nor this. not in cifs6.txt, either. */
2454 case SMB_INFO_QUERY_ALL_EAS
:
2455 if (total_data
< 28)
2456 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2458 tvs
.actime
= make_unix_date2(pdata
+8);
2459 tvs
.modtime
= make_unix_date2(pdata
+12);
2460 size
= IVAL(pdata
,16);
2461 dosmode
= IVAL(pdata
,24);
2464 case SMB_SET_FILE_BASIC_INFO
:
2465 case SMB_FILE_BASIC_INFORMATION
:
2467 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2469 time_t changed_time
;
2471 if (total_data
< 36)
2472 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2474 /* Ignore create time at offset pdata. */
2477 tvs
.actime
= interpret_long_date(pdata
+8);
2479 write_time
= interpret_long_date(pdata
+16);
2480 changed_time
= interpret_long_date(pdata
+24);
2482 tvs
.modtime
= MIN(write_time
, changed_time
);
2484 if (write_time
> tvs
.modtime
&& write_time
!= 0xffffffff) {
2485 tvs
.modtime
= write_time
;
2488 /* Prefer a defined time to an undefined one. */
2489 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
2490 tvs
.modtime
= (write_time
== (time_t)0 || write_time
== (time_t)-1
2495 dosmode
= IVAL(pdata
,32);
2499 case SMB_FILE_ALLOCATION_INFORMATION
:
2500 case SMB_SET_FILE_ALLOCATION_INFO
:
2503 SMB_BIG_UINT allocation_size
;
2506 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2508 allocation_size
= (SMB_BIG_UINT
)IVAL(pdata
,0);
2509 #ifdef LARGE_SMB_OFF_T
2510 allocation_size
|= (((SMB_BIG_UINT
)IVAL(pdata
,4)) << 32);
2511 #else /* LARGE_SMB_OFF_T */
2512 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2513 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2514 #endif /* LARGE_SMB_OFF_T */
2515 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2516 fname
, (double)allocation_size
));
2518 if (allocation_size
)
2519 allocation_size
= SMB_ROUNDUP(allocation_size
,SMB_ROUNDUP_ALLOCATION_SIZE
);
2521 if(allocation_size
!= get_file_size(sbuf
)) {
2522 SMB_STRUCT_STAT new_sbuf
;
2524 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2525 fname
, (double)allocation_size
));
2528 files_struct
*new_fsp
= NULL
;
2529 int access_mode
= 0;
2532 if(global_oplock_break
) {
2533 /* Queue this file modify as we are the process of an oplock break. */
2535 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2536 DEBUGADD(2,( "in oplock break state.\n"));
2538 push_oplock_pending_smb_message(inbuf
, length
);
2542 new_fsp
= open_file_shared1(conn
, fname
, &sbuf
,FILE_WRITE_DATA
,
2543 SET_OPEN_MODE(DOS_OPEN_RDWR
),
2544 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
2545 0, 0, &access_mode
, &action
);
2547 if (new_fsp
== NULL
)
2548 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2549 ret
= vfs_allocate_file_space(new_fsp
, allocation_size
);
2550 if (vfs_fstat(new_fsp
,new_fsp
->fd
,&new_sbuf
) != 0) {
2551 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp
->fnum
, strerror(errno
)));
2554 close_file(new_fsp
,True
);
2556 ret
= vfs_allocate_file_space(fsp
, allocation_size
);
2557 if (vfs_fstat(fsp
,fd
,&new_sbuf
) != 0) {
2558 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp
->fnum
, strerror(errno
)));
2563 return ERROR_NT(NT_STATUS_DISK_FULL
);
2565 /* Allocate can trucate size... */
2566 size
= get_file_size(new_sbuf
);
2572 case SMB_FILE_END_OF_FILE_INFORMATION
:
2573 case SMB_SET_FILE_END_OF_FILE_INFO
:
2576 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2578 size
= IVAL(pdata
,0);
2579 #ifdef LARGE_SMB_OFF_T
2580 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2581 #else /* LARGE_SMB_OFF_T */
2582 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2583 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2584 #endif /* LARGE_SMB_OFF_T */
2585 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname
, (double)size
));
2589 case SMB_FILE_DISPOSITION_INFORMATION
:
2590 case SMB_SET_FILE_DISPOSITION_INFO
: /* Set delete on close for open file. */
2592 BOOL delete_on_close
;
2596 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2598 delete_on_close
= (CVAL(pdata
,0) ? True
: False
);
2600 if (tran_call
!= TRANSACT2_SETFILEINFO
)
2601 return(ERROR_DOS(ERRDOS
,ERRunknownlevel
));
2604 return(UNIXERROR(ERRDOS
,ERRbadfid
));
2606 status
= set_delete_on_close_internal(fsp
, delete_on_close
);
2607 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
2608 return ERROR_NT(status
);
2610 /* The set is across all open files on this dev/inode pair. */
2611 status
=set_delete_on_close_over_all(fsp
, delete_on_close
);
2612 if (NT_STATUS_V(status
) != NT_STATUS_V(NT_STATUS_OK
))
2613 return ERROR_NT(status
);
2619 * CIFS UNIX extensions.
2622 case SMB_SET_FILE_UNIX_BASIC
:
2624 uint32 raw_unixmode
;
2626 if (total_data
< 100)
2627 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2629 if(IVAL(pdata
, 0) != SMB_SIZE_NO_CHANGE_LO
&&
2630 IVAL(pdata
, 4) != SMB_SIZE_NO_CHANGE_HI
) {
2631 size
=IVAL(pdata
,0); /* first 8 Bytes are size */
2632 #ifdef LARGE_SMB_OFF_T
2633 size
|= (((SMB_OFF_T
)IVAL(pdata
,4)) << 32);
2634 #else /* LARGE_SMB_OFF_T */
2635 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
2636 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2637 #endif /* LARGE_SMB_OFF_T */
2639 pdata
+=24; /* ctime & st_blocks are not changed */
2640 tvs
.actime
= interpret_long_unix_date(pdata
); /* access_time */
2641 tvs
.modtime
= interpret_long_unix_date(pdata
+8); /* modification_time */
2643 set_owner
= (uid_t
)IVAL(pdata
,0);
2645 set_grp
= (gid_t
)IVAL(pdata
,0);
2647 raw_unixmode
= IVAL(pdata
,28);
2648 unixmode
= unix_perms_from_wire(conn
, &sbuf
, raw_unixmode
);
2649 dosmode
= 0; /* Ensure dos mode change doesn't override this. */
2651 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2652 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2653 fname
, (double)size
, (unsigned int)set_owner
, (unsigned int)set_grp
, (int)raw_unixmode
));
2655 if (!VALID_STAT(sbuf
)) {
2658 * The only valid use of this is to create character and block
2659 * devices, and named pipes. This is deprecated (IMHO) and
2660 * a new info level should be used for mknod. JRA.
2663 #if !defined(HAVE_MAKEDEV_FN)
2664 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2665 #else /* HAVE_MAKEDEV_FN */
2666 uint32 file_type
= IVAL(pdata
,0);
2667 uint32 dev_major
= IVAL(pdata
,4);
2668 uint32 dev_minor
= IVAL(pdata
,12);
2670 uid_t myuid
= geteuid();
2671 gid_t mygid
= getegid();
2674 if (tran_call
== TRANSACT2_SETFILEINFO
)
2675 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2677 if (raw_unixmode
== SMB_MODE_NO_CHANGE
)
2678 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2680 dev
= makedev(dev_major
, dev_minor
);
2682 /* We can only create as the owner/group we are. */
2684 if ((set_owner
!= myuid
) && (set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
))
2685 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2686 if ((set_grp
!= mygid
) && (set_grp
!= (gid_t
)SMB_GID_NO_CHANGE
))
2687 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2689 if (file_type
!= UNIX_TYPE_CHARDEV
&& file_type
!= UNIX_TYPE_BLKDEV
&&
2690 file_type
!= UNIX_TYPE_FIFO
)
2691 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2693 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2694 0%o for file %s\n", (double)dev
, unixmode
, fname
));
2696 /* Ok - do the mknod. */
2697 if (conn
->vfs_ops
.mknod(conn
,dos_to_unix_static(fname
), unixmode
, dev
) != 0)
2698 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2701 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2703 #endif /* HAVE_MAKEDEV_FN */
2708 * Deal with the UNIX specific mode set.
2711 if (raw_unixmode
!= SMB_MODE_NO_CHANGE
) {
2712 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
2713 (unsigned int)unixmode
, fname
));
2714 if (vfs_chmod(conn
,fname
,unixmode
) != 0)
2715 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2719 * Deal with the UNIX specific uid set.
2722 if ((set_owner
!= (uid_t
)SMB_UID_NO_CHANGE
) && (sbuf
.st_uid
!= set_owner
)) {
2723 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
2724 (unsigned int)set_owner
, fname
));
2725 if (vfs_chown(conn
,fname
,set_owner
, (gid_t
)-1) != 0)
2726 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2730 * Deal with the UNIX specific gid set.
2733 if ((set_grp
!= (uid_t
)SMB_GID_NO_CHANGE
) && (sbuf
.st_gid
!= set_grp
)) {
2734 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
2735 (unsigned int)set_owner
, fname
));
2736 if (vfs_chown(conn
,fname
,(uid_t
)-1, set_grp
) != 0)
2737 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2742 case SMB_SET_FILE_UNIX_LINK
:
2745 /* Set a symbolic link. */
2746 /* Don't allow this if follow links is false. */
2748 if (!lp_symlinks(SNUM(conn
)))
2749 return(ERROR_DOS(ERRDOS
,ERRnoaccess
));
2751 /* Disallow if already exists. */
2752 if (VALID_STAT(sbuf
))
2753 return(ERROR_DOS(ERRDOS
,ERRbadpath
));
2755 pstrcpy(link_dest
, pdata
);
2757 if (ensure_link_is_safe(conn
, link_dest
, link_dest
) != 0)
2758 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2759 dos_to_unix(link_dest
);
2762 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
2763 fname
, link_dest
));
2765 if (conn
->vfs_ops
.symlink(conn
,link_dest
,fname
) != 0)
2766 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2768 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2772 case SMB_SET_FILE_UNIX_HLINK
:
2776 /* Set a hard link. */
2778 /* Disallow if already exists. */
2779 if (VALID_STAT(sbuf
))
2780 return(ERROR_DOS(ERRDOS
,ERRbadpath
));
2782 pstrcpy(link_dest
, pdata
);
2784 if (ensure_link_is_safe(conn
, link_dest
, link_dest
) != 0)
2785 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2787 dos_to_unix(link_dest
);
2790 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
2791 fname
, link_dest
));
2793 if (conn
->vfs_ops
.link(conn
,link_dest
,fname
) != 0)
2794 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2796 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2801 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2804 /* get some defaults (no modifications) if any info is zero or -1. */
2805 if (tvs
.actime
== (time_t)0 || tvs
.actime
== (time_t)-1)
2806 tvs
.actime
= sbuf
.st_atime
;
2808 if (tvs
.modtime
== (time_t)0 || tvs
.modtime
== (time_t)-1)
2809 tvs
.modtime
= sbuf
.st_mtime
;
2811 DEBUG(6,("actime: %s " , ctime(&tvs
.actime
)));
2812 DEBUG(6,("modtime: %s ", ctime(&tvs
.modtime
)));
2813 DEBUG(6,("size: %.0f ", (double)size
));
2814 if (S_ISDIR(sbuf
.st_mode
))
2819 DEBUG(6,("dosmode: %x\n" , dosmode
));
2821 if(!((info_level
== SMB_SET_FILE_END_OF_FILE_INFO
) ||
2822 (info_level
== SMB_SET_FILE_ALLOCATION_INFO
) ||
2823 (info_level
== SMB_FILE_ALLOCATION_INFORMATION
) ||
2824 (info_level
== SMB_FILE_END_OF_FILE_INFORMATION
))) {
2826 * Only do this test if we are not explicitly
2827 * changing the size of a file.
2830 size
= get_file_size(sbuf
);
2834 * Try and set the times, size and mode of this file -
2835 * if they are different from the current values
2838 if (sbuf
.st_mtime
!= tvs
.modtime
|| sbuf
.st_atime
!= tvs
.actime
) {
2841 * This was a setfileinfo on an open file.
2842 * NT does this a lot. It's actually pointless
2843 * setting the time here, as it will be overwritten
2844 * on the next write, so we save the request
2845 * away and will set it on file close. JRA.
2848 if (tvs
.modtime
!= (time_t)0 && tvs
.modtime
!= (time_t)-1) {
2849 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2850 ctime(&tvs
.modtime
) ));
2851 fsp
->pending_modtime
= tvs
.modtime
;
2856 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2858 if(file_utime(conn
, fname
, &tvs
)!=0)
2859 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2863 /* check the mode isn't different, before changing it */
2864 if ((dosmode
!= 0) && (dosmode
!= dos_mode(conn
, fname
, &sbuf
))) {
2866 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2869 if(file_chmod(conn
, fname
, dosmode
, NULL
)) {
2870 DEBUG(2,("chmod of %s failed (%s)\n", fname
, strerror(errno
)));
2871 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2875 if(size
!= get_file_size(sbuf
)) {
2879 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2880 fname
, (double)size
));
2883 files_struct
*new_fsp
= NULL
;
2884 int access_mode
= 0;
2887 if(global_oplock_break
) {
2888 /* Queue this file modify as we are the process of an oplock break. */
2890 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2891 DEBUGADD(2,( "in oplock break state.\n"));
2893 push_oplock_pending_smb_message(inbuf
, length
);
2897 new_fsp
= open_file_shared(conn
, fname
, &sbuf
,
2898 SET_OPEN_MODE(DOS_OPEN_RDWR
),
2899 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
2900 0, 0, &access_mode
, &action
);
2902 if (new_fsp
== NULL
)
2903 return(UNIXERROR(ERRDOS
,ERRbadpath
));
2904 ret
= vfs_set_filelen(new_fsp
, size
);
2905 close_file(new_fsp
,True
);
2907 ret
= vfs_set_filelen(fsp
, size
);
2911 return (UNIXERROR(ERRHRD
,ERRdiskfull
));
2915 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2919 /****************************************************************************
2920 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2921 ****************************************************************************/
2923 static int call_trans2mkdir(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2924 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2926 char *params
= *pparams
;
2929 SMB_STRUCT_STAT sbuf
;
2930 BOOL bad_path
= False
;
2932 if (!CAN_WRITE(conn
))
2933 return ERROR_DOS(ERRSRV
,ERRaccess
);
2935 if (total_params
< 4)
2936 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2938 pstrcpy(directory
, ¶ms
[4]);
2940 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
2942 unix_convert(directory
,conn
,0,&bad_path
,&sbuf
);
2943 if (check_name(directory
,conn
))
2944 ret
= vfs_mkdir(conn
,directory
,unix_mode(conn
,aDIR
,directory
));
2947 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno
)));
2948 set_bad_path_error(errno
, bad_path
);
2949 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
2952 /* Realloc the parameter and data sizes */
2953 params
= Realloc(*pparams
,2);
2955 return ERROR_DOS(ERRDOS
,ERRnomem
);
2960 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
2965 /****************************************************************************
2966 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2967 We don't actually do this - we just send a null response.
2968 ****************************************************************************/
2970 static int call_trans2findnotifyfirst(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
2971 char **pparams
, int total_params
, char **ppdata
, int total_data
)
2973 static uint16 fnf_handle
= 257;
2974 char *params
= *pparams
;
2977 if (total_params
< 6)
2978 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
2980 info_level
= SVAL(params
,4);
2981 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
2983 switch (info_level
) {
2988 return ERROR_DOS(ERRDOS
,ERRunknownlevel
);
2991 /* Realloc the parameter and data sizes */
2992 params
= Realloc(*pparams
,6);
2994 return ERROR_DOS(ERRDOS
,ERRnomem
);
2997 SSVAL(params
,0,fnf_handle
);
2998 SSVAL(params
,2,0); /* No changes */
2999 SSVAL(params
,4,0); /* No EA errors */
3006 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0);
3011 /****************************************************************************
3012 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3013 changes). Currently this does nothing.
3014 ****************************************************************************/
3016 static int call_trans2findnotifynext(connection_struct
*conn
, char *inbuf
, char *outbuf
, int length
, int bufsize
,
3017 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3019 char *params
= *pparams
;
3021 DEBUG(3,("call_trans2findnotifynext\n"));
3023 /* Realloc the parameter and data sizes */
3024 params
= Realloc(*pparams
,4);
3026 return ERROR_DOS(ERRDOS
,ERRnomem
);
3029 SSVAL(params
,0,0); /* No changes */
3030 SSVAL(params
,2,0); /* No EA errors */
3032 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0);
3037 /****************************************************************************
3038 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3039 ****************************************************************************/
3041 static int call_trans2getdfsreferral(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
3042 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3044 char *params
= *pparams
;
3045 enum remote_arch_types ra_type
= get_remote_arch();
3046 BOOL NT_arch
= ((ra_type
== RA_WINNT
) || (ra_type
== RA_WIN2K
));
3049 int max_referral_level
;
3051 DEBUG(10,("call_trans2getdfsreferral\n"));
3053 if (total_params
< 2)
3054 return(ERROR_DOS(ERRDOS
,ERRinvalidparam
));
3056 max_referral_level
= SVAL(params
,0);
3058 if(!lp_host_msdfs())
3059 return ERROR_DOS(ERRDOS
,ERRbadfunc
);
3061 /* if pathname is in UNICODE, convert to DOS */
3062 /* NT always sends in UNICODE, may not set UNICODE flag */
3063 if(NT_arch
|| (SVAL(inbuf
,smb_flg2
) & FLAGS2_UNICODE_STRINGS
)) {
3064 unistr_to_dos(pathname
, ¶ms
[2], sizeof(pathname
));
3065 DEBUG(10,("UNICODE referral for %s\n",pathname
));
3067 pstrcpy(pathname
,¶ms
[2]);
3069 if((reply_size
= setup_dfs_referral(pathname
,max_referral_level
,ppdata
)) < 0)
3070 return ERROR_DOS(ERRDOS
,ERRbadfile
);
3072 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_UNICODE_STRINGS
| FLAGS2_DFS_PATHNAMES
);
3073 send_trans2_replies(outbuf
,bufsize
,0,0,*ppdata
,reply_size
);
3078 #define LMCAT_SPL 0x53
3079 #define LMFUNC_GETJOBID 0x60
3081 /****************************************************************************
3082 reply to a TRANS2_IOCTL - used for OS/2 printing.
3083 ****************************************************************************/
3085 static int call_trans2ioctl(connection_struct
*conn
, char* inbuf
, char* outbuf
, int length
, int bufsize
,
3086 char **pparams
, int total_params
, char **ppdata
, int total_data
)
3088 char *pdata
= *ppdata
;
3089 files_struct
*fsp
= file_fsp(inbuf
,smb_vwv15
);
3091 if ((SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3092 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3093 pdata
= Realloc(*ppdata
, 32);
3095 return ERROR_DOS(ERRDOS
,ERRnomem
);
3098 SSVAL(pdata
,0,fsp
->print_jobid
); /* Job number */
3099 StrnCpy(pdata
+2, global_myname
, 15); /* Our NetBIOS name */
3100 StrnCpy(pdata
+18, lp_servicename(SNUM(conn
)), 13); /* Service name */
3101 send_trans2_replies(outbuf
,bufsize
,*pparams
,0,*ppdata
,32);
3104 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3105 return ERROR_DOS(ERRSRV
,ERRerror
);
3109 /****************************************************************************
3110 Reply to a SMBfindclose (stop trans2 directory search).
3111 ****************************************************************************/
3113 int reply_findclose(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3116 int dptr_num
=SVALS(inbuf
,smb_vwv0
);
3117 START_PROFILE(SMBfindclose
);
3119 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num
));
3121 dptr_close(&dptr_num
);
3123 outsize
= set_message(outbuf
,0,0,True
);
3125 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num
));
3127 END_PROFILE(SMBfindclose
);
3131 /****************************************************************************
3132 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3133 ****************************************************************************/
3135 int reply_findnclose(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3139 START_PROFILE(SMBfindnclose
);
3141 dptr_num
= SVAL(inbuf
,smb_vwv0
);
3143 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num
));
3145 /* We never give out valid handles for a
3146 findnotifyfirst - so any dptr_num is ok here.
3149 outsize
= set_message(outbuf
,0,0,True
);
3151 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num
));
3153 END_PROFILE(SMBfindnclose
);
3157 /****************************************************************************
3158 Reply to a SMBtranss2 - just ignore it!
3159 ****************************************************************************/
3161 int reply_transs2(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3163 START_PROFILE(SMBtranss2
);
3164 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
3165 END_PROFILE(SMBtranss2
);
3169 /****************************************************************************
3170 Reply to a SMBtrans2.
3171 ****************************************************************************/
3173 int reply_trans2(connection_struct
*conn
, char *inbuf
,char *outbuf
,int length
,int bufsize
)
3176 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
3177 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
3179 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
3180 unsigned int max_data_reply
= SVAL(inbuf
, smb_mdrcnt
);
3181 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
3182 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
3183 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
3184 int32 timeout
= IVALS(inbuf
,smb_timeout
);
3186 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
3187 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
3188 char *params
= NULL
, *data
= NULL
;
3189 int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
3190 START_PROFILE(SMBtrans2
);
3192 if(global_oplock_break
&& (tran_call
== TRANSACT2_OPEN
)) {
3193 /* Queue this open message as we are the process of an
3196 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3197 DEBUGADD(2,( "in oplock break state.\n"));
3199 push_oplock_pending_smb_message(inbuf
, length
);
3200 END_PROFILE(SMBtrans2
);
3204 if (IS_IPC(conn
) && (tran_call
!= TRANSACT2_OPEN
)
3205 && (tran_call
!= TRANSACT2_GET_DFS_REFERRAL
)) {
3206 END_PROFILE(SMBtrans2
);
3207 return ERROR_DOS(ERRSRV
,ERRaccess
);
3210 outsize
= set_message(outbuf
,0,0,True
);
3212 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3213 is so as a sanity check */
3216 * Need to have rc=0 for ioctl to get job id for OS/2.
3217 * Network printing will fail if function is not successful.
3218 * Similar function in reply.c will be used if protocol
3219 * is LANMAN1.0 instead of LM1.2X002.
3220 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3221 * outbuf doesn't have to be set(only job id is used).
3223 if ( (suwcnt
== 4) && (tran_call
== TRANSACT2_IOCTL
) &&
3224 (SVAL(inbuf
,(smb_setup
+4)) == LMCAT_SPL
) &&
3225 (SVAL(inbuf
,(smb_setup
+6)) == LMFUNC_GETJOBID
)) {
3226 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3228 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt
));
3229 DEBUG(2,("Transaction is %d\n",tran_call
));
3230 END_PROFILE(SMBtrans2
);
3231 return ERROR_DOS(ERRSRV
,ERRerror
);
3235 /* Allocate the space for the maximum needed parameters and data */
3236 if (total_params
> 0)
3237 params
= (char *)malloc(total_params
);
3239 data
= (char *)malloc(total_data
);
3241 if ((total_params
&& !params
) || (total_data
&& !data
)) {
3242 DEBUG(2,("Out of memory in reply_trans2\n"));
3245 END_PROFILE(SMBtrans2
);
3246 return ERROR_DOS(ERRDOS
,ERRnomem
);
3249 /* Copy the param and data bytes sent with this request into
3250 the params buffer */
3251 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
3252 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
3254 if (num_params
> total_params
|| num_data
> total_data
)
3255 exit_server("invalid params in reply_trans2");
3258 memcpy( params
, smb_base(inbuf
) + SVAL(inbuf
, smb_psoff
), num_params
);
3260 memcpy( data
, smb_base(inbuf
) + SVAL(inbuf
, smb_dsoff
), num_data
);
3262 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
) {
3263 /* We need to send an interim response then receive the rest
3264 of the parameter/data bytes */
3265 outsize
= set_message(outbuf
,0,0,True
);
3266 if (!send_smb(smbd_server_fd(),outbuf
))
3267 exit_server("reply_trans2: send_smb failed.");
3269 while (num_data_sofar
< total_data
||
3270 num_params_sofar
< total_params
) {
3273 ret
= receive_next_smb(inbuf
,bufsize
,SMB_SECONDARY_WAIT
);
3276 (CVAL(inbuf
, smb_com
) != SMBtranss2
)) || !ret
) {
3277 outsize
= set_message(outbuf
,0,0,True
);
3279 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3281 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3282 (smb_read_error
== READ_ERROR
) ? "error" : "timeout" ));
3285 END_PROFILE(SMBtrans2
);
3286 return ERROR_DOS(ERRSRV
,ERRerror
);
3289 /* Revise total_params and total_data in case
3290 they have changed downwards */
3291 total_params
= SVAL(inbuf
, smb_tpscnt
);
3292 total_data
= SVAL(inbuf
, smb_tdscnt
);
3293 num_params_sofar
+= (num_params
= SVAL(inbuf
,smb_spscnt
));
3294 num_data_sofar
+= ( num_data
= SVAL(inbuf
, smb_sdscnt
));
3295 if (num_params_sofar
> total_params
|| num_data_sofar
> total_data
)
3296 exit_server("data overflow in trans2");
3298 memcpy( ¶ms
[ SVAL(inbuf
, smb_spsdisp
)],
3299 smb_base(inbuf
) + SVAL(inbuf
, smb_spsoff
), num_params
);
3300 memcpy( &data
[SVAL(inbuf
, smb_sdsdisp
)],
3301 smb_base(inbuf
)+ SVAL(inbuf
, smb_sdsoff
), num_data
);
3305 if (Protocol
>= PROTOCOL_NT1
)
3306 SSVAL(outbuf
,smb_flg2
,SVAL(outbuf
,smb_flg2
) | FLAGS2_IS_LONG_NAME
);
3308 /* Now we must call the relevant TRANS2 function */
3310 case TRANSACT2_OPEN
:
3311 START_PROFILE_NESTED(Trans2_open
);
3312 outsize
= call_trans2open(conn
, inbuf
, outbuf
, bufsize
,
3313 ¶ms
, total_params
, &data
, total_data
);
3314 END_PROFILE_NESTED(Trans2_open
);
3317 case TRANSACT2_FINDFIRST
:
3318 START_PROFILE_NESTED(Trans2_findfirst
);
3319 outsize
= call_trans2findfirst(conn
, inbuf
, outbuf
, bufsize
,
3320 ¶ms
, total_params
, &data
, total_data
);
3321 END_PROFILE_NESTED(Trans2_findfirst
);
3324 case TRANSACT2_FINDNEXT
:
3325 START_PROFILE_NESTED(Trans2_findnext
);
3326 outsize
= call_trans2findnext(conn
, inbuf
, outbuf
, length
, bufsize
,
3327 ¶ms
, total_params
, &data
, total_data
);
3328 END_PROFILE_NESTED(Trans2_findnext
);
3331 case TRANSACT2_QFSINFO
:
3332 START_PROFILE_NESTED(Trans2_qfsinfo
);
3333 outsize
= call_trans2qfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3334 ¶ms
, total_params
, &data
, total_data
);
3335 END_PROFILE_NESTED(Trans2_qfsinfo
);
3338 case TRANSACT2_SETFSINFO
:
3339 START_PROFILE_NESTED(Trans2_setfsinfo
);
3340 outsize
= call_trans2setfsinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3341 ¶ms
, total_params
, &data
, total_data
);
3342 END_PROFILE_NESTED(Trans2_setfsinfo
);
3345 case TRANSACT2_QPATHINFO
:
3346 case TRANSACT2_QFILEINFO
:
3347 START_PROFILE_NESTED(Trans2_qpathinfo
);
3348 outsize
= call_trans2qfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3349 ¶ms
, total_params
, &data
, total_data
);
3350 END_PROFILE_NESTED(Trans2_qpathinfo
);
3352 case TRANSACT2_SETPATHINFO
:
3353 case TRANSACT2_SETFILEINFO
:
3354 START_PROFILE_NESTED(Trans2_setpathinfo
);
3355 outsize
= call_trans2setfilepathinfo(conn
, inbuf
, outbuf
, length
, bufsize
,
3356 ¶ms
, total_params
, &data
, total_data
);
3357 END_PROFILE_NESTED(Trans2_setpathinfo
);
3360 case TRANSACT2_FINDNOTIFYFIRST
:
3361 START_PROFILE_NESTED(Trans2_findnotifyfirst
);
3362 outsize
= call_trans2findnotifyfirst(conn
, inbuf
, outbuf
, length
, bufsize
,
3363 ¶ms
, total_params
, &data
, total_data
);
3364 END_PROFILE_NESTED(Trans2_findnotifyfirst
);
3367 case TRANSACT2_FINDNOTIFYNEXT
:
3368 START_PROFILE_NESTED(Trans2_findnotifynext
);
3369 outsize
= call_trans2findnotifynext(conn
, inbuf
, outbuf
, length
, bufsize
,
3370 ¶ms
, total_params
, &data
, total_data
);
3371 END_PROFILE_NESTED(Trans2_findnotifynext
);
3373 case TRANSACT2_MKDIR
:
3374 START_PROFILE_NESTED(Trans2_mkdir
);
3375 outsize
= call_trans2mkdir(conn
, inbuf
, outbuf
, length
, bufsize
,
3376 ¶ms
, total_params
, &data
, total_data
);
3377 END_PROFILE_NESTED(Trans2_mkdir
);
3380 case TRANSACT2_GET_DFS_REFERRAL
:
3381 START_PROFILE_NESTED(Trans2_get_dfs_referral
);
3382 outsize
= call_trans2getdfsreferral(conn
,inbuf
,outbuf
,length
, bufsize
,
3383 ¶ms
, total_params
, &data
, total_data
);
3384 END_PROFILE_NESTED(Trans2_get_dfs_referral
);
3386 case TRANSACT2_IOCTL
:
3387 START_PROFILE_NESTED(Trans2_ioctl
);
3388 outsize
= call_trans2ioctl(conn
,inbuf
,outbuf
,length
, bufsize
,
3389 ¶ms
, total_params
, &data
, total_data
);
3390 END_PROFILE_NESTED(Trans2_ioctl
);
3393 /* Error in request */
3394 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call
));
3397 END_PROFILE(SMBtrans2
);
3398 return ERROR_DOS(ERRSRV
,ERRerror
);
3401 /* As we do not know how many data packets will need to be
3402 returned here the various call_trans2xxxx calls
3403 must send their own. Thus a call_trans2xxx routine only
3404 returns a value other than -1 when it wants to send
3410 END_PROFILE(SMBtrans2
);
3411 return outsize
; /* If a correct response was needed the
3412 call_trans2xxx calls have already sent
3413 it. If outsize != -1 then it is returning */