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 return strcasecmp(str,mask) == 0;
332 /****************************************************************************
333 Return the filetype for UNIX extensions.
334 ****************************************************************************/
336 static uint32 unix_filetype(mode_t mode)
339 return UNIX_TYPE_FILE;
340 else if(S_ISDIR(mode))
341 return UNIX_TYPE_DIR;
343 else if(S_ISLNK(mode))
344 return UNIX_TYPE_SYMLINK;
347 else if(S_ISCHR(mode))
348 return UNIX_TYPE_CHARDEV;
351 else if(S_ISBLK(mode))
352 return UNIX_TYPE_BLKDEV;
355 else if(S_ISFIFO(mode))
356 return UNIX_TYPE_FIFO;
359 else if(S_ISSOCK(mode))
360 return UNIX_TYPE_SOCKET;
363 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
364 return UNIX_TYPE_UNKNOWN;
367 /****************************************************************************
368 Return the major devicenumber for UNIX extensions.
369 ****************************************************************************/
371 static uint32 unix_dev_major(SMB_DEV_T dev)
373 #if defined(HAVE_DEVICE_MAJOR_FN)
374 return (uint32)major(dev);
376 return (uint32)(dev >> 8);
380 /****************************************************************************
381 Return the minor devicenumber for UNIX extensions.
382 ****************************************************************************/
384 static uint32 unix_dev_minor(SMB_DEV_T dev)
386 #if defined(HAVE_DEVICE_MINOR_FN)
387 return (uint32)minor(dev);
389 return (uint32)(dev & 0xff);
393 /****************************************************************************
394 Map wire perms onto standard UNIX permissions. Obey share restrictions.
395 ****************************************************************************/
397 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
401 if (perms == SMB_MODE_NO_CHANGE)
404 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
405 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
406 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
407 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
408 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
409 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
410 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
411 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
412 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
414 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
417 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
420 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
423 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
424 ret &= lp_dir_mask(SNUM(conn));
425 /* Add in force bits */
426 ret |= lp_force_dir_mode(SNUM(conn));
428 /* Apply mode mask */
429 ret &= lp_create_mask(SNUM(conn));
430 /* Add in force bits */
431 ret |= lp_force_create_mode(SNUM(conn));
437 /****************************************************************************
438 checks for SMB_TIME_NO_CHANGE and if not found
439 calls interpret_long_date
440 ****************************************************************************/
441 time_t interpret_long_unix_date(char *p)
443 DEBUG(1,("interpret_long_unix_date\n"));
444 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
445 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
448 return interpret_long_date(p);
452 /****************************************************************************
453 Get a level dependent lanman2 dir entry.
454 ****************************************************************************/
456 static BOOL get_lanman2_dir_entry(connection_struct *conn,
457 void *inbuf, void *outbuf,
458 char *path_mask,int dirtype,int info_level,
459 int requires_resume_key,
460 BOOL dont_descend,char **ppdata,
461 char *base_data, int space_remaining,
462 BOOL *out_of_space, BOOL *got_exact_match,
467 SMB_STRUCT_STAT sbuf;
471 char *p, *q, *pdata = *ppdata;
475 SMB_OFF_T file_size = 0;
476 SMB_BIG_UINT allocation_size = 0;
478 time_t mdate=0, adate=0, cdate=0;
481 int nt_extmode; /* Used for NT connections instead of mode */
482 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
485 *out_of_space = False;
486 *got_exact_match = False;
491 p = strrchr_m(path_mask,'/');
498 pstrcpy(mask, path_mask);
503 /* Needed if we run out of space */
504 prev_dirpos = TellDir(conn->dirptr);
505 dname = ReadDirName(conn->dirptr);
508 * Due to bugs in NT client redirectors we are not using
509 * resume keys any more - set them to zero.
510 * Check out the related comments in findfirst/findnext.
516 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
517 (long)conn->dirptr,TellDir(conn->dirptr)));
522 pstrcpy(fname,dname);
524 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
525 got_match = mask_match(fname, mask, case_sensitive);
527 if(!got_match && !mangle_is_8_3(fname, False)) {
530 * It turns out that NT matches wildcards against
531 * both long *and* short names. This may explain some
532 * of the wildcard wierdness from old DOS clients
533 * that some people have been seeing.... JRA.
537 pstrcpy( newname, fname);
538 mangle_map( newname, True, False, SNUM(conn));
539 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
540 got_match = mask_match(newname, mask, case_sensitive);
544 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
545 if (dont_descend && !isdots)
548 pstrcpy(pathreal,conn->dirpath);
550 pstrcat(pathreal,"/");
551 pstrcat(pathreal,dname);
553 if (INFO_LEVEL_IS_UNIX(info_level)) {
554 if (VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
555 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
556 pathreal,strerror(errno)));
559 } else if (VFS_STAT(conn,pathreal,&sbuf) != 0) {
561 /* Needed to show the msdfs symlinks as
564 if(lp_host_msdfs() &&
565 lp_msdfs_root(SNUM(conn)) &&
566 is_msdfs_link(conn, pathreal, NULL, NULL,
569 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
570 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
574 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
575 pathreal,strerror(errno)));
580 mode = dos_mode(conn,pathreal,&sbuf);
582 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
583 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
587 file_size = get_file_size(sbuf);
588 allocation_size = get_allocation_size(NULL,&sbuf);
589 mdate = sbuf.st_mtime;
590 adate = sbuf.st_atime;
591 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
593 if (lp_dos_filetime_resolution(SNUM(conn))) {
602 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
608 mangle_map(fname,False,True,SNUM(conn));
613 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
615 switch (info_level) {
616 case SMB_INFO_STANDARD:
617 if(requires_resume_key) {
621 put_dos_date2(p,l1_fdateCreation,cdate);
622 put_dos_date2(p,l1_fdateLastAccess,adate);
623 put_dos_date2(p,l1_fdateLastWrite,mdate);
624 SIVAL(p,l1_cbFile,(uint32)file_size);
625 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
626 SSVAL(p,l1_attrFile,mode);
629 p += align_string(outbuf, p, 0);
630 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
631 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
632 SCVAL(nameptr, -1, len-2);
634 SCVAL(nameptr, -1, len-1);
638 case SMB_INFO_QUERY_EA_SIZE:
639 if(requires_resume_key) {
643 put_dos_date2(p,l2_fdateCreation,cdate);
644 put_dos_date2(p,l2_fdateLastAccess,adate);
645 put_dos_date2(p,l2_fdateLastWrite,mdate);
646 SIVAL(p,l2_cbFile,(uint32)file_size);
647 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
648 SSVAL(p,l2_attrFile,mode);
649 SIVAL(p,l2_cbList,0); /* No extended attributes */
652 p += align_string(outbuf, p, 0);
653 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
654 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
655 SCVAL(nameptr, -1, len-2);
657 SCVAL(nameptr, -1, len-1);
661 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
662 was_8_3 = mangle_is_8_3(fname, True);
664 SIVAL(p,0,reskey); p += 4;
665 put_long_date(p,cdate); p += 8;
666 put_long_date(p,adate); p += 8;
667 put_long_date(p,mdate); p += 8;
668 put_long_date(p,mdate); p += 8;
669 SOFF_T(p,0,file_size);
670 SOFF_T(p,8,allocation_size);
672 SIVAL(p,0,nt_extmode); p += 4;
674 SIVAL(p,0,0); p += 4;
675 /* Clear the short name buffer. This is
676 * IMPORTANT as not doing so will trigger
677 * a Win2k client bug. JRA.
681 pstring mangled_name;
682 pstrcpy(mangled_name, fname);
683 mangle_map(mangled_name,True,True,SNUM(conn));
684 mangled_name[12] = 0;
685 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
692 len = srvstr_push(outbuf, p, fname, -1, 0);
695 len = PTR_DIFF(p, pdata);
696 len = (len + 3) & ~3;
701 case SMB_FIND_FILE_DIRECTORY_INFO:
703 SIVAL(p,0,reskey); p += 4;
704 put_long_date(p,cdate); p += 8;
705 put_long_date(p,adate); p += 8;
706 put_long_date(p,mdate); p += 8;
707 put_long_date(p,mdate); p += 8;
708 SOFF_T(p,0,file_size);
709 SOFF_T(p,8,allocation_size);
711 SIVAL(p,0,nt_extmode); p += 4;
713 len = srvstr_push(outbuf, p, fname, -1, 0);
716 len = PTR_DIFF(p, pdata);
717 len = (len + 3) & ~3;
722 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
724 SIVAL(p,0,reskey); p += 4;
725 put_long_date(p,cdate); p += 8;
726 put_long_date(p,adate); p += 8;
727 put_long_date(p,mdate); p += 8;
728 put_long_date(p,mdate); p += 8;
729 SOFF_T(p,0,file_size);
730 SOFF_T(p,8,allocation_size);
732 SIVAL(p,0,nt_extmode); p += 4;
734 SIVAL(p,0,0); p += 4;
736 len = srvstr_push(outbuf, p, fname, -1, 0);
740 len = PTR_DIFF(p, pdata);
741 len = (len + 3) & ~3;
746 case SMB_FIND_FILE_NAMES_INFO:
748 SIVAL(p,0,reskey); p += 4;
750 /* this must *not* be null terminated or w2k gets in a loop trying to set an
751 acl on a dir (tridge) */
752 len = srvstr_push(outbuf, p, fname, -1, 0);
755 len = PTR_DIFF(p, pdata);
756 len = (len + 3) & ~3;
761 /* CIFS UNIX Extension. */
763 case SMB_FIND_FILE_UNIX:
765 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
767 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
768 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
771 SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
774 put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
775 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
776 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
779 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
783 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
787 SIVAL(p,0,unix_filetype(sbuf.st_mode));
790 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
794 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
798 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
801 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
805 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
809 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
812 len = PTR_DIFF(p, pdata);
813 len = (len + 3) & ~3;
814 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
816 /* End of SMB_QUERY_FILE_UNIX_BASIC */
825 if (PTR_DIFF(p,pdata) > space_remaining) {
826 /* Move the dirptr back to prev_dirpos */
827 SeekDir(conn->dirptr, prev_dirpos);
828 *out_of_space = True;
829 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
830 return False; /* Not finished - just out of space */
833 /* Setup the last_filename pointer, as an offset from base_data */
834 *last_name_off = PTR_DIFF(nameptr,base_data);
835 /* Advance the data pointer to the next slot */
841 /****************************************************************************
842 Reply to a TRANS2_FINDFIRST.
843 ****************************************************************************/
845 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
846 char **pparams, int total_params, char **ppdata, int total_data)
848 /* We must be careful here that we don't return more than the
849 allowed number of data bytes. If this means returning fewer than
850 maxentries then so be it. We assume that the redirector has
851 enough room for the fixed number of parameter bytes it has
853 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
854 char *params = *pparams;
855 char *pdata = *ppdata;
856 int dirtype = SVAL(params,0);
857 int maxentries = SVAL(params,2);
858 BOOL close_after_first = BITSETW(params+4,0);
859 BOOL close_if_end = BITSETW(params+4,1);
860 BOOL requires_resume_key = BITSETW(params+4,2);
861 int info_level = SVAL(params,6);
869 BOOL finished = False;
870 BOOL dont_descend = False;
871 BOOL out_of_space = False;
873 BOOL bad_path = False;
874 SMB_STRUCT_STAT sbuf;
876 if (total_params < 12)
877 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
879 *directory = *mask = 0;
881 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
882 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
883 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
884 info_level, max_data_bytes));
886 switch (info_level) {
887 case SMB_INFO_STANDARD:
888 case SMB_INFO_QUERY_EA_SIZE:
889 case SMB_FIND_FILE_DIRECTORY_INFO:
890 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
891 case SMB_FIND_FILE_NAMES_INFO:
892 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
894 case SMB_FIND_FILE_UNIX:
895 if (!lp_unix_extensions())
896 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
899 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
902 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
904 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
906 unix_convert(directory,conn,0,&bad_path,&sbuf);
907 if(!check_name(directory,conn)) {
908 set_bad_path_error(errno, bad_path);
909 return(UNIXERROR(ERRDOS,ERRbadpath));
912 p = strrchr_m(directory,'/');
914 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
915 if((directory[0] == '.') && (directory[1] == '\0'))
918 pstrcpy(mask,directory);
919 pstrcpy(directory,"./");
925 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
927 pdata = Realloc(*ppdata, max_data_bytes + 1024);
929 return(ERROR_DOS(ERRDOS,ERRnomem));
932 memset((char *)pdata,'\0',max_data_bytes + 1024);
934 /* Realloc the params space */
935 params = Realloc(*pparams, 10);
937 return ERROR_DOS(ERRDOS,ERRnomem);
940 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
942 return(UNIXERROR(ERRDOS,ERRbadfile));
944 /* Save the wildcard match and attribs we are using on this directory -
945 needed as lanman2 assumes these are being saved between calls */
947 if(!(wcard = strdup(mask))) {
948 dptr_close(&dptr_num);
949 return ERROR_DOS(ERRDOS,ERRnomem);
952 dptr_set_wcard(dptr_num, wcard);
953 dptr_set_attr(dptr_num, dirtype);
955 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
957 /* We don't need to check for VOL here as this is returned by
958 a different TRANS2 call. */
960 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
961 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
965 space_remaining = max_data_bytes;
966 out_of_space = False;
968 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
969 BOOL got_exact_match = False;
971 /* this is a heuristic to avoid seeking the dirptr except when
972 absolutely necessary. It allows for a filename of about 40 chars */
973 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
977 finished = !get_lanman2_dir_entry(conn,
979 mask,dirtype,info_level,
980 requires_resume_key,dont_descend,
981 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
985 if (finished && out_of_space)
988 if (!finished && !out_of_space)
992 * As an optimisation if we know we aren't looking
993 * for a wildcard name (ie. the name matches the wildcard exactly)
994 * then we can finish on any (first) match.
995 * This speeds up large directory searches. JRA.
1001 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1004 /* Check if we can close the dirptr */
1005 if(close_after_first || (finished && close_if_end)) {
1006 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1007 dptr_close(&dptr_num);
1011 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1012 * from observation of NT.
1015 if(numentries == 0) {
1016 dptr_close(&dptr_num);
1017 return ERROR_DOS(ERRDOS,ERRbadfile);
1020 /* At this point pdata points to numentries directory entries. */
1022 /* Set up the return parameter block */
1023 SSVAL(params,0,dptr_num);
1024 SSVAL(params,2,numentries);
1025 SSVAL(params,4,finished);
1026 SSVAL(params,6,0); /* Never an EA error */
1027 SSVAL(params,8,last_name_off);
1029 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1031 if ((! *directory) && dptr_path(dptr_num))
1032 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1034 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1035 smb_fn_name(CVAL(inbuf,smb_com)),
1036 mask, directory, dirtype, numentries ) );
1039 * Force a name mangle here to ensure that the
1040 * mask as an 8.3 name is top of the mangled cache.
1041 * The reasons for this are subtle. Don't remove
1042 * this code unless you know what you are doing
1043 * (see PR#13758). JRA.
1046 if(!mangle_is_8_3_wildcards( mask, False))
1047 mangle_map(mask, True, True, SNUM(conn));
1052 /****************************************************************************
1053 Reply to a TRANS2_FINDNEXT.
1054 ****************************************************************************/
1056 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1057 char **pparams, int total_params, char **ppdata, int total_data)
1059 /* We must be careful here that we don't return more than the
1060 allowed number of data bytes. If this means returning fewer than
1061 maxentries then so be it. We assume that the redirector has
1062 enough room for the fixed number of parameter bytes it has
1064 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1065 char *params = *pparams;
1066 char *pdata = *ppdata;
1067 int dptr_num = SVAL(params,0);
1068 int maxentries = SVAL(params,2);
1069 uint16 info_level = SVAL(params,4);
1070 uint32 resume_key = IVAL(params,6);
1071 BOOL close_after_request = BITSETW(params+10,0);
1072 BOOL close_if_end = BITSETW(params+10,1);
1073 BOOL requires_resume_key = BITSETW(params+10,2);
1074 BOOL continue_bit = BITSETW(params+10,3);
1075 pstring resume_name;
1081 int i, last_name_off=0;
1082 BOOL finished = False;
1083 BOOL dont_descend = False;
1084 BOOL out_of_space = False;
1085 int space_remaining;
1087 if (total_params < 12)
1088 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1090 *mask = *directory = *resume_name = 0;
1092 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
1094 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1095 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1096 resume_key = %d resume name = %s continue=%d level = %d\n",
1097 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1098 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1100 switch (info_level) {
1101 case SMB_INFO_STANDARD:
1102 case SMB_INFO_QUERY_EA_SIZE:
1103 case SMB_FIND_FILE_DIRECTORY_INFO:
1104 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1105 case SMB_FIND_FILE_NAMES_INFO:
1106 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1108 case SMB_FIND_FILE_UNIX:
1109 if (!lp_unix_extensions())
1110 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1113 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1116 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1118 return ERROR_DOS(ERRDOS,ERRnomem);
1121 memset((char *)pdata,'\0',max_data_bytes + 1024);
1123 /* Realloc the params space */
1124 params = Realloc(*pparams, 6*SIZEOFWORD);
1125 if( params == NULL )
1126 return ERROR_DOS(ERRDOS,ERRnomem);
1130 /* Check that the dptr is valid */
1131 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1132 return ERROR_DOS(ERRDOS,ERRnofiles);
1134 string_set(&conn->dirpath,dptr_path(dptr_num));
1136 /* Get the wildcard mask from the dptr */
1137 if((p = dptr_wcard(dptr_num))== NULL) {
1138 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1139 return ERROR_DOS(ERRDOS,ERRnofiles);
1143 pstrcpy(directory,conn->dirpath);
1145 /* Get the attr mask from the dptr */
1146 dirtype = dptr_attr(dptr_num);
1148 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1149 dptr_num, mask, dirtype,
1151 TellDir(conn->dirptr)));
1153 /* We don't need to check for VOL here as this is returned by
1154 a different TRANS2 call. */
1156 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1157 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1158 dont_descend = True;
1161 space_remaining = max_data_bytes;
1162 out_of_space = False;
1165 * Seek to the correct position. We no longer use the resume key but
1166 * depend on the last file name instead.
1169 if(requires_resume_key && *resume_name && !continue_bit) {
1172 * Fix for NT redirector problem triggered by resume key indexes
1173 * changing between directory scans. We now return a resume key of 0
1174 * and instead look for the filename to continue from (also given
1175 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1176 * findfirst/findnext (as is usual) then the directory pointer
1177 * should already be at the correct place. Check this by scanning
1178 * backwards looking for an exact (ie. case sensitive) filename match.
1179 * If we get to the beginning of the directory and haven't found it then scan
1180 * forwards again looking for a match. JRA.
1183 int current_pos, start_pos;
1184 const char *dname = NULL;
1185 pstring dname_pstring;
1186 void *dirptr = conn->dirptr;
1187 start_pos = TellDir(dirptr);
1188 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1189 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1191 SeekDir(dirptr, current_pos);
1192 dname = ReadDirName(dirptr);
1195 * Remember, mangle_map is called by
1196 * get_lanman2_dir_entry(), so the resume name
1197 * could be mangled. Ensure we do the same
1201 /* make sure we get a copy that mangle_map can modify */
1203 pstrcpy(dname_pstring, dname);
1204 mangle_map( dname_pstring, False, True, SNUM(conn));
1206 if(strcsequal( resume_name, dname_pstring)) {
1207 SeekDir(dirptr, current_pos+1);
1208 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1215 * Scan forward from start if not found going backwards.
1218 if(current_pos < 0) {
1219 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1220 SeekDir(dirptr, start_pos);
1221 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
1224 * Remember, mangle_map is called by
1225 * get_lanman2_dir_entry(), so the resume name
1226 * could be mangled. Ensure we do the same
1231 /* make sure we get a copy that mangle_map can modify */
1233 pstrcpy(dname_pstring, dname);
1234 mangle_map(dname_pstring, False, True, SNUM(conn));
1236 if(strcsequal( resume_name, dname_pstring)) {
1237 SeekDir(dirptr, current_pos+1);
1238 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1243 } /* end if current_pos */
1244 } /* end if requires_resume_key && !continue_bit */
1246 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1247 BOOL got_exact_match = False;
1249 /* this is a heuristic to avoid seeking the dirptr except when
1250 absolutely necessary. It allows for a filename of about 40 chars */
1251 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1252 out_of_space = True;
1255 finished = !get_lanman2_dir_entry(conn,
1257 mask,dirtype,info_level,
1258 requires_resume_key,dont_descend,
1259 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1263 if (finished && out_of_space)
1266 if (!finished && !out_of_space)
1270 * As an optimisation if we know we aren't looking
1271 * for a wildcard name (ie. the name matches the wildcard exactly)
1272 * then we can finish on any (first) match.
1273 * This speeds up large directory searches. JRA.
1279 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1282 /* Check if we can close the dirptr */
1283 if(close_after_request || (finished && close_if_end)) {
1284 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1285 dptr_close(&dptr_num); /* This frees up the saved mask */
1288 /* Set up the return parameter block */
1289 SSVAL(params,0,numentries);
1290 SSVAL(params,2,finished);
1291 SSVAL(params,4,0); /* Never an EA error */
1292 SSVAL(params,6,last_name_off);
1294 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1296 if ((! *directory) && dptr_path(dptr_num))
1297 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1299 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1300 smb_fn_name(CVAL(inbuf,smb_com)),
1301 mask, directory, dirtype, numentries ) );
1306 /****************************************************************************
1307 Reply to a TRANS2_QFSINFO (query filesystem info).
1308 ****************************************************************************/
1310 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
1311 int length, int bufsize,
1312 char **pparams, int total_params, char **ppdata, int total_data)
1314 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1315 char *pdata = *ppdata;
1316 char *params = *pparams;
1317 uint16 info_level = SVAL(params,0);
1320 char *vname = volume_label(SNUM(conn));
1321 int snum = SNUM(conn);
1322 char *fstype = lp_fstype(SNUM(conn));
1324 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1326 if(VFS_STAT(conn,".",&st)!=0) {
1327 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1328 return ERROR_DOS(ERRSRV,ERRinvdevice);
1331 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1332 if ( pdata == NULL )
1333 return ERROR_DOS(ERRDOS,ERRnomem);
1336 memset((char *)pdata,'\0',max_data_bytes + 1024);
1338 switch (info_level) {
1339 case SMB_INFO_ALLOCATION:
1341 SMB_BIG_UINT dfree,dsize,bsize;
1343 VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1344 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1345 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1346 SIVAL(pdata,l1_cUnit,dsize);
1347 SIVAL(pdata,l1_cUnitAvail,dfree);
1348 SSVAL(pdata,l1_cbSector,512);
1349 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1350 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1351 (unsigned int)dfree, 512));
1355 case SMB_INFO_VOLUME:
1356 /* Return volume name */
1358 * Add volume serial number - hash of a combination of
1359 * the called hostname and the service name.
1361 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1362 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_TERMINATE);
1363 SCVAL(pdata,l2_vol_cch,len);
1364 data_len = l2_vol_szVolLabel + len;
1365 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1366 (unsigned)st.st_ctime, len, vname));
1369 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1370 case SMB_FS_ATTRIBUTE_INFORMATION:
1372 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1373 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1374 (HAVE_SYS_QUOTAS ? FILE_VOLUME_QUOTAS: 0)); /* FS ATTRIBUTES */
1376 SIVAL(pdata,4,255); /* Max filename component length */
1377 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1378 and will think we can't do long filenames */
1379 len = srvstr_push(outbuf, pdata+12, fstype, -1, 0);
1381 data_len = 12 + len;
1384 case SMB_QUERY_FS_LABEL_INFO:
1385 case SMB_FS_LABEL_INFORMATION:
1386 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1391 case SMB_QUERY_FS_VOLUME_INFO:
1392 case SMB_FS_VOLUME_INFORMATION:
1395 * Add volume serial number - hash of a combination of
1396 * the called hostname and the service name.
1398 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1399 (str_checksum(local_machine)<<16));
1401 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1402 SIVAL(pdata,12,len);
1404 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1405 (int)strlen(vname),vname, lp_servicename(snum)));
1408 case SMB_QUERY_FS_SIZE_INFO:
1409 case SMB_FS_SIZE_INFORMATION:
1411 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1413 VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1414 block_size = lp_block_size(snum);
1415 if (bsize < block_size) {
1416 SMB_BIG_UINT factor = block_size/bsize;
1421 if (bsize > block_size) {
1422 SMB_BIG_UINT factor = bsize/block_size;
1427 bytes_per_sector = 512;
1428 sectors_per_unit = bsize/bytes_per_sector;
1429 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1430 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1431 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1432 SBIG_UINT(pdata,0,dsize);
1433 SBIG_UINT(pdata,8,dfree);
1434 SIVAL(pdata,16,sectors_per_unit);
1435 SIVAL(pdata,20,bytes_per_sector);
1439 case SMB_FS_FULL_SIZE_INFORMATION:
1441 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1443 VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1444 block_size = lp_block_size(snum);
1445 if (bsize < block_size) {
1446 SMB_BIG_UINT factor = block_size/bsize;
1451 if (bsize > block_size) {
1452 SMB_BIG_UINT factor = bsize/block_size;
1457 bytes_per_sector = 512;
1458 sectors_per_unit = bsize/bytes_per_sector;
1459 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1460 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1461 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1462 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1463 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1464 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1465 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1466 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1470 case SMB_QUERY_FS_DEVICE_INFO:
1471 case SMB_FS_DEVICE_INFORMATION:
1473 SIVAL(pdata,0,0); /* dev type */
1474 SIVAL(pdata,4,0); /* characteristics */
1477 case SMB_FS_QUOTA_INFORMATION:
1479 * what we have to send --metze:
1481 * Unknown1: 24 NULL bytes
1482 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1483 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1484 * Quota Flags: 2 byte :
1485 * Unknown3: 6 NULL bytes
1489 * details for Quota Flags:
1491 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1492 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1493 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1494 * 0x0001 Enable Quotas: enable quota for this fs
1498 /* we need to fake up a fsp here,
1499 * because its not send in this call
1502 SMB_NTQUOTA_STRUCT quotas;
1505 ZERO_STRUCT(quotas);
1512 if (conn->admin_user != True) {
1513 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1514 lp_servicename(SNUM(conn)),conn->user));
1515 return ERROR_DOS(ERRDOS,ERRnoaccess);
1518 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1519 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1520 return ERROR_DOS(ERRSRV,ERRerror);
1525 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
1527 /* Unknown1 24 NULL bytes*/
1528 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
1529 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
1530 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
1532 /* Default Soft Quota 8 bytes */
1533 SBIG_UINT(pdata,24,quotas.softlim);
1535 /* Default Hard Quota 8 bytes */
1536 SBIG_UINT(pdata,32,quotas.hardlim);
1538 /* Quota flag 2 bytes */
1539 SSVAL(pdata,40,quotas.qflags);
1541 /* Unknown3 6 NULL bytes */
1547 case SMB_FS_OBJECTID_INFORMATION:
1552 * Query the version and capabilities of the CIFS UNIX extensions
1556 case SMB_QUERY_CIFS_UNIX_INFO:
1557 if (!lp_unix_extensions())
1558 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1560 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
1561 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
1562 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
1565 case SMB_MAC_QUERY_FS_INFO:
1567 * Thursby MAC extension... ONLY on NTFS filesystems
1568 * once we do streams then we don't need this
1570 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1572 SIVAL(pdata,84,0x100); /* Don't support mac... */
1577 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1581 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1583 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1588 /****************************************************************************
1589 Reply to a TRANS2_SETFSINFO (set filesystem info).
1590 ****************************************************************************/
1592 static int call_trans2setfsinfo(connection_struct *conn,
1593 char *inbuf, char *outbuf, int length, int bufsize,
1594 char **pparams, int total_params, char **ppdata, int total_data)
1596 char *pdata = *ppdata;
1597 char *params = *pparams;
1598 files_struct *fsp = NULL;
1601 SMB_NTQUOTA_STRUCT quotas;
1603 ZERO_STRUCT(quotas);
1605 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
1608 if ((conn->admin_user != True)||!CAN_WRITE(conn)) {
1609 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1610 lp_servicename(SNUM(conn)),conn->user));
1611 return ERROR_DOS(ERRSRV,ERRaccess);
1615 if (total_params < 4) {
1616 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
1618 return ERROR_DOS(ERRDOS,ERRinvalidparam);
1621 fsp = file_fsp(params,0);
1622 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
1623 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
1624 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
1627 info_level = SVAL(params,2);
1629 switch(info_level) {
1630 case SMB_FS_QUOTA_INFORMATION:
1631 /* note: normaly there're 48 bytes,
1632 * but we didn't use the last 6 bytes for now
1635 if (total_data < 42) {
1636 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
1638 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1641 /* unknown_1 24 NULL bytes in pdata*/
1643 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
1644 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
1645 #ifdef LARGE_SMB_OFF_T
1646 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
1647 #else /* LARGE_SMB_OFF_T */
1648 if ((IVAL(pdata,28) != 0)&&
1649 ((quotas.softlim != 0xFFFFFFFF)||
1650 (IVAL(pdata,28)!=0xFFFFFFFF)))) {
1651 /* more than 32 bits? */
1652 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1654 #endif /* LARGE_SMB_OFF_T */
1656 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
1657 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
1658 #ifdef LARGE_SMB_OFF_T
1659 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
1660 #else /* LARGE_SMB_OFF_T */
1661 if ((IVAL(pdata,36) != 0)&&
1662 ((quotas.hardlim != 0xFFFFFFFF)||
1663 (IVAL(pdata,36)!=0xFFFFFFFF)))) {
1664 /* more than 32 bits? */
1665 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1667 #endif /* LARGE_SMB_OFF_T */
1669 /* quota_flags 2 bytes **/
1670 quotas.qflags = SVAL(pdata,40);
1672 /* unknown_2 6 NULL bytes follow*/
1674 /* now set the quotas */
1675 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1676 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1677 return ERROR_DOS(ERRSRV,ERRerror);
1682 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
1684 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1689 * sending this reply works fine,
1690 * but I'm not sure it's the same
1691 * like windows do...
1694 outsize = set_message(outbuf,10,0,True);
1699 /****************************************************************************
1700 * Utility function to set bad path error.
1701 ****************************************************************************/
1703 NTSTATUS set_bad_path_error(int err, BOOL bad_path)
1705 if((err == ENOENT) && bad_path) {
1706 unix_ERR_class = ERRDOS;
1707 unix_ERR_code = ERRbadpath;
1708 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1710 return NT_STATUS_OK;
1713 /****************************************************************************
1714 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1715 file name or file id).
1716 ****************************************************************************/
1718 static int call_trans2qfilepathinfo(connection_struct *conn,
1719 char *inbuf, char *outbuf, int length,
1721 char **pparams, int total_params, char **ppdata, int total_data)
1723 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1724 char *params = *pparams;
1725 char *pdata = *ppdata;
1726 uint16 tran_call = SVAL(inbuf, smb_setup0);
1729 SMB_OFF_T file_size=0;
1730 SMB_BIG_UINT allocation_size=0;
1731 unsigned int data_size;
1732 SMB_STRUCT_STAT sbuf;
1733 pstring fname, dos_fname;
1738 BOOL bad_path = False;
1739 BOOL delete_pending = False;
1742 files_struct *fsp = NULL;
1745 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1747 if (tran_call == TRANSACT2_QFILEINFO) {
1748 if (total_params < 4)
1749 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1751 fsp = file_fsp(params,0);
1752 info_level = SVAL(params,2);
1754 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1756 if(fsp && (fsp->fake_file_handle)) {
1758 * This is actually for the QUOTA_FAKE_FILE --metze
1761 pstrcpy(fname, fsp->fsp_name);
1762 unix_convert(fname,conn,0,&bad_path,&sbuf);
1763 if (!check_name(fname,conn)) {
1764 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
1765 set_bad_path_error(errno, bad_path);
1766 return(UNIXERROR(ERRDOS,ERRbadpath));
1769 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1771 * This is actually a QFILEINFO on a directory
1772 * handle (returned from an NT SMB). NT5.0 seems
1773 * to do this call. JRA.
1775 pstrcpy(fname, fsp->fsp_name);
1776 unix_convert(fname,conn,0,&bad_path,&sbuf);
1777 if (!check_name(fname,conn)) {
1778 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1779 set_bad_path_error(errno, bad_path);
1780 return(UNIXERROR(ERRDOS,ERRbadpath));
1783 if (INFO_LEVEL_IS_UNIX(info_level)) {
1784 /* Always do lstat for UNIX calls. */
1785 if (VFS_LSTAT(conn,fname,&sbuf)) {
1786 DEBUG(3,("call_trans2qfilepathinfo: VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1787 set_bad_path_error(errno, bad_path);
1788 return(UNIXERROR(ERRDOS,ERRbadpath));
1790 } else if (!VALID_STAT(sbuf) && VFS_STAT(conn,fname,&sbuf)) {
1791 DEBUG(3,("call_trans2qfilepathinfo: VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1792 set_bad_path_error(errno, bad_path);
1793 return(UNIXERROR(ERRDOS,ERRbadpath));
1796 delete_pending = fsp->directory_delete_on_close;
1799 * Original code - this is an open file.
1801 CHECK_FSP(fsp,conn);
1803 pstrcpy(fname, fsp->fsp_name);
1804 if (VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
1805 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1806 return(UNIXERROR(ERRDOS,ERRbadfid));
1808 if((pos = VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1809 return(UNIXERROR(ERRDOS,ERRnoaccess));
1811 delete_pending = fsp->delete_on_close;
1815 if (total_params < 6)
1816 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1818 info_level = SVAL(params,0);
1820 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1822 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1824 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1826 unix_convert(fname,conn,0,&bad_path,&sbuf);
1827 if (!check_name(fname,conn)) {
1828 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1829 set_bad_path_error(errno, bad_path);
1830 return(UNIXERROR(ERRDOS,ERRbadpath));
1833 if (INFO_LEVEL_IS_UNIX(info_level)) {
1834 /* Always do lstat for UNIX calls. */
1835 if (VFS_LSTAT(conn,fname,&sbuf)) {
1836 DEBUG(3,("call_trans2qfilepathinfo: VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1837 set_bad_path_error(errno, bad_path);
1838 return(UNIXERROR(ERRDOS,ERRbadpath));
1840 } else if (!VALID_STAT(sbuf) && VFS_STAT(conn,fname,&sbuf)) {
1841 DEBUG(3,("call_trans2qfilepathinfo: VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1842 set_bad_path_error(errno, bad_path);
1843 return(UNIXERROR(ERRDOS,ERRbadpath));
1847 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
1848 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1850 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1851 fname,info_level,tran_call,total_data));
1853 p = strrchr_m(fname,'/');
1859 mode = dos_mode(conn,fname,&sbuf);
1860 fullpathname = fname;
1861 file_size = get_file_size(sbuf);
1862 allocation_size = get_allocation_size(fsp,&sbuf);
1866 params = Realloc(*pparams,2);
1868 return ERROR_DOS(ERRDOS,ERRnomem);
1870 memset((char *)params,'\0',2);
1871 data_size = max_data_bytes + 1024;
1872 pdata = Realloc(*ppdata, data_size);
1873 if ( pdata == NULL )
1874 return ERROR_DOS(ERRDOS,ERRnomem);
1877 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1878 /* uggh, EAs for OS2 */
1879 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1880 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1883 memset((char *)pdata,'\0',data_size);
1885 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1887 if (lp_dos_filetime_resolution(SNUM(conn))) {
1889 sbuf.st_atime &= ~1;
1890 sbuf.st_mtime &= ~1;
1891 sbuf.st_mtime &= ~1;
1894 /* NT expects the name to be in an exact form of the *full*
1895 filename. See the trans2 torture test */
1896 if (strequal(base_name,".")) {
1897 pstrcpy(dos_fname, "\\");
1899 snprintf(dos_fname, sizeof(dos_fname), "\\%s", fname);
1900 string_replace(dos_fname, '/', '\\');
1903 switch (info_level) {
1904 case SMB_INFO_STANDARD:
1905 case SMB_INFO_QUERY_EA_SIZE:
1906 data_size = (info_level==1?22:26);
1907 put_dos_date2(pdata,l1_fdateCreation,c_time);
1908 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1909 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1910 SIVAL(pdata,l1_cbFile,(uint32)file_size);
1911 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1912 SSVAL(pdata,l1_attrFile,mode);
1913 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1916 case SMB_INFO_QUERY_EAS_FROM_LIST:
1918 put_dos_date2(pdata,0,c_time);
1919 put_dos_date2(pdata,4,sbuf.st_atime);
1920 put_dos_date2(pdata,8,sbuf.st_mtime);
1921 SIVAL(pdata,12,(uint32)file_size);
1922 SIVAL(pdata,16,(uint32)allocation_size);
1923 SIVAL(pdata,20,mode);
1926 case SMB_INFO_QUERY_ALL_EAS:
1928 SIVAL(pdata,0,data_size);
1932 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1934 case SMB_FILE_BASIC_INFORMATION:
1935 case SMB_QUERY_FILE_BASIC_INFO:
1937 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1938 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1943 put_long_date(pdata,c_time);
1944 put_long_date(pdata+8,sbuf.st_atime);
1945 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1946 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1947 SIVAL(pdata,32,mode);
1949 DEBUG(5,("SMB_QFBI - "));
1951 time_t create_time = c_time;
1952 DEBUG(5,("create: %s ", ctime(&create_time)));
1954 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1955 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1956 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1957 DEBUG(5,("mode: %x\n", mode));
1961 case SMB_FILE_STANDARD_INFORMATION:
1962 case SMB_QUERY_FILE_STANDARD_INFO:
1965 SOFF_T(pdata,0,allocation_size);
1966 SOFF_T(pdata,8,file_size);
1967 SIVAL(pdata,16,sbuf.st_nlink);
1969 SCVAL(pdata,21,(mode&aDIR)?1:0);
1972 case SMB_FILE_EA_INFORMATION:
1973 case SMB_QUERY_FILE_EA_INFO:
1977 /* Get the 8.3 name - used if NT SMB was negotiated. */
1978 case SMB_QUERY_FILE_ALT_NAME_INFO:
1979 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1983 pstrcpy(short_name,base_name);
1984 /* Mangle if not already 8.3 */
1985 if(!mangle_is_8_3(short_name, True)) {
1986 mangle_map(short_name,True,True,SNUM(conn));
1988 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
1989 data_size = 4 + len;
1994 case SMB_QUERY_FILE_NAME_INFO:
1996 this must be *exactly* right for ACLs on mapped drives to work
1998 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
1999 data_size = 4 + len;
2003 case SMB_FILE_ALLOCATION_INFORMATION:
2004 case SMB_QUERY_FILE_ALLOCATION_INFO:
2006 SOFF_T(pdata,0,allocation_size);
2009 case SMB_FILE_END_OF_FILE_INFORMATION:
2010 case SMB_QUERY_FILE_END_OF_FILEINFO:
2012 SOFF_T(pdata,0,file_size);
2015 case SMB_QUERY_FILE_ALL_INFO:
2016 put_long_date(pdata,c_time);
2017 put_long_date(pdata+8,sbuf.st_atime);
2018 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2019 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2020 SIVAL(pdata,32,mode);
2022 SOFF_T(pdata,0,allocation_size);
2023 SOFF_T(pdata,8,file_size);
2024 SIVAL(pdata,16,sbuf.st_nlink);
2025 SCVAL(pdata,20,delete_pending);
2026 SCVAL(pdata,21,(mode&aDIR)?1:0);
2028 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
2029 pdata += 8; /* index number */
2030 pdata += 4; /* EA info */
2032 SIVAL(pdata,0,0xA9);
2034 SIVAL(pdata,0,0xd01BF);
2036 SOFF_T(pdata,0,pos); /* current offset */
2038 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
2040 pdata += 4; /* alignment */
2041 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_TERMINATE);
2044 data_size = PTR_DIFF(pdata,(*ppdata));
2047 case SMB_FILE_INTERNAL_INFORMATION:
2048 /* This should be an index number - looks like
2051 I think this causes us to fail the IFSKIT
2052 BasicFileInformationTest. -tpot */
2054 SIVAL(pdata,0,sbuf.st_dev);
2055 SIVAL(pdata,4,sbuf.st_ino);
2059 case SMB_FILE_ACCESS_INFORMATION:
2060 SIVAL(pdata,0,0x12019F); /* ??? */
2064 case SMB_FILE_NAME_INFORMATION:
2065 /* Pathname with leading '\'. */
2068 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2069 SIVAL(pdata,0,byte_len);
2070 data_size = 4 + byte_len;
2074 case SMB_FILE_DISPOSITION_INFORMATION:
2076 SCVAL(pdata,0,delete_pending);
2079 case SMB_FILE_POSITION_INFORMATION:
2081 SOFF_T(pdata,0,pos);
2084 case SMB_FILE_MODE_INFORMATION:
2085 SIVAL(pdata,0,mode);
2089 case SMB_FILE_ALIGNMENT_INFORMATION:
2090 SIVAL(pdata,0,0); /* No alignment needed. */
2095 /* Not yet finished... JRA */
2098 put_long_date(pdata,c_time);
2099 put_long_date(pdata+8,sbuf.st_atime);
2100 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2101 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2102 SIVAL(pdata,32,mode);
2103 SIVAL(pdata,36,0); /* ??? */
2104 SIVAL(pdata,40,0x20); /* ??? */
2105 SIVAL(pdata,44,0); /* ??? */
2106 SOFF_T(pdata,48,size);
2107 SIVAL(pdata,56,0x1); /* ??? */
2108 SIVAL(pdata,60,0); /* ??? */
2109 SIVAL(pdata,64,0); /* ??? */
2110 SIVAL(pdata,68,length); /* Following string length in bytes. */
2111 dos_PutUniCode(pdata+72,,False);
2118 * NT4 server just returns "invalid query" to this - if we try to answer
2119 * it then NTws gets a BSOD! (tridge).
2120 * W2K seems to want this. JRA.
2122 case SMB_QUERY_FILE_STREAM_INFO:
2124 case SMB_FILE_STREAM_INFORMATION:
2128 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2129 SIVAL(pdata,0,0); /* ??? */
2130 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2131 SOFF_T(pdata,8,file_size);
2132 SIVAL(pdata,16,allocation_size);
2133 SIVAL(pdata,20,0); /* ??? */
2134 data_size = 24 + byte_len;
2138 case SMB_FILE_COMPRESSION_INFORMATION:
2139 SOFF_T(pdata,0,allocation_size);
2140 SIVAL(pdata,8,0); /* ??? */
2141 SIVAL(pdata,12,0); /* ??? */
2145 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2146 put_long_date(pdata,c_time);
2147 put_long_date(pdata+8,sbuf.st_atime);
2148 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2149 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2150 SIVAL(pdata,32,allocation_size);
2151 SOFF_T(pdata,40,file_size);
2152 SIVAL(pdata,48,mode);
2153 SIVAL(pdata,52,0); /* ??? */
2157 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2158 SIVAL(pdata,0,mode);
2164 * CIFS UNIX Extensions.
2167 case SMB_QUERY_FILE_UNIX_BASIC:
2169 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2171 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2174 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2177 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2178 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2179 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2182 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2186 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2190 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2193 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2197 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2201 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2204 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2208 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2211 data_size = PTR_DIFF(pdata,(*ppdata));
2215 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2217 for (i=0; i<100; i++)
2218 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2224 case SMB_QUERY_FILE_UNIX_LINK:
2229 if(!S_ISLNK(sbuf.st_mode))
2230 return(UNIXERROR(ERRSRV,ERRbadlink));
2232 return(UNIXERROR(ERRDOS,ERRbadlink));
2234 len = VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2236 return(UNIXERROR(ERRDOS,ERRnoaccess));
2238 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2240 data_size = PTR_DIFF(pdata,(*ppdata));
2246 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2249 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
2254 /****************************************************************************
2255 Deal with the internal needs of setting the delete on close flag. Note that
2256 as the tdb locking is recursive, it is safe to call this from within
2257 open_file_shared. JRA.
2258 ****************************************************************************/
2260 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
2263 * Only allow delete on close for writable shares.
2266 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
2267 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2269 return NT_STATUS_ACCESS_DENIED;
2272 * Only allow delete on close for files/directories opened with delete intent.
2275 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
2276 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2278 return NT_STATUS_ACCESS_DENIED;
2281 if(fsp->is_directory) {
2282 fsp->directory_delete_on_close = delete_on_close;
2283 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2284 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2286 fsp->delete_on_close = delete_on_close;
2287 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2288 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2291 return NT_STATUS_OK;
2294 /****************************************************************************
2295 Sets the delete on close flag over all share modes on this file.
2296 Modify the share mode entry for all files open
2297 on this device and inode to tell other smbds we have
2298 changed the delete on close flag. This will be noticed
2299 in the close code, the last closer will delete the file
2301 ****************************************************************************/
2303 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
2305 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2306 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2308 if (fsp->is_directory || fsp->is_stat)
2309 return NT_STATUS_OK;
2311 if (lock_share_entry_fsp(fsp) == False)
2312 return NT_STATUS_ACCESS_DENIED;
2314 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2315 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2317 unlock_share_entry_fsp(fsp);
2318 return NT_STATUS_ACCESS_DENIED;
2321 unlock_share_entry_fsp(fsp);
2322 return NT_STATUS_OK;
2325 /****************************************************************************
2326 Returns true if this pathname is within the share, and thus safe.
2327 ****************************************************************************/
2329 static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in, char *link_dest_out)
2332 char resolved_name[PATH_MAX+1];
2334 pstring resolved_name;
2336 fstring last_component;
2340 BOOL bad_path = False;
2341 SMB_STRUCT_STAT sbuf;
2343 pstrcpy(link_dest, link_dest_in);
2344 unix_convert(link_dest,conn,0,&bad_path,&sbuf);
2346 /* Store the UNIX converted path. */
2347 pstrcpy(link_dest_out, link_dest);
2349 p = strrchr(link_dest, '/');
2351 fstrcpy(last_component, p+1);
2354 fstrcpy(last_component, link_dest);
2355 pstrcpy(link_dest, "./");
2358 if (VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
2361 pstrcpy(link_dest, resolved_name);
2362 pstrcat(link_dest, "/");
2363 pstrcat(link_dest, last_component);
2365 if (*link_dest != '/') {
2366 /* Relative path. */
2367 pstrcpy(link_test, conn->connectpath);
2368 pstrcat(link_test, "/");
2369 pstrcat(link_test, link_dest);
2371 pstrcpy(link_test, link_dest);
2375 * Check if the link is within the share.
2378 if (strncmp(conn->connectpath, link_test, strlen(conn->connectpath))) {
2385 /****************************************************************************
2386 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2387 ****************************************************************************/
2389 static int call_trans2setfilepathinfo(connection_struct *conn,
2390 char *inbuf, char *outbuf, int length, int bufsize,
2391 char **pparams, int total_params, char **ppdata, int total_data)
2393 char *params = *pparams;
2394 char *pdata = *ppdata;
2395 uint16 tran_call = SVAL(inbuf, smb_setup0);
2400 SMB_STRUCT_STAT sbuf;
2403 BOOL bad_path = False;
2404 files_struct *fsp = NULL;
2405 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
2406 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
2407 mode_t unixmode = 0;
2410 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2412 if (tran_call == TRANSACT2_SETFILEINFO) {
2413 if (total_params < 4)
2414 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2416 fsp = file_fsp(params,0);
2417 info_level = SVAL(params,2);
2419 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2421 * This is actually a SETFILEINFO on a directory
2422 * handle (returned from an NT SMB). NT5.0 seems
2423 * to do this call. JRA.
2425 pstrcpy(fname, fsp->fsp_name);
2426 unix_convert(fname,conn,0,&bad_path,&sbuf);
2427 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
2428 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2429 set_bad_path_error(errno, bad_path);
2430 return(UNIXERROR(ERRDOS,ERRbadpath));
2432 } else if (fsp && fsp->print_file) {
2434 * Doing a DELETE_ON_CLOSE should cancel a print job.
2436 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
2437 fsp->share_mode = FILE_DELETE_ON_CLOSE;
2439 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
2442 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2445 return (UNIXERROR(ERRDOS,ERRbadpath));
2448 * Original code - this is an open file.
2450 CHECK_FSP(fsp,conn);
2452 pstrcpy(fname, fsp->fsp_name);
2455 if (VFS_FSTAT(fsp,fd,&sbuf) != 0) {
2456 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2457 return(UNIXERROR(ERRDOS,ERRbadfid));
2462 if (total_params < 6)
2463 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2465 info_level = SVAL(params,0);
2466 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2467 unix_convert(fname,conn,0,&bad_path,&sbuf);
2468 if(!check_name(fname, conn)) {
2469 set_bad_path_error(errno, bad_path);
2470 return(UNIXERROR(ERRDOS,ERRbadpath));
2474 * For CIFS UNIX extensions the target name may not exist.
2477 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
2478 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
2479 set_bad_path_error(errno, bad_path);
2480 return(UNIXERROR(ERRDOS,ERRbadpath));
2484 if (!CAN_WRITE(conn))
2485 return ERROR_DOS(ERRSRV,ERRaccess);
2487 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2488 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2490 if (VALID_STAT(sbuf))
2491 unixmode = sbuf.st_mode;
2493 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2494 tran_call,fname,info_level,total_data));
2496 /* Realloc the parameter and data sizes */
2497 params = Realloc(*pparams,2);
2499 return ERROR_DOS(ERRDOS,ERRnomem);
2505 /* the pending modtime overrides the current modtime */
2506 sbuf.st_mtime = fsp->pending_modtime;
2509 size = get_file_size(sbuf);
2510 tvs.modtime = sbuf.st_mtime;
2511 tvs.actime = sbuf.st_atime;
2512 dosmode = dos_mode(conn,fname,&sbuf);
2513 unixmode = sbuf.st_mode;
2515 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
2516 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
2518 switch (info_level) {
2519 case SMB_INFO_STANDARD:
2521 if (total_data < l1_cbFile+4)
2522 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2525 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2528 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2530 dosmode = SVAL(pdata,l1_attrFile);
2531 size = IVAL(pdata,l1_cbFile);
2536 case SMB_INFO_SET_EA:
2537 return(ERROR_DOS(ERRDOS,ERReasnotsupported));
2539 /* XXXX um, i don't think this is right.
2540 it's also not in the cifs6.txt spec.
2542 case SMB_INFO_QUERY_EAS_FROM_LIST:
2543 if (total_data < 28)
2544 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2546 tvs.actime = make_unix_date2(pdata+8);
2547 tvs.modtime = make_unix_date2(pdata+12);
2548 size = IVAL(pdata,16);
2549 dosmode = IVAL(pdata,24);
2552 /* XXXX nor this. not in cifs6.txt, either. */
2553 case SMB_INFO_QUERY_ALL_EAS:
2554 if (total_data < 28)
2555 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2557 tvs.actime = make_unix_date2(pdata+8);
2558 tvs.modtime = make_unix_date2(pdata+12);
2559 size = IVAL(pdata,16);
2560 dosmode = IVAL(pdata,24);
2563 case SMB_SET_FILE_BASIC_INFO:
2564 case SMB_FILE_BASIC_INFORMATION:
2566 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2568 time_t changed_time;
2570 if (total_data < 36)
2571 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2573 /* Ignore create time at offset pdata. */
2576 tvs.actime = interpret_long_date(pdata+8);
2578 write_time = interpret_long_date(pdata+16);
2579 changed_time = interpret_long_date(pdata+24);
2581 tvs.modtime = MIN(write_time, changed_time);
2583 if (write_time > tvs.modtime && write_time != 0xffffffff) {
2584 tvs.modtime = write_time;
2586 /* Prefer a defined time to an undefined one. */
2587 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2588 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2589 ? changed_time : write_time);
2592 dosmode = IVAL(pdata,32);
2596 case SMB_FILE_ALLOCATION_INFORMATION:
2597 case SMB_SET_FILE_ALLOCATION_INFO:
2600 SMB_BIG_UINT allocation_size;
2603 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2605 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
2606 #ifdef LARGE_SMB_OFF_T
2607 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
2608 #else /* LARGE_SMB_OFF_T */
2609 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2610 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2611 #endif /* LARGE_SMB_OFF_T */
2612 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2613 fname, (double)allocation_size ));
2615 if (allocation_size)
2616 allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
2618 if(allocation_size != get_file_size(sbuf)) {
2619 SMB_STRUCT_STAT new_sbuf;
2621 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2622 fname, (double)allocation_size ));
2625 files_struct *new_fsp = NULL;
2626 int access_mode = 0;
2629 if(global_oplock_break) {
2630 /* Queue this file modify as we are the process of an oplock break. */
2632 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2633 DEBUGADD(2,( "in oplock break state.\n"));
2635 push_oplock_pending_smb_message(inbuf, length);
2639 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
2640 SET_OPEN_MODE(DOS_OPEN_RDWR),
2641 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2642 0, 0, &access_mode, &action);
2644 if (new_fsp == NULL)
2645 return(UNIXERROR(ERRDOS,ERRbadpath));
2646 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2647 if (VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2648 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2649 new_fsp->fnum, strerror(errno)));
2652 close_file(new_fsp,True);
2654 ret = vfs_allocate_file_space(fsp, allocation_size);
2655 if (VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
2656 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2657 fsp->fnum, strerror(errno)));
2662 return ERROR_NT(NT_STATUS_DISK_FULL);
2664 /* Allocate can truncate size... */
2665 size = get_file_size(new_sbuf);
2671 case SMB_FILE_END_OF_FILE_INFORMATION:
2672 case SMB_SET_FILE_END_OF_FILE_INFO:
2675 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2677 size = IVAL(pdata,0);
2678 #ifdef LARGE_SMB_OFF_T
2679 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2680 #else /* LARGE_SMB_OFF_T */
2681 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2682 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2683 #endif /* LARGE_SMB_OFF_T */
2684 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2688 case SMB_FILE_DISPOSITION_INFORMATION:
2689 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2691 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2695 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2697 if (tran_call != TRANSACT2_SETFILEINFO)
2698 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2701 return(UNIXERROR(ERRDOS,ERRbadfid));
2703 status = set_delete_on_close_internal(fsp, delete_on_close);
2705 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2706 return ERROR_NT(status);
2708 /* The set is across all open files on this dev/inode pair. */
2709 status =set_delete_on_close_over_all(fsp, delete_on_close);
2710 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2711 return ERROR_NT(status);
2717 * CIFS UNIX extensions.
2720 case SMB_SET_FILE_UNIX_BASIC:
2722 uint32 raw_unixmode;
2724 if (total_data < 100)
2725 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2727 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
2728 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
2729 size=IVAL(pdata,0); /* first 8 Bytes are size */
2730 #ifdef LARGE_SMB_OFF_T
2731 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2732 #else /* LARGE_SMB_OFF_T */
2733 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2734 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2735 #endif /* LARGE_SMB_OFF_T */
2737 pdata+=24; /* ctime & st_blocks are not changed */
2738 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
2739 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
2741 set_owner = (uid_t)IVAL(pdata,0);
2743 set_grp = (gid_t)IVAL(pdata,0);
2745 raw_unixmode = IVAL(pdata,28);
2746 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
2747 dosmode = 0; /* Ensure dos mode change doesn't override this. */
2749 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2750 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2751 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
2753 if (!VALID_STAT(sbuf)) {
2756 * The only valid use of this is to create character and block
2757 * devices, and named pipes. This is deprecated (IMHO) and
2758 * a new info level should be used for mknod. JRA.
2761 #if !defined(HAVE_MAKEDEV_FN)
2762 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2763 #else /* HAVE_MAKEDEV_FN */
2764 uint32 file_type = IVAL(pdata,0);
2765 uint32 dev_major = IVAL(pdata,4);
2766 uint32 dev_minor = IVAL(pdata,12);
2768 uid_t myuid = geteuid();
2769 gid_t mygid = getegid();
2772 if (tran_call == TRANSACT2_SETFILEINFO)
2773 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2775 if (raw_unixmode == SMB_MODE_NO_CHANGE)
2776 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2778 dev = makedev(dev_major, dev_minor);
2780 /* We can only create as the owner/group we are. */
2782 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
2783 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2784 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
2785 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2787 if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
2788 file_type != UNIX_TYPE_FIFO)
2789 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2791 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2792 0%o for file %s\n", (double)dev, unixmode, fname ));
2794 /* Ok - do the mknod. */
2795 if (VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
2796 return(UNIXERROR(ERRDOS,ERRnoaccess));
2798 inherit_access_acl(conn, fname, unixmode);
2801 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2803 #endif /* HAVE_MAKEDEV_FN */
2808 * Deal with the UNIX specific mode set.
2811 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
2812 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
2813 (unsigned int)unixmode, fname ));
2814 if (VFS_CHMOD(conn,fname,unixmode) != 0)
2815 return(UNIXERROR(ERRDOS,ERRnoaccess));
2819 * Deal with the UNIX specific uid set.
2822 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
2823 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
2824 (unsigned int)set_owner, fname ));
2825 if (VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
2826 return(UNIXERROR(ERRDOS,ERRnoaccess));
2830 * Deal with the UNIX specific gid set.
2833 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
2834 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
2835 (unsigned int)set_owner, fname ));
2836 if (VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
2837 return(UNIXERROR(ERRDOS,ERRnoaccess));
2842 case SMB_SET_FILE_UNIX_LINK:
2845 /* Set a symbolic link. */
2846 /* Don't allow this if follow links is false. */
2848 if (!lp_symlinks(SNUM(conn)))
2849 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2851 /* Disallow if already exists. */
2852 if (VALID_STAT(sbuf))
2853 return(ERROR_DOS(ERRDOS,ERRbadpath));
2855 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2857 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2858 return(UNIXERROR(ERRDOS,ERRnoaccess));
2860 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
2861 fname, link_dest ));
2863 if (VFS_SYMLINK(conn,link_dest,fname) != 0)
2864 return(UNIXERROR(ERRDOS,ERRnoaccess));
2866 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2870 case SMB_SET_FILE_UNIX_HLINK:
2874 /* Set a hard link. */
2876 /* Disallow if already exists. */
2877 if (VALID_STAT(sbuf))
2878 return(ERROR_DOS(ERRDOS,ERRbadpath));
2880 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2882 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2883 return(UNIXERROR(ERRDOS,ERRnoaccess));
2885 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
2886 fname, link_dest ));
2888 if (VFS_LINK(conn,link_dest,fname) != 0)
2889 return(UNIXERROR(ERRDOS,ERRnoaccess));
2891 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2896 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2899 /* get some defaults (no modifications) if any info is zero or -1. */
2900 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2901 tvs.actime = sbuf.st_atime;
2903 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2904 tvs.modtime = sbuf.st_mtime;
2906 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2907 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2908 DEBUG(6,("size: %.0f ", (double)size));
2910 if (S_ISDIR(sbuf.st_mode))
2915 DEBUG(6,("dosmode: %x\n" , dosmode));
2917 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2918 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2919 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2920 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2923 * Only do this test if we are not explicitly
2924 * changing the size of a file.
2927 size = get_file_size(sbuf);
2931 * Try and set the times, size and mode of this file -
2932 * if they are different from the current values
2934 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2937 * This was a setfileinfo on an open file.
2938 * NT does this a lot. It's actually pointless
2939 * setting the time here, as it will be overwritten
2940 * on the next write, so we save the request
2941 * away and will set it on file close. JRA.
2944 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2945 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2946 fsp->pending_modtime = tvs.modtime;
2951 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2953 if(file_utime(conn, fname, &tvs)!=0)
2954 return(UNIXERROR(ERRDOS,ERRnoaccess));
2958 /* check the mode isn't different, before changing it */
2959 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
2961 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
2963 if(file_chmod(conn, fname, dosmode, NULL)) {
2964 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2965 return(UNIXERROR(ERRDOS,ERRnoaccess));
2969 if (size != get_file_size(sbuf)) {
2973 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2974 fname, (double)size ));
2977 files_struct *new_fsp = NULL;
2978 int access_mode = 0;
2981 if(global_oplock_break) {
2982 /* Queue this file modify as we are the process of an oplock break. */
2984 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2985 DEBUGADD(2,( "in oplock break state.\n"));
2987 push_oplock_pending_smb_message(inbuf, length);
2991 new_fsp = open_file_shared(conn, fname, &sbuf,
2992 SET_OPEN_MODE(DOS_OPEN_RDWR),
2993 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2994 0, 0, &access_mode, &action);
2996 if (new_fsp == NULL)
2997 return(UNIXERROR(ERRDOS,ERRbadpath));
2998 ret = vfs_set_filelen(new_fsp, size);
2999 close_file(new_fsp,True);
3001 ret = vfs_set_filelen(fsp, size);
3005 return (UNIXERROR(ERRHRD,ERRdiskfull));
3009 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3014 /****************************************************************************
3015 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3016 ****************************************************************************/
3018 static int call_trans2mkdir(connection_struct *conn,
3019 char *inbuf, char *outbuf, int length, int bufsize,
3020 char **pparams, int total_params, char **ppdata, int total_data)
3022 char *params = *pparams;
3025 SMB_STRUCT_STAT sbuf;
3026 BOOL bad_path = False;
3028 if (!CAN_WRITE(conn))
3029 return ERROR_DOS(ERRSRV,ERRaccess);
3031 if (total_params < 4)
3032 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3034 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
3036 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3038 unix_convert(directory,conn,0,&bad_path,&sbuf);
3039 if (check_name(directory,conn))
3040 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3043 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3044 set_bad_path_error(errno, bad_path);
3045 return(UNIXERROR(ERRDOS,ERRnoaccess));
3048 /* Realloc the parameter and data sizes */
3049 params = Realloc(*pparams,2);
3051 return ERROR_DOS(ERRDOS,ERRnomem);
3056 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3061 /****************************************************************************
3062 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3063 We don't actually do this - we just send a null response.
3064 ****************************************************************************/
3066 static int call_trans2findnotifyfirst(connection_struct *conn,
3067 char *inbuf, char *outbuf, int length, int bufsize,
3068 char **pparams, int total_params, char **ppdata, int total_data)
3070 static uint16 fnf_handle = 257;
3071 char *params = *pparams;
3074 if (total_params < 6)
3075 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3077 info_level = SVAL(params,4);
3078 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3080 switch (info_level) {
3085 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3088 /* Realloc the parameter and data sizes */
3089 params = Realloc(*pparams,6);
3091 return ERROR_DOS(ERRDOS,ERRnomem);
3094 SSVAL(params,0,fnf_handle);
3095 SSVAL(params,2,0); /* No changes */
3096 SSVAL(params,4,0); /* No EA errors */
3103 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
3108 /****************************************************************************
3109 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3110 changes). Currently this does nothing.
3111 ****************************************************************************/
3113 static int call_trans2findnotifynext(connection_struct *conn,
3114 char *inbuf, char *outbuf, int length, int bufsize,
3115 char **pparams, int total_params, char **ppdata, int total_data)
3117 char *params = *pparams;
3119 DEBUG(3,("call_trans2findnotifynext\n"));
3121 /* Realloc the parameter and data sizes */
3122 params = Realloc(*pparams,4);
3124 return ERROR_DOS(ERRDOS,ERRnomem);
3127 SSVAL(params,0,0); /* No changes */
3128 SSVAL(params,2,0); /* No EA errors */
3130 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
3135 /****************************************************************************
3136 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3137 ****************************************************************************/
3139 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
3140 char* outbuf, int length, int bufsize,
3141 char **pparams, int total_params, char **ppdata, int total_data)
3143 char *params = *pparams;
3146 int max_referral_level;
3148 DEBUG(10,("call_trans2getdfsreferral\n"));
3150 if (total_params < 2)
3151 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3153 max_referral_level = SVAL(params,0);
3155 if(!lp_host_msdfs())
3156 return ERROR_DOS(ERRDOS,ERRbadfunc);
3158 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
3160 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
3161 return ERROR_DOS(ERRDOS,ERRbadfile);
3163 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
3164 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
3169 #define LMCAT_SPL 0x53
3170 #define LMFUNC_GETJOBID 0x60
3172 /****************************************************************************
3173 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3174 ****************************************************************************/
3176 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
3177 char* outbuf, int length, int bufsize,
3178 char **pparams, int total_params, char **ppdata, int total_data)
3180 char *pdata = *ppdata;
3181 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
3183 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3184 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3185 pdata = Realloc(*ppdata, 32);
3187 return ERROR_DOS(ERRDOS,ERRnomem);
3190 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3191 CAN ACCEPT THIS IN UNICODE. JRA. */
3193 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
3194 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3195 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3196 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3199 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3200 return ERROR_DOS(ERRSRV,ERRerror);
3204 /****************************************************************************
3205 Reply to a SMBfindclose (stop trans2 directory search).
3206 ****************************************************************************/
3208 int reply_findclose(connection_struct *conn,
3209 char *inbuf,char *outbuf,int length,int bufsize)
3212 int dptr_num=SVALS(inbuf,smb_vwv0);
3213 START_PROFILE(SMBfindclose);
3215 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3217 dptr_close(&dptr_num);
3219 outsize = set_message(outbuf,0,0,True);
3221 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3223 END_PROFILE(SMBfindclose);
3227 /****************************************************************************
3228 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3229 ****************************************************************************/
3231 int reply_findnclose(connection_struct *conn,
3232 char *inbuf,char *outbuf,int length,int bufsize)
3236 START_PROFILE(SMBfindnclose);
3238 dptr_num = SVAL(inbuf,smb_vwv0);
3240 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3242 /* We never give out valid handles for a
3243 findnotifyfirst - so any dptr_num is ok here.
3246 outsize = set_message(outbuf,0,0,True);
3248 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3250 END_PROFILE(SMBfindnclose);
3254 /****************************************************************************
3255 Reply to a SMBtranss2 - just ignore it!
3256 ****************************************************************************/
3258 int reply_transs2(connection_struct *conn,
3259 char *inbuf,char *outbuf,int length,int bufsize)
3261 START_PROFILE(SMBtranss2);
3262 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3263 END_PROFILE(SMBtranss2);
3267 /****************************************************************************
3268 Reply to a SMBtrans2.
3269 ****************************************************************************/
3271 int reply_trans2(connection_struct *conn,
3272 char *inbuf,char *outbuf,int length,int bufsize)
3275 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
3276 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
3278 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
3279 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
3280 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
3281 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
3282 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
3283 int32 timeout = IVALS(inbuf,smb_timeout);
3285 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
3286 unsigned int tran_call = SVAL(inbuf, smb_setup0);
3287 char *params = NULL, *data = NULL;
3288 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
3289 START_PROFILE(SMBtrans2);
3291 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
3292 /* Queue this open message as we are the process of an
3295 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3296 DEBUGADD(2,( "in oplock break state.\n"));
3298 push_oplock_pending_smb_message(inbuf, length);
3299 END_PROFILE(SMBtrans2);
3303 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
3304 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
3305 END_PROFILE(SMBtrans2);
3306 return ERROR_DOS(ERRSRV,ERRaccess);
3309 outsize = set_message(outbuf,0,0,True);
3311 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3312 is so as a sanity check */
3315 * Need to have rc=0 for ioctl to get job id for OS/2.
3316 * Network printing will fail if function is not successful.
3317 * Similar function in reply.c will be used if protocol
3318 * is LANMAN1.0 instead of LM1.2X002.
3319 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3320 * outbuf doesn't have to be set(only job id is used).
3322 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
3323 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3324 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3325 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3327 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
3328 DEBUG(2,("Transaction is %d\n",tran_call));
3329 END_PROFILE(SMBtrans2);
3330 ERROR_DOS(ERRDOS,ERRinvalidparam);
3334 /* Allocate the space for the maximum needed parameters and data */
3335 if (total_params > 0)
3336 params = (char *)malloc(total_params);
3338 data = (char *)malloc(total_data);
3340 if ((total_params && !params) || (total_data && !data)) {
3341 DEBUG(2,("Out of memory in reply_trans2\n"));
3344 END_PROFILE(SMBtrans2);
3345 return ERROR_DOS(ERRDOS,ERRnomem);
3348 /* Copy the param and data bytes sent with this request into
3349 the params buffer */
3350 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
3351 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
3353 if (num_params > total_params || num_data > total_data)
3354 exit_server("invalid params in reply_trans2");
3357 unsigned int psoff = SVAL(inbuf, smb_psoff);
3358 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
3360 if (smb_base(inbuf) + psoff + num_params > inbuf + length)
3362 memcpy( params, smb_base(inbuf) + psoff, num_params);
3365 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
3366 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
3368 if (smb_base(inbuf) + dsoff + num_data > inbuf + length)
3370 memcpy( data, smb_base(inbuf) + dsoff, num_data);
3373 if(num_data_sofar < total_data || num_params_sofar < total_params) {
3374 /* We need to send an interim response then receive the rest
3375 of the parameter/data bytes */
3376 outsize = set_message(outbuf,0,0,True);
3377 if (!send_smb(smbd_server_fd(),outbuf))
3378 exit_server("reply_trans2: send_smb failed.");
3380 while (num_data_sofar < total_data ||
3381 num_params_sofar < total_params) {
3383 unsigned int param_disp;
3384 unsigned int param_off;
3385 unsigned int data_disp;
3386 unsigned int data_off;
3388 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
3391 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
3392 outsize = set_message(outbuf,0,0,True);
3394 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3396 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3397 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
3401 /* Revise total_params and total_data in case
3402 they have changed downwards */
3403 if (SVAL(inbuf, smb_tpscnt) < total_params)
3404 total_params = SVAL(inbuf, smb_tpscnt);
3405 if (SVAL(inbuf, smb_tdscnt) < total_data)
3406 total_data = SVAL(inbuf, smb_tdscnt);
3408 num_params = SVAL(inbuf,smb_spscnt);
3409 param_off = SVAL(inbuf, smb_spsoff);
3410 param_disp = SVAL(inbuf, smb_spsdisp);
3411 num_params_sofar += num_params;
3413 num_data = SVAL(inbuf, smb_sdscnt);
3414 data_off = SVAL(inbuf, smb_sdsoff);
3415 data_disp = SVAL(inbuf, smb_sdsdisp);
3416 num_data_sofar += num_data;
3418 if (num_params_sofar > total_params || num_data_sofar > total_data)
3422 if (param_disp + num_params >= total_params)
3424 if ((param_disp + num_params < param_disp) ||
3425 (param_disp + num_params < num_params))
3427 if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize)
3429 if (params + param_disp < params)
3432 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
3435 if (data_disp + num_data >= total_data)
3437 if ((data_disp + num_data < data_disp) ||
3438 (data_disp + num_data < num_data))
3440 if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize)
3442 if (data + data_disp < data)
3445 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
3450 if (Protocol >= PROTOCOL_NT1) {
3451 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
3454 /* Now we must call the relevant TRANS2 function */
3456 case TRANSACT2_OPEN:
3457 START_PROFILE_NESTED(Trans2_open);
3458 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
3459 ¶ms, total_params, &data, total_data);
3460 END_PROFILE_NESTED(Trans2_open);
3463 case TRANSACT2_FINDFIRST:
3464 START_PROFILE_NESTED(Trans2_findfirst);
3465 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
3466 ¶ms, total_params, &data, total_data);
3467 END_PROFILE_NESTED(Trans2_findfirst);
3470 case TRANSACT2_FINDNEXT:
3471 START_PROFILE_NESTED(Trans2_findnext);
3472 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
3473 ¶ms, total_params, &data, total_data);
3474 END_PROFILE_NESTED(Trans2_findnext);
3477 case TRANSACT2_QFSINFO:
3478 START_PROFILE_NESTED(Trans2_qfsinfo);
3479 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
3480 ¶ms, total_params, &data, total_data);
3481 END_PROFILE_NESTED(Trans2_qfsinfo);
3484 case TRANSACT2_SETFSINFO:
3485 START_PROFILE_NESTED(Trans2_setfsinfo);
3486 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
3487 ¶ms, total_params, &data, total_data);
3488 END_PROFILE_NESTED(Trans2_setfsinfo);
3491 case TRANSACT2_QPATHINFO:
3492 case TRANSACT2_QFILEINFO:
3493 START_PROFILE_NESTED(Trans2_qpathinfo);
3494 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3495 ¶ms, total_params, &data, total_data);
3496 END_PROFILE_NESTED(Trans2_qpathinfo);
3498 case TRANSACT2_SETPATHINFO:
3499 case TRANSACT2_SETFILEINFO:
3500 START_PROFILE_NESTED(Trans2_setpathinfo);
3501 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3502 ¶ms, total_params, &data, total_data);
3503 END_PROFILE_NESTED(Trans2_setpathinfo);
3506 case TRANSACT2_FINDNOTIFYFIRST:
3507 START_PROFILE_NESTED(Trans2_findnotifyfirst);
3508 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
3509 ¶ms, total_params, &data, total_data);
3510 END_PROFILE_NESTED(Trans2_findnotifyfirst);
3513 case TRANSACT2_FINDNOTIFYNEXT:
3514 START_PROFILE_NESTED(Trans2_findnotifynext);
3515 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
3516 ¶ms, total_params, &data, total_data);
3517 END_PROFILE_NESTED(Trans2_findnotifynext);
3519 case TRANSACT2_MKDIR:
3520 START_PROFILE_NESTED(Trans2_mkdir);
3521 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
3522 ¶ms, total_params, &data, total_data);
3523 END_PROFILE_NESTED(Trans2_mkdir);
3526 case TRANSACT2_GET_DFS_REFERRAL:
3527 START_PROFILE_NESTED(Trans2_get_dfs_referral);
3528 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
3529 ¶ms, total_params, &data, total_data);
3530 END_PROFILE_NESTED(Trans2_get_dfs_referral);
3532 case TRANSACT2_IOCTL:
3533 START_PROFILE_NESTED(Trans2_ioctl);
3534 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
3535 ¶ms, total_params, &data, total_data);
3536 END_PROFILE_NESTED(Trans2_ioctl);
3539 /* Error in request */
3540 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
3543 END_PROFILE(SMBtrans2);
3544 return ERROR_DOS(ERRSRV,ERRerror);
3547 /* As we do not know how many data packets will need to be
3548 returned here the various call_trans2xxxx calls
3549 must send their own. Thus a call_trans2xxx routine only
3550 returns a value other than -1 when it wants to send
3556 END_PROFILE(SMBtrans2);
3557 return outsize; /* If a correct response was needed the
3558 call_trans2xxx calls have already sent
3559 it. If outsize != -1 then it is returning */
3565 END_PROFILE(SMBtrans2);
3566 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);