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 (SMB_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 (SMB_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);
735 SIVAL(p,4,0); /* ea size */
736 len = srvstr_push(outbuf, p+8, 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));
1325 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1327 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1328 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1329 return ERROR_DOS(ERRSRV,ERRinvdevice);
1332 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1333 if ( pdata == NULL )
1334 return ERROR_DOS(ERRDOS,ERRnomem);
1337 memset((char *)pdata,'\0',max_data_bytes + 1024);
1339 switch (info_level) {
1340 case SMB_INFO_ALLOCATION:
1342 SMB_BIG_UINT dfree,dsize,bsize;
1344 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1345 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1346 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1347 SIVAL(pdata,l1_cUnit,dsize);
1348 SIVAL(pdata,l1_cUnitAvail,dfree);
1349 SSVAL(pdata,l1_cbSector,512);
1350 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1351 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1352 (unsigned int)dfree, 512));
1356 case SMB_INFO_VOLUME:
1357 /* Return volume name */
1359 * Add volume serial number - hash of a combination of
1360 * the called hostname and the service name.
1362 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1363 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, 0);
1364 SCVAL(pdata,l2_vol_cch,len);
1365 data_len = l2_vol_szVolLabel + len;
1366 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1367 (unsigned)st.st_ctime, len, vname));
1370 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1371 case SMB_FS_ATTRIBUTE_INFORMATION:
1374 #if defined(HAVE_SYS_QUOTAS)
1375 quota_flag = FILE_VOLUME_QUOTAS;
1378 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1379 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1380 quota_flag); /* FS ATTRIBUTES */
1382 SIVAL(pdata,4,255); /* Max filename component length */
1383 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1384 and will think we can't do long filenames */
1385 len = srvstr_push(outbuf, pdata+12, fstype, -1, 0);
1387 data_len = 12 + len;
1390 case SMB_QUERY_FS_LABEL_INFO:
1391 case SMB_FS_LABEL_INFORMATION:
1392 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1397 case SMB_QUERY_FS_VOLUME_INFO:
1398 case SMB_FS_VOLUME_INFORMATION:
1401 * Add volume serial number - hash of a combination of
1402 * the called hostname and the service name.
1404 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1405 (str_checksum(local_machine)<<16));
1407 len = srvstr_push(outbuf, pdata+18, vname, -1, 0);
1408 SIVAL(pdata,12,len);
1410 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1411 (int)strlen(vname),vname, lp_servicename(snum)));
1414 case SMB_QUERY_FS_SIZE_INFO:
1415 case SMB_FS_SIZE_INFORMATION:
1417 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1419 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1420 block_size = lp_block_size(snum);
1421 if (bsize < block_size) {
1422 SMB_BIG_UINT factor = block_size/bsize;
1427 if (bsize > block_size) {
1428 SMB_BIG_UINT factor = bsize/block_size;
1433 bytes_per_sector = 512;
1434 sectors_per_unit = bsize/bytes_per_sector;
1435 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1436 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1437 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1438 SBIG_UINT(pdata,0,dsize);
1439 SBIG_UINT(pdata,8,dfree);
1440 SIVAL(pdata,16,sectors_per_unit);
1441 SIVAL(pdata,20,bytes_per_sector);
1445 case SMB_FS_FULL_SIZE_INFORMATION:
1447 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1449 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1450 block_size = lp_block_size(snum);
1451 if (bsize < block_size) {
1452 SMB_BIG_UINT factor = block_size/bsize;
1457 if (bsize > block_size) {
1458 SMB_BIG_UINT factor = bsize/block_size;
1463 bytes_per_sector = 512;
1464 sectors_per_unit = bsize/bytes_per_sector;
1465 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1466 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1467 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1468 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1469 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1470 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1471 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1472 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1476 case SMB_QUERY_FS_DEVICE_INFO:
1477 case SMB_FS_DEVICE_INFORMATION:
1479 SIVAL(pdata,0,0); /* dev type */
1480 SIVAL(pdata,4,0); /* characteristics */
1483 #ifdef HAVE_SYS_QUOTAS
1484 case SMB_FS_QUOTA_INFORMATION:
1486 * what we have to send --metze:
1488 * Unknown1: 24 NULL bytes
1489 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1490 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1491 * Quota Flags: 2 byte :
1492 * Unknown3: 6 NULL bytes
1496 * details for Quota Flags:
1498 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1499 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1500 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1501 * 0x0001 Enable Quotas: enable quota for this fs
1505 /* we need to fake up a fsp here,
1506 * because its not send in this call
1509 SMB_NTQUOTA_STRUCT quotas;
1512 ZERO_STRUCT(quotas);
1519 if (conn->admin_user != True) {
1520 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1521 lp_servicename(SNUM(conn)),conn->user));
1522 return ERROR_DOS(ERRDOS,ERRnoaccess);
1525 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1526 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1527 return ERROR_DOS(ERRSRV,ERRerror);
1532 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
1534 /* Unknown1 24 NULL bytes*/
1535 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
1536 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
1537 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
1539 /* Default Soft Quota 8 bytes */
1540 SBIG_UINT(pdata,24,quotas.softlim);
1542 /* Default Hard Quota 8 bytes */
1543 SBIG_UINT(pdata,32,quotas.hardlim);
1545 /* Quota flag 2 bytes */
1546 SSVAL(pdata,40,quotas.qflags);
1548 /* Unknown3 6 NULL bytes */
1554 #endif /* HAVE_SYS_QUOTAS */
1555 case SMB_FS_OBJECTID_INFORMATION:
1560 * Query the version and capabilities of the CIFS UNIX extensions
1564 case SMB_QUERY_CIFS_UNIX_INFO:
1565 if (!lp_unix_extensions())
1566 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1568 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
1569 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
1570 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
1573 case SMB_MAC_QUERY_FS_INFO:
1575 * Thursby MAC extension... ONLY on NTFS filesystems
1576 * once we do streams then we don't need this
1578 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1580 SIVAL(pdata,84,0x100); /* Don't support mac... */
1585 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1589 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1591 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1596 #ifdef HAVE_SYS_QUOTAS
1597 /****************************************************************************
1598 Reply to a TRANS2_SETFSINFO (set filesystem info).
1599 ****************************************************************************/
1601 static int call_trans2setfsinfo(connection_struct *conn,
1602 char *inbuf, char *outbuf, int length, int bufsize,
1603 char **pparams, int total_params, char **ppdata, int total_data)
1605 char *pdata = *ppdata;
1606 char *params = *pparams;
1607 files_struct *fsp = NULL;
1610 SMB_NTQUOTA_STRUCT quotas;
1612 ZERO_STRUCT(quotas);
1614 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
1617 if ((conn->admin_user != True)||!CAN_WRITE(conn)) {
1618 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1619 lp_servicename(SNUM(conn)),conn->user));
1620 return ERROR_DOS(ERRSRV,ERRaccess);
1624 if (total_params < 4) {
1625 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
1627 return ERROR_DOS(ERRDOS,ERRinvalidparam);
1630 fsp = file_fsp(params,0);
1632 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
1633 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
1634 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
1637 info_level = SVAL(params,2);
1639 switch(info_level) {
1640 case SMB_FS_QUOTA_INFORMATION:
1641 /* note: normaly there're 48 bytes,
1642 * but we didn't use the last 6 bytes for now
1645 if (total_data < 42) {
1646 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
1648 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1651 /* unknown_1 24 NULL bytes in pdata*/
1653 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
1654 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
1655 #ifdef LARGE_SMB_OFF_T
1656 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
1657 #else /* LARGE_SMB_OFF_T */
1658 if ((IVAL(pdata,28) != 0)&&
1659 ((quotas.softlim != 0xFFFFFFFF)||
1660 (IVAL(pdata,28)!=0xFFFFFFFF))) {
1661 /* more than 32 bits? */
1662 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1664 #endif /* LARGE_SMB_OFF_T */
1666 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
1667 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
1668 #ifdef LARGE_SMB_OFF_T
1669 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
1670 #else /* LARGE_SMB_OFF_T */
1671 if ((IVAL(pdata,36) != 0)&&
1672 ((quotas.hardlim != 0xFFFFFFFF)||
1673 (IVAL(pdata,36)!=0xFFFFFFFF))) {
1674 /* more than 32 bits? */
1675 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1677 #endif /* LARGE_SMB_OFF_T */
1679 /* quota_flags 2 bytes **/
1680 quotas.qflags = SVAL(pdata,40);
1682 /* unknown_2 6 NULL bytes follow*/
1684 /* now set the quotas */
1685 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1686 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1687 return ERROR_DOS(ERRSRV,ERRerror);
1692 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
1694 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1699 * sending this reply works fine,
1700 * but I'm not sure it's the same
1701 * like windows do...
1704 outsize = set_message(outbuf,10,0,True);
1708 #endif /* HAVE_SYS_QUOTAS */
1710 /****************************************************************************
1711 * Utility function to set bad path error.
1712 ****************************************************************************/
1714 NTSTATUS set_bad_path_error(int err, BOOL bad_path)
1716 if((err == ENOENT) && bad_path) {
1717 unix_ERR_class = ERRDOS;
1718 unix_ERR_code = ERRbadpath;
1719 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1721 return NT_STATUS_OK;
1724 /****************************************************************************
1725 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1726 file name or file id).
1727 ****************************************************************************/
1729 static int call_trans2qfilepathinfo(connection_struct *conn,
1730 char *inbuf, char *outbuf, int length,
1732 char **pparams, int total_params, char **ppdata, int total_data)
1734 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1735 char *params = *pparams;
1736 char *pdata = *ppdata;
1737 uint16 tran_call = SVAL(inbuf, smb_setup0);
1740 SMB_OFF_T file_size=0;
1741 SMB_BIG_UINT allocation_size=0;
1742 unsigned int data_size;
1743 SMB_STRUCT_STAT sbuf;
1744 pstring fname, dos_fname;
1749 BOOL bad_path = False;
1750 BOOL delete_pending = False;
1753 files_struct *fsp = NULL;
1756 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1758 if (tran_call == TRANSACT2_QFILEINFO) {
1759 if (total_params < 4)
1760 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1762 fsp = file_fsp(params,0);
1763 info_level = SVAL(params,2);
1765 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1767 if(fsp && (fsp->fake_file_handle)) {
1769 * This is actually for the QUOTA_FAKE_FILE --metze
1772 pstrcpy(fname, fsp->fsp_name);
1773 unix_convert(fname,conn,0,&bad_path,&sbuf);
1774 if (!check_name(fname,conn)) {
1775 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
1776 set_bad_path_error(errno, bad_path);
1777 return(UNIXERROR(ERRDOS,ERRbadpath));
1780 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1782 * This is actually a QFILEINFO on a directory
1783 * handle (returned from an NT SMB). NT5.0 seems
1784 * to do this call. JRA.
1786 pstrcpy(fname, fsp->fsp_name);
1787 unix_convert(fname,conn,0,&bad_path,&sbuf);
1788 if (!check_name(fname,conn)) {
1789 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1790 set_bad_path_error(errno, bad_path);
1791 return(UNIXERROR(ERRDOS,ERRbadpath));
1794 if (INFO_LEVEL_IS_UNIX(info_level)) {
1795 /* Always do lstat for UNIX calls. */
1796 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
1797 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1798 set_bad_path_error(errno, bad_path);
1799 return(UNIXERROR(ERRDOS,ERRbadpath));
1801 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
1802 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1803 set_bad_path_error(errno, bad_path);
1804 return(UNIXERROR(ERRDOS,ERRbadpath));
1807 delete_pending = fsp->directory_delete_on_close;
1810 * Original code - this is an open file.
1812 CHECK_FSP(fsp,conn);
1814 pstrcpy(fname, fsp->fsp_name);
1815 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
1816 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1817 return(UNIXERROR(ERRDOS,ERRbadfid));
1819 if((pos = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1820 return(UNIXERROR(ERRDOS,ERRnoaccess));
1822 delete_pending = fsp->delete_on_close;
1826 if (total_params < 6)
1827 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1829 info_level = SVAL(params,0);
1831 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1833 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1835 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1837 unix_convert(fname,conn,0,&bad_path,&sbuf);
1838 if (!check_name(fname,conn)) {
1839 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1840 set_bad_path_error(errno, bad_path);
1841 return(UNIXERROR(ERRDOS,ERRbadpath));
1844 if (INFO_LEVEL_IS_UNIX(info_level)) {
1845 /* Always do lstat for UNIX calls. */
1846 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
1847 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1848 set_bad_path_error(errno, bad_path);
1849 return(UNIXERROR(ERRDOS,ERRbadpath));
1851 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
1852 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1853 set_bad_path_error(errno, bad_path);
1854 return(UNIXERROR(ERRDOS,ERRbadpath));
1858 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
1859 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1861 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1862 fname,info_level,tran_call,total_data));
1864 p = strrchr_m(fname,'/');
1870 mode = dos_mode(conn,fname,&sbuf);
1871 fullpathname = fname;
1872 file_size = get_file_size(sbuf);
1873 allocation_size = get_allocation_size(fsp,&sbuf);
1877 params = Realloc(*pparams,2);
1879 return ERROR_DOS(ERRDOS,ERRnomem);
1881 memset((char *)params,'\0',2);
1882 data_size = max_data_bytes + 1024;
1883 pdata = Realloc(*ppdata, data_size);
1884 if ( pdata == NULL )
1885 return ERROR_DOS(ERRDOS,ERRnomem);
1888 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1889 /* uggh, EAs for OS2 */
1890 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1891 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1894 memset((char *)pdata,'\0',data_size);
1896 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1898 if (lp_dos_filetime_resolution(SNUM(conn))) {
1900 sbuf.st_atime &= ~1;
1901 sbuf.st_mtime &= ~1;
1902 sbuf.st_mtime &= ~1;
1905 /* NT expects the name to be in an exact form of the *full*
1906 filename. See the trans2 torture test */
1907 if (strequal(base_name,".")) {
1908 pstrcpy(dos_fname, "\\");
1910 snprintf(dos_fname, sizeof(dos_fname), "\\%s", fname);
1911 string_replace(dos_fname, '/', '\\');
1914 switch (info_level) {
1915 case SMB_INFO_STANDARD:
1916 case SMB_INFO_QUERY_EA_SIZE:
1917 data_size = (info_level==1?22:26);
1918 put_dos_date2(pdata,l1_fdateCreation,c_time);
1919 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1920 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1921 SIVAL(pdata,l1_cbFile,(uint32)file_size);
1922 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1923 SSVAL(pdata,l1_attrFile,mode);
1924 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1927 case SMB_INFO_IS_NAME_VALID:
1928 if (tran_call == TRANSACT2_QFILEINFO) {
1929 /* os/2 needs this ? really ?*/
1930 return ERROR_DOS(ERRDOS,ERRbadfunc);
1935 case SMB_INFO_QUERY_EAS_FROM_LIST:
1937 put_dos_date2(pdata,0,c_time);
1938 put_dos_date2(pdata,4,sbuf.st_atime);
1939 put_dos_date2(pdata,8,sbuf.st_mtime);
1940 SIVAL(pdata,12,(uint32)file_size);
1941 SIVAL(pdata,16,(uint32)allocation_size);
1942 SIVAL(pdata,20,mode);
1945 case SMB_INFO_QUERY_ALL_EAS:
1947 SIVAL(pdata,0,data_size);
1950 case SMB_FILE_BASIC_INFORMATION:
1951 case SMB_QUERY_FILE_BASIC_INFO:
1953 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1954 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1959 put_long_date(pdata,c_time);
1960 put_long_date(pdata+8,sbuf.st_atime);
1961 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1962 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1963 SIVAL(pdata,32,mode);
1965 DEBUG(5,("SMB_QFBI - "));
1967 time_t create_time = c_time;
1968 DEBUG(5,("create: %s ", ctime(&create_time)));
1970 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1971 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1972 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1973 DEBUG(5,("mode: %x\n", mode));
1977 case SMB_FILE_STANDARD_INFORMATION:
1978 case SMB_QUERY_FILE_STANDARD_INFO:
1981 SOFF_T(pdata,0,allocation_size);
1982 SOFF_T(pdata,8,file_size);
1983 SIVAL(pdata,16,sbuf.st_nlink);
1985 SCVAL(pdata,21,(mode&aDIR)?1:0);
1988 case SMB_FILE_EA_INFORMATION:
1989 case SMB_QUERY_FILE_EA_INFO:
1993 /* Get the 8.3 name - used if NT SMB was negotiated. */
1994 case SMB_QUERY_FILE_ALT_NAME_INFO:
1995 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1999 pstrcpy(short_name,base_name);
2000 /* Mangle if not already 8.3 */
2001 if(!mangle_is_8_3(short_name, True)) {
2002 mangle_map(short_name,True,True,SNUM(conn));
2004 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2005 data_size = 4 + len;
2010 case SMB_QUERY_FILE_NAME_INFO:
2012 this must be *exactly* right for ACLs on mapped drives to work
2014 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2015 data_size = 4 + len;
2019 case SMB_FILE_ALLOCATION_INFORMATION:
2020 case SMB_QUERY_FILE_ALLOCATION_INFO:
2022 SOFF_T(pdata,0,allocation_size);
2025 case SMB_FILE_END_OF_FILE_INFORMATION:
2026 case SMB_QUERY_FILE_END_OF_FILEINFO:
2028 SOFF_T(pdata,0,file_size);
2031 case SMB_QUERY_FILE_ALL_INFO:
2032 case SMB_FILE_ALL_INFORMATION:
2033 put_long_date(pdata,c_time);
2034 put_long_date(pdata+8,sbuf.st_atime);
2035 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2036 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2037 SIVAL(pdata,32,mode);
2039 SOFF_T(pdata,0,allocation_size);
2040 SOFF_T(pdata,8,file_size);
2041 SIVAL(pdata,16,sbuf.st_nlink);
2042 SCVAL(pdata,20,delete_pending);
2043 SCVAL(pdata,21,(mode&aDIR)?1:0);
2045 pdata += 4; /* EA info */
2046 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, 0);
2049 data_size = PTR_DIFF(pdata,(*ppdata));
2052 case SMB_FILE_INTERNAL_INFORMATION:
2053 /* This should be an index number - looks like
2056 I think this causes us to fail the IFSKIT
2057 BasicFileInformationTest. -tpot */
2059 SIVAL(pdata,0,sbuf.st_dev);
2060 SIVAL(pdata,4,sbuf.st_ino);
2064 case SMB_FILE_ACCESS_INFORMATION:
2065 SIVAL(pdata,0,0x12019F); /* ??? */
2069 case SMB_FILE_NAME_INFORMATION:
2070 /* Pathname with leading '\'. */
2073 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2074 SIVAL(pdata,0,byte_len);
2075 data_size = 4 + byte_len;
2079 case SMB_FILE_DISPOSITION_INFORMATION:
2081 SCVAL(pdata,0,delete_pending);
2084 case SMB_FILE_POSITION_INFORMATION:
2086 SOFF_T(pdata,0,pos);
2089 case SMB_FILE_MODE_INFORMATION:
2090 SIVAL(pdata,0,mode);
2094 case SMB_FILE_ALIGNMENT_INFORMATION:
2095 SIVAL(pdata,0,0); /* No alignment needed. */
2101 * NT4 server just returns "invalid query" to this - if we try to answer
2102 * it then NTws gets a BSOD! (tridge).
2103 * W2K seems to want this. JRA.
2105 case SMB_QUERY_FILE_STREAM_INFO:
2107 case SMB_FILE_STREAM_INFORMATION:
2111 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2112 SIVAL(pdata,0,0); /* ??? */
2113 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2114 SOFF_T(pdata,8,file_size);
2115 SIVAL(pdata,16,allocation_size);
2116 SIVAL(pdata,20,0); /* ??? */
2117 data_size = 24 + byte_len;
2121 case SMB_QUERY_COMPRESSION_INFO:
2122 case SMB_FILE_COMPRESSION_INFORMATION:
2123 SOFF_T(pdata,0,file_size);
2124 SIVAL(pdata,8,0); /* ??? */
2125 SIVAL(pdata,12,0); /* ??? */
2129 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2130 put_long_date(pdata,c_time);
2131 put_long_date(pdata+8,sbuf.st_atime);
2132 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2133 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2134 SIVAL(pdata,32,allocation_size);
2135 SOFF_T(pdata,40,file_size);
2136 SIVAL(pdata,48,mode);
2137 SIVAL(pdata,52,0); /* ??? */
2141 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2142 SIVAL(pdata,0,mode);
2148 * CIFS UNIX Extensions.
2151 case SMB_QUERY_FILE_UNIX_BASIC:
2153 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2155 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2158 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2161 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2162 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2163 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2166 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2170 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2174 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2177 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2181 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2185 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2188 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2192 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2195 data_size = PTR_DIFF(pdata,(*ppdata));
2199 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2201 for (i=0; i<100; i++)
2202 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2208 case SMB_QUERY_FILE_UNIX_LINK:
2213 if(!S_ISLNK(sbuf.st_mode))
2214 return(UNIXERROR(ERRSRV,ERRbadlink));
2216 return(UNIXERROR(ERRDOS,ERRbadlink));
2218 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2220 return(UNIXERROR(ERRDOS,ERRnoaccess));
2222 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2224 data_size = PTR_DIFF(pdata,(*ppdata));
2230 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2233 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
2238 /****************************************************************************
2239 Deal with the internal needs of setting the delete on close flag. Note that
2240 as the tdb locking is recursive, it is safe to call this from within
2241 open_file_shared. JRA.
2242 ****************************************************************************/
2244 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
2247 * Only allow delete on close for writable shares.
2250 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
2251 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2253 return NT_STATUS_ACCESS_DENIED;
2256 * Only allow delete on close for files/directories opened with delete intent.
2259 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
2260 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2262 return NT_STATUS_ACCESS_DENIED;
2265 if(fsp->is_directory) {
2266 fsp->directory_delete_on_close = delete_on_close;
2267 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2268 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2270 fsp->delete_on_close = delete_on_close;
2271 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2272 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2275 return NT_STATUS_OK;
2278 /****************************************************************************
2279 Sets the delete on close flag over all share modes on this file.
2280 Modify the share mode entry for all files open
2281 on this device and inode to tell other smbds we have
2282 changed the delete on close flag. This will be noticed
2283 in the close code, the last closer will delete the file
2285 ****************************************************************************/
2287 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
2289 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2290 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2292 if (fsp->is_directory || fsp->is_stat)
2293 return NT_STATUS_OK;
2295 if (lock_share_entry_fsp(fsp) == False)
2296 return NT_STATUS_ACCESS_DENIED;
2298 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2299 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2301 unlock_share_entry_fsp(fsp);
2302 return NT_STATUS_ACCESS_DENIED;
2305 unlock_share_entry_fsp(fsp);
2306 return NT_STATUS_OK;
2309 /****************************************************************************
2310 Returns true if this pathname is within the share, and thus safe.
2311 ****************************************************************************/
2313 static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in, char *link_dest_out)
2316 char resolved_name[PATH_MAX+1];
2318 pstring resolved_name;
2320 fstring last_component;
2324 BOOL bad_path = False;
2325 SMB_STRUCT_STAT sbuf;
2327 pstrcpy(link_dest, link_dest_in);
2328 unix_convert(link_dest,conn,0,&bad_path,&sbuf);
2330 /* Store the UNIX converted path. */
2331 pstrcpy(link_dest_out, link_dest);
2333 p = strrchr(link_dest, '/');
2335 fstrcpy(last_component, p+1);
2338 fstrcpy(last_component, link_dest);
2339 pstrcpy(link_dest, "./");
2342 if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
2345 pstrcpy(link_dest, resolved_name);
2346 pstrcat(link_dest, "/");
2347 pstrcat(link_dest, last_component);
2349 if (*link_dest != '/') {
2350 /* Relative path. */
2351 pstrcpy(link_test, conn->connectpath);
2352 pstrcat(link_test, "/");
2353 pstrcat(link_test, link_dest);
2355 pstrcpy(link_test, link_dest);
2359 * Check if the link is within the share.
2362 if (strncmp(conn->connectpath, link_test, strlen(conn->connectpath))) {
2369 /****************************************************************************
2370 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2371 ****************************************************************************/
2373 static int call_trans2setfilepathinfo(connection_struct *conn,
2374 char *inbuf, char *outbuf, int length, int bufsize,
2375 char **pparams, int total_params, char **ppdata, int total_data)
2377 char *params = *pparams;
2378 char *pdata = *ppdata;
2379 uint16 tran_call = SVAL(inbuf, smb_setup0);
2384 SMB_STRUCT_STAT sbuf;
2387 BOOL bad_path = False;
2388 files_struct *fsp = NULL;
2389 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
2390 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
2391 mode_t unixmode = 0;
2394 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2396 if (tran_call == TRANSACT2_SETFILEINFO) {
2397 if (total_params < 4)
2398 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2400 fsp = file_fsp(params,0);
2401 info_level = SVAL(params,2);
2403 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2405 * This is actually a SETFILEINFO on a directory
2406 * handle (returned from an NT SMB). NT5.0 seems
2407 * to do this call. JRA.
2409 pstrcpy(fname, fsp->fsp_name);
2410 unix_convert(fname,conn,0,&bad_path,&sbuf);
2411 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
2412 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2413 set_bad_path_error(errno, bad_path);
2414 return(UNIXERROR(ERRDOS,ERRbadpath));
2416 } else if (fsp && fsp->print_file) {
2418 * Doing a DELETE_ON_CLOSE should cancel a print job.
2420 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
2421 fsp->share_mode = FILE_DELETE_ON_CLOSE;
2423 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
2426 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2429 return (UNIXERROR(ERRDOS,ERRbadpath));
2432 * Original code - this is an open file.
2434 CHECK_FSP(fsp,conn);
2436 pstrcpy(fname, fsp->fsp_name);
2439 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
2440 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2441 return(UNIXERROR(ERRDOS,ERRbadfid));
2446 if (total_params < 6)
2447 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2449 info_level = SVAL(params,0);
2450 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2451 unix_convert(fname,conn,0,&bad_path,&sbuf);
2452 if(!check_name(fname, conn)) {
2453 set_bad_path_error(errno, bad_path);
2454 return(UNIXERROR(ERRDOS,ERRbadpath));
2458 * For CIFS UNIX extensions the target name may not exist.
2461 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
2462 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
2463 set_bad_path_error(errno, bad_path);
2464 return(UNIXERROR(ERRDOS,ERRbadpath));
2468 if (!CAN_WRITE(conn))
2469 return ERROR_DOS(ERRSRV,ERRaccess);
2471 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2472 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2474 if (VALID_STAT(sbuf))
2475 unixmode = sbuf.st_mode;
2477 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2478 tran_call,fname,info_level,total_data));
2480 /* Realloc the parameter and data sizes */
2481 params = Realloc(*pparams,2);
2483 return ERROR_DOS(ERRDOS,ERRnomem);
2489 /* the pending modtime overrides the current modtime */
2490 sbuf.st_mtime = fsp->pending_modtime;
2493 size = get_file_size(sbuf);
2494 tvs.modtime = sbuf.st_mtime;
2495 tvs.actime = sbuf.st_atime;
2496 dosmode = dos_mode(conn,fname,&sbuf);
2497 unixmode = sbuf.st_mode;
2499 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
2500 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
2502 switch (info_level) {
2503 case SMB_INFO_STANDARD:
2505 if (total_data < l1_cbFile+4)
2506 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2509 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2512 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2514 dosmode = SVAL(pdata,l1_attrFile);
2515 size = IVAL(pdata,l1_cbFile);
2520 case SMB_INFO_SET_EA:
2521 return(ERROR_DOS(ERRDOS,ERReasnotsupported));
2523 /* XXXX um, i don't think this is right.
2524 it's also not in the cifs6.txt spec.
2526 case SMB_INFO_QUERY_EAS_FROM_LIST:
2527 if (total_data < 28)
2528 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2530 tvs.actime = make_unix_date2(pdata+8);
2531 tvs.modtime = make_unix_date2(pdata+12);
2532 size = IVAL(pdata,16);
2533 dosmode = IVAL(pdata,24);
2536 /* XXXX nor this. not in cifs6.txt, either. */
2537 case SMB_INFO_QUERY_ALL_EAS:
2538 if (total_data < 28)
2539 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2541 tvs.actime = make_unix_date2(pdata+8);
2542 tvs.modtime = make_unix_date2(pdata+12);
2543 size = IVAL(pdata,16);
2544 dosmode = IVAL(pdata,24);
2547 case SMB_SET_FILE_BASIC_INFO:
2548 case SMB_FILE_BASIC_INFORMATION:
2550 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2552 time_t changed_time;
2554 if (total_data < 36)
2555 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2557 /* Ignore create time at offset pdata. */
2560 tvs.actime = interpret_long_date(pdata+8);
2562 write_time = interpret_long_date(pdata+16);
2563 changed_time = interpret_long_date(pdata+24);
2565 tvs.modtime = MIN(write_time, changed_time);
2567 if (write_time > tvs.modtime && write_time != 0xffffffff) {
2568 tvs.modtime = write_time;
2570 /* Prefer a defined time to an undefined one. */
2571 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2572 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2573 ? changed_time : write_time);
2576 dosmode = IVAL(pdata,32);
2580 case SMB_FILE_ALLOCATION_INFORMATION:
2581 case SMB_SET_FILE_ALLOCATION_INFO:
2584 SMB_BIG_UINT allocation_size;
2587 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2589 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
2590 #ifdef LARGE_SMB_OFF_T
2591 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
2592 #else /* LARGE_SMB_OFF_T */
2593 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2594 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2595 #endif /* LARGE_SMB_OFF_T */
2596 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2597 fname, (double)allocation_size ));
2599 if (allocation_size)
2600 allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
2602 if(allocation_size != get_file_size(sbuf)) {
2603 SMB_STRUCT_STAT new_sbuf;
2605 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2606 fname, (double)allocation_size ));
2609 files_struct *new_fsp = NULL;
2610 int access_mode = 0;
2613 if(global_oplock_break) {
2614 /* Queue this file modify as we are the process of an oplock break. */
2616 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2617 DEBUGADD(2,( "in oplock break state.\n"));
2619 push_oplock_pending_smb_message(inbuf, length);
2623 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
2624 SET_OPEN_MODE(DOS_OPEN_RDWR),
2625 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2626 0, 0, &access_mode, &action);
2628 if (new_fsp == NULL)
2629 return(UNIXERROR(ERRDOS,ERRbadpath));
2630 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2631 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2632 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2633 new_fsp->fnum, strerror(errno)));
2636 close_file(new_fsp,True);
2638 ret = vfs_allocate_file_space(fsp, allocation_size);
2639 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
2640 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2641 fsp->fnum, strerror(errno)));
2646 return ERROR_NT(NT_STATUS_DISK_FULL);
2648 /* Allocate can truncate size... */
2649 size = get_file_size(new_sbuf);
2655 case SMB_FILE_END_OF_FILE_INFORMATION:
2656 case SMB_SET_FILE_END_OF_FILE_INFO:
2659 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2661 size = IVAL(pdata,0);
2662 #ifdef LARGE_SMB_OFF_T
2663 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2664 #else /* LARGE_SMB_OFF_T */
2665 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2666 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2667 #endif /* LARGE_SMB_OFF_T */
2668 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2672 case SMB_FILE_DISPOSITION_INFORMATION:
2673 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2675 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2679 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2681 if (tran_call != TRANSACT2_SETFILEINFO)
2682 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2685 return(UNIXERROR(ERRDOS,ERRbadfid));
2687 status = set_delete_on_close_internal(fsp, delete_on_close);
2689 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2690 return ERROR_NT(status);
2692 /* The set is across all open files on this dev/inode pair. */
2693 status =set_delete_on_close_over_all(fsp, delete_on_close);
2694 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2695 return ERROR_NT(status);
2701 * CIFS UNIX extensions.
2704 case SMB_SET_FILE_UNIX_BASIC:
2706 uint32 raw_unixmode;
2708 if (total_data < 100)
2709 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2711 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
2712 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
2713 size=IVAL(pdata,0); /* first 8 Bytes are size */
2714 #ifdef LARGE_SMB_OFF_T
2715 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2716 #else /* LARGE_SMB_OFF_T */
2717 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2718 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2719 #endif /* LARGE_SMB_OFF_T */
2721 pdata+=24; /* ctime & st_blocks are not changed */
2722 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
2723 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
2725 set_owner = (uid_t)IVAL(pdata,0);
2727 set_grp = (gid_t)IVAL(pdata,0);
2729 raw_unixmode = IVAL(pdata,28);
2730 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
2731 dosmode = 0; /* Ensure dos mode change doesn't override this. */
2733 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2734 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2735 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
2737 if (!VALID_STAT(sbuf)) {
2740 * The only valid use of this is to create character and block
2741 * devices, and named pipes. This is deprecated (IMHO) and
2742 * a new info level should be used for mknod. JRA.
2745 #if !defined(HAVE_MAKEDEV_FN)
2746 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2747 #else /* HAVE_MAKEDEV_FN */
2748 uint32 file_type = IVAL(pdata,0);
2749 uint32 dev_major = IVAL(pdata,4);
2750 uint32 dev_minor = IVAL(pdata,12);
2752 uid_t myuid = geteuid();
2753 gid_t mygid = getegid();
2756 if (tran_call == TRANSACT2_SETFILEINFO)
2757 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2759 if (raw_unixmode == SMB_MODE_NO_CHANGE)
2760 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2762 dev = makedev(dev_major, dev_minor);
2764 /* We can only create as the owner/group we are. */
2766 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
2767 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2768 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
2769 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2771 if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
2772 file_type != UNIX_TYPE_FIFO)
2773 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2775 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2776 0%o for file %s\n", (double)dev, unixmode, fname ));
2778 /* Ok - do the mknod. */
2779 if (SMB_VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
2780 return(UNIXERROR(ERRDOS,ERRnoaccess));
2782 inherit_access_acl(conn, fname, unixmode);
2785 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2787 #endif /* HAVE_MAKEDEV_FN */
2792 * Deal with the UNIX specific mode set.
2795 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
2796 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
2797 (unsigned int)unixmode, fname ));
2798 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
2799 return(UNIXERROR(ERRDOS,ERRnoaccess));
2803 * Deal with the UNIX specific uid set.
2806 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
2807 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
2808 (unsigned int)set_owner, fname ));
2809 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
2810 return(UNIXERROR(ERRDOS,ERRnoaccess));
2814 * Deal with the UNIX specific gid set.
2817 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
2818 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
2819 (unsigned int)set_owner, fname ));
2820 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
2821 return(UNIXERROR(ERRDOS,ERRnoaccess));
2826 case SMB_SET_FILE_UNIX_LINK:
2829 /* Set a symbolic link. */
2830 /* Don't allow this if follow links is false. */
2832 if (!lp_symlinks(SNUM(conn)))
2833 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2835 /* Disallow if already exists. */
2836 if (VALID_STAT(sbuf))
2837 return(ERROR_DOS(ERRDOS,ERRbadpath));
2839 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2841 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2842 return(UNIXERROR(ERRDOS,ERRnoaccess));
2844 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
2845 fname, link_dest ));
2847 if (SMB_VFS_SYMLINK(conn,link_dest,fname) != 0)
2848 return(UNIXERROR(ERRDOS,ERRnoaccess));
2850 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2854 case SMB_SET_FILE_UNIX_HLINK:
2858 /* Set a hard link. */
2860 /* Disallow if already exists. */
2861 if (VALID_STAT(sbuf))
2862 return(ERROR_DOS(ERRDOS,ERRbadpath));
2864 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2866 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2867 return(UNIXERROR(ERRDOS,ERRnoaccess));
2869 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
2870 fname, link_dest ));
2872 if (SMB_VFS_LINK(conn,link_dest,fname) != 0)
2873 return(UNIXERROR(ERRDOS,ERRnoaccess));
2875 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2880 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2883 /* get some defaults (no modifications) if any info is zero or -1. */
2884 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2885 tvs.actime = sbuf.st_atime;
2887 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2888 tvs.modtime = sbuf.st_mtime;
2890 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2891 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2892 DEBUG(6,("size: %.0f ", (double)size));
2894 if (S_ISDIR(sbuf.st_mode))
2899 DEBUG(6,("dosmode: %x\n" , dosmode));
2901 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2902 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2903 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2904 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2907 * Only do this test if we are not explicitly
2908 * changing the size of a file.
2911 size = get_file_size(sbuf);
2915 * Try and set the times, size and mode of this file -
2916 * if they are different from the current values
2918 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2921 * This was a setfileinfo on an open file.
2922 * NT does this a lot. It's actually pointless
2923 * setting the time here, as it will be overwritten
2924 * on the next write, so we save the request
2925 * away and will set it on file close. JRA.
2928 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2929 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2930 fsp->pending_modtime = tvs.modtime;
2935 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2937 if(file_utime(conn, fname, &tvs)!=0)
2938 return(UNIXERROR(ERRDOS,ERRnoaccess));
2942 /* check the mode isn't different, before changing it */
2943 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
2945 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
2947 if(file_chmod(conn, fname, dosmode, NULL)) {
2948 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2949 return(UNIXERROR(ERRDOS,ERRnoaccess));
2953 if (size != get_file_size(sbuf)) {
2957 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2958 fname, (double)size ));
2961 files_struct *new_fsp = NULL;
2962 int access_mode = 0;
2965 if(global_oplock_break) {
2966 /* Queue this file modify as we are the process of an oplock break. */
2968 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2969 DEBUGADD(2,( "in oplock break state.\n"));
2971 push_oplock_pending_smb_message(inbuf, length);
2975 new_fsp = open_file_shared(conn, fname, &sbuf,
2976 SET_OPEN_MODE(DOS_OPEN_RDWR),
2977 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2978 0, 0, &access_mode, &action);
2980 if (new_fsp == NULL)
2981 return(UNIXERROR(ERRDOS,ERRbadpath));
2982 ret = vfs_set_filelen(new_fsp, size);
2983 close_file(new_fsp,True);
2985 ret = vfs_set_filelen(fsp, size);
2989 return (UNIXERROR(ERRHRD,ERRdiskfull));
2993 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2998 /****************************************************************************
2999 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3000 ****************************************************************************/
3002 static int call_trans2mkdir(connection_struct *conn,
3003 char *inbuf, char *outbuf, int length, int bufsize,
3004 char **pparams, int total_params, char **ppdata, int total_data)
3006 char *params = *pparams;
3009 SMB_STRUCT_STAT sbuf;
3010 BOOL bad_path = False;
3012 if (!CAN_WRITE(conn))
3013 return ERROR_DOS(ERRSRV,ERRaccess);
3015 if (total_params < 4)
3016 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3018 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
3020 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3022 unix_convert(directory,conn,0,&bad_path,&sbuf);
3023 if (check_name(directory,conn))
3024 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3027 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3028 set_bad_path_error(errno, bad_path);
3029 return(UNIXERROR(ERRDOS,ERRnoaccess));
3032 /* Realloc the parameter and data sizes */
3033 params = Realloc(*pparams,2);
3035 return ERROR_DOS(ERRDOS,ERRnomem);
3040 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3045 /****************************************************************************
3046 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3047 We don't actually do this - we just send a null response.
3048 ****************************************************************************/
3050 static int call_trans2findnotifyfirst(connection_struct *conn,
3051 char *inbuf, char *outbuf, int length, int bufsize,
3052 char **pparams, int total_params, char **ppdata, int total_data)
3054 static uint16 fnf_handle = 257;
3055 char *params = *pparams;
3058 if (total_params < 6)
3059 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3061 info_level = SVAL(params,4);
3062 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3064 switch (info_level) {
3069 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3072 /* Realloc the parameter and data sizes */
3073 params = Realloc(*pparams,6);
3075 return ERROR_DOS(ERRDOS,ERRnomem);
3078 SSVAL(params,0,fnf_handle);
3079 SSVAL(params,2,0); /* No changes */
3080 SSVAL(params,4,0); /* No EA errors */
3087 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
3092 /****************************************************************************
3093 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3094 changes). Currently this does nothing.
3095 ****************************************************************************/
3097 static int call_trans2findnotifynext(connection_struct *conn,
3098 char *inbuf, char *outbuf, int length, int bufsize,
3099 char **pparams, int total_params, char **ppdata, int total_data)
3101 char *params = *pparams;
3103 DEBUG(3,("call_trans2findnotifynext\n"));
3105 /* Realloc the parameter and data sizes */
3106 params = Realloc(*pparams,4);
3108 return ERROR_DOS(ERRDOS,ERRnomem);
3111 SSVAL(params,0,0); /* No changes */
3112 SSVAL(params,2,0); /* No EA errors */
3114 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
3119 /****************************************************************************
3120 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3121 ****************************************************************************/
3123 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
3124 char* outbuf, int length, int bufsize,
3125 char **pparams, int total_params, char **ppdata, int total_data)
3127 char *params = *pparams;
3130 int max_referral_level;
3132 DEBUG(10,("call_trans2getdfsreferral\n"));
3134 if (total_params < 2)
3135 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3137 max_referral_level = SVAL(params,0);
3139 if(!lp_host_msdfs())
3140 return ERROR_DOS(ERRDOS,ERRbadfunc);
3142 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
3144 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
3145 return ERROR_DOS(ERRDOS,ERRbadfile);
3147 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
3148 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
3153 #define LMCAT_SPL 0x53
3154 #define LMFUNC_GETJOBID 0x60
3156 /****************************************************************************
3157 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3158 ****************************************************************************/
3160 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
3161 char* outbuf, int length, int bufsize,
3162 char **pparams, int total_params, char **ppdata, int total_data)
3164 char *pdata = *ppdata;
3165 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
3167 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3168 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3169 pdata = Realloc(*ppdata, 32);
3171 return ERROR_DOS(ERRDOS,ERRnomem);
3174 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3175 CAN ACCEPT THIS IN UNICODE. JRA. */
3177 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
3178 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3179 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3180 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3183 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3184 return ERROR_DOS(ERRSRV,ERRerror);
3188 /****************************************************************************
3189 Reply to a SMBfindclose (stop trans2 directory search).
3190 ****************************************************************************/
3192 int reply_findclose(connection_struct *conn,
3193 char *inbuf,char *outbuf,int length,int bufsize)
3196 int dptr_num=SVALS(inbuf,smb_vwv0);
3197 START_PROFILE(SMBfindclose);
3199 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3201 dptr_close(&dptr_num);
3203 outsize = set_message(outbuf,0,0,True);
3205 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3207 END_PROFILE(SMBfindclose);
3211 /****************************************************************************
3212 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3213 ****************************************************************************/
3215 int reply_findnclose(connection_struct *conn,
3216 char *inbuf,char *outbuf,int length,int bufsize)
3220 START_PROFILE(SMBfindnclose);
3222 dptr_num = SVAL(inbuf,smb_vwv0);
3224 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3226 /* We never give out valid handles for a
3227 findnotifyfirst - so any dptr_num is ok here.
3230 outsize = set_message(outbuf,0,0,True);
3232 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3234 END_PROFILE(SMBfindnclose);
3238 /****************************************************************************
3239 Reply to a SMBtranss2 - just ignore it!
3240 ****************************************************************************/
3242 int reply_transs2(connection_struct *conn,
3243 char *inbuf,char *outbuf,int length,int bufsize)
3245 START_PROFILE(SMBtranss2);
3246 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3247 END_PROFILE(SMBtranss2);
3251 /****************************************************************************
3252 Reply to a SMBtrans2.
3253 ****************************************************************************/
3255 int reply_trans2(connection_struct *conn,
3256 char *inbuf,char *outbuf,int length,int bufsize)
3259 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
3260 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
3262 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
3263 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
3264 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
3265 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
3266 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
3267 int32 timeout = IVALS(inbuf,smb_timeout);
3269 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
3270 unsigned int tran_call = SVAL(inbuf, smb_setup0);
3271 char *params = NULL, *data = NULL;
3272 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
3273 START_PROFILE(SMBtrans2);
3275 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
3276 /* Queue this open message as we are the process of an
3279 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3280 DEBUGADD(2,( "in oplock break state.\n"));
3282 push_oplock_pending_smb_message(inbuf, length);
3283 END_PROFILE(SMBtrans2);
3287 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
3288 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
3289 END_PROFILE(SMBtrans2);
3290 return ERROR_DOS(ERRSRV,ERRaccess);
3293 outsize = set_message(outbuf,0,0,True);
3295 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3296 is so as a sanity check */
3299 * Need to have rc=0 for ioctl to get job id for OS/2.
3300 * Network printing will fail if function is not successful.
3301 * Similar function in reply.c will be used if protocol
3302 * is LANMAN1.0 instead of LM1.2X002.
3303 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3304 * outbuf doesn't have to be set(only job id is used).
3306 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
3307 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3308 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3309 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3311 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
3312 DEBUG(2,("Transaction is %d\n",tran_call));
3313 END_PROFILE(SMBtrans2);
3314 ERROR_DOS(ERRDOS,ERRinvalidparam);
3318 /* Allocate the space for the maximum needed parameters and data */
3319 if (total_params > 0)
3320 params = (char *)malloc(total_params);
3322 data = (char *)malloc(total_data);
3324 if ((total_params && !params) || (total_data && !data)) {
3325 DEBUG(2,("Out of memory in reply_trans2\n"));
3328 END_PROFILE(SMBtrans2);
3329 return ERROR_DOS(ERRDOS,ERRnomem);
3332 /* Copy the param and data bytes sent with this request into
3333 the params buffer */
3334 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
3335 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
3337 if (num_params > total_params || num_data > total_data)
3338 exit_server("invalid params in reply_trans2");
3341 unsigned int psoff = SVAL(inbuf, smb_psoff);
3342 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
3344 if (smb_base(inbuf) + psoff + num_params > inbuf + length)
3346 memcpy( params, smb_base(inbuf) + psoff, num_params);
3349 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
3350 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
3352 if (smb_base(inbuf) + dsoff + num_data > inbuf + length)
3354 memcpy( data, smb_base(inbuf) + dsoff, num_data);
3357 if(num_data_sofar < total_data || num_params_sofar < total_params) {
3358 /* We need to send an interim response then receive the rest
3359 of the parameter/data bytes */
3360 outsize = set_message(outbuf,0,0,True);
3361 if (!send_smb(smbd_server_fd(),outbuf))
3362 exit_server("reply_trans2: send_smb failed.");
3364 while (num_data_sofar < total_data ||
3365 num_params_sofar < total_params) {
3367 unsigned int param_disp;
3368 unsigned int param_off;
3369 unsigned int data_disp;
3370 unsigned int data_off;
3372 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
3375 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
3376 outsize = set_message(outbuf,0,0,True);
3378 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3380 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3381 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
3385 /* Revise total_params and total_data in case
3386 they have changed downwards */
3387 if (SVAL(inbuf, smb_tpscnt) < total_params)
3388 total_params = SVAL(inbuf, smb_tpscnt);
3389 if (SVAL(inbuf, smb_tdscnt) < total_data)
3390 total_data = SVAL(inbuf, smb_tdscnt);
3392 num_params = SVAL(inbuf,smb_spscnt);
3393 param_off = SVAL(inbuf, smb_spsoff);
3394 param_disp = SVAL(inbuf, smb_spsdisp);
3395 num_params_sofar += num_params;
3397 num_data = SVAL(inbuf, smb_sdscnt);
3398 data_off = SVAL(inbuf, smb_sdsoff);
3399 data_disp = SVAL(inbuf, smb_sdsdisp);
3400 num_data_sofar += num_data;
3402 if (num_params_sofar > total_params || num_data_sofar > total_data)
3406 if (param_disp + num_params >= total_params)
3408 if ((param_disp + num_params < param_disp) ||
3409 (param_disp + num_params < num_params))
3411 if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize)
3413 if (params + param_disp < params)
3416 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
3419 if (data_disp + num_data >= total_data)
3421 if ((data_disp + num_data < data_disp) ||
3422 (data_disp + num_data < num_data))
3424 if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize)
3426 if (data + data_disp < data)
3429 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
3434 if (Protocol >= PROTOCOL_NT1) {
3435 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
3438 /* Now we must call the relevant TRANS2 function */
3440 case TRANSACT2_OPEN:
3441 START_PROFILE_NESTED(Trans2_open);
3442 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
3443 ¶ms, total_params, &data, total_data);
3444 END_PROFILE_NESTED(Trans2_open);
3447 case TRANSACT2_FINDFIRST:
3448 START_PROFILE_NESTED(Trans2_findfirst);
3449 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
3450 ¶ms, total_params, &data, total_data);
3451 END_PROFILE_NESTED(Trans2_findfirst);
3454 case TRANSACT2_FINDNEXT:
3455 START_PROFILE_NESTED(Trans2_findnext);
3456 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
3457 ¶ms, total_params, &data, total_data);
3458 END_PROFILE_NESTED(Trans2_findnext);
3461 case TRANSACT2_QFSINFO:
3462 START_PROFILE_NESTED(Trans2_qfsinfo);
3463 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
3464 ¶ms, total_params, &data, total_data);
3465 END_PROFILE_NESTED(Trans2_qfsinfo);
3468 #ifdef HAVE_SYS_QUOTAS
3469 case TRANSACT2_SETFSINFO:
3470 START_PROFILE_NESTED(Trans2_setfsinfo);
3471 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
3472 ¶ms, total_params, &data, total_data);
3473 END_PROFILE_NESTED(Trans2_setfsinfo);
3476 case TRANSACT2_QPATHINFO:
3477 case TRANSACT2_QFILEINFO:
3478 START_PROFILE_NESTED(Trans2_qpathinfo);
3479 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3480 ¶ms, total_params, &data, total_data);
3481 END_PROFILE_NESTED(Trans2_qpathinfo);
3483 case TRANSACT2_SETPATHINFO:
3484 case TRANSACT2_SETFILEINFO:
3485 START_PROFILE_NESTED(Trans2_setpathinfo);
3486 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3487 ¶ms, total_params, &data, total_data);
3488 END_PROFILE_NESTED(Trans2_setpathinfo);
3491 case TRANSACT2_FINDNOTIFYFIRST:
3492 START_PROFILE_NESTED(Trans2_findnotifyfirst);
3493 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
3494 ¶ms, total_params, &data, total_data);
3495 END_PROFILE_NESTED(Trans2_findnotifyfirst);
3498 case TRANSACT2_FINDNOTIFYNEXT:
3499 START_PROFILE_NESTED(Trans2_findnotifynext);
3500 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
3501 ¶ms, total_params, &data, total_data);
3502 END_PROFILE_NESTED(Trans2_findnotifynext);
3504 case TRANSACT2_MKDIR:
3505 START_PROFILE_NESTED(Trans2_mkdir);
3506 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
3507 ¶ms, total_params, &data, total_data);
3508 END_PROFILE_NESTED(Trans2_mkdir);
3511 case TRANSACT2_GET_DFS_REFERRAL:
3512 START_PROFILE_NESTED(Trans2_get_dfs_referral);
3513 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
3514 ¶ms, total_params, &data, total_data);
3515 END_PROFILE_NESTED(Trans2_get_dfs_referral);
3517 case TRANSACT2_IOCTL:
3518 START_PROFILE_NESTED(Trans2_ioctl);
3519 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
3520 ¶ms, total_params, &data, total_data);
3521 END_PROFILE_NESTED(Trans2_ioctl);
3524 /* Error in request */
3525 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
3528 END_PROFILE(SMBtrans2);
3529 return ERROR_DOS(ERRSRV,ERRerror);
3532 /* As we do not know how many data packets will need to be
3533 returned here the various call_trans2xxxx calls
3534 must send their own. Thus a call_trans2xxx routine only
3535 returns a value other than -1 when it wants to send
3541 END_PROFILE(SMBtrans2);
3542 return outsize; /* If a correct response was needed the
3543 call_trans2xxx calls have already sent
3544 it. If outsize != -1 then it is returning */
3550 END_PROFILE(SMBtrans2);
3551 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);