2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2001
5 Copyright (C) Stefan (metze) Metzmacher 2003
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern BOOL case_sensitive;
28 extern int smb_read_error;
29 extern fstring local_machine;
30 extern int global_oplock_break;
31 extern uint32 global_client_caps;
32 extern struct current_user current_user;
34 #define get_file_size(sbuf) ((sbuf).st_size)
36 /* given a stat buffer return the allocated size on disk, taking into
37 account sparse files */
38 SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
41 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
42 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
44 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
46 if (!ret && fsp && fsp->initial_allocation_size)
47 ret = fsp->initial_allocation_size;
48 ret = SMB_ROUNDUP(ret,SMB_ROUNDUP_ALLOCATION_SIZE);
52 /****************************************************************************
53 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,
66 /* As we are using a protocol > LANMAN1 then the max_send
67 variable must have been set in the sessetupX call.
68 This takes precedence over the max_xmit field in the
69 global struct. These different max_xmit variables should
70 be merged as this is now too confusing */
73 int data_to_send = datasize;
74 int params_to_send = paramsize;
78 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
79 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
80 int data_alignment_offset = 0;
82 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
84 set_message(outbuf,10,0,True);
86 /* If there genuinely are no parameters or data to send just send the empty packet */
88 if(params_to_send == 0 && data_to_send == 0) {
89 if (!send_smb(smbd_server_fd(),outbuf))
90 exit_server("send_trans2_replies: send_smb failed.");
94 /* When sending params and data ensure that both are nicely aligned */
95 /* Only do this alignment when there is also data to send - else
96 can cause NT redirector problems. */
98 if (((params_to_send % 4) != 0) && (data_to_send != 0))
99 data_alignment_offset = 4 - (params_to_send % 4);
101 /* Space is bufsize minus Netbios over TCP header minus SMB header */
102 /* The alignment_offset is to align the param bytes on an even byte
103 boundary. NT 4.0 Beta needs this to work correctly. */
105 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
107 /* useable_space can never be more than max_send minus the alignment offset. */
109 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
111 while (params_to_send || data_to_send) {
112 /* Calculate whether we will totally or partially fill this packet */
114 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
116 /* We can never send more than useable_space */
118 * Note that 'useable_space' does not include the alignment offsets,
119 * but we must include the alignment offsets in the calculation of
120 * the length of the data we send over the wire, as the alignment offsets
121 * are sent here. Fix from Marc_Jacobsen@hp.com.
124 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
126 set_message(outbuf, 10, total_sent_thistime, True);
128 /* Set total params and data to be sent */
129 SSVAL(outbuf,smb_tprcnt,paramsize);
130 SSVAL(outbuf,smb_tdrcnt,datasize);
132 /* Calculate how many parameters and data we can fit into
133 * this packet. Parameters get precedence
136 params_sent_thistime = MIN(params_to_send,useable_space);
137 data_sent_thistime = useable_space - params_sent_thistime;
138 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
140 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
142 /* smb_proff is the offset from the start of the SMB header to the
143 parameter bytes, however the first 4 bytes of outbuf are
144 the Netbios over TCP header. Thus use smb_base() to subtract
145 them from the calculation */
147 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
149 if(params_sent_thistime == 0)
150 SSVAL(outbuf,smb_prdisp,0);
152 /* Absolute displacement of param bytes sent in this packet */
153 SSVAL(outbuf,smb_prdisp,pp - params);
155 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
156 if(data_sent_thistime == 0) {
157 SSVAL(outbuf,smb_droff,0);
158 SSVAL(outbuf,smb_drdisp, 0);
160 /* The offset of the data bytes is the offset of the
161 parameter bytes plus the number of parameters being sent this time */
162 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
163 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
164 SSVAL(outbuf,smb_drdisp, pd - pdata);
167 /* Copy the param bytes into the packet */
169 if(params_sent_thistime)
170 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
172 /* Copy in the data bytes */
173 if(data_sent_thistime)
174 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
175 data_alignment_offset,pd,data_sent_thistime);
177 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
178 params_sent_thistime, data_sent_thistime, useable_space));
179 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
180 params_to_send, data_to_send, paramsize, datasize));
182 /* Send the packet */
183 if (!send_smb(smbd_server_fd(),outbuf))
184 exit_server("send_trans2_replies: send_smb failed.");
186 pp += params_sent_thistime;
187 pd += data_sent_thistime;
189 params_to_send -= params_sent_thistime;
190 data_to_send -= data_sent_thistime;
193 if(params_to_send < 0 || data_to_send < 0) {
194 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
195 params_to_send, data_to_send));
203 /****************************************************************************
204 Reply to a TRANSACT2_OPEN.
205 ****************************************************************************/
207 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
208 char **pparams, int total_params, char **ppdata, int total_data)
210 char *params = *pparams;
215 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);
251 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
253 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
254 fname,open_mode, open_attr, open_ofun, open_size));
257 return(ERROR_DOS(ERRSRV,ERRaccess));
259 /* XXXX we need to handle passed times, sattr and flags */
261 unix_convert(fname,conn,0,&bad_path,&sbuf);
263 if (!check_name(fname,conn)) {
264 set_bad_path_error(errno, bad_path);
265 return(UNIXERROR(ERRDOS,ERRnoaccess));
268 unixmode = unix_mode(conn,open_attr | aARCH, fname);
270 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
271 oplock_request, &rmode,&smb_action);
274 set_bad_path_error(errno, bad_path);
275 return(UNIXERROR(ERRDOS,ERRnoaccess));
278 size = get_file_size(sbuf);
279 fmode = dos_mode(conn,fname,&sbuf);
280 mtime = sbuf.st_mtime;
283 close_file(fsp,False);
284 return(ERROR_DOS(ERRDOS,ERRnoaccess));
287 /* Realloc the size of parameters and data we will return */
288 params = Realloc(*pparams, 28);
290 return(ERROR_DOS(ERRDOS,ERRnomem));
293 memset((char *)params,'\0',28);
294 SSVAL(params,0,fsp->fnum);
295 SSVAL(params,2,fmode);
296 put_dos_date2(params,4, mtime);
297 SIVAL(params,8, (uint32)size);
298 SSVAL(params,12,rmode);
300 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
301 smb_action |= EXTENDED_OPLOCK_GRANTED;
303 SSVAL(params,18,smb_action);
306 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
308 SIVAL(params,20,inode);
310 /* Send the required number of replies */
311 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
316 /*********************************************************
317 Routine to check if a given string matches exactly.
318 as a special case a mask of "." does NOT match. That
319 is required for correct wildcard semantics
320 Case can be significant or not.
321 **********************************************************/
323 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
325 if (mask[0] == '.' && mask[1] == 0)
328 return strcmp(str,mask)==0;
329 if (StrCaseCmp(str,mask) != 0) {
332 if (ms_has_wild(str)) {
338 /****************************************************************************
339 Return the filetype for UNIX extensions.
340 ****************************************************************************/
342 static uint32 unix_filetype(mode_t mode)
345 return UNIX_TYPE_FILE;
346 else if(S_ISDIR(mode))
347 return UNIX_TYPE_DIR;
349 else if(S_ISLNK(mode))
350 return UNIX_TYPE_SYMLINK;
353 else if(S_ISCHR(mode))
354 return UNIX_TYPE_CHARDEV;
357 else if(S_ISBLK(mode))
358 return UNIX_TYPE_BLKDEV;
361 else if(S_ISFIFO(mode))
362 return UNIX_TYPE_FIFO;
365 else if(S_ISSOCK(mode))
366 return UNIX_TYPE_SOCKET;
369 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
370 return UNIX_TYPE_UNKNOWN;
373 /****************************************************************************
374 Return the major devicenumber for UNIX extensions.
375 ****************************************************************************/
377 static uint32 unix_dev_major(SMB_DEV_T dev)
379 #if defined(HAVE_DEVICE_MAJOR_FN)
380 return (uint32)major(dev);
382 return (uint32)(dev >> 8);
386 /****************************************************************************
387 Return the minor devicenumber for UNIX extensions.
388 ****************************************************************************/
390 static uint32 unix_dev_minor(SMB_DEV_T dev)
392 #if defined(HAVE_DEVICE_MINOR_FN)
393 return (uint32)minor(dev);
395 return (uint32)(dev & 0xff);
399 /****************************************************************************
400 Map wire perms onto standard UNIX permissions. Obey share restrictions.
401 ****************************************************************************/
403 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
407 if (perms == SMB_MODE_NO_CHANGE)
410 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
411 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
412 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
413 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
414 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
415 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
416 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
417 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
418 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
420 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
423 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
426 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
429 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
430 ret &= lp_dir_mask(SNUM(conn));
431 /* Add in force bits */
432 ret |= lp_force_dir_mode(SNUM(conn));
434 /* Apply mode mask */
435 ret &= lp_create_mask(SNUM(conn));
436 /* Add in force bits */
437 ret |= lp_force_create_mode(SNUM(conn));
443 /****************************************************************************
444 checks for SMB_TIME_NO_CHANGE and if not found
445 calls interpret_long_date
446 ****************************************************************************/
447 time_t interpret_long_unix_date(char *p)
449 DEBUG(1,("interpret_long_unix_date\n"));
450 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
451 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
454 return interpret_long_date(p);
458 /****************************************************************************
459 Get a level dependent lanman2 dir entry.
460 ****************************************************************************/
462 static BOOL get_lanman2_dir_entry(connection_struct *conn,
463 void *inbuf, void *outbuf,
464 char *path_mask,int dirtype,int info_level,
465 int requires_resume_key,
466 BOOL dont_descend,char **ppdata,
467 char *base_data, int space_remaining,
468 BOOL *out_of_space, BOOL *got_exact_match,
473 SMB_STRUCT_STAT sbuf;
477 char *p, *q, *pdata = *ppdata;
481 SMB_OFF_T file_size = 0;
482 SMB_BIG_UINT allocation_size = 0;
484 time_t mdate=0, adate=0, cdate=0;
487 int nt_extmode; /* Used for NT connections instead of mode */
488 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
491 *out_of_space = False;
492 *got_exact_match = False;
497 p = strrchr_m(path_mask,'/');
504 pstrcpy(mask, path_mask);
509 /* Needed if we run out of space */
510 prev_dirpos = TellDir(conn->dirptr);
511 dname = ReadDirName(conn->dirptr);
514 * Due to bugs in NT client redirectors we are not using
515 * resume keys any more - set them to zero.
516 * Check out the related comments in findfirst/findnext.
522 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
523 (long)conn->dirptr,TellDir(conn->dirptr)));
528 pstrcpy(fname,dname);
530 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
531 got_match = mask_match(fname, mask, case_sensitive);
533 if(!got_match && !mangle_is_8_3(fname, False)) {
536 * It turns out that NT matches wildcards against
537 * both long *and* short names. This may explain some
538 * of the wildcard wierdness from old DOS clients
539 * that some people have been seeing.... JRA.
543 pstrcpy( newname, fname);
544 mangle_map( newname, True, False, SNUM(conn));
545 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
546 got_match = mask_match(newname, mask, case_sensitive);
550 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
551 if (dont_descend && !isdots)
554 pstrcpy(pathreal,conn->dirpath);
556 pstrcat(pathreal,"/");
557 pstrcat(pathreal,dname);
559 if (INFO_LEVEL_IS_UNIX(info_level)) {
560 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
561 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
562 pathreal,strerror(errno)));
565 } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
567 /* Needed to show the msdfs symlinks as
570 if(lp_host_msdfs() &&
571 lp_msdfs_root(SNUM(conn)) &&
572 is_msdfs_link(conn, pathreal, NULL, NULL,
575 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
576 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
580 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
581 pathreal,strerror(errno)));
586 mode = dos_mode(conn,pathreal,&sbuf);
588 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
589 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
593 file_size = get_file_size(sbuf);
594 allocation_size = get_allocation_size(NULL,&sbuf);
595 mdate = sbuf.st_mtime;
596 adate = sbuf.st_atime;
597 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
599 if (lp_dos_filetime_resolution(SNUM(conn))) {
608 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
614 mangle_map(fname,False,True,SNUM(conn));
619 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
621 switch (info_level) {
622 case SMB_INFO_STANDARD:
623 if(requires_resume_key) {
627 put_dos_date2(p,l1_fdateCreation,cdate);
628 put_dos_date2(p,l1_fdateLastAccess,adate);
629 put_dos_date2(p,l1_fdateLastWrite,mdate);
630 SIVAL(p,l1_cbFile,(uint32)file_size);
631 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
632 SSVAL(p,l1_attrFile,mode);
635 p += align_string(outbuf, p, 0);
636 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
637 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
638 SCVAL(nameptr, -1, len-2);
640 SCVAL(nameptr, -1, len-1);
644 case SMB_INFO_QUERY_EA_SIZE:
645 if(requires_resume_key) {
649 put_dos_date2(p,l2_fdateCreation,cdate);
650 put_dos_date2(p,l2_fdateLastAccess,adate);
651 put_dos_date2(p,l2_fdateLastWrite,mdate);
652 SIVAL(p,l2_cbFile,(uint32)file_size);
653 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
654 SSVAL(p,l2_attrFile,mode);
655 SIVAL(p,l2_cbList,0); /* No extended attributes */
658 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
659 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
660 SCVAL(nameptr, -1, len-2);
662 SCVAL(nameptr, -1, len-1);
666 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
667 was_8_3 = mangle_is_8_3(fname, True);
669 SIVAL(p,0,reskey); p += 4;
670 put_long_date(p,cdate); p += 8;
671 put_long_date(p,adate); p += 8;
672 put_long_date(p,mdate); p += 8;
673 put_long_date(p,mdate); p += 8;
674 SOFF_T(p,0,file_size);
675 SOFF_T(p,8,allocation_size);
677 SIVAL(p,0,nt_extmode); p += 4;
679 SIVAL(p,0,0); p += 4;
680 /* Clear the short name buffer. This is
681 * IMPORTANT as not doing so will trigger
682 * a Win2k client bug. JRA.
686 pstring mangled_name;
687 pstrcpy(mangled_name, fname);
688 mangle_map(mangled_name,True,True,SNUM(conn));
689 mangled_name[12] = 0;
690 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
697 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
700 len = PTR_DIFF(p, pdata);
701 len = (len + 3) & ~3;
706 case SMB_FIND_FILE_DIRECTORY_INFO:
708 SIVAL(p,0,reskey); p += 4;
709 put_long_date(p,cdate); p += 8;
710 put_long_date(p,adate); p += 8;
711 put_long_date(p,mdate); p += 8;
712 put_long_date(p,mdate); p += 8;
713 SOFF_T(p,0,file_size);
714 SOFF_T(p,8,allocation_size);
716 SIVAL(p,0,nt_extmode); p += 4;
718 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
721 len = PTR_DIFF(p, pdata);
722 len = (len + 3) & ~3;
727 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
729 SIVAL(p,0,reskey); p += 4;
730 put_long_date(p,cdate); p += 8;
731 put_long_date(p,adate); p += 8;
732 put_long_date(p,mdate); p += 8;
733 put_long_date(p,mdate); p += 8;
734 SOFF_T(p,0,file_size);
735 SOFF_T(p,8,allocation_size);
737 SIVAL(p,0,nt_extmode);
740 SIVAL(p,4,0); /* ea size */
741 len = srvstr_push(outbuf, p+8, fname, -1, STR_TERMINATE_ASCII);
745 len = PTR_DIFF(p, pdata);
746 len = (len + 3) & ~3;
751 case SMB_FIND_FILE_NAMES_INFO:
753 SIVAL(p,0,reskey); p += 4;
755 /* this must *not* be null terminated or w2k gets in a loop trying to set an
756 acl on a dir (tridge) */
757 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
760 len = PTR_DIFF(p, pdata);
761 len = (len + 3) & ~3;
766 /* CIFS UNIX Extension. */
768 case SMB_FIND_FILE_UNIX:
770 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
772 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
773 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
776 SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
779 put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
780 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
781 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
784 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
788 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
792 SIVAL(p,0,unix_filetype(sbuf.st_mode));
795 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
799 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
803 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
806 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
810 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
814 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
817 len = PTR_DIFF(p, pdata);
818 len = (len + 3) & ~3;
819 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
821 /* End of SMB_QUERY_FILE_UNIX_BASIC */
830 if (PTR_DIFF(p,pdata) > space_remaining) {
831 /* Move the dirptr back to prev_dirpos */
832 SeekDir(conn->dirptr, prev_dirpos);
833 *out_of_space = True;
834 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
835 return False; /* Not finished - just out of space */
838 /* Setup the last_filename pointer, as an offset from base_data */
839 *last_name_off = PTR_DIFF(nameptr,base_data);
840 /* Advance the data pointer to the next slot */
846 /****************************************************************************
847 Reply to a TRANS2_FINDFIRST.
848 ****************************************************************************/
850 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
851 char **pparams, int total_params, char **ppdata, int total_data)
853 /* We must be careful here that we don't return more than the
854 allowed number of data bytes. If this means returning fewer than
855 maxentries then so be it. We assume that the redirector has
856 enough room for the fixed number of parameter bytes it has
858 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
859 char *params = *pparams;
860 char *pdata = *ppdata;
861 int dirtype = SVAL(params,0);
862 int maxentries = SVAL(params,2);
863 BOOL close_after_first = BITSETW(params+4,0);
864 BOOL close_if_end = BITSETW(params+4,1);
865 BOOL requires_resume_key = BITSETW(params+4,2);
866 int info_level = SVAL(params,6);
874 BOOL finished = False;
875 BOOL dont_descend = False;
876 BOOL out_of_space = False;
878 BOOL bad_path = False;
879 SMB_STRUCT_STAT sbuf;
881 if (total_params < 12)
882 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
884 *directory = *mask = 0;
886 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
887 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
888 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
889 info_level, max_data_bytes));
891 switch (info_level) {
892 case SMB_INFO_STANDARD:
893 case SMB_INFO_QUERY_EA_SIZE:
894 case SMB_FIND_FILE_DIRECTORY_INFO:
895 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
896 case SMB_FIND_FILE_NAMES_INFO:
897 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
899 case SMB_FIND_FILE_UNIX:
900 if (!lp_unix_extensions())
901 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
904 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
907 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
909 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
911 unix_convert(directory,conn,0,&bad_path,&sbuf);
912 if(!check_name(directory,conn)) {
913 set_bad_path_error(errno, bad_path);
914 return(UNIXERROR(ERRDOS,ERRbadpath));
917 p = strrchr_m(directory,'/');
919 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
920 if((directory[0] == '.') && (directory[1] == '\0'))
923 pstrcpy(mask,directory);
924 pstrcpy(directory,"./");
930 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
932 pdata = Realloc(*ppdata, max_data_bytes + 1024);
934 return(ERROR_DOS(ERRDOS,ERRnomem));
937 memset((char *)pdata,'\0',max_data_bytes + 1024);
939 /* Realloc the params space */
940 params = Realloc(*pparams, 10);
942 return ERROR_DOS(ERRDOS,ERRnomem);
945 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
947 return(UNIXERROR(ERRDOS,ERRbadfile));
949 /* Save the wildcard match and attribs we are using on this directory -
950 needed as lanman2 assumes these are being saved between calls */
952 if(!(wcard = strdup(mask))) {
953 dptr_close(&dptr_num);
954 return ERROR_DOS(ERRDOS,ERRnomem);
957 dptr_set_wcard(dptr_num, wcard);
958 dptr_set_attr(dptr_num, dirtype);
960 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
962 /* We don't need to check for VOL here as this is returned by
963 a different TRANS2 call. */
965 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
966 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
970 space_remaining = max_data_bytes;
971 out_of_space = False;
973 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
974 BOOL got_exact_match = False;
976 /* this is a heuristic to avoid seeking the dirptr except when
977 absolutely necessary. It allows for a filename of about 40 chars */
978 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
982 finished = !get_lanman2_dir_entry(conn,
984 mask,dirtype,info_level,
985 requires_resume_key,dont_descend,
986 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
990 if (finished && out_of_space)
993 if (!finished && !out_of_space)
997 * As an optimisation if we know we aren't looking
998 * for a wildcard name (ie. the name matches the wildcard exactly)
999 * then we can finish on any (first) match.
1000 * This speeds up large directory searches. JRA.
1006 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1009 /* Check if we can close the dirptr */
1010 if(close_after_first || (finished && close_if_end)) {
1011 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1012 dptr_close(&dptr_num);
1016 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1017 * from observation of NT.
1020 if(numentries == 0) {
1021 dptr_close(&dptr_num);
1022 return ERROR_DOS(ERRDOS,ERRbadfile);
1025 /* At this point pdata points to numentries directory entries. */
1027 /* Set up the return parameter block */
1028 SSVAL(params,0,dptr_num);
1029 SSVAL(params,2,numentries);
1030 SSVAL(params,4,finished);
1031 SSVAL(params,6,0); /* Never an EA error */
1032 SSVAL(params,8,last_name_off);
1034 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1036 if ((! *directory) && dptr_path(dptr_num))
1037 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1039 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1040 smb_fn_name(CVAL(inbuf,smb_com)),
1041 mask, directory, dirtype, numentries ) );
1044 * Force a name mangle here to ensure that the
1045 * mask as an 8.3 name is top of the mangled cache.
1046 * The reasons for this are subtle. Don't remove
1047 * this code unless you know what you are doing
1048 * (see PR#13758). JRA.
1051 if(!mangle_is_8_3_wildcards( mask, False))
1052 mangle_map(mask, True, True, SNUM(conn));
1057 /****************************************************************************
1058 Reply to a TRANS2_FINDNEXT.
1059 ****************************************************************************/
1061 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1062 char **pparams, int total_params, char **ppdata, int total_data)
1064 /* We must be careful here that we don't return more than the
1065 allowed number of data bytes. If this means returning fewer than
1066 maxentries then so be it. We assume that the redirector has
1067 enough room for the fixed number of parameter bytes it has
1069 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1070 char *params = *pparams;
1071 char *pdata = *ppdata;
1072 int dptr_num = SVAL(params,0);
1073 int maxentries = SVAL(params,2);
1074 uint16 info_level = SVAL(params,4);
1075 uint32 resume_key = IVAL(params,6);
1076 BOOL close_after_request = BITSETW(params+10,0);
1077 BOOL close_if_end = BITSETW(params+10,1);
1078 BOOL requires_resume_key = BITSETW(params+10,2);
1079 BOOL continue_bit = BITSETW(params+10,3);
1080 pstring resume_name;
1086 int i, last_name_off=0;
1087 BOOL finished = False;
1088 BOOL dont_descend = False;
1089 BOOL out_of_space = False;
1090 int space_remaining;
1092 if (total_params < 12)
1093 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1095 *mask = *directory = *resume_name = 0;
1097 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
1099 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1100 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1101 resume_key = %d resume name = %s continue=%d level = %d\n",
1102 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1103 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1105 switch (info_level) {
1106 case SMB_INFO_STANDARD:
1107 case SMB_INFO_QUERY_EA_SIZE:
1108 case SMB_FIND_FILE_DIRECTORY_INFO:
1109 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1110 case SMB_FIND_FILE_NAMES_INFO:
1111 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1113 case SMB_FIND_FILE_UNIX:
1114 if (!lp_unix_extensions())
1115 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1118 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1121 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1123 return ERROR_DOS(ERRDOS,ERRnomem);
1126 memset((char *)pdata,'\0',max_data_bytes + 1024);
1128 /* Realloc the params space */
1129 params = Realloc(*pparams, 6*SIZEOFWORD);
1130 if( params == NULL )
1131 return ERROR_DOS(ERRDOS,ERRnomem);
1135 /* Check that the dptr is valid */
1136 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1137 return ERROR_DOS(ERRDOS,ERRnofiles);
1139 string_set(&conn->dirpath,dptr_path(dptr_num));
1141 /* Get the wildcard mask from the dptr */
1142 if((p = dptr_wcard(dptr_num))== NULL) {
1143 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1144 return ERROR_DOS(ERRDOS,ERRnofiles);
1148 pstrcpy(directory,conn->dirpath);
1150 /* Get the attr mask from the dptr */
1151 dirtype = dptr_attr(dptr_num);
1153 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1154 dptr_num, mask, dirtype,
1156 TellDir(conn->dirptr)));
1158 /* We don't need to check for VOL here as this is returned by
1159 a different TRANS2 call. */
1161 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1162 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1163 dont_descend = True;
1166 space_remaining = max_data_bytes;
1167 out_of_space = False;
1170 * Seek to the correct position. We no longer use the resume key but
1171 * depend on the last file name instead.
1174 if(requires_resume_key && *resume_name && !continue_bit) {
1177 * Fix for NT redirector problem triggered by resume key indexes
1178 * changing between directory scans. We now return a resume key of 0
1179 * and instead look for the filename to continue from (also given
1180 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1181 * findfirst/findnext (as is usual) then the directory pointer
1182 * should already be at the correct place. Check this by scanning
1183 * backwards looking for an exact (ie. case sensitive) filename match.
1184 * If we get to the beginning of the directory and haven't found it then scan
1185 * forwards again looking for a match. JRA.
1188 int current_pos, start_pos;
1189 const char *dname = NULL;
1190 pstring dname_pstring;
1191 void *dirptr = conn->dirptr;
1192 start_pos = TellDir(dirptr);
1193 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1194 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1196 SeekDir(dirptr, current_pos);
1197 dname = ReadDirName(dirptr);
1200 * Remember, mangle_map is called by
1201 * get_lanman2_dir_entry(), so the resume name
1202 * could be mangled. Ensure we do the same
1206 /* make sure we get a copy that mangle_map can modify */
1208 pstrcpy(dname_pstring, dname);
1209 mangle_map( dname_pstring, False, True, SNUM(conn));
1211 if(strcsequal( resume_name, dname_pstring)) {
1212 SeekDir(dirptr, current_pos+1);
1213 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1220 * Scan forward from start if not found going backwards.
1223 if(current_pos < 0) {
1224 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1225 SeekDir(dirptr, start_pos);
1226 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
1229 * Remember, mangle_map is called by
1230 * get_lanman2_dir_entry(), so the resume name
1231 * could be mangled. Ensure we do the same
1236 /* make sure we get a copy that mangle_map can modify */
1238 pstrcpy(dname_pstring, dname);
1239 mangle_map(dname_pstring, False, True, SNUM(conn));
1241 if(strcsequal( resume_name, dname_pstring)) {
1242 SeekDir(dirptr, current_pos+1);
1243 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1248 } /* end if current_pos */
1249 } /* end if requires_resume_key && !continue_bit */
1251 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1252 BOOL got_exact_match = False;
1254 /* this is a heuristic to avoid seeking the dirptr except when
1255 absolutely necessary. It allows for a filename of about 40 chars */
1256 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1257 out_of_space = True;
1260 finished = !get_lanman2_dir_entry(conn,
1262 mask,dirtype,info_level,
1263 requires_resume_key,dont_descend,
1264 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1268 if (finished && out_of_space)
1271 if (!finished && !out_of_space)
1275 * As an optimisation if we know we aren't looking
1276 * for a wildcard name (ie. the name matches the wildcard exactly)
1277 * then we can finish on any (first) match.
1278 * This speeds up large directory searches. JRA.
1284 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1287 /* Check if we can close the dirptr */
1288 if(close_after_request || (finished && close_if_end)) {
1289 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1290 dptr_close(&dptr_num); /* This frees up the saved mask */
1293 /* Set up the return parameter block */
1294 SSVAL(params,0,numentries);
1295 SSVAL(params,2,finished);
1296 SSVAL(params,4,0); /* Never an EA error */
1297 SSVAL(params,6,last_name_off);
1299 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1301 if ((! *directory) && dptr_path(dptr_num))
1302 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1304 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1305 smb_fn_name(CVAL(inbuf,smb_com)),
1306 mask, directory, dirtype, numentries ) );
1311 /****************************************************************************
1312 Reply to a TRANS2_QFSINFO (query filesystem info).
1313 ****************************************************************************/
1315 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
1316 int length, int bufsize,
1317 char **pparams, int total_params, char **ppdata, int total_data)
1319 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1320 char *pdata = *ppdata;
1321 char *params = *pparams;
1322 uint16 info_level = SVAL(params,0);
1325 char *vname = volume_label(SNUM(conn));
1326 int snum = SNUM(conn);
1327 char *fstype = lp_fstype(SNUM(conn));
1330 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1332 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1333 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1334 return ERROR_DOS(ERRSRV,ERRinvdevice);
1337 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1338 if ( pdata == NULL )
1339 return ERROR_DOS(ERRDOS,ERRnomem);
1342 memset((char *)pdata,'\0',max_data_bytes + 1024);
1344 switch (info_level) {
1345 case SMB_INFO_ALLOCATION:
1347 SMB_BIG_UINT dfree,dsize,bsize;
1349 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1350 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1351 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1352 SIVAL(pdata,l1_cUnit,dsize);
1353 SIVAL(pdata,l1_cUnitAvail,dfree);
1354 SSVAL(pdata,l1_cbSector,512);
1355 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1356 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1357 (unsigned int)dfree, 512));
1361 case SMB_INFO_VOLUME:
1362 /* Return volume name */
1364 * Add volume serial number - hash of a combination of
1365 * the called hostname and the service name.
1367 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1368 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1369 SCVAL(pdata,l2_vol_cch,len);
1370 data_len = l2_vol_szVolLabel + len;
1371 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1372 (unsigned)st.st_ctime, len, vname));
1375 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1376 case SMB_FS_ATTRIBUTE_INFORMATION:
1379 #if defined(HAVE_SYS_QUOTAS)
1380 quota_flag = FILE_VOLUME_QUOTAS;
1383 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1384 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1385 quota_flag); /* FS ATTRIBUTES */
1387 SIVAL(pdata,4,255); /* Max filename component length */
1388 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1389 and will think we can't do long filenames */
1390 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1392 data_len = 12 + len;
1395 case SMB_QUERY_FS_LABEL_INFO:
1396 case SMB_FS_LABEL_INFORMATION:
1397 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1402 case SMB_QUERY_FS_VOLUME_INFO:
1403 case SMB_FS_VOLUME_INFORMATION:
1406 * Add volume serial number - hash of a combination of
1407 * the called hostname and the service name.
1409 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1410 (str_checksum(local_machine)<<16));
1412 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1413 SIVAL(pdata,12,len);
1415 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1416 (int)strlen(vname),vname, lp_servicename(snum)));
1419 case SMB_QUERY_FS_SIZE_INFO:
1420 case SMB_FS_SIZE_INFORMATION:
1422 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1424 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1425 block_size = lp_block_size(snum);
1426 if (bsize < block_size) {
1427 SMB_BIG_UINT factor = block_size/bsize;
1432 if (bsize > block_size) {
1433 SMB_BIG_UINT factor = bsize/block_size;
1438 bytes_per_sector = 512;
1439 sectors_per_unit = bsize/bytes_per_sector;
1440 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1441 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1442 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1443 SBIG_UINT(pdata,0,dsize);
1444 SBIG_UINT(pdata,8,dfree);
1445 SIVAL(pdata,16,sectors_per_unit);
1446 SIVAL(pdata,20,bytes_per_sector);
1450 case SMB_FS_FULL_SIZE_INFORMATION:
1452 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1454 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1455 block_size = lp_block_size(snum);
1456 if (bsize < block_size) {
1457 SMB_BIG_UINT factor = block_size/bsize;
1462 if (bsize > block_size) {
1463 SMB_BIG_UINT factor = bsize/block_size;
1468 bytes_per_sector = 512;
1469 sectors_per_unit = bsize/bytes_per_sector;
1470 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1471 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1472 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1473 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1474 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1475 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1476 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1477 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1481 case SMB_QUERY_FS_DEVICE_INFO:
1482 case SMB_FS_DEVICE_INFORMATION:
1484 SIVAL(pdata,0,0); /* dev type */
1485 SIVAL(pdata,4,0); /* characteristics */
1488 #ifdef HAVE_SYS_QUOTAS
1489 case SMB_FS_QUOTA_INFORMATION:
1491 * what we have to send --metze:
1493 * Unknown1: 24 NULL bytes
1494 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1495 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1496 * Quota Flags: 2 byte :
1497 * Unknown3: 6 NULL bytes
1501 * details for Quota Flags:
1503 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1504 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1505 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1506 * 0x0001 Enable Quotas: enable quota for this fs
1510 /* we need to fake up a fsp here,
1511 * because its not send in this call
1514 SMB_NTQUOTA_STRUCT quotas;
1517 ZERO_STRUCT(quotas);
1524 if (conn->admin_user != True) {
1525 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1526 lp_servicename(SNUM(conn)),conn->user));
1527 return ERROR_DOS(ERRDOS,ERRnoaccess);
1530 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1531 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1532 return ERROR_DOS(ERRSRV,ERRerror);
1537 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
1539 /* Unknown1 24 NULL bytes*/
1540 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
1541 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
1542 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
1544 /* Default Soft Quota 8 bytes */
1545 SBIG_UINT(pdata,24,quotas.softlim);
1547 /* Default Hard Quota 8 bytes */
1548 SBIG_UINT(pdata,32,quotas.hardlim);
1550 /* Quota flag 2 bytes */
1551 SSVAL(pdata,40,quotas.qflags);
1553 /* Unknown3 6 NULL bytes */
1559 #endif /* HAVE_SYS_QUOTAS */
1560 case SMB_FS_OBJECTID_INFORMATION:
1565 * Query the version and capabilities of the CIFS UNIX extensions
1569 case SMB_QUERY_CIFS_UNIX_INFO:
1570 if (!lp_unix_extensions())
1571 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1573 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
1574 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
1575 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
1578 case SMB_MAC_QUERY_FS_INFO:
1580 * Thursby MAC extension... ONLY on NTFS filesystems
1581 * once we do streams then we don't need this
1583 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1585 SIVAL(pdata,84,0x100); /* Don't support mac... */
1590 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1594 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1596 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1601 #ifdef HAVE_SYS_QUOTAS
1602 /****************************************************************************
1603 Reply to a TRANS2_SETFSINFO (set filesystem info).
1604 ****************************************************************************/
1606 static int call_trans2setfsinfo(connection_struct *conn,
1607 char *inbuf, char *outbuf, int length, int bufsize,
1608 char **pparams, int total_params, char **ppdata, int total_data)
1610 char *pdata = *ppdata;
1611 char *params = *pparams;
1612 files_struct *fsp = NULL;
1615 SMB_NTQUOTA_STRUCT quotas;
1617 ZERO_STRUCT(quotas);
1619 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
1622 if ((conn->admin_user != True)||!CAN_WRITE(conn)) {
1623 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1624 lp_servicename(SNUM(conn)),conn->user));
1625 return ERROR_DOS(ERRSRV,ERRaccess);
1629 if (total_params < 4) {
1630 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
1632 return ERROR_DOS(ERRDOS,ERRinvalidparam);
1635 fsp = file_fsp(params,0);
1637 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
1638 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
1639 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
1642 info_level = SVAL(params,2);
1644 switch(info_level) {
1645 case SMB_FS_QUOTA_INFORMATION:
1646 /* note: normaly there're 48 bytes,
1647 * but we didn't use the last 6 bytes for now
1650 if (total_data < 42) {
1651 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
1653 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1656 /* unknown_1 24 NULL bytes in pdata*/
1658 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
1659 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
1660 #ifdef LARGE_SMB_OFF_T
1661 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
1662 #else /* LARGE_SMB_OFF_T */
1663 if ((IVAL(pdata,28) != 0)&&
1664 ((quotas.softlim != 0xFFFFFFFF)||
1665 (IVAL(pdata,28)!=0xFFFFFFFF))) {
1666 /* more than 32 bits? */
1667 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1669 #endif /* LARGE_SMB_OFF_T */
1671 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
1672 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
1673 #ifdef LARGE_SMB_OFF_T
1674 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
1675 #else /* LARGE_SMB_OFF_T */
1676 if ((IVAL(pdata,36) != 0)&&
1677 ((quotas.hardlim != 0xFFFFFFFF)||
1678 (IVAL(pdata,36)!=0xFFFFFFFF))) {
1679 /* more than 32 bits? */
1680 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1682 #endif /* LARGE_SMB_OFF_T */
1684 /* quota_flags 2 bytes **/
1685 quotas.qflags = SVAL(pdata,40);
1687 /* unknown_2 6 NULL bytes follow*/
1689 /* now set the quotas */
1690 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1691 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1692 return ERROR_DOS(ERRSRV,ERRerror);
1697 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
1699 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1704 * sending this reply works fine,
1705 * but I'm not sure it's the same
1706 * like windows do...
1709 outsize = set_message(outbuf,10,0,True);
1713 #endif /* HAVE_SYS_QUOTAS */
1715 /****************************************************************************
1716 * Utility function to set bad path error.
1717 ****************************************************************************/
1719 NTSTATUS set_bad_path_error(int err, BOOL bad_path)
1721 if((err == ENOENT) && bad_path) {
1722 unix_ERR_class = ERRDOS;
1723 unix_ERR_code = ERRbadpath;
1724 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1726 return NT_STATUS_OK;
1729 /****************************************************************************
1730 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1731 file name or file id).
1732 ****************************************************************************/
1734 static int call_trans2qfilepathinfo(connection_struct *conn,
1735 char *inbuf, char *outbuf, int length,
1737 char **pparams, int total_params, char **ppdata, int total_data)
1739 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1740 char *params = *pparams;
1741 char *pdata = *ppdata;
1742 uint16 tran_call = SVAL(inbuf, smb_setup0);
1745 SMB_OFF_T file_size=0;
1746 SMB_BIG_UINT allocation_size=0;
1747 unsigned int data_size;
1748 SMB_STRUCT_STAT sbuf;
1749 pstring fname, dos_fname;
1754 BOOL bad_path = False;
1755 BOOL delete_pending = False;
1758 files_struct *fsp = NULL;
1761 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1763 if (tran_call == TRANSACT2_QFILEINFO) {
1764 if (total_params < 4)
1765 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1767 fsp = file_fsp(params,0);
1768 info_level = SVAL(params,2);
1770 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1772 if(fsp && (fsp->fake_file_handle)) {
1774 * This is actually for the QUOTA_FAKE_FILE --metze
1777 pstrcpy(fname, fsp->fsp_name);
1778 unix_convert(fname,conn,0,&bad_path,&sbuf);
1779 if (!check_name(fname,conn)) {
1780 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
1781 set_bad_path_error(errno, bad_path);
1782 return(UNIXERROR(ERRDOS,ERRbadpath));
1785 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1787 * This is actually a QFILEINFO on a directory
1788 * handle (returned from an NT SMB). NT5.0 seems
1789 * to do this call. JRA.
1791 pstrcpy(fname, fsp->fsp_name);
1792 unix_convert(fname,conn,0,&bad_path,&sbuf);
1793 if (!check_name(fname,conn)) {
1794 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1795 set_bad_path_error(errno, bad_path);
1796 return(UNIXERROR(ERRDOS,ERRbadpath));
1799 if (INFO_LEVEL_IS_UNIX(info_level)) {
1800 /* Always do lstat for UNIX calls. */
1801 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
1802 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1803 set_bad_path_error(errno, bad_path);
1804 return(UNIXERROR(ERRDOS,ERRbadpath));
1806 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
1807 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1808 set_bad_path_error(errno, bad_path);
1809 return(UNIXERROR(ERRDOS,ERRbadpath));
1812 delete_pending = fsp->directory_delete_on_close;
1815 * Original code - this is an open file.
1817 CHECK_FSP(fsp,conn);
1819 pstrcpy(fname, fsp->fsp_name);
1820 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
1821 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1822 return(UNIXERROR(ERRDOS,ERRbadfid));
1824 pos = fsp->position_information;
1825 delete_pending = fsp->delete_on_close;
1829 if (total_params < 6)
1830 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1832 info_level = SVAL(params,0);
1834 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1836 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1838 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1840 unix_convert(fname,conn,0,&bad_path,&sbuf);
1841 if (!check_name(fname,conn)) {
1842 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1843 set_bad_path_error(errno, bad_path);
1844 return(UNIXERROR(ERRDOS,ERRbadpath));
1847 if (INFO_LEVEL_IS_UNIX(info_level)) {
1848 /* Always do lstat for UNIX calls. */
1849 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
1850 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1851 set_bad_path_error(errno, bad_path);
1852 return(UNIXERROR(ERRDOS,ERRbadpath));
1854 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
1855 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1856 set_bad_path_error(errno, bad_path);
1857 return(UNIXERROR(ERRDOS,ERRbadpath));
1861 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
1862 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1864 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1865 fname,info_level,tran_call,total_data));
1867 p = strrchr_m(fname,'/');
1873 mode = dos_mode(conn,fname,&sbuf);
1875 mode = FILE_ATTRIBUTE_NORMAL;
1877 fullpathname = fname;
1878 file_size = get_file_size(sbuf);
1879 allocation_size = get_allocation_size(fsp,&sbuf);
1883 params = Realloc(*pparams,2);
1885 return ERROR_DOS(ERRDOS,ERRnomem);
1887 memset((char *)params,'\0',2);
1888 data_size = max_data_bytes + 1024;
1889 pdata = Realloc(*ppdata, data_size);
1890 if ( pdata == NULL )
1891 return ERROR_DOS(ERRDOS,ERRnomem);
1894 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1895 /* uggh, EAs for OS2 */
1896 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1897 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1900 memset((char *)pdata,'\0',data_size);
1902 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1904 if (lp_dos_filetime_resolution(SNUM(conn))) {
1906 sbuf.st_atime &= ~1;
1907 sbuf.st_mtime &= ~1;
1908 sbuf.st_mtime &= ~1;
1911 /* NT expects the name to be in an exact form of the *full*
1912 filename. See the trans2 torture test */
1913 if (strequal(base_name,".")) {
1914 pstrcpy(dos_fname, "\\");
1916 pstr_sprintf(dos_fname, "\\%s", fname);
1917 string_replace(dos_fname, '/', '\\');
1920 switch (info_level) {
1921 case SMB_INFO_STANDARD:
1922 case SMB_INFO_QUERY_EA_SIZE:
1923 data_size = (info_level==1?22:26);
1924 put_dos_date2(pdata,l1_fdateCreation,c_time);
1925 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1926 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1927 SIVAL(pdata,l1_cbFile,(uint32)file_size);
1928 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1929 SSVAL(pdata,l1_attrFile,mode);
1930 SIVAL(pdata,l1_attrFile+2,0); /* this is what win2003 does */
1933 case SMB_INFO_IS_NAME_VALID:
1934 if (tran_call == TRANSACT2_QFILEINFO) {
1935 /* os/2 needs this ? really ?*/
1936 return ERROR_DOS(ERRDOS,ERRbadfunc);
1941 case SMB_INFO_QUERY_EAS_FROM_LIST:
1943 put_dos_date2(pdata,0,c_time);
1944 put_dos_date2(pdata,4,sbuf.st_atime);
1945 put_dos_date2(pdata,8,sbuf.st_mtime);
1946 SIVAL(pdata,12,(uint32)file_size);
1947 SIVAL(pdata,16,(uint32)allocation_size);
1948 SIVAL(pdata,20,mode);
1951 case SMB_INFO_QUERY_ALL_EAS:
1953 SIVAL(pdata,0,0); /* ea size */
1956 case SMB_FILE_BASIC_INFORMATION:
1957 case SMB_QUERY_FILE_BASIC_INFO:
1959 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1960 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1965 put_long_date(pdata,c_time);
1966 put_long_date(pdata+8,sbuf.st_atime);
1967 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1968 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1969 SIVAL(pdata,32,mode);
1971 DEBUG(5,("SMB_QFBI - "));
1973 time_t create_time = c_time;
1974 DEBUG(5,("create: %s ", ctime(&create_time)));
1976 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1977 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1978 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1979 DEBUG(5,("mode: %x\n", mode));
1983 case SMB_FILE_STANDARD_INFORMATION:
1984 case SMB_QUERY_FILE_STANDARD_INFO:
1987 SOFF_T(pdata,0,allocation_size);
1988 SOFF_T(pdata,8,file_size);
1989 if (delete_pending & sbuf.st_nlink)
1990 SIVAL(pdata,16,sbuf.st_nlink - 1);
1992 SIVAL(pdata,16,sbuf.st_nlink);
1994 SCVAL(pdata,21,(mode&aDIR)?1:0);
1997 case SMB_FILE_EA_INFORMATION:
1998 case SMB_QUERY_FILE_EA_INFO:
2002 /* Get the 8.3 name - used if NT SMB was negotiated. */
2003 case SMB_QUERY_FILE_ALT_NAME_INFO:
2004 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2008 pstrcpy(short_name,base_name);
2009 /* Mangle if not already 8.3 */
2010 if(!mangle_is_8_3(short_name, True)) {
2011 mangle_map(short_name,True,True,SNUM(conn));
2013 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2014 data_size = 4 + len;
2019 case SMB_QUERY_FILE_NAME_INFO:
2021 this must be *exactly* right for ACLs on mapped drives to work
2023 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2024 data_size = 4 + len;
2028 case SMB_FILE_ALLOCATION_INFORMATION:
2029 case SMB_QUERY_FILE_ALLOCATION_INFO:
2031 SOFF_T(pdata,0,allocation_size);
2034 case SMB_FILE_END_OF_FILE_INFORMATION:
2035 case SMB_QUERY_FILE_END_OF_FILEINFO:
2037 SOFF_T(pdata,0,file_size);
2040 case SMB_QUERY_FILE_ALL_INFO:
2041 case SMB_FILE_ALL_INFORMATION:
2042 put_long_date(pdata,c_time);
2043 put_long_date(pdata+8,sbuf.st_atime);
2044 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2045 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2046 SIVAL(pdata,32,mode);
2048 SOFF_T(pdata,0,allocation_size);
2049 SOFF_T(pdata,8,file_size);
2050 if (delete_pending && sbuf.st_nlink)
2051 SIVAL(pdata,16,sbuf.st_nlink - 1);
2053 SIVAL(pdata,16,sbuf.st_nlink);
2054 SCVAL(pdata,20,delete_pending);
2055 SCVAL(pdata,21,(mode&aDIR)?1:0);
2057 pdata += 4; /* EA info */
2058 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2061 data_size = PTR_DIFF(pdata,(*ppdata));
2064 case SMB_FILE_INTERNAL_INFORMATION:
2065 /* This should be an index number - looks like
2068 I think this causes us to fail the IFSKIT
2069 BasicFileInformationTest. -tpot */
2071 SIVAL(pdata,0,sbuf.st_dev);
2072 SIVAL(pdata,4,sbuf.st_ino);
2076 case SMB_FILE_ACCESS_INFORMATION:
2077 SIVAL(pdata,0,0x12019F); /* ??? */
2081 case SMB_FILE_NAME_INFORMATION:
2082 /* Pathname with leading '\'. */
2085 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2086 SIVAL(pdata,0,byte_len);
2087 data_size = 4 + byte_len;
2091 case SMB_FILE_DISPOSITION_INFORMATION:
2093 SCVAL(pdata,0,delete_pending);
2096 case SMB_FILE_POSITION_INFORMATION:
2098 SOFF_T(pdata,0,pos);
2101 case SMB_FILE_MODE_INFORMATION:
2102 SIVAL(pdata,0,mode);
2106 case SMB_FILE_ALIGNMENT_INFORMATION:
2107 SIVAL(pdata,0,0); /* No alignment needed. */
2113 * NT4 server just returns "invalid query" to this - if we try to answer
2114 * it then NTws gets a BSOD! (tridge).
2115 * W2K seems to want this. JRA.
2117 case SMB_QUERY_FILE_STREAM_INFO:
2119 case SMB_FILE_STREAM_INFORMATION:
2123 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2124 SIVAL(pdata,0,0); /* ??? */
2125 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2126 SOFF_T(pdata,8,file_size);
2127 SIVAL(pdata,16,allocation_size);
2128 SIVAL(pdata,20,0); /* ??? */
2129 data_size = 24 + byte_len;
2133 case SMB_QUERY_COMPRESSION_INFO:
2134 case SMB_FILE_COMPRESSION_INFORMATION:
2135 SOFF_T(pdata,0,file_size);
2136 SIVAL(pdata,8,0); /* ??? */
2137 SIVAL(pdata,12,0); /* ??? */
2141 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2142 put_long_date(pdata,c_time);
2143 put_long_date(pdata+8,sbuf.st_atime);
2144 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2145 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2146 SIVAL(pdata,32,allocation_size);
2147 SOFF_T(pdata,40,file_size);
2148 SIVAL(pdata,48,mode);
2149 SIVAL(pdata,52,0); /* ??? */
2153 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2154 SIVAL(pdata,0,mode);
2160 * CIFS UNIX Extensions.
2163 case SMB_QUERY_FILE_UNIX_BASIC:
2165 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2167 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2170 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2173 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2174 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2175 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2178 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2182 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2186 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2189 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2193 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2197 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2200 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2204 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2207 data_size = PTR_DIFF(pdata,(*ppdata));
2211 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2213 for (i=0; i<100; i++)
2214 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2220 case SMB_QUERY_FILE_UNIX_LINK:
2225 if(!S_ISLNK(sbuf.st_mode))
2226 return(UNIXERROR(ERRSRV,ERRbadlink));
2228 return(UNIXERROR(ERRDOS,ERRbadlink));
2230 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2232 return(UNIXERROR(ERRDOS,ERRnoaccess));
2234 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2236 data_size = PTR_DIFF(pdata,(*ppdata));
2242 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2245 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
2250 /****************************************************************************
2251 Deal with the internal needs of setting the delete on close flag. Note that
2252 as the tdb locking is recursive, it is safe to call this from within
2253 open_file_shared. JRA.
2254 ****************************************************************************/
2256 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
2259 * Only allow delete on close for writable shares.
2262 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
2263 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2265 return NT_STATUS_ACCESS_DENIED;
2268 * Only allow delete on close for files/directories opened with delete intent.
2271 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
2272 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2274 return NT_STATUS_ACCESS_DENIED;
2277 if(fsp->is_directory) {
2278 fsp->directory_delete_on_close = delete_on_close;
2279 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2280 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2282 fsp->delete_on_close = delete_on_close;
2283 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2284 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2287 return NT_STATUS_OK;
2290 /****************************************************************************
2291 Sets the delete on close flag over all share modes on this file.
2292 Modify the share mode entry for all files open
2293 on this device and inode to tell other smbds we have
2294 changed the delete on close flag. This will be noticed
2295 in the close code, the last closer will delete the file
2297 ****************************************************************************/
2299 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
2301 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2302 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2304 if (fsp->is_directory || fsp->is_stat)
2305 return NT_STATUS_OK;
2307 if (lock_share_entry_fsp(fsp) == False)
2308 return NT_STATUS_ACCESS_DENIED;
2310 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2311 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2313 unlock_share_entry_fsp(fsp);
2314 return NT_STATUS_ACCESS_DENIED;
2317 unlock_share_entry_fsp(fsp);
2318 return NT_STATUS_OK;
2321 /****************************************************************************
2322 Returns true if this pathname is within the share, and thus safe.
2323 ****************************************************************************/
2325 static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in, char *link_dest_out)
2328 char resolved_name[PATH_MAX+1];
2330 pstring resolved_name;
2332 fstring last_component;
2336 BOOL bad_path = False;
2337 SMB_STRUCT_STAT sbuf;
2339 pstrcpy(link_dest, link_dest_in);
2340 unix_convert(link_dest,conn,0,&bad_path,&sbuf);
2342 /* Store the UNIX converted path. */
2343 pstrcpy(link_dest_out, link_dest);
2345 p = strrchr(link_dest, '/');
2347 fstrcpy(last_component, p+1);
2350 fstrcpy(last_component, link_dest);
2351 pstrcpy(link_dest, "./");
2354 if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
2357 pstrcpy(link_dest, resolved_name);
2358 pstrcat(link_dest, "/");
2359 pstrcat(link_dest, last_component);
2361 if (*link_dest != '/') {
2362 /* Relative path. */
2363 pstrcpy(link_test, conn->connectpath);
2364 pstrcat(link_test, "/");
2365 pstrcat(link_test, link_dest);
2367 pstrcpy(link_test, link_dest);
2371 * Check if the link is within the share.
2374 if (strncmp(conn->connectpath, link_test, strlen(conn->connectpath))) {
2381 /****************************************************************************
2382 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2383 ****************************************************************************/
2385 static int call_trans2setfilepathinfo(connection_struct *conn,
2386 char *inbuf, char *outbuf, int length, int bufsize,
2387 char **pparams, int total_params, char **ppdata, int total_data)
2389 char *params = *pparams;
2390 char *pdata = *ppdata;
2391 uint16 tran_call = SVAL(inbuf, smb_setup0);
2396 SMB_STRUCT_STAT sbuf;
2399 BOOL bad_path = False;
2400 files_struct *fsp = NULL;
2401 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
2402 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
2403 mode_t unixmode = 0;
2406 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2408 if (tran_call == TRANSACT2_SETFILEINFO) {
2409 if (total_params < 4)
2410 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2412 fsp = file_fsp(params,0);
2413 info_level = SVAL(params,2);
2415 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2417 * This is actually a SETFILEINFO on a directory
2418 * handle (returned from an NT SMB). NT5.0 seems
2419 * to do this call. JRA.
2421 pstrcpy(fname, fsp->fsp_name);
2422 unix_convert(fname,conn,0,&bad_path,&sbuf);
2423 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
2424 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2425 set_bad_path_error(errno, bad_path);
2426 return(UNIXERROR(ERRDOS,ERRbadpath));
2428 } else if (fsp && fsp->print_file) {
2430 * Doing a DELETE_ON_CLOSE should cancel a print job.
2432 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
2433 fsp->share_mode = FILE_DELETE_ON_CLOSE;
2435 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
2438 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2441 return (UNIXERROR(ERRDOS,ERRbadpath));
2444 * Original code - this is an open file.
2446 CHECK_FSP(fsp,conn);
2448 pstrcpy(fname, fsp->fsp_name);
2451 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
2452 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2453 return(UNIXERROR(ERRDOS,ERRbadfid));
2458 if (total_params < 6)
2459 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2461 info_level = SVAL(params,0);
2462 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2463 unix_convert(fname,conn,0,&bad_path,&sbuf);
2464 if(!check_name(fname, conn)) {
2465 set_bad_path_error(errno, bad_path);
2466 return(UNIXERROR(ERRDOS,ERRbadpath));
2470 * For CIFS UNIX extensions the target name may not exist.
2473 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
2474 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
2475 set_bad_path_error(errno, bad_path);
2476 return(UNIXERROR(ERRDOS,ERRbadpath));
2480 if (!CAN_WRITE(conn))
2481 return ERROR_DOS(ERRSRV,ERRaccess);
2483 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2484 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2486 if (VALID_STAT(sbuf))
2487 unixmode = sbuf.st_mode;
2489 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2490 tran_call,fname,info_level,total_data));
2492 /* Realloc the parameter and data sizes */
2493 params = Realloc(*pparams,2);
2495 return ERROR_DOS(ERRDOS,ERRnomem);
2501 /* the pending modtime overrides the current modtime */
2502 sbuf.st_mtime = fsp->pending_modtime;
2505 size = get_file_size(sbuf);
2506 tvs.modtime = sbuf.st_mtime;
2507 tvs.actime = sbuf.st_atime;
2508 dosmode = dos_mode(conn,fname,&sbuf);
2509 unixmode = sbuf.st_mode;
2511 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
2512 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
2514 switch (info_level) {
2515 case SMB_INFO_STANDARD:
2517 if (total_data < 12)
2518 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2521 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2523 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2527 case SMB_INFO_SET_EA:
2528 return(ERROR_DOS(ERRDOS,ERReasnotsupported));
2530 /* XXXX um, i don't think this is right.
2531 it's also not in the cifs6.txt spec.
2533 case SMB_INFO_QUERY_EAS_FROM_LIST:
2534 if (total_data < 28)
2535 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2537 tvs.actime = make_unix_date2(pdata+8);
2538 tvs.modtime = make_unix_date2(pdata+12);
2539 size = IVAL(pdata,16);
2540 dosmode = IVAL(pdata,24);
2543 /* XXXX nor this. not in cifs6.txt, either. */
2544 case SMB_INFO_QUERY_ALL_EAS:
2545 if (total_data < 28)
2546 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2548 tvs.actime = make_unix_date2(pdata+8);
2549 tvs.modtime = make_unix_date2(pdata+12);
2550 size = IVAL(pdata,16);
2551 dosmode = IVAL(pdata,24);
2554 case SMB_SET_FILE_BASIC_INFO:
2555 case SMB_FILE_BASIC_INFORMATION:
2557 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2559 time_t changed_time;
2561 if (total_data < 36)
2562 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2564 /* Ignore create time at offset pdata. */
2567 tvs.actime = interpret_long_date(pdata+8);
2569 write_time = interpret_long_date(pdata+16);
2570 changed_time = interpret_long_date(pdata+24);
2572 tvs.modtime = MIN(write_time, changed_time);
2574 if (write_time > tvs.modtime && write_time != 0xffffffff) {
2575 tvs.modtime = write_time;
2577 /* Prefer a defined time to an undefined one. */
2578 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2579 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2580 ? changed_time : write_time);
2583 dosmode = IVAL(pdata,32);
2587 case SMB_FILE_ALLOCATION_INFORMATION:
2588 case SMB_SET_FILE_ALLOCATION_INFO:
2591 SMB_BIG_UINT allocation_size;
2594 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2596 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
2597 #ifdef LARGE_SMB_OFF_T
2598 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
2599 #else /* LARGE_SMB_OFF_T */
2600 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2601 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2602 #endif /* LARGE_SMB_OFF_T */
2603 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2604 fname, (double)allocation_size ));
2606 if (allocation_size)
2607 allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
2609 if(allocation_size != get_file_size(sbuf)) {
2610 SMB_STRUCT_STAT new_sbuf;
2612 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2613 fname, (double)allocation_size ));
2616 files_struct *new_fsp = NULL;
2617 int access_mode = 0;
2620 if(global_oplock_break) {
2621 /* Queue this file modify as we are the process of an oplock break. */
2623 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2624 DEBUGADD(2,( "in oplock break state.\n"));
2626 push_oplock_pending_smb_message(inbuf, length);
2630 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
2631 SET_OPEN_MODE(DOS_OPEN_RDWR),
2632 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2633 0, 0, &access_mode, &action);
2635 if (new_fsp == NULL)
2636 return(UNIXERROR(ERRDOS,ERRbadpath));
2637 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2638 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2639 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2640 new_fsp->fnum, strerror(errno)));
2643 close_file(new_fsp,True);
2645 ret = vfs_allocate_file_space(fsp, allocation_size);
2646 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
2647 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2648 fsp->fnum, strerror(errno)));
2653 return ERROR_NT(NT_STATUS_DISK_FULL);
2655 /* Allocate can truncate size... */
2656 size = get_file_size(new_sbuf);
2662 case SMB_FILE_END_OF_FILE_INFORMATION:
2663 case SMB_SET_FILE_END_OF_FILE_INFO:
2666 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2668 size = IVAL(pdata,0);
2669 #ifdef LARGE_SMB_OFF_T
2670 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2671 #else /* LARGE_SMB_OFF_T */
2672 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2673 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2674 #endif /* LARGE_SMB_OFF_T */
2675 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2679 case SMB_FILE_DISPOSITION_INFORMATION:
2680 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2682 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2686 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2688 /* Just ignore this set on a path. */
2689 if (tran_call != TRANSACT2_SETFILEINFO)
2693 return(UNIXERROR(ERRDOS,ERRbadfid));
2695 status = set_delete_on_close_internal(fsp, delete_on_close);
2697 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2698 return ERROR_NT(status);
2700 /* The set is across all open files on this dev/inode pair. */
2701 status =set_delete_on_close_over_all(fsp, delete_on_close);
2702 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2703 return ERROR_NT(status);
2708 case SMB_FILE_POSITION_INFORMATION:
2710 SMB_BIG_UINT position_information;
2713 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2715 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
2716 #ifdef LARGE_SMB_OFF_T
2717 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
2718 #else /* LARGE_SMB_OFF_T */
2719 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2720 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2721 #endif /* LARGE_SMB_OFF_T */
2722 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
2723 fname, (double)position_information ));
2725 fsp->position_information = position_information;
2730 * CIFS UNIX extensions.
2733 case SMB_SET_FILE_UNIX_BASIC:
2735 uint32 raw_unixmode;
2737 if (total_data < 100)
2738 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2740 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
2741 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
2742 size=IVAL(pdata,0); /* first 8 Bytes are size */
2743 #ifdef LARGE_SMB_OFF_T
2744 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2745 #else /* LARGE_SMB_OFF_T */
2746 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2747 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2748 #endif /* LARGE_SMB_OFF_T */
2750 pdata+=24; /* ctime & st_blocks are not changed */
2751 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
2752 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
2754 set_owner = (uid_t)IVAL(pdata,0);
2756 set_grp = (gid_t)IVAL(pdata,0);
2758 raw_unixmode = IVAL(pdata,28);
2759 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
2760 dosmode = 0; /* Ensure dos mode change doesn't override this. */
2762 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2763 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2764 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
2766 if (!VALID_STAT(sbuf)) {
2769 * The only valid use of this is to create character and block
2770 * devices, and named pipes. This is deprecated (IMHO) and
2771 * a new info level should be used for mknod. JRA.
2774 #if !defined(HAVE_MAKEDEV_FN)
2775 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2776 #else /* HAVE_MAKEDEV_FN */
2777 uint32 file_type = IVAL(pdata,0);
2778 uint32 dev_major = IVAL(pdata,4);
2779 uint32 dev_minor = IVAL(pdata,12);
2781 uid_t myuid = geteuid();
2782 gid_t mygid = getegid();
2785 if (tran_call == TRANSACT2_SETFILEINFO)
2786 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2788 if (raw_unixmode == SMB_MODE_NO_CHANGE)
2789 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2791 dev = makedev(dev_major, dev_minor);
2793 /* We can only create as the owner/group we are. */
2795 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
2796 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2797 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
2798 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2800 if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
2801 file_type != UNIX_TYPE_FIFO)
2802 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2804 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2805 0%o for file %s\n", (double)dev, unixmode, fname ));
2807 /* Ok - do the mknod. */
2808 if (SMB_VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
2809 return(UNIXERROR(ERRDOS,ERRnoaccess));
2811 inherit_access_acl(conn, fname, unixmode);
2814 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2816 #endif /* HAVE_MAKEDEV_FN */
2821 * Deal with the UNIX specific mode set.
2824 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
2825 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
2826 (unsigned int)unixmode, fname ));
2827 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
2828 return(UNIXERROR(ERRDOS,ERRnoaccess));
2832 * Deal with the UNIX specific uid set.
2835 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
2836 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
2837 (unsigned int)set_owner, fname ));
2838 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
2839 return(UNIXERROR(ERRDOS,ERRnoaccess));
2843 * Deal with the UNIX specific gid set.
2846 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
2847 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
2848 (unsigned int)set_owner, fname ));
2849 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
2850 return(UNIXERROR(ERRDOS,ERRnoaccess));
2855 case SMB_SET_FILE_UNIX_LINK:
2858 /* Set a symbolic link. */
2859 /* Don't allow this if follow links is false. */
2861 if (!lp_symlinks(SNUM(conn)))
2862 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2864 /* Disallow if already exists. */
2865 if (VALID_STAT(sbuf))
2866 return(ERROR_DOS(ERRDOS,ERRbadpath));
2868 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2870 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2871 return(UNIXERROR(ERRDOS,ERRnoaccess));
2873 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
2874 fname, link_dest ));
2876 if (SMB_VFS_SYMLINK(conn,link_dest,fname) != 0)
2877 return(UNIXERROR(ERRDOS,ERRnoaccess));
2879 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2883 case SMB_SET_FILE_UNIX_HLINK:
2887 /* Set a hard link. */
2889 /* Disallow if already exists. */
2890 if (VALID_STAT(sbuf))
2891 return(ERROR_DOS(ERRDOS,ERRbadpath));
2893 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2895 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2896 return(UNIXERROR(ERRDOS,ERRnoaccess));
2898 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
2899 fname, link_dest ));
2901 if (SMB_VFS_LINK(conn,link_dest,fname) != 0)
2902 return(UNIXERROR(ERRDOS,ERRnoaccess));
2904 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2909 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2912 /* get some defaults (no modifications) if any info is zero or -1. */
2913 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2914 tvs.actime = sbuf.st_atime;
2916 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2917 tvs.modtime = sbuf.st_mtime;
2919 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2920 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2921 DEBUG(6,("size: %.0f ", (double)size));
2923 if (dosmode == FILE_ATTRIBUTE_NORMAL)
2927 if (S_ISDIR(sbuf.st_mode))
2933 DEBUG(6,("dosmode: %x\n" , dosmode));
2935 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2936 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2937 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2938 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2941 * Only do this test if we are not explicitly
2942 * changing the size of a file.
2945 size = get_file_size(sbuf);
2949 * Try and set the times, size and mode of this file -
2950 * if they are different from the current values
2952 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2955 * This was a setfileinfo on an open file.
2956 * NT does this a lot. It's actually pointless
2957 * setting the time here, as it will be overwritten
2958 * on the next write, so we save the request
2959 * away and will set it on file close. JRA.
2962 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2963 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2964 fsp->pending_modtime = tvs.modtime;
2969 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2971 if(file_utime(conn, fname, &tvs)!=0)
2972 return(UNIXERROR(ERRDOS,ERRnoaccess));
2976 /* check the mode isn't different, before changing it */
2977 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
2979 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
2981 if(file_chmod(conn, fname, dosmode, NULL)) {
2982 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2983 return(UNIXERROR(ERRDOS,ERRnoaccess));
2987 if (size != get_file_size(sbuf)) {
2991 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2992 fname, (double)size ));
2995 files_struct *new_fsp = NULL;
2996 int access_mode = 0;
2999 if(global_oplock_break) {
3000 /* Queue this file modify as we are the process of an oplock break. */
3002 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3003 DEBUGADD(2,( "in oplock break state.\n"));
3005 push_oplock_pending_smb_message(inbuf, length);
3009 new_fsp = open_file_shared(conn, fname, &sbuf,
3010 SET_OPEN_MODE(DOS_OPEN_RDWR),
3011 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3012 0, 0, &access_mode, &action);
3014 if (new_fsp == NULL)
3015 return(UNIXERROR(ERRDOS,ERRbadpath));
3016 ret = vfs_set_filelen(new_fsp, size);
3017 close_file(new_fsp,True);
3019 ret = vfs_set_filelen(fsp, size);
3023 return (UNIXERROR(ERRHRD,ERRdiskfull));
3027 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3032 /****************************************************************************
3033 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3034 ****************************************************************************/
3036 static int call_trans2mkdir(connection_struct *conn,
3037 char *inbuf, char *outbuf, int length, int bufsize,
3038 char **pparams, int total_params, char **ppdata, int total_data)
3040 char *params = *pparams;
3043 SMB_STRUCT_STAT sbuf;
3044 BOOL bad_path = False;
3046 if (!CAN_WRITE(conn))
3047 return ERROR_DOS(ERRSRV,ERRaccess);
3049 if (total_params < 4)
3050 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3052 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
3054 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3056 unix_convert(directory,conn,0,&bad_path,&sbuf);
3057 if (check_name(directory,conn))
3058 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3061 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3062 set_bad_path_error(errno, bad_path);
3063 return(UNIXERROR(ERRDOS,ERRnoaccess));
3066 /* Realloc the parameter and data sizes */
3067 params = Realloc(*pparams,2);
3069 return ERROR_DOS(ERRDOS,ERRnomem);
3074 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3079 /****************************************************************************
3080 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3081 We don't actually do this - we just send a null response.
3082 ****************************************************************************/
3084 static int call_trans2findnotifyfirst(connection_struct *conn,
3085 char *inbuf, char *outbuf, int length, int bufsize,
3086 char **pparams, int total_params, char **ppdata, int total_data)
3088 static uint16 fnf_handle = 257;
3089 char *params = *pparams;
3092 if (total_params < 6)
3093 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3095 info_level = SVAL(params,4);
3096 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3098 switch (info_level) {
3103 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3106 /* Realloc the parameter and data sizes */
3107 params = Realloc(*pparams,6);
3109 return ERROR_DOS(ERRDOS,ERRnomem);
3112 SSVAL(params,0,fnf_handle);
3113 SSVAL(params,2,0); /* No changes */
3114 SSVAL(params,4,0); /* No EA errors */
3121 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
3126 /****************************************************************************
3127 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3128 changes). Currently this does nothing.
3129 ****************************************************************************/
3131 static int call_trans2findnotifynext(connection_struct *conn,
3132 char *inbuf, char *outbuf, int length, int bufsize,
3133 char **pparams, int total_params, char **ppdata, int total_data)
3135 char *params = *pparams;
3137 DEBUG(3,("call_trans2findnotifynext\n"));
3139 /* Realloc the parameter and data sizes */
3140 params = Realloc(*pparams,4);
3142 return ERROR_DOS(ERRDOS,ERRnomem);
3145 SSVAL(params,0,0); /* No changes */
3146 SSVAL(params,2,0); /* No EA errors */
3148 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
3153 /****************************************************************************
3154 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3155 ****************************************************************************/
3157 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
3158 char* outbuf, int length, int bufsize,
3159 char **pparams, int total_params, char **ppdata, int total_data)
3161 char *params = *pparams;
3164 int max_referral_level;
3166 DEBUG(10,("call_trans2getdfsreferral\n"));
3168 if (total_params < 2)
3169 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3171 max_referral_level = SVAL(params,0);
3173 if(!lp_host_msdfs())
3174 return ERROR_DOS(ERRDOS,ERRbadfunc);
3176 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
3178 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
3179 return ERROR_DOS(ERRDOS,ERRbadfile);
3181 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
3182 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
3187 #define LMCAT_SPL 0x53
3188 #define LMFUNC_GETJOBID 0x60
3190 /****************************************************************************
3191 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3192 ****************************************************************************/
3194 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
3195 char* outbuf, int length, int bufsize,
3196 char **pparams, int total_params, char **ppdata, int total_data)
3198 char *pdata = *ppdata;
3199 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
3201 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3202 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3203 pdata = Realloc(*ppdata, 32);
3205 return ERROR_DOS(ERRDOS,ERRnomem);
3208 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3209 CAN ACCEPT THIS IN UNICODE. JRA. */
3211 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
3212 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3213 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3214 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3217 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3218 return ERROR_DOS(ERRSRV,ERRerror);
3222 /****************************************************************************
3223 Reply to a SMBfindclose (stop trans2 directory search).
3224 ****************************************************************************/
3226 int reply_findclose(connection_struct *conn,
3227 char *inbuf,char *outbuf,int length,int bufsize)
3230 int dptr_num=SVALS(inbuf,smb_vwv0);
3231 START_PROFILE(SMBfindclose);
3233 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3235 dptr_close(&dptr_num);
3237 outsize = set_message(outbuf,0,0,True);
3239 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3241 END_PROFILE(SMBfindclose);
3245 /****************************************************************************
3246 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3247 ****************************************************************************/
3249 int reply_findnclose(connection_struct *conn,
3250 char *inbuf,char *outbuf,int length,int bufsize)
3254 START_PROFILE(SMBfindnclose);
3256 dptr_num = SVAL(inbuf,smb_vwv0);
3258 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3260 /* We never give out valid handles for a
3261 findnotifyfirst - so any dptr_num is ok here.
3264 outsize = set_message(outbuf,0,0,True);
3266 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3268 END_PROFILE(SMBfindnclose);
3272 /****************************************************************************
3273 Reply to a SMBtranss2 - just ignore it!
3274 ****************************************************************************/
3276 int reply_transs2(connection_struct *conn,
3277 char *inbuf,char *outbuf,int length,int bufsize)
3279 START_PROFILE(SMBtranss2);
3280 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3281 END_PROFILE(SMBtranss2);
3285 /****************************************************************************
3286 Reply to a SMBtrans2.
3287 ****************************************************************************/
3289 int reply_trans2(connection_struct *conn,
3290 char *inbuf,char *outbuf,int length,int bufsize)
3293 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
3294 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
3296 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
3297 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
3298 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
3299 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
3300 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
3301 int32 timeout = IVALS(inbuf,smb_timeout);
3303 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
3304 unsigned int tran_call = SVAL(inbuf, smb_setup0);
3305 char *params = NULL, *data = NULL;
3306 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
3307 START_PROFILE(SMBtrans2);
3309 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
3310 /* Queue this open message as we are the process of an
3313 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3314 DEBUGADD(2,( "in oplock break state.\n"));
3316 push_oplock_pending_smb_message(inbuf, length);
3317 END_PROFILE(SMBtrans2);
3321 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
3322 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
3323 END_PROFILE(SMBtrans2);
3324 return ERROR_DOS(ERRSRV,ERRaccess);
3327 outsize = set_message(outbuf,0,0,True);
3329 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3330 is so as a sanity check */
3333 * Need to have rc=0 for ioctl to get job id for OS/2.
3334 * Network printing will fail if function is not successful.
3335 * Similar function in reply.c will be used if protocol
3336 * is LANMAN1.0 instead of LM1.2X002.
3337 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3338 * outbuf doesn't have to be set(only job id is used).
3340 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
3341 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3342 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3343 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3345 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
3346 DEBUG(2,("Transaction is %d\n",tran_call));
3347 END_PROFILE(SMBtrans2);
3348 ERROR_DOS(ERRDOS,ERRinvalidparam);
3352 /* Allocate the space for the maximum needed parameters and data */
3353 if (total_params > 0)
3354 params = (char *)malloc(total_params);
3356 data = (char *)malloc(total_data);
3358 if ((total_params && !params) || (total_data && !data)) {
3359 DEBUG(2,("Out of memory in reply_trans2\n"));
3362 END_PROFILE(SMBtrans2);
3363 return ERROR_DOS(ERRDOS,ERRnomem);
3366 /* Copy the param and data bytes sent with this request into
3367 the params buffer */
3368 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
3369 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
3371 if (num_params > total_params || num_data > total_data)
3372 exit_server("invalid params in reply_trans2");
3375 unsigned int psoff = SVAL(inbuf, smb_psoff);
3376 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
3378 if (smb_base(inbuf) + psoff + num_params > inbuf + length)
3380 memcpy( params, smb_base(inbuf) + psoff, num_params);
3383 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
3384 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
3386 if (smb_base(inbuf) + dsoff + num_data > inbuf + length)
3388 memcpy( data, smb_base(inbuf) + dsoff, num_data);
3391 srv_signing_trans_start(SVAL(inbuf,smb_mid));
3393 if(num_data_sofar < total_data || num_params_sofar < total_params) {
3394 /* We need to send an interim response then receive the rest
3395 of the parameter/data bytes */
3396 outsize = set_message(outbuf,0,0,True);
3397 if (!send_smb(smbd_server_fd(),outbuf))
3398 exit_server("reply_trans2: send_smb failed.");
3400 while (num_data_sofar < total_data ||
3401 num_params_sofar < total_params) {
3403 unsigned int param_disp;
3404 unsigned int param_off;
3405 unsigned int data_disp;
3406 unsigned int data_off;
3408 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
3411 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
3412 outsize = set_message(outbuf,0,0,True);
3414 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3416 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3417 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
3421 /* Revise total_params and total_data in case
3422 they have changed downwards */
3423 if (SVAL(inbuf, smb_tpscnt) < total_params)
3424 total_params = SVAL(inbuf, smb_tpscnt);
3425 if (SVAL(inbuf, smb_tdscnt) < total_data)
3426 total_data = SVAL(inbuf, smb_tdscnt);
3428 num_params = SVAL(inbuf,smb_spscnt);
3429 param_off = SVAL(inbuf, smb_spsoff);
3430 param_disp = SVAL(inbuf, smb_spsdisp);
3431 num_params_sofar += num_params;
3433 num_data = SVAL(inbuf, smb_sdscnt);
3434 data_off = SVAL(inbuf, smb_sdsoff);
3435 data_disp = SVAL(inbuf, smb_sdsdisp);
3436 num_data_sofar += num_data;
3438 if (num_params_sofar > total_params || num_data_sofar > total_data)
3442 if (param_disp + num_params >= total_params)
3444 if ((param_disp + num_params < param_disp) ||
3445 (param_disp + num_params < num_params))
3447 if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize)
3449 if (params + param_disp < params)
3452 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
3455 if (data_disp + num_data >= total_data)
3457 if ((data_disp + num_data < data_disp) ||
3458 (data_disp + num_data < num_data))
3460 if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize)
3462 if (data + data_disp < data)
3465 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
3470 if (Protocol >= PROTOCOL_NT1) {
3471 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
3474 /* Now we must call the relevant TRANS2 function */
3476 case TRANSACT2_OPEN:
3477 START_PROFILE_NESTED(Trans2_open);
3478 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
3479 ¶ms, total_params, &data, total_data);
3480 END_PROFILE_NESTED(Trans2_open);
3483 case TRANSACT2_FINDFIRST:
3484 START_PROFILE_NESTED(Trans2_findfirst);
3485 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
3486 ¶ms, total_params, &data, total_data);
3487 END_PROFILE_NESTED(Trans2_findfirst);
3490 case TRANSACT2_FINDNEXT:
3491 START_PROFILE_NESTED(Trans2_findnext);
3492 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
3493 ¶ms, total_params, &data, total_data);
3494 END_PROFILE_NESTED(Trans2_findnext);
3497 case TRANSACT2_QFSINFO:
3498 START_PROFILE_NESTED(Trans2_qfsinfo);
3499 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
3500 ¶ms, total_params, &data, total_data);
3501 END_PROFILE_NESTED(Trans2_qfsinfo);
3504 #ifdef HAVE_SYS_QUOTAS
3505 case TRANSACT2_SETFSINFO:
3506 START_PROFILE_NESTED(Trans2_setfsinfo);
3507 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
3508 ¶ms, total_params, &data, total_data);
3509 END_PROFILE_NESTED(Trans2_setfsinfo);
3512 case TRANSACT2_QPATHINFO:
3513 case TRANSACT2_QFILEINFO:
3514 START_PROFILE_NESTED(Trans2_qpathinfo);
3515 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3516 ¶ms, total_params, &data, total_data);
3517 END_PROFILE_NESTED(Trans2_qpathinfo);
3519 case TRANSACT2_SETPATHINFO:
3520 case TRANSACT2_SETFILEINFO:
3521 START_PROFILE_NESTED(Trans2_setpathinfo);
3522 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3523 ¶ms, total_params, &data, total_data);
3524 END_PROFILE_NESTED(Trans2_setpathinfo);
3527 case TRANSACT2_FINDNOTIFYFIRST:
3528 START_PROFILE_NESTED(Trans2_findnotifyfirst);
3529 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
3530 ¶ms, total_params, &data, total_data);
3531 END_PROFILE_NESTED(Trans2_findnotifyfirst);
3534 case TRANSACT2_FINDNOTIFYNEXT:
3535 START_PROFILE_NESTED(Trans2_findnotifynext);
3536 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
3537 ¶ms, total_params, &data, total_data);
3538 END_PROFILE_NESTED(Trans2_findnotifynext);
3540 case TRANSACT2_MKDIR:
3541 START_PROFILE_NESTED(Trans2_mkdir);
3542 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
3543 ¶ms, total_params, &data, total_data);
3544 END_PROFILE_NESTED(Trans2_mkdir);
3547 case TRANSACT2_GET_DFS_REFERRAL:
3548 START_PROFILE_NESTED(Trans2_get_dfs_referral);
3549 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
3550 ¶ms, total_params, &data, total_data);
3551 END_PROFILE_NESTED(Trans2_get_dfs_referral);
3553 case TRANSACT2_IOCTL:
3554 START_PROFILE_NESTED(Trans2_ioctl);
3555 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
3556 ¶ms, total_params, &data, total_data);
3557 END_PROFILE_NESTED(Trans2_ioctl);
3560 /* Error in request */
3561 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
3564 END_PROFILE(SMBtrans2);
3565 srv_signing_trans_stop();
3566 return ERROR_DOS(ERRSRV,ERRerror);
3569 /* As we do not know how many data packets will need to be
3570 returned here the various call_trans2xxxx calls
3571 must send their own. Thus a call_trans2xxx routine only
3572 returns a value other than -1 when it wants to send
3576 srv_signing_trans_stop();
3580 END_PROFILE(SMBtrans2);
3581 return outsize; /* If a correct response was needed the
3582 call_trans2xxx calls have already sent
3583 it. If outsize != -1 then it is returning */
3587 srv_signing_trans_stop();
3590 END_PROFILE(SMBtrans2);
3591 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);