2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
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 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
267 unixmode = unix_mode(conn,open_attr | aARCH, fname);
269 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
270 oplock_request, &rmode,&smb_action);
273 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
276 size = get_file_size(sbuf);
277 fmode = dos_mode(conn,fname,&sbuf);
278 mtime = sbuf.st_mtime;
281 close_file(fsp,False);
282 return(ERROR_DOS(ERRDOS,ERRnoaccess));
285 /* Realloc the size of parameters and data we will return */
286 params = Realloc(*pparams, 28);
288 return(ERROR_DOS(ERRDOS,ERRnomem));
291 memset((char *)params,'\0',28);
292 SSVAL(params,0,fsp->fnum);
293 SSVAL(params,2,fmode);
294 put_dos_date2(params,4, mtime);
295 SIVAL(params,8, (uint32)size);
296 SSVAL(params,12,rmode);
298 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
299 smb_action |= EXTENDED_OPLOCK_GRANTED;
301 SSVAL(params,18,smb_action);
304 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
306 SIVAL(params,20,inode);
308 /* Send the required number of replies */
309 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
314 /*********************************************************
315 Routine to check if a given string matches exactly.
316 as a special case a mask of "." does NOT match. That
317 is required for correct wildcard semantics
318 Case can be significant or not.
319 **********************************************************/
321 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
323 if (mask[0] == '.' && mask[1] == 0)
326 return strcmp(str,mask)==0;
327 if (StrCaseCmp(str,mask) != 0) {
330 if (ms_has_wild(str)) {
336 /****************************************************************************
337 Return the filetype for UNIX extensions.
338 ****************************************************************************/
340 static uint32 unix_filetype(mode_t mode)
343 return UNIX_TYPE_FILE;
344 else if(S_ISDIR(mode))
345 return UNIX_TYPE_DIR;
347 else if(S_ISLNK(mode))
348 return UNIX_TYPE_SYMLINK;
351 else if(S_ISCHR(mode))
352 return UNIX_TYPE_CHARDEV;
355 else if(S_ISBLK(mode))
356 return UNIX_TYPE_BLKDEV;
359 else if(S_ISFIFO(mode))
360 return UNIX_TYPE_FIFO;
363 else if(S_ISSOCK(mode))
364 return UNIX_TYPE_SOCKET;
367 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
368 return UNIX_TYPE_UNKNOWN;
371 /****************************************************************************
372 Return the major devicenumber for UNIX extensions.
373 ****************************************************************************/
375 static uint32 unix_dev_major(SMB_DEV_T dev)
377 #if defined(HAVE_DEVICE_MAJOR_FN)
378 return (uint32)major(dev);
380 return (uint32)(dev >> 8);
384 /****************************************************************************
385 Return the minor devicenumber for UNIX extensions.
386 ****************************************************************************/
388 static uint32 unix_dev_minor(SMB_DEV_T dev)
390 #if defined(HAVE_DEVICE_MINOR_FN)
391 return (uint32)minor(dev);
393 return (uint32)(dev & 0xff);
397 /****************************************************************************
398 Map wire perms onto standard UNIX permissions. Obey share restrictions.
399 ****************************************************************************/
401 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
405 if (perms == SMB_MODE_NO_CHANGE)
408 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
409 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
410 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
411 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
412 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
413 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
414 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
415 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
416 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
418 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
421 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
424 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
427 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
428 ret &= lp_dir_mask(SNUM(conn));
429 /* Add in force bits */
430 ret |= lp_force_dir_mode(SNUM(conn));
432 /* Apply mode mask */
433 ret &= lp_create_mask(SNUM(conn));
434 /* Add in force bits */
435 ret |= lp_force_create_mode(SNUM(conn));
441 /****************************************************************************
442 Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
443 ****************************************************************************/
445 time_t interpret_long_unix_date(char *p)
447 DEBUG(1,("interpret_long_unix_date\n"));
448 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
449 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
452 return interpret_long_date(p);
456 /****************************************************************************
457 Get a level dependent lanman2 dir entry.
458 ****************************************************************************/
460 static BOOL get_lanman2_dir_entry(connection_struct *conn,
461 void *inbuf, void *outbuf,
462 char *path_mask,int dirtype,int info_level,
463 int requires_resume_key,
464 BOOL dont_descend,char **ppdata,
465 char *base_data, int space_remaining,
466 BOOL *out_of_space, BOOL *got_exact_match,
471 SMB_STRUCT_STAT sbuf;
475 char *p, *q, *pdata = *ppdata;
479 SMB_OFF_T file_size = 0;
480 SMB_BIG_UINT allocation_size = 0;
482 time_t mdate=0, adate=0, cdate=0;
485 int nt_extmode; /* Used for NT connections instead of mode */
486 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
489 *out_of_space = False;
490 *got_exact_match = False;
495 p = strrchr_m(path_mask,'/');
502 pstrcpy(mask, path_mask);
507 /* Needed if we run out of space */
508 prev_dirpos = TellDir(conn->dirptr);
509 dname = ReadDirName(conn->dirptr);
512 * Due to bugs in NT client redirectors we are not using
513 * resume keys any more - set them to zero.
514 * Check out the related comments in findfirst/findnext.
520 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
521 (long)conn->dirptr,TellDir(conn->dirptr)));
526 pstrcpy(fname,dname);
528 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
529 got_match = mask_match(fname, mask, case_sensitive);
531 if(!got_match && !mangle_is_8_3(fname, False)) {
534 * It turns out that NT matches wildcards against
535 * both long *and* short names. This may explain some
536 * of the wildcard wierdness from old DOS clients
537 * that some people have been seeing.... JRA.
541 pstrcpy( newname, fname);
542 mangle_map( newname, True, False, SNUM(conn));
543 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
544 got_match = mask_match(newname, mask, case_sensitive);
548 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
549 if (dont_descend && !isdots)
552 pstrcpy(pathreal,conn->dirpath);
554 pstrcat(pathreal,"/");
555 pstrcat(pathreal,dname);
557 if (INFO_LEVEL_IS_UNIX(info_level)) {
558 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
559 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
560 pathreal,strerror(errno)));
563 } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
565 /* Needed to show the msdfs symlinks as
568 if(lp_host_msdfs() &&
569 lp_msdfs_root(SNUM(conn)) &&
570 is_msdfs_link(conn, pathreal, NULL, NULL,
573 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
574 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
578 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
579 pathreal,strerror(errno)));
584 mode = dos_mode(conn,pathreal,&sbuf);
586 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
587 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
591 file_size = get_file_size(sbuf);
592 allocation_size = get_allocation_size(NULL,&sbuf);
593 mdate = sbuf.st_mtime;
594 adate = sbuf.st_atime;
595 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
597 if (lp_dos_filetime_resolution(SNUM(conn))) {
606 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
612 mangle_map(fname,False,True,SNUM(conn));
617 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
619 switch (info_level) {
620 case SMB_INFO_STANDARD:
621 if(requires_resume_key) {
625 put_dos_date2(p,l1_fdateCreation,cdate);
626 put_dos_date2(p,l1_fdateLastAccess,adate);
627 put_dos_date2(p,l1_fdateLastWrite,mdate);
628 SIVAL(p,l1_cbFile,(uint32)file_size);
629 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
630 SSVAL(p,l1_attrFile,mode);
633 p += align_string(outbuf, p, 0);
634 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
635 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
636 SCVAL(nameptr, -1, len-2);
638 SCVAL(nameptr, -1, len-1);
642 case SMB_INFO_QUERY_EA_SIZE:
643 if(requires_resume_key) {
647 put_dos_date2(p,l2_fdateCreation,cdate);
648 put_dos_date2(p,l2_fdateLastAccess,adate);
649 put_dos_date2(p,l2_fdateLastWrite,mdate);
650 SIVAL(p,l2_cbFile,(uint32)file_size);
651 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
652 SSVAL(p,l2_attrFile,mode);
653 SIVAL(p,l2_cbList,0); /* No extended attributes */
656 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
657 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
658 SCVAL(nameptr, -1, len-2);
660 SCVAL(nameptr, -1, len-1);
664 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
665 was_8_3 = mangle_is_8_3(fname, True);
667 SIVAL(p,0,reskey); p += 4;
668 put_long_date(p,cdate); p += 8;
669 put_long_date(p,adate); p += 8;
670 put_long_date(p,mdate); p += 8;
671 put_long_date(p,mdate); p += 8;
672 SOFF_T(p,0,file_size);
673 SOFF_T(p,8,allocation_size);
675 SIVAL(p,0,nt_extmode); p += 4;
677 SIVAL(p,0,0); p += 4;
678 /* Clear the short name buffer. This is
679 * IMPORTANT as not doing so will trigger
680 * a Win2k client bug. JRA.
684 pstring mangled_name;
685 pstrcpy(mangled_name, fname);
686 mangle_map(mangled_name,True,True,SNUM(conn));
687 mangled_name[12] = 0;
688 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
695 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
698 len = PTR_DIFF(p, pdata);
699 len = (len + 3) & ~3;
704 case SMB_FIND_FILE_DIRECTORY_INFO:
706 SIVAL(p,0,reskey); p += 4;
707 put_long_date(p,cdate); p += 8;
708 put_long_date(p,adate); p += 8;
709 put_long_date(p,mdate); p += 8;
710 put_long_date(p,mdate); p += 8;
711 SOFF_T(p,0,file_size);
712 SOFF_T(p,8,allocation_size);
714 SIVAL(p,0,nt_extmode); p += 4;
716 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
719 len = PTR_DIFF(p, pdata);
720 len = (len + 3) & ~3;
725 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
727 SIVAL(p,0,reskey); p += 4;
728 put_long_date(p,cdate); p += 8;
729 put_long_date(p,adate); p += 8;
730 put_long_date(p,mdate); p += 8;
731 put_long_date(p,mdate); p += 8;
732 SOFF_T(p,0,file_size);
733 SOFF_T(p,8,allocation_size);
735 SIVAL(p,0,nt_extmode);
738 SIVAL(p,4,0); /* ea size */
739 len = srvstr_push(outbuf, p+8, fname, -1, STR_TERMINATE_ASCII);
743 len = PTR_DIFF(p, pdata);
744 len = (len + 3) & ~3;
749 case SMB_FIND_FILE_NAMES_INFO:
751 SIVAL(p,0,reskey); p += 4;
753 /* this must *not* be null terminated or w2k gets in a loop trying to set an
754 acl on a dir (tridge) */
755 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
758 len = PTR_DIFF(p, pdata);
759 len = (len + 3) & ~3;
764 case SMB_FIND_FILE_LEVEL_261:
766 SIVAL(p,0,reskey); p += 4;
767 put_long_date(p,cdate); p += 8;
768 put_long_date(p,adate); p += 8;
769 put_long_date(p,mdate); p += 8;
770 put_long_date(p,mdate); p += 8;
771 SOFF_T(p,0,file_size);
772 SOFF_T(p,8,allocation_size);
774 SIVAL(p,0,nt_extmode);
776 len = srvstr_push(outbuf, p + 20, fname, -1, STR_TERMINATE_ASCII);
778 memset(p+4,'\0',16); /* EA size. Unknown 0 1 2 */
779 p += 20 + len; /* Strlen, EA size. Unknown 0 1 2, string itself */
780 len = PTR_DIFF(p, pdata);
781 len = (len + 3) & ~3;
786 case SMB_FIND_FILE_LEVEL_262:
787 was_8_3 = mangle_is_8_3(fname, True);
789 SIVAL(p,0,reskey); p += 4;
790 put_long_date(p,cdate); p += 8;
791 put_long_date(p,adate); p += 8;
792 put_long_date(p,mdate); p += 8;
793 put_long_date(p,mdate); p += 8;
794 SOFF_T(p,0,file_size);
795 SOFF_T(p,8,allocation_size);
797 SIVAL(p,0,nt_extmode); p += 4;
799 SIVAL(p,0,0); p += 4;
800 /* Clear the short name buffer. This is
801 * IMPORTANT as not doing so will trigger
802 * a Win2k client bug. JRA.
806 pstring mangled_name;
807 pstrcpy(mangled_name, fname);
808 mangle_map(mangled_name,True,True,SNUM(conn));
809 mangled_name[12] = 0;
810 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
817 memset(p, '\0', 10); /* 2 4 byte unknowns plus a zero reserved. */
819 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
822 len = PTR_DIFF(p, pdata);
823 len = (len + 3) & ~3;
828 /* CIFS UNIX Extension. */
830 case SMB_FIND_FILE_UNIX:
832 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
834 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
835 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
838 SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
841 put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
842 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
843 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
846 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
850 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
854 SIVAL(p,0,unix_filetype(sbuf.st_mode));
857 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
861 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
865 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
868 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
872 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
876 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
879 len = PTR_DIFF(p, pdata);
880 len = (len + 3) & ~3;
881 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
883 /* End of SMB_QUERY_FILE_UNIX_BASIC */
892 if (PTR_DIFF(p,pdata) > space_remaining) {
893 /* Move the dirptr back to prev_dirpos */
894 SeekDir(conn->dirptr, prev_dirpos);
895 *out_of_space = True;
896 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
897 return False; /* Not finished - just out of space */
900 /* Setup the last_filename pointer, as an offset from base_data */
901 *last_name_off = PTR_DIFF(nameptr,base_data);
902 /* Advance the data pointer to the next slot */
908 /****************************************************************************
909 Reply to a TRANS2_FINDFIRST.
910 ****************************************************************************/
912 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
913 char **pparams, int total_params, char **ppdata, int total_data)
915 /* We must be careful here that we don't return more than the
916 allowed number of data bytes. If this means returning fewer than
917 maxentries then so be it. We assume that the redirector has
918 enough room for the fixed number of parameter bytes it has
920 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
921 char *params = *pparams;
922 char *pdata = *ppdata;
923 int dirtype = SVAL(params,0);
924 int maxentries = SVAL(params,2);
925 BOOL close_after_first = BITSETW(params+4,0);
926 BOOL close_if_end = BITSETW(params+4,1);
927 BOOL requires_resume_key = BITSETW(params+4,2);
928 int info_level = SVAL(params,6);
936 BOOL finished = False;
937 BOOL dont_descend = False;
938 BOOL out_of_space = False;
940 BOOL bad_path = False;
941 SMB_STRUCT_STAT sbuf;
943 if (total_params < 12)
944 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
946 *directory = *mask = 0;
948 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
949 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
950 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
951 info_level, max_data_bytes));
953 switch (info_level) {
954 case SMB_INFO_STANDARD:
955 case SMB_INFO_QUERY_EA_SIZE:
956 case SMB_FIND_FILE_DIRECTORY_INFO:
957 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
958 case SMB_FIND_FILE_NAMES_INFO:
959 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
960 case SMB_FIND_FILE_LEVEL_261:
961 case SMB_FIND_FILE_LEVEL_262:
963 case SMB_FIND_FILE_UNIX:
964 if (!lp_unix_extensions())
965 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
968 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
971 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
973 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
975 unix_convert(directory,conn,0,&bad_path,&sbuf);
976 if(!check_name(directory,conn)) {
977 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
980 p = strrchr_m(directory,'/');
982 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
983 if((directory[0] == '.') && (directory[1] == '\0'))
986 pstrcpy(mask,directory);
987 pstrcpy(directory,"./");
993 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
995 pdata = Realloc(*ppdata, max_data_bytes + 1024);
997 return(ERROR_DOS(ERRDOS,ERRnomem));
1000 memset((char *)pdata,'\0',max_data_bytes + 1024);
1002 /* Realloc the params space */
1003 params = Realloc(*pparams, 10);
1005 return ERROR_DOS(ERRDOS,ERRnomem);
1008 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1010 return(UNIXERROR(ERRDOS,ERRbadfile));
1012 /* Save the wildcard match and attribs we are using on this directory -
1013 needed as lanman2 assumes these are being saved between calls */
1015 if(!(wcard = strdup(mask))) {
1016 dptr_close(&dptr_num);
1017 return ERROR_DOS(ERRDOS,ERRnomem);
1020 dptr_set_wcard(dptr_num, wcard);
1021 dptr_set_attr(dptr_num, dirtype);
1023 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
1025 /* We don't need to check for VOL here as this is returned by
1026 a different TRANS2 call. */
1028 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1029 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1030 dont_descend = True;
1033 space_remaining = max_data_bytes;
1034 out_of_space = False;
1036 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1037 BOOL got_exact_match = False;
1039 /* this is a heuristic to avoid seeking the dirptr except when
1040 absolutely necessary. It allows for a filename of about 40 chars */
1041 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1042 out_of_space = True;
1045 finished = !get_lanman2_dir_entry(conn,
1047 mask,dirtype,info_level,
1048 requires_resume_key,dont_descend,
1049 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1053 if (finished && out_of_space)
1056 if (!finished && !out_of_space)
1060 * As an optimisation if we know we aren't looking
1061 * for a wildcard name (ie. the name matches the wildcard exactly)
1062 * then we can finish on any (first) match.
1063 * This speeds up large directory searches. JRA.
1069 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1072 /* Check if we can close the dirptr */
1073 if(close_after_first || (finished && close_if_end)) {
1074 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1075 dptr_close(&dptr_num);
1079 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1080 * from observation of NT.
1083 if(numentries == 0) {
1084 dptr_close(&dptr_num);
1085 return ERROR_DOS(ERRDOS,ERRbadfile);
1088 /* At this point pdata points to numentries directory entries. */
1090 /* Set up the return parameter block */
1091 SSVAL(params,0,dptr_num);
1092 SSVAL(params,2,numentries);
1093 SSVAL(params,4,finished);
1094 SSVAL(params,6,0); /* Never an EA error */
1095 SSVAL(params,8,last_name_off);
1097 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1099 if ((! *directory) && dptr_path(dptr_num))
1100 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1102 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1103 smb_fn_name(CVAL(inbuf,smb_com)),
1104 mask, directory, dirtype, numentries ) );
1107 * Force a name mangle here to ensure that the
1108 * mask as an 8.3 name is top of the mangled cache.
1109 * The reasons for this are subtle. Don't remove
1110 * this code unless you know what you are doing
1111 * (see PR#13758). JRA.
1114 if(!mangle_is_8_3_wildcards( mask, False))
1115 mangle_map(mask, True, True, SNUM(conn));
1120 /****************************************************************************
1121 Reply to a TRANS2_FINDNEXT.
1122 ****************************************************************************/
1124 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1125 char **pparams, int total_params, char **ppdata, int total_data)
1127 /* We must be careful here that we don't return more than the
1128 allowed number of data bytes. If this means returning fewer than
1129 maxentries then so be it. We assume that the redirector has
1130 enough room for the fixed number of parameter bytes it has
1132 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1133 char *params = *pparams;
1134 char *pdata = *ppdata;
1135 int dptr_num = SVAL(params,0);
1136 int maxentries = SVAL(params,2);
1137 uint16 info_level = SVAL(params,4);
1138 uint32 resume_key = IVAL(params,6);
1139 BOOL close_after_request = BITSETW(params+10,0);
1140 BOOL close_if_end = BITSETW(params+10,1);
1141 BOOL requires_resume_key = BITSETW(params+10,2);
1142 BOOL continue_bit = BITSETW(params+10,3);
1143 pstring resume_name;
1149 int i, last_name_off=0;
1150 BOOL finished = False;
1151 BOOL dont_descend = False;
1152 BOOL out_of_space = False;
1153 int space_remaining;
1155 if (total_params < 12)
1156 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1158 *mask = *directory = *resume_name = 0;
1160 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
1162 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1163 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1164 resume_key = %d resume name = %s continue=%d level = %d\n",
1165 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1166 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1168 switch (info_level) {
1169 case SMB_INFO_STANDARD:
1170 case SMB_INFO_QUERY_EA_SIZE:
1171 case SMB_FIND_FILE_DIRECTORY_INFO:
1172 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1173 case SMB_FIND_FILE_NAMES_INFO:
1174 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1176 case SMB_FIND_FILE_UNIX:
1177 if (!lp_unix_extensions())
1178 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1181 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1184 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1186 return ERROR_DOS(ERRDOS,ERRnomem);
1189 memset((char *)pdata,'\0',max_data_bytes + 1024);
1191 /* Realloc the params space */
1192 params = Realloc(*pparams, 6*SIZEOFWORD);
1193 if( params == NULL )
1194 return ERROR_DOS(ERRDOS,ERRnomem);
1198 /* Check that the dptr is valid */
1199 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1200 return ERROR_DOS(ERRDOS,ERRnofiles);
1202 string_set(&conn->dirpath,dptr_path(dptr_num));
1204 /* Get the wildcard mask from the dptr */
1205 if((p = dptr_wcard(dptr_num))== NULL) {
1206 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1207 return ERROR_DOS(ERRDOS,ERRnofiles);
1211 pstrcpy(directory,conn->dirpath);
1213 /* Get the attr mask from the dptr */
1214 dirtype = dptr_attr(dptr_num);
1216 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1217 dptr_num, mask, dirtype,
1219 TellDir(conn->dirptr)));
1221 /* We don't need to check for VOL here as this is returned by
1222 a different TRANS2 call. */
1224 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1225 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1226 dont_descend = True;
1229 space_remaining = max_data_bytes;
1230 out_of_space = False;
1233 * Seek to the correct position. We no longer use the resume key but
1234 * depend on the last file name instead.
1237 if(requires_resume_key && *resume_name && !continue_bit) {
1240 * Fix for NT redirector problem triggered by resume key indexes
1241 * changing between directory scans. We now return a resume key of 0
1242 * and instead look for the filename to continue from (also given
1243 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1244 * findfirst/findnext (as is usual) then the directory pointer
1245 * should already be at the correct place. Check this by scanning
1246 * backwards looking for an exact (ie. case sensitive) filename match.
1247 * If we get to the beginning of the directory and haven't found it then scan
1248 * forwards again looking for a match. JRA.
1251 int current_pos, start_pos;
1252 const char *dname = NULL;
1253 pstring dname_pstring;
1254 void *dirptr = conn->dirptr;
1255 start_pos = TellDir(dirptr);
1256 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1257 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1259 SeekDir(dirptr, current_pos);
1260 dname = ReadDirName(dirptr);
1263 * Remember, mangle_map is called by
1264 * get_lanman2_dir_entry(), so the resume name
1265 * could be mangled. Ensure we do the same
1269 /* make sure we get a copy that mangle_map can modify */
1271 pstrcpy(dname_pstring, dname);
1272 mangle_map( dname_pstring, False, True, SNUM(conn));
1274 if(strcsequal( resume_name, dname_pstring)) {
1275 SeekDir(dirptr, current_pos+1);
1276 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1283 * Scan forward from start if not found going backwards.
1286 if(current_pos < 0) {
1287 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1288 SeekDir(dirptr, start_pos);
1289 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
1292 * Remember, mangle_map is called by
1293 * get_lanman2_dir_entry(), so the resume name
1294 * could be mangled. Ensure we do the same
1299 /* make sure we get a copy that mangle_map can modify */
1301 pstrcpy(dname_pstring, dname);
1302 mangle_map(dname_pstring, False, True, SNUM(conn));
1304 if(strcsequal( resume_name, dname_pstring)) {
1305 SeekDir(dirptr, current_pos+1);
1306 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1311 } /* end if current_pos */
1312 } /* end if requires_resume_key && !continue_bit */
1314 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1315 BOOL got_exact_match = False;
1317 /* this is a heuristic to avoid seeking the dirptr except when
1318 absolutely necessary. It allows for a filename of about 40 chars */
1319 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1320 out_of_space = True;
1323 finished = !get_lanman2_dir_entry(conn,
1325 mask,dirtype,info_level,
1326 requires_resume_key,dont_descend,
1327 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1331 if (finished && out_of_space)
1334 if (!finished && !out_of_space)
1338 * As an optimisation if we know we aren't looking
1339 * for a wildcard name (ie. the name matches the wildcard exactly)
1340 * then we can finish on any (first) match.
1341 * This speeds up large directory searches. JRA.
1347 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1350 /* Check if we can close the dirptr */
1351 if(close_after_request || (finished && close_if_end)) {
1352 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1353 dptr_close(&dptr_num); /* This frees up the saved mask */
1356 /* Set up the return parameter block */
1357 SSVAL(params,0,numentries);
1358 SSVAL(params,2,finished);
1359 SSVAL(params,4,0); /* Never an EA error */
1360 SSVAL(params,6,last_name_off);
1362 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1364 if ((! *directory) && dptr_path(dptr_num))
1365 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1367 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1368 smb_fn_name(CVAL(inbuf,smb_com)),
1369 mask, directory, dirtype, numentries ) );
1374 /****************************************************************************
1375 Reply to a TRANS2_QFSINFO (query filesystem info).
1376 ****************************************************************************/
1378 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
1379 int length, int bufsize,
1380 char **pparams, int total_params, char **ppdata, int total_data)
1382 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1383 char *pdata = *ppdata;
1384 char *params = *pparams;
1385 uint16 info_level = SVAL(params,0);
1388 char *vname = volume_label(SNUM(conn));
1389 int snum = SNUM(conn);
1390 char *fstype = lp_fstype(SNUM(conn));
1393 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1395 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1396 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1397 return ERROR_DOS(ERRSRV,ERRinvdevice);
1400 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1401 if ( pdata == NULL )
1402 return ERROR_DOS(ERRDOS,ERRnomem);
1405 memset((char *)pdata,'\0',max_data_bytes + 1024);
1407 switch (info_level) {
1408 case SMB_INFO_ALLOCATION:
1410 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1412 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1413 block_size = lp_block_size(snum);
1414 if (bsize < block_size) {
1415 SMB_BIG_UINT factor = block_size/bsize;
1420 if (bsize > block_size) {
1421 SMB_BIG_UINT factor = bsize/block_size;
1426 bytes_per_sector = 512;
1427 sectors_per_unit = bsize/bytes_per_sector;
1429 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1430 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
1431 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1433 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1434 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
1435 SIVAL(pdata,l1_cUnit,dsize);
1436 SIVAL(pdata,l1_cUnitAvail,dfree);
1437 SSVAL(pdata,l1_cbSector,bytes_per_sector);
1441 case SMB_INFO_VOLUME:
1442 /* Return volume name */
1444 * Add volume serial number - hash of a combination of
1445 * the called hostname and the service name.
1447 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1448 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1449 SCVAL(pdata,l2_vol_cch,len);
1450 data_len = l2_vol_szVolLabel + len;
1451 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1452 (unsigned)st.st_ctime, len, vname));
1455 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1456 case SMB_FS_ATTRIBUTE_INFORMATION:
1459 #if defined(HAVE_SYS_QUOTAS)
1460 quota_flag = FILE_VOLUME_QUOTAS;
1463 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1464 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1465 quota_flag); /* FS ATTRIBUTES */
1467 SIVAL(pdata,4,255); /* Max filename component length */
1468 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1469 and will think we can't do long filenames */
1470 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1472 data_len = 12 + len;
1475 case SMB_QUERY_FS_LABEL_INFO:
1476 case SMB_FS_LABEL_INFORMATION:
1477 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1482 case SMB_QUERY_FS_VOLUME_INFO:
1483 case SMB_FS_VOLUME_INFORMATION:
1486 * Add volume serial number - hash of a combination of
1487 * the called hostname and the service name.
1489 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1490 (str_checksum(local_machine)<<16));
1492 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1493 SIVAL(pdata,12,len);
1495 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1496 (int)strlen(vname),vname, lp_servicename(snum)));
1499 case SMB_QUERY_FS_SIZE_INFO:
1500 case SMB_FS_SIZE_INFORMATION:
1502 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1504 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1505 block_size = lp_block_size(snum);
1506 if (bsize < block_size) {
1507 SMB_BIG_UINT factor = block_size/bsize;
1512 if (bsize > block_size) {
1513 SMB_BIG_UINT factor = bsize/block_size;
1518 bytes_per_sector = 512;
1519 sectors_per_unit = bsize/bytes_per_sector;
1520 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1521 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1522 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1523 SBIG_UINT(pdata,0,dsize);
1524 SBIG_UINT(pdata,8,dfree);
1525 SIVAL(pdata,16,sectors_per_unit);
1526 SIVAL(pdata,20,bytes_per_sector);
1530 case SMB_FS_FULL_SIZE_INFORMATION:
1532 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1534 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1535 block_size = lp_block_size(snum);
1536 if (bsize < block_size) {
1537 SMB_BIG_UINT factor = block_size/bsize;
1542 if (bsize > block_size) {
1543 SMB_BIG_UINT factor = bsize/block_size;
1548 bytes_per_sector = 512;
1549 sectors_per_unit = bsize/bytes_per_sector;
1550 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1551 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1552 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1553 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1554 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1555 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1556 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1557 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1561 case SMB_QUERY_FS_DEVICE_INFO:
1562 case SMB_FS_DEVICE_INFORMATION:
1564 SIVAL(pdata,0,0); /* dev type */
1565 SIVAL(pdata,4,0); /* characteristics */
1568 #ifdef HAVE_SYS_QUOTAS
1569 case SMB_FS_QUOTA_INFORMATION:
1571 * what we have to send --metze:
1573 * Unknown1: 24 NULL bytes
1574 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1575 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1576 * Quota Flags: 2 byte :
1577 * Unknown3: 6 NULL bytes
1581 * details for Quota Flags:
1583 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1584 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1585 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1586 * 0x0001 Enable Quotas: enable quota for this fs
1590 /* we need to fake up a fsp here,
1591 * because its not send in this call
1594 SMB_NTQUOTA_STRUCT quotas;
1597 ZERO_STRUCT(quotas);
1604 if (conn->admin_user != True) {
1605 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1606 lp_servicename(SNUM(conn)),conn->user));
1607 return ERROR_DOS(ERRDOS,ERRnoaccess);
1610 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1611 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1612 return ERROR_DOS(ERRSRV,ERRerror);
1617 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
1619 /* Unknown1 24 NULL bytes*/
1620 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
1621 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
1622 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
1624 /* Default Soft Quota 8 bytes */
1625 SBIG_UINT(pdata,24,quotas.softlim);
1627 /* Default Hard Quota 8 bytes */
1628 SBIG_UINT(pdata,32,quotas.hardlim);
1630 /* Quota flag 2 bytes */
1631 SSVAL(pdata,40,quotas.qflags);
1633 /* Unknown3 6 NULL bytes */
1639 #endif /* HAVE_SYS_QUOTAS */
1640 case SMB_FS_OBJECTID_INFORMATION:
1645 * Query the version and capabilities of the CIFS UNIX extensions
1649 case SMB_QUERY_CIFS_UNIX_INFO:
1650 if (!lp_unix_extensions())
1651 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1653 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
1654 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
1655 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
1658 case SMB_MAC_QUERY_FS_INFO:
1660 * Thursby MAC extension... ONLY on NTFS filesystems
1661 * once we do streams then we don't need this
1663 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1665 SIVAL(pdata,84,0x100); /* Don't support mac... */
1670 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1674 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1676 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1681 #ifdef HAVE_SYS_QUOTAS
1682 /****************************************************************************
1683 Reply to a TRANS2_SETFSINFO (set filesystem info).
1684 ****************************************************************************/
1686 static int call_trans2setfsinfo(connection_struct *conn,
1687 char *inbuf, char *outbuf, int length, int bufsize,
1688 char **pparams, int total_params, char **ppdata, int total_data)
1690 char *pdata = *ppdata;
1691 char *params = *pparams;
1692 files_struct *fsp = NULL;
1695 SMB_NTQUOTA_STRUCT quotas;
1697 ZERO_STRUCT(quotas);
1699 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
1702 if ((conn->admin_user != True)||!CAN_WRITE(conn)) {
1703 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1704 lp_servicename(SNUM(conn)),conn->user));
1705 return ERROR_DOS(ERRSRV,ERRaccess);
1709 if (total_params < 4) {
1710 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
1712 return ERROR_DOS(ERRDOS,ERRinvalidparam);
1715 fsp = file_fsp(params,0);
1717 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
1718 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
1719 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
1722 info_level = SVAL(params,2);
1724 switch(info_level) {
1725 case SMB_FS_QUOTA_INFORMATION:
1726 /* note: normaly there're 48 bytes,
1727 * but we didn't use the last 6 bytes for now
1730 if (total_data < 42) {
1731 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
1733 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1736 /* unknown_1 24 NULL bytes in pdata*/
1738 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
1739 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
1740 #ifdef LARGE_SMB_OFF_T
1741 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
1742 #else /* LARGE_SMB_OFF_T */
1743 if ((IVAL(pdata,28) != 0)&&
1744 ((quotas.softlim != 0xFFFFFFFF)||
1745 (IVAL(pdata,28)!=0xFFFFFFFF))) {
1746 /* more than 32 bits? */
1747 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1749 #endif /* LARGE_SMB_OFF_T */
1751 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
1752 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
1753 #ifdef LARGE_SMB_OFF_T
1754 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
1755 #else /* LARGE_SMB_OFF_T */
1756 if ((IVAL(pdata,36) != 0)&&
1757 ((quotas.hardlim != 0xFFFFFFFF)||
1758 (IVAL(pdata,36)!=0xFFFFFFFF))) {
1759 /* more than 32 bits? */
1760 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1762 #endif /* LARGE_SMB_OFF_T */
1764 /* quota_flags 2 bytes **/
1765 quotas.qflags = SVAL(pdata,40);
1767 /* unknown_2 6 NULL bytes follow*/
1769 /* now set the quotas */
1770 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1771 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1772 return ERROR_DOS(ERRSRV,ERRerror);
1777 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
1779 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1784 * sending this reply works fine,
1785 * but I'm not sure it's the same
1786 * like windows do...
1789 outsize = set_message(outbuf,10,0,True);
1793 #endif /* HAVE_SYS_QUOTAS */
1795 /****************************************************************************
1796 * Utility function to set bad path error.
1797 ****************************************************************************/
1799 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
1801 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
1802 err, (int)bad_path ));
1806 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1808 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
1811 return UNIXERROR(def_class,def_code);
1814 /****************************************************************************
1815 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1816 file name or file id).
1817 ****************************************************************************/
1819 static int call_trans2qfilepathinfo(connection_struct *conn,
1820 char *inbuf, char *outbuf, int length,
1822 char **pparams, int total_params, char **ppdata, int total_data)
1824 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1825 char *params = *pparams;
1826 char *pdata = *ppdata;
1827 uint16 tran_call = SVAL(inbuf, smb_setup0);
1830 SMB_OFF_T file_size=0;
1831 SMB_BIG_UINT allocation_size=0;
1832 unsigned int data_size;
1833 SMB_STRUCT_STAT sbuf;
1834 pstring fname, dos_fname;
1839 BOOL bad_path = False;
1840 BOOL delete_pending = False;
1843 files_struct *fsp = NULL;
1844 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
1847 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1849 if (tran_call == TRANSACT2_QFILEINFO) {
1850 if (total_params < 4)
1851 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1853 fsp = file_fsp(params,0);
1854 info_level = SVAL(params,2);
1856 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1858 if(fsp && (fsp->fake_file_handle)) {
1860 * This is actually for the QUOTA_FAKE_FILE --metze
1863 pstrcpy(fname, fsp->fsp_name);
1864 unix_convert(fname,conn,0,&bad_path,&sbuf);
1865 if (!check_name(fname,conn)) {
1866 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
1867 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1870 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1872 * This is actually a QFILEINFO on a directory
1873 * handle (returned from an NT SMB). NT5.0 seems
1874 * to do this call. JRA.
1876 pstrcpy(fname, fsp->fsp_name);
1877 unix_convert(fname,conn,0,&bad_path,&sbuf);
1878 if (!check_name(fname,conn)) {
1879 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1880 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1883 if (INFO_LEVEL_IS_UNIX(info_level)) {
1884 /* Always do lstat for UNIX calls. */
1885 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
1886 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1887 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1889 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
1890 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1891 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1894 delete_pending = fsp->directory_delete_on_close;
1897 * Original code - this is an open file.
1899 CHECK_FSP(fsp,conn);
1901 pstrcpy(fname, fsp->fsp_name);
1902 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
1903 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1904 return(UNIXERROR(ERRDOS,ERRbadfid));
1906 pos = fsp->position_information;
1907 delete_pending = fsp->delete_on_close;
1908 desired_access = fsp->desired_access;
1912 if (total_params < 6)
1913 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1915 info_level = SVAL(params,0);
1917 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1919 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1921 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1923 unix_convert(fname,conn,0,&bad_path,&sbuf);
1924 if (!check_name(fname,conn)) {
1925 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1926 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1929 if (INFO_LEVEL_IS_UNIX(info_level)) {
1930 /* Always do lstat for UNIX calls. */
1931 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
1932 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1933 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1935 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
1936 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1937 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1941 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
1942 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1944 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
1945 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
1947 p = strrchr_m(fname,'/');
1953 mode = dos_mode(conn,fname,&sbuf);
1955 mode = FILE_ATTRIBUTE_NORMAL;
1957 fullpathname = fname;
1958 file_size = get_file_size(sbuf);
1959 allocation_size = get_allocation_size(fsp,&sbuf);
1963 params = Realloc(*pparams,2);
1965 return ERROR_DOS(ERRDOS,ERRnomem);
1967 memset((char *)params,'\0',2);
1968 data_size = max_data_bytes + 1024;
1969 pdata = Realloc(*ppdata, data_size);
1970 if ( pdata == NULL )
1971 return ERROR_DOS(ERRDOS,ERRnomem);
1974 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1975 /* uggh, EAs for OS2 */
1976 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1977 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1980 memset((char *)pdata,'\0',data_size);
1982 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1984 if (lp_dos_filetime_resolution(SNUM(conn))) {
1986 sbuf.st_atime &= ~1;
1987 sbuf.st_mtime &= ~1;
1988 sbuf.st_mtime &= ~1;
1991 /* NT expects the name to be in an exact form of the *full*
1992 filename. See the trans2 torture test */
1993 if (strequal(base_name,".")) {
1994 pstrcpy(dos_fname, "\\");
1996 pstr_sprintf(dos_fname, "\\%s", fname);
1997 string_replace(dos_fname, '/', '\\');
2000 switch (info_level) {
2001 case SMB_INFO_STANDARD:
2002 case SMB_INFO_QUERY_EA_SIZE:
2003 data_size = (info_level==1?22:26);
2004 put_dos_date2(pdata,l1_fdateCreation,c_time);
2005 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2006 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2007 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2008 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2009 SSVAL(pdata,l1_attrFile,mode);
2010 SIVAL(pdata,l1_attrFile+2,0); /* this is what win2003 does */
2013 case SMB_INFO_IS_NAME_VALID:
2014 if (tran_call == TRANSACT2_QFILEINFO) {
2015 /* os/2 needs this ? really ?*/
2016 return ERROR_DOS(ERRDOS,ERRbadfunc);
2021 case SMB_INFO_QUERY_EAS_FROM_LIST:
2023 put_dos_date2(pdata,0,c_time);
2024 put_dos_date2(pdata,4,sbuf.st_atime);
2025 put_dos_date2(pdata,8,sbuf.st_mtime);
2026 SIVAL(pdata,12,(uint32)file_size);
2027 SIVAL(pdata,16,(uint32)allocation_size);
2028 SIVAL(pdata,20,mode);
2031 case SMB_INFO_QUERY_ALL_EAS:
2033 SIVAL(pdata,0,0); /* ea size */
2036 case SMB_FILE_BASIC_INFORMATION:
2037 case SMB_QUERY_FILE_BASIC_INFO:
2039 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
2040 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2045 put_long_date(pdata,c_time);
2046 put_long_date(pdata+8,sbuf.st_atime);
2047 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2048 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2049 SIVAL(pdata,32,mode);
2051 DEBUG(5,("SMB_QFBI - "));
2053 time_t create_time = c_time;
2054 DEBUG(5,("create: %s ", ctime(&create_time)));
2056 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2057 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2058 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2059 DEBUG(5,("mode: %x\n", mode));
2063 case SMB_FILE_STANDARD_INFORMATION:
2064 case SMB_QUERY_FILE_STANDARD_INFO:
2067 SOFF_T(pdata,0,allocation_size);
2068 SOFF_T(pdata,8,file_size);
2069 if (delete_pending & sbuf.st_nlink)
2070 SIVAL(pdata,16,sbuf.st_nlink - 1);
2072 SIVAL(pdata,16,sbuf.st_nlink);
2074 SCVAL(pdata,21,(mode&aDIR)?1:0);
2077 case SMB_FILE_EA_INFORMATION:
2078 case SMB_QUERY_FILE_EA_INFO:
2082 /* Get the 8.3 name - used if NT SMB was negotiated. */
2083 case SMB_QUERY_FILE_ALT_NAME_INFO:
2084 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2088 pstrcpy(short_name,base_name);
2089 /* Mangle if not already 8.3 */
2090 if(!mangle_is_8_3(short_name, True)) {
2091 mangle_map(short_name,True,True,SNUM(conn));
2093 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2094 data_size = 4 + len;
2099 case SMB_QUERY_FILE_NAME_INFO:
2101 this must be *exactly* right for ACLs on mapped drives to work
2103 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2104 data_size = 4 + len;
2108 case SMB_FILE_ALLOCATION_INFORMATION:
2109 case SMB_QUERY_FILE_ALLOCATION_INFO:
2111 SOFF_T(pdata,0,allocation_size);
2114 case SMB_FILE_END_OF_FILE_INFORMATION:
2115 case SMB_QUERY_FILE_END_OF_FILEINFO:
2117 SOFF_T(pdata,0,file_size);
2120 case SMB_QUERY_FILE_ALL_INFO:
2121 case SMB_FILE_ALL_INFORMATION:
2122 put_long_date(pdata,c_time);
2123 put_long_date(pdata+8,sbuf.st_atime);
2124 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2125 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2126 SIVAL(pdata,32,mode);
2128 SOFF_T(pdata,0,allocation_size);
2129 SOFF_T(pdata,8,file_size);
2130 if (delete_pending && sbuf.st_nlink)
2131 SIVAL(pdata,16,sbuf.st_nlink - 1);
2133 SIVAL(pdata,16,sbuf.st_nlink);
2134 SCVAL(pdata,20,delete_pending);
2135 SCVAL(pdata,21,(mode&aDIR)?1:0);
2137 pdata += 4; /* EA info */
2138 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2141 data_size = PTR_DIFF(pdata,(*ppdata));
2144 case SMB_FILE_INTERNAL_INFORMATION:
2145 /* This should be an index number - looks like
2148 I think this causes us to fail the IFSKIT
2149 BasicFileInformationTest. -tpot */
2151 SIVAL(pdata,0,sbuf.st_dev);
2152 SIVAL(pdata,4,sbuf.st_ino);
2156 case SMB_FILE_ACCESS_INFORMATION:
2157 SIVAL(pdata,0,desired_access);
2161 case SMB_FILE_NAME_INFORMATION:
2162 /* Pathname with leading '\'. */
2165 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2166 SIVAL(pdata,0,byte_len);
2167 data_size = 4 + byte_len;
2171 case SMB_FILE_DISPOSITION_INFORMATION:
2173 SCVAL(pdata,0,delete_pending);
2176 case SMB_FILE_POSITION_INFORMATION:
2178 SOFF_T(pdata,0,pos);
2181 case SMB_FILE_MODE_INFORMATION:
2182 SIVAL(pdata,0,mode);
2186 case SMB_FILE_ALIGNMENT_INFORMATION:
2187 SIVAL(pdata,0,0); /* No alignment needed. */
2193 * NT4 server just returns "invalid query" to this - if we try to answer
2194 * it then NTws gets a BSOD! (tridge).
2195 * W2K seems to want this. JRA.
2197 case SMB_QUERY_FILE_STREAM_INFO:
2199 case SMB_FILE_STREAM_INFORMATION:
2203 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2204 SIVAL(pdata,0,0); /* ??? */
2205 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2206 SOFF_T(pdata,8,file_size);
2207 SIVAL(pdata,16,allocation_size);
2208 SIVAL(pdata,20,0); /* ??? */
2209 data_size = 24 + byte_len;
2213 case SMB_QUERY_COMPRESSION_INFO:
2214 case SMB_FILE_COMPRESSION_INFORMATION:
2215 SOFF_T(pdata,0,file_size);
2216 SIVAL(pdata,8,0); /* ??? */
2217 SIVAL(pdata,12,0); /* ??? */
2221 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2222 put_long_date(pdata,c_time);
2223 put_long_date(pdata+8,sbuf.st_atime);
2224 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2225 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2226 SIVAL(pdata,32,allocation_size);
2227 SOFF_T(pdata,40,file_size);
2228 SIVAL(pdata,48,mode);
2229 SIVAL(pdata,52,0); /* ??? */
2233 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2234 SIVAL(pdata,0,mode);
2240 * CIFS UNIX Extensions.
2243 case SMB_QUERY_FILE_UNIX_BASIC:
2245 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2247 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2250 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2253 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2254 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2255 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2258 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2262 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2266 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2269 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2273 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2277 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2280 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2284 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2287 data_size = PTR_DIFF(pdata,(*ppdata));
2291 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2293 for (i=0; i<100; i++)
2294 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2300 case SMB_QUERY_FILE_UNIX_LINK:
2305 if(!S_ISLNK(sbuf.st_mode))
2306 return(UNIXERROR(ERRSRV,ERRbadlink));
2308 return(UNIXERROR(ERRDOS,ERRbadlink));
2310 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2312 return(UNIXERROR(ERRDOS,ERRnoaccess));
2314 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2316 data_size = PTR_DIFF(pdata,(*ppdata));
2322 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2325 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
2330 /****************************************************************************
2331 Deal with the internal needs of setting the delete on close flag. Note that
2332 as the tdb locking is recursive, it is safe to call this from within
2333 open_file_shared. JRA.
2334 ****************************************************************************/
2336 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
2339 * Only allow delete on close for writable shares.
2342 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
2343 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2345 return NT_STATUS_ACCESS_DENIED;
2348 * Only allow delete on close for files/directories opened with delete intent.
2351 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
2352 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2354 return NT_STATUS_ACCESS_DENIED;
2357 if(fsp->is_directory) {
2358 fsp->directory_delete_on_close = delete_on_close;
2359 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2360 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2362 fsp->delete_on_close = delete_on_close;
2363 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2364 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2367 return NT_STATUS_OK;
2370 /****************************************************************************
2371 Sets the delete on close flag over all share modes on this file.
2372 Modify the share mode entry for all files open
2373 on this device and inode to tell other smbds we have
2374 changed the delete on close flag. This will be noticed
2375 in the close code, the last closer will delete the file
2377 ****************************************************************************/
2379 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
2381 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2382 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2384 if (fsp->is_directory || fsp->is_stat)
2385 return NT_STATUS_OK;
2387 if (lock_share_entry_fsp(fsp) == False)
2388 return NT_STATUS_ACCESS_DENIED;
2390 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2391 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2393 unlock_share_entry_fsp(fsp);
2394 return NT_STATUS_ACCESS_DENIED;
2397 unlock_share_entry_fsp(fsp);
2398 return NT_STATUS_OK;
2401 /****************************************************************************
2402 Returns true if this pathname is within the share, and thus safe.
2403 ****************************************************************************/
2405 static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in, char *link_dest_out)
2408 char resolved_name[PATH_MAX+1];
2410 pstring resolved_name;
2412 fstring last_component;
2416 BOOL bad_path = False;
2417 SMB_STRUCT_STAT sbuf;
2419 pstrcpy(link_dest, link_dest_in);
2420 unix_convert(link_dest,conn,0,&bad_path,&sbuf);
2422 /* Store the UNIX converted path. */
2423 pstrcpy(link_dest_out, link_dest);
2425 p = strrchr(link_dest, '/');
2427 fstrcpy(last_component, p+1);
2430 fstrcpy(last_component, link_dest);
2431 pstrcpy(link_dest, "./");
2434 if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
2437 pstrcpy(link_dest, resolved_name);
2438 pstrcat(link_dest, "/");
2439 pstrcat(link_dest, last_component);
2441 if (*link_dest != '/') {
2442 /* Relative path. */
2443 pstrcpy(link_test, conn->connectpath);
2444 pstrcat(link_test, "/");
2445 pstrcat(link_test, link_dest);
2447 pstrcpy(link_test, link_dest);
2451 * Check if the link is within the share.
2454 if (strncmp(conn->connectpath, link_test, strlen(conn->connectpath))) {
2461 /****************************************************************************
2462 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2463 ****************************************************************************/
2465 static int call_trans2setfilepathinfo(connection_struct *conn,
2466 char *inbuf, char *outbuf, int length, int bufsize,
2467 char **pparams, int total_params, char **ppdata, int total_data)
2469 char *params = *pparams;
2470 char *pdata = *ppdata;
2471 uint16 tran_call = SVAL(inbuf, smb_setup0);
2476 SMB_STRUCT_STAT sbuf;
2479 BOOL bad_path = False;
2480 files_struct *fsp = NULL;
2481 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
2482 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
2483 mode_t unixmode = 0;
2486 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2488 if (tran_call == TRANSACT2_SETFILEINFO) {
2489 if (total_params < 4)
2490 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2492 fsp = file_fsp(params,0);
2493 info_level = SVAL(params,2);
2495 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2497 * This is actually a SETFILEINFO on a directory
2498 * handle (returned from an NT SMB). NT5.0 seems
2499 * to do this call. JRA.
2501 pstrcpy(fname, fsp->fsp_name);
2502 unix_convert(fname,conn,0,&bad_path,&sbuf);
2503 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
2504 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2505 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2507 } else if (fsp && fsp->print_file) {
2509 * Doing a DELETE_ON_CLOSE should cancel a print job.
2511 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
2512 fsp->share_mode = FILE_DELETE_ON_CLOSE;
2514 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
2517 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2520 return (UNIXERROR(ERRDOS,ERRbadpath));
2523 * Original code - this is an open file.
2525 CHECK_FSP(fsp,conn);
2527 pstrcpy(fname, fsp->fsp_name);
2530 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
2531 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2532 return(UNIXERROR(ERRDOS,ERRbadfid));
2537 if (total_params < 6)
2538 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2540 info_level = SVAL(params,0);
2541 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2542 unix_convert(fname,conn,0,&bad_path,&sbuf);
2545 * For CIFS UNIX extensions the target name may not exist.
2548 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
2549 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
2550 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2553 if(!check_name(fname, conn)) {
2554 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2559 if (!CAN_WRITE(conn))
2560 return ERROR_DOS(ERRSRV,ERRaccess);
2562 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2563 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2565 if (VALID_STAT(sbuf))
2566 unixmode = sbuf.st_mode;
2568 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
2569 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
2571 /* Realloc the parameter and data sizes */
2572 params = Realloc(*pparams,2);
2574 return ERROR_DOS(ERRDOS,ERRnomem);
2580 /* the pending modtime overrides the current modtime */
2581 sbuf.st_mtime = fsp->pending_modtime;
2584 size = get_file_size(sbuf);
2585 tvs.modtime = sbuf.st_mtime;
2586 tvs.actime = sbuf.st_atime;
2587 dosmode = dos_mode(conn,fname,&sbuf);
2588 unixmode = sbuf.st_mode;
2590 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
2591 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
2593 switch (info_level) {
2594 case SMB_INFO_STANDARD:
2596 if (total_data < 12)
2597 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2600 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2602 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2606 case SMB_INFO_SET_EA:
2607 return(ERROR_DOS(ERRDOS,ERReasnotsupported));
2609 /* XXXX um, i don't think this is right.
2610 it's also not in the cifs6.txt spec.
2612 case SMB_INFO_QUERY_EAS_FROM_LIST:
2613 if (total_data < 28)
2614 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2616 tvs.actime = make_unix_date2(pdata+8);
2617 tvs.modtime = make_unix_date2(pdata+12);
2618 size = IVAL(pdata,16);
2619 dosmode = IVAL(pdata,24);
2622 /* XXXX nor this. not in cifs6.txt, either. */
2623 case SMB_INFO_QUERY_ALL_EAS:
2624 if (total_data < 28)
2625 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2627 tvs.actime = make_unix_date2(pdata+8);
2628 tvs.modtime = make_unix_date2(pdata+12);
2629 size = IVAL(pdata,16);
2630 dosmode = IVAL(pdata,24);
2633 case SMB_SET_FILE_BASIC_INFO:
2634 case SMB_FILE_BASIC_INFORMATION:
2636 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2638 time_t changed_time;
2640 if (total_data < 36)
2641 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2643 /* Ignore create time at offset pdata. */
2646 tvs.actime = interpret_long_date(pdata+8);
2648 write_time = interpret_long_date(pdata+16);
2649 changed_time = interpret_long_date(pdata+24);
2651 tvs.modtime = MIN(write_time, changed_time);
2653 if (write_time > tvs.modtime && write_time != 0xffffffff) {
2654 tvs.modtime = write_time;
2656 /* Prefer a defined time to an undefined one. */
2657 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2658 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2659 ? changed_time : write_time);
2662 dosmode = IVAL(pdata,32);
2666 case SMB_FILE_ALLOCATION_INFORMATION:
2667 case SMB_SET_FILE_ALLOCATION_INFO:
2670 SMB_BIG_UINT allocation_size;
2673 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2675 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
2676 #ifdef LARGE_SMB_OFF_T
2677 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
2678 #else /* LARGE_SMB_OFF_T */
2679 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2680 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2681 #endif /* LARGE_SMB_OFF_T */
2682 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2683 fname, (double)allocation_size ));
2685 if (allocation_size)
2686 allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
2688 if(allocation_size != get_file_size(sbuf)) {
2689 SMB_STRUCT_STAT new_sbuf;
2691 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2692 fname, (double)allocation_size ));
2695 files_struct *new_fsp = NULL;
2696 int access_mode = 0;
2699 if(global_oplock_break) {
2700 /* Queue this file modify as we are the process of an oplock break. */
2702 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2703 DEBUGADD(2,( "in oplock break state.\n"));
2705 push_oplock_pending_smb_message(inbuf, length);
2709 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
2710 SET_OPEN_MODE(DOS_OPEN_RDWR),
2711 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2712 0, 0, &access_mode, &action);
2714 if (new_fsp == NULL)
2715 return(UNIXERROR(ERRDOS,ERRbadpath));
2716 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2717 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2718 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2719 new_fsp->fnum, strerror(errno)));
2722 close_file(new_fsp,True);
2724 ret = vfs_allocate_file_space(fsp, allocation_size);
2725 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
2726 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2727 fsp->fnum, strerror(errno)));
2732 return ERROR_NT(NT_STATUS_DISK_FULL);
2734 /* Allocate can truncate size... */
2735 size = get_file_size(new_sbuf);
2741 case SMB_FILE_END_OF_FILE_INFORMATION:
2742 case SMB_SET_FILE_END_OF_FILE_INFO:
2745 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2747 size = IVAL(pdata,0);
2748 #ifdef LARGE_SMB_OFF_T
2749 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2750 #else /* LARGE_SMB_OFF_T */
2751 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2752 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2753 #endif /* LARGE_SMB_OFF_T */
2754 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2758 case SMB_FILE_DISPOSITION_INFORMATION:
2759 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2761 BOOL delete_on_close;
2765 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2767 delete_on_close = (CVAL(pdata,0) ? True : False);
2769 /* Just ignore this set on a path. */
2770 if (tran_call != TRANSACT2_SETFILEINFO)
2774 return(UNIXERROR(ERRDOS,ERRbadfid));
2776 status = set_delete_on_close_internal(fsp, delete_on_close);
2778 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2779 return ERROR_NT(status);
2781 /* The set is across all open files on this dev/inode pair. */
2782 status =set_delete_on_close_over_all(fsp, delete_on_close);
2783 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2784 return ERROR_NT(status);
2789 case SMB_FILE_POSITION_INFORMATION:
2791 SMB_BIG_UINT position_information;
2794 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2796 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
2797 #ifdef LARGE_SMB_OFF_T
2798 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
2799 #else /* LARGE_SMB_OFF_T */
2800 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2801 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2802 #endif /* LARGE_SMB_OFF_T */
2803 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
2804 fname, (double)position_information ));
2806 fsp->position_information = position_information;
2811 * CIFS UNIX extensions.
2814 case SMB_SET_FILE_UNIX_BASIC:
2816 uint32 raw_unixmode;
2818 if (total_data < 100)
2819 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2821 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
2822 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
2823 size=IVAL(pdata,0); /* first 8 Bytes are size */
2824 #ifdef LARGE_SMB_OFF_T
2825 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2826 #else /* LARGE_SMB_OFF_T */
2827 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2828 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2829 #endif /* LARGE_SMB_OFF_T */
2831 pdata+=24; /* ctime & st_blocks are not changed */
2832 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
2833 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
2835 set_owner = (uid_t)IVAL(pdata,0);
2837 set_grp = (gid_t)IVAL(pdata,0);
2839 raw_unixmode = IVAL(pdata,28);
2840 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
2841 dosmode = 0; /* Ensure dos mode change doesn't override this. */
2843 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2844 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2845 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
2847 if (!VALID_STAT(sbuf)) {
2850 * The only valid use of this is to create character and block
2851 * devices, and named pipes. This is deprecated (IMHO) and
2852 * a new info level should be used for mknod. JRA.
2855 #if !defined(HAVE_MAKEDEV_FN)
2856 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2857 #else /* HAVE_MAKEDEV_FN */
2858 uint32 file_type = IVAL(pdata,0);
2859 uint32 dev_major = IVAL(pdata,4);
2860 uint32 dev_minor = IVAL(pdata,12);
2862 uid_t myuid = geteuid();
2863 gid_t mygid = getegid();
2866 if (tran_call == TRANSACT2_SETFILEINFO)
2867 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2869 if (raw_unixmode == SMB_MODE_NO_CHANGE)
2870 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2872 dev = makedev(dev_major, dev_minor);
2874 /* We can only create as the owner/group we are. */
2876 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
2877 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2878 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
2879 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2881 if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
2882 file_type != UNIX_TYPE_FIFO)
2883 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2885 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2886 0%o for file %s\n", (double)dev, unixmode, fname ));
2888 /* Ok - do the mknod. */
2889 if (SMB_VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
2890 return(UNIXERROR(ERRDOS,ERRnoaccess));
2892 inherit_access_acl(conn, fname, unixmode);
2895 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2897 #endif /* HAVE_MAKEDEV_FN */
2902 * Deal with the UNIX specific mode set.
2905 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
2906 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
2907 (unsigned int)unixmode, fname ));
2908 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
2909 return(UNIXERROR(ERRDOS,ERRnoaccess));
2913 * Deal with the UNIX specific uid set.
2916 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
2917 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
2918 (unsigned int)set_owner, fname ));
2919 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
2920 return(UNIXERROR(ERRDOS,ERRnoaccess));
2924 * Deal with the UNIX specific gid set.
2927 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
2928 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
2929 (unsigned int)set_owner, fname ));
2930 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
2931 return(UNIXERROR(ERRDOS,ERRnoaccess));
2936 case SMB_SET_FILE_UNIX_LINK:
2939 /* Set a symbolic link. */
2940 /* Don't allow this if follow links is false. */
2942 if (!lp_symlinks(SNUM(conn)))
2943 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2945 /* Disallow if already exists. */
2946 if (VALID_STAT(sbuf))
2947 return(ERROR_DOS(ERRDOS,ERRbadpath));
2949 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2951 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2952 return(UNIXERROR(ERRDOS,ERRnoaccess));
2954 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
2955 fname, link_dest ));
2957 if (SMB_VFS_SYMLINK(conn,link_dest,fname) != 0)
2958 return(UNIXERROR(ERRDOS,ERRnoaccess));
2960 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2964 case SMB_SET_FILE_UNIX_HLINK:
2968 /* Set a hard link. */
2970 /* Disallow if already exists. */
2971 if (VALID_STAT(sbuf))
2972 return(ERROR_DOS(ERRDOS,ERRbadpath));
2974 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2976 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2977 return(UNIXERROR(ERRDOS,ERRnoaccess));
2979 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
2980 fname, link_dest ));
2982 if (SMB_VFS_LINK(conn,link_dest,fname) != 0)
2983 return(UNIXERROR(ERRDOS,ERRnoaccess));
2985 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2989 case SMB_FILE_RENAME_INFORMATION:
2999 if (total_data < 12)
3000 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3002 overwrite = (CVAL(pdata,0) ? True : False);
3003 root_fid = IVAL(pdata,4);
3004 len = IVAL(pdata,8);
3005 srvstr_pull(inbuf, newname, &pdata[12], sizeof(newname), len, 0);
3007 /* Check the new name has no '\' characters. */
3008 if (strchr_m(newname, '\\') || strchr_m(newname, '/'))
3009 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3011 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3013 /* Create the base directory. */
3014 pstrcpy(base_name, fname);
3015 p = strrchr_m(base_name, '/');
3018 /* Append the new name. */
3019 pstrcat(base_name, "/");
3020 pstrcat(base_name, newname);
3023 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3024 fsp->fnum, fsp->fsp_name, base_name ));
3025 status = rename_internals_fsp(conn, fsp, base_name, overwrite);
3027 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3029 status = rename_internals(conn, fname, base_name, overwrite);
3031 if (!NT_STATUS_IS_OK(status))
3032 return ERROR_NT(status);
3033 process_pending_change_notify_queue((time_t)0);
3035 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3039 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3042 /* get some defaults (no modifications) if any info is zero or -1. */
3043 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
3044 tvs.actime = sbuf.st_atime;
3046 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3047 tvs.modtime = sbuf.st_mtime;
3049 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
3050 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
3051 DEBUG(6,("size: %.0f ", (double)size));
3054 if (S_ISDIR(sbuf.st_mode))
3060 DEBUG(6,("dosmode: %x\n" , dosmode));
3062 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
3063 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
3064 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
3065 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
3068 * Only do this test if we are not explicitly
3069 * changing the size of a file.
3072 size = get_file_size(sbuf);
3076 * Try and set the times, size and mode of this file -
3077 * if they are different from the current values
3079 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
3082 * This was a setfileinfo on an open file.
3083 * NT does this a lot. It's actually pointless
3084 * setting the time here, as it will be overwritten
3085 * on the next write, so we save the request
3086 * away and will set it on file close. JRA.
3089 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3090 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3091 fsp->pending_modtime = tvs.modtime;
3096 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3098 if(file_utime(conn, fname, &tvs)!=0)
3099 return(UNIXERROR(ERRDOS,ERRnoaccess));
3103 /* check the mode isn't different, before changing it */
3104 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
3106 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
3108 if(file_chmod(conn, fname, dosmode, NULL)) {
3109 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
3110 return(UNIXERROR(ERRDOS,ERRnoaccess));
3114 if (size != get_file_size(sbuf)) {
3118 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3119 fname, (double)size ));
3122 files_struct *new_fsp = NULL;
3123 int access_mode = 0;
3126 if(global_oplock_break) {
3127 /* Queue this file modify as we are the process of an oplock break. */
3129 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3130 DEBUGADD(2,( "in oplock break state.\n"));
3132 push_oplock_pending_smb_message(inbuf, length);
3136 new_fsp = open_file_shared(conn, fname, &sbuf,
3137 SET_OPEN_MODE(DOS_OPEN_RDWR),
3138 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3139 0, 0, &access_mode, &action);
3141 if (new_fsp == NULL)
3142 return(UNIXERROR(ERRDOS,ERRbadpath));
3143 ret = vfs_set_filelen(new_fsp, size);
3144 close_file(new_fsp,True);
3146 ret = vfs_set_filelen(fsp, size);
3150 return (UNIXERROR(ERRHRD,ERRdiskfull));
3154 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3159 /****************************************************************************
3160 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3161 ****************************************************************************/
3163 static int call_trans2mkdir(connection_struct *conn,
3164 char *inbuf, char *outbuf, int length, int bufsize,
3165 char **pparams, int total_params, char **ppdata, int total_data)
3167 char *params = *pparams;
3170 SMB_STRUCT_STAT sbuf;
3171 BOOL bad_path = False;
3173 if (!CAN_WRITE(conn))
3174 return ERROR_DOS(ERRSRV,ERRaccess);
3176 if (total_params < 4)
3177 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3179 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
3181 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3183 unix_convert(directory,conn,0,&bad_path,&sbuf);
3184 if (check_name(directory,conn))
3185 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3188 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3189 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
3192 /* Realloc the parameter and data sizes */
3193 params = Realloc(*pparams,2);
3195 return ERROR_DOS(ERRDOS,ERRnomem);
3200 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3205 /****************************************************************************
3206 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3207 We don't actually do this - we just send a null response.
3208 ****************************************************************************/
3210 static int call_trans2findnotifyfirst(connection_struct *conn,
3211 char *inbuf, char *outbuf, int length, int bufsize,
3212 char **pparams, int total_params, char **ppdata, int total_data)
3214 static uint16 fnf_handle = 257;
3215 char *params = *pparams;
3218 if (total_params < 6)
3219 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3221 info_level = SVAL(params,4);
3222 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3224 switch (info_level) {
3229 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3232 /* Realloc the parameter and data sizes */
3233 params = Realloc(*pparams,6);
3235 return ERROR_DOS(ERRDOS,ERRnomem);
3238 SSVAL(params,0,fnf_handle);
3239 SSVAL(params,2,0); /* No changes */
3240 SSVAL(params,4,0); /* No EA errors */
3247 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
3252 /****************************************************************************
3253 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3254 changes). Currently this does nothing.
3255 ****************************************************************************/
3257 static int call_trans2findnotifynext(connection_struct *conn,
3258 char *inbuf, char *outbuf, int length, int bufsize,
3259 char **pparams, int total_params, char **ppdata, int total_data)
3261 char *params = *pparams;
3263 DEBUG(3,("call_trans2findnotifynext\n"));
3265 /* Realloc the parameter and data sizes */
3266 params = Realloc(*pparams,4);
3268 return ERROR_DOS(ERRDOS,ERRnomem);
3271 SSVAL(params,0,0); /* No changes */
3272 SSVAL(params,2,0); /* No EA errors */
3274 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
3279 /****************************************************************************
3280 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3281 ****************************************************************************/
3283 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
3284 char* outbuf, int length, int bufsize,
3285 char **pparams, int total_params, char **ppdata, int total_data)
3287 char *params = *pparams;
3290 int max_referral_level;
3292 DEBUG(10,("call_trans2getdfsreferral\n"));
3294 if (total_params < 2)
3295 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3297 max_referral_level = SVAL(params,0);
3299 if(!lp_host_msdfs())
3300 return ERROR_DOS(ERRDOS,ERRbadfunc);
3302 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
3304 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
3305 return UNIXERROR(ERRDOS,ERRbadfile);
3307 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
3308 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
3313 #define LMCAT_SPL 0x53
3314 #define LMFUNC_GETJOBID 0x60
3316 /****************************************************************************
3317 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3318 ****************************************************************************/
3320 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
3321 char* outbuf, int length, int bufsize,
3322 char **pparams, int total_params, char **ppdata, int total_data)
3324 char *pdata = *ppdata;
3325 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
3327 /* check for an invalid fid before proceeding */
3330 return(ERROR_DOS(ERRDOS,ERRbadfid));
3332 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3333 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3334 pdata = Realloc(*ppdata, 32);
3336 return ERROR_DOS(ERRDOS,ERRnomem);
3339 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3340 CAN ACCEPT THIS IN UNICODE. JRA. */
3342 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
3343 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3344 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3345 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3348 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3349 return ERROR_DOS(ERRSRV,ERRerror);
3353 /****************************************************************************
3354 Reply to a SMBfindclose (stop trans2 directory search).
3355 ****************************************************************************/
3357 int reply_findclose(connection_struct *conn,
3358 char *inbuf,char *outbuf,int length,int bufsize)
3361 int dptr_num=SVALS(inbuf,smb_vwv0);
3362 START_PROFILE(SMBfindclose);
3364 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3366 dptr_close(&dptr_num);
3368 outsize = set_message(outbuf,0,0,True);
3370 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3372 END_PROFILE(SMBfindclose);
3376 /****************************************************************************
3377 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3378 ****************************************************************************/
3380 int reply_findnclose(connection_struct *conn,
3381 char *inbuf,char *outbuf,int length,int bufsize)
3385 START_PROFILE(SMBfindnclose);
3387 dptr_num = SVAL(inbuf,smb_vwv0);
3389 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3391 /* We never give out valid handles for a
3392 findnotifyfirst - so any dptr_num is ok here.
3395 outsize = set_message(outbuf,0,0,True);
3397 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3399 END_PROFILE(SMBfindnclose);
3403 /****************************************************************************
3404 Reply to a SMBtranss2 - just ignore it!
3405 ****************************************************************************/
3407 int reply_transs2(connection_struct *conn,
3408 char *inbuf,char *outbuf,int length,int bufsize)
3410 START_PROFILE(SMBtranss2);
3411 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3412 END_PROFILE(SMBtranss2);
3416 /****************************************************************************
3417 Reply to a SMBtrans2.
3418 ****************************************************************************/
3420 int reply_trans2(connection_struct *conn,
3421 char *inbuf,char *outbuf,int length,int bufsize)
3424 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
3425 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
3427 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
3428 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
3429 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
3430 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
3431 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
3432 int32 timeout = IVALS(inbuf,smb_timeout);
3434 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
3435 unsigned int tran_call = SVAL(inbuf, smb_setup0);
3436 char *params = NULL, *data = NULL;
3437 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
3438 START_PROFILE(SMBtrans2);
3440 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
3441 /* Queue this open message as we are the process of an
3444 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3445 DEBUGADD(2,( "in oplock break state.\n"));
3447 push_oplock_pending_smb_message(inbuf, length);
3448 END_PROFILE(SMBtrans2);
3452 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
3453 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
3454 END_PROFILE(SMBtrans2);
3455 return ERROR_DOS(ERRSRV,ERRaccess);
3458 outsize = set_message(outbuf,0,0,True);
3460 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3461 is so as a sanity check */
3464 * Need to have rc=0 for ioctl to get job id for OS/2.
3465 * Network printing will fail if function is not successful.
3466 * Similar function in reply.c will be used if protocol
3467 * is LANMAN1.0 instead of LM1.2X002.
3468 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3469 * outbuf doesn't have to be set(only job id is used).
3471 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
3472 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3473 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3474 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3476 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
3477 DEBUG(2,("Transaction is %d\n",tran_call));
3478 END_PROFILE(SMBtrans2);
3479 ERROR_DOS(ERRDOS,ERRinvalidparam);
3483 /* Allocate the space for the maximum needed parameters and data */
3484 if (total_params > 0)
3485 params = (char *)malloc(total_params);
3487 data = (char *)malloc(total_data);
3489 if ((total_params && !params) || (total_data && !data)) {
3490 DEBUG(2,("Out of memory in reply_trans2\n"));
3493 END_PROFILE(SMBtrans2);
3494 return ERROR_DOS(ERRDOS,ERRnomem);
3497 /* Copy the param and data bytes sent with this request into
3498 the params buffer */
3499 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
3500 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
3502 if (num_params > total_params || num_data > total_data)
3503 exit_server("invalid params in reply_trans2");
3506 unsigned int psoff = SVAL(inbuf, smb_psoff);
3507 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
3509 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
3510 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
3512 memcpy( params, smb_base(inbuf) + psoff, num_params);
3515 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
3516 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
3518 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
3519 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
3521 memcpy( data, smb_base(inbuf) + dsoff, num_data);
3524 srv_signing_trans_start(SVAL(inbuf,smb_mid));
3526 if(num_data_sofar < total_data || num_params_sofar < total_params) {
3527 /* We need to send an interim response then receive the rest
3528 of the parameter/data bytes */
3529 outsize = set_message(outbuf,0,0,True);
3530 srv_signing_trans_stop();
3531 if (!send_smb(smbd_server_fd(),outbuf))
3532 exit_server("reply_trans2: send_smb failed.");
3534 while (num_data_sofar < total_data ||
3535 num_params_sofar < total_params) {
3537 unsigned int param_disp;
3538 unsigned int param_off;
3539 unsigned int data_disp;
3540 unsigned int data_off;
3542 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
3545 * The sequence number for the trans reply is always
3546 * based on the last secondary received.
3549 srv_signing_trans_start(SVAL(inbuf,smb_mid));
3552 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
3553 outsize = set_message(outbuf,0,0,True);
3555 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3557 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3558 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
3562 /* Revise total_params and total_data in case
3563 they have changed downwards */
3564 if (SVAL(inbuf, smb_tpscnt) < total_params)
3565 total_params = SVAL(inbuf, smb_tpscnt);
3566 if (SVAL(inbuf, smb_tdscnt) < total_data)
3567 total_data = SVAL(inbuf, smb_tdscnt);
3569 num_params = SVAL(inbuf,smb_spscnt);
3570 param_off = SVAL(inbuf, smb_spsoff);
3571 param_disp = SVAL(inbuf, smb_spsdisp);
3572 num_params_sofar += num_params;
3574 num_data = SVAL(inbuf, smb_sdscnt);
3575 data_off = SVAL(inbuf, smb_sdsoff);
3576 data_disp = SVAL(inbuf, smb_sdsdisp);
3577 num_data_sofar += num_data;
3579 if (num_params_sofar > total_params || num_data_sofar > total_data)
3583 if (param_disp + num_params >= total_params)
3585 if ((param_disp + num_params < param_disp) ||
3586 (param_disp + num_params < num_params))
3588 if (param_disp > total_params)
3590 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
3591 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
3593 if (params + param_disp < params)
3596 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
3599 if (data_disp + num_data >= total_data)
3601 if ((data_disp + num_data < data_disp) ||
3602 (data_disp + num_data < num_data))
3604 if (data_disp > total_data)
3606 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
3607 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
3609 if (data + data_disp < data)
3612 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
3617 if (Protocol >= PROTOCOL_NT1) {
3618 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
3621 /* Now we must call the relevant TRANS2 function */
3623 case TRANSACT2_OPEN:
3624 START_PROFILE_NESTED(Trans2_open);
3625 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
3626 ¶ms, total_params, &data, total_data);
3627 END_PROFILE_NESTED(Trans2_open);
3630 case TRANSACT2_FINDFIRST:
3631 START_PROFILE_NESTED(Trans2_findfirst);
3632 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
3633 ¶ms, total_params, &data, total_data);
3634 END_PROFILE_NESTED(Trans2_findfirst);
3637 case TRANSACT2_FINDNEXT:
3638 START_PROFILE_NESTED(Trans2_findnext);
3639 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
3640 ¶ms, total_params, &data, total_data);
3641 END_PROFILE_NESTED(Trans2_findnext);
3644 case TRANSACT2_QFSINFO:
3645 START_PROFILE_NESTED(Trans2_qfsinfo);
3646 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
3647 ¶ms, total_params, &data, total_data);
3648 END_PROFILE_NESTED(Trans2_qfsinfo);
3651 #ifdef HAVE_SYS_QUOTAS
3652 case TRANSACT2_SETFSINFO:
3653 START_PROFILE_NESTED(Trans2_setfsinfo);
3654 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
3655 ¶ms, total_params, &data, total_data);
3656 END_PROFILE_NESTED(Trans2_setfsinfo);
3659 case TRANSACT2_QPATHINFO:
3660 case TRANSACT2_QFILEINFO:
3661 START_PROFILE_NESTED(Trans2_qpathinfo);
3662 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3663 ¶ms, total_params, &data, total_data);
3664 END_PROFILE_NESTED(Trans2_qpathinfo);
3666 case TRANSACT2_SETPATHINFO:
3667 case TRANSACT2_SETFILEINFO:
3668 START_PROFILE_NESTED(Trans2_setpathinfo);
3669 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3670 ¶ms, total_params, &data, total_data);
3671 END_PROFILE_NESTED(Trans2_setpathinfo);
3674 case TRANSACT2_FINDNOTIFYFIRST:
3675 START_PROFILE_NESTED(Trans2_findnotifyfirst);
3676 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
3677 ¶ms, total_params, &data, total_data);
3678 END_PROFILE_NESTED(Trans2_findnotifyfirst);
3681 case TRANSACT2_FINDNOTIFYNEXT:
3682 START_PROFILE_NESTED(Trans2_findnotifynext);
3683 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
3684 ¶ms, total_params, &data, total_data);
3685 END_PROFILE_NESTED(Trans2_findnotifynext);
3687 case TRANSACT2_MKDIR:
3688 START_PROFILE_NESTED(Trans2_mkdir);
3689 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
3690 ¶ms, total_params, &data, total_data);
3691 END_PROFILE_NESTED(Trans2_mkdir);
3694 case TRANSACT2_GET_DFS_REFERRAL:
3695 START_PROFILE_NESTED(Trans2_get_dfs_referral);
3696 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
3697 ¶ms, total_params, &data, total_data);
3698 END_PROFILE_NESTED(Trans2_get_dfs_referral);
3700 case TRANSACT2_IOCTL:
3701 START_PROFILE_NESTED(Trans2_ioctl);
3702 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
3703 ¶ms, total_params, &data, total_data);
3704 END_PROFILE_NESTED(Trans2_ioctl);
3707 /* Error in request */
3708 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
3711 END_PROFILE(SMBtrans2);
3712 srv_signing_trans_stop();
3713 return ERROR_DOS(ERRSRV,ERRerror);
3716 /* As we do not know how many data packets will need to be
3717 returned here the various call_trans2xxxx calls
3718 must send their own. Thus a call_trans2xxx routine only
3719 returns a value other than -1 when it wants to send
3723 srv_signing_trans_stop();
3727 END_PROFILE(SMBtrans2);
3728 return outsize; /* If a correct response was needed the
3729 call_trans2xxx calls have already sent
3730 it. If outsize != -1 then it is returning */
3734 srv_signing_trans_stop();
3737 END_PROFILE(SMBtrans2);
3738 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);