2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2001
6 Extensively modified by Andrew Tridgell, 1995
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern BOOL case_sensitive;
27 extern int smb_read_error;
28 extern fstring local_machine;
29 extern int global_oplock_break;
30 extern uint32 global_client_caps;
31 extern pstring global_myname;
33 /****************************************************************************
34 Send the required number of replies back.
35 We assume all fields other than the data fields are
36 set correctly for the type of call.
37 HACK ! Always assumes smb_setup field is zero.
38 ****************************************************************************/
40 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
41 int paramsize, char *pdata, int datasize)
43 /* As we are using a protocol > LANMAN1 then the max_send
44 variable must have been set in the sessetupX call.
45 This takes precedence over the max_xmit field in the
46 global struct. These different max_xmit variables should
47 be merged as this is now too confusing */
50 int data_to_send = datasize;
51 int params_to_send = paramsize;
55 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
56 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
57 int data_alignment_offset = 0;
59 /* Initially set the wcnt area to be 10 - this is true for all
61 set_message(outbuf,10,0,True);
63 /* If there genuinely are no parameters or data to send just send
65 if(params_to_send == 0 && data_to_send == 0)
67 if (!send_smb(smbd_server_fd(),outbuf))
68 exit_server("send_trans2_replies: send_smb failed.");
72 /* When sending params and data ensure that both are nicely aligned */
73 /* Only do this alignment when there is also data to send - else
74 can cause NT redirector problems. */
75 if (((params_to_send % 4) != 0) && (data_to_send != 0))
76 data_alignment_offset = 4 - (params_to_send % 4);
78 /* Space is bufsize minus Netbios over TCP header minus SMB header */
79 /* The alignment_offset is to align the param bytes on an even byte
80 boundary. NT 4.0 Beta needs this to work correctly. */
81 useable_space = bufsize - ((smb_buf(outbuf)+
82 alignment_offset+data_alignment_offset) -
85 /* useable_space can never be more than max_send minus the
87 useable_space = MIN(useable_space,
88 max_send - (alignment_offset+data_alignment_offset));
91 while (params_to_send || data_to_send)
93 /* Calculate whether we will totally or partially fill this packet */
94 total_sent_thistime = params_to_send + data_to_send +
95 alignment_offset + data_alignment_offset;
96 /* We can never send more than useable_space */
98 * Note that 'useable_space' does not include the alignment offsets,
99 * but we must include the alignment offsets in the calculation of
100 * the length of the data we send over the wire, as the alignment offsets
101 * are sent here. Fix from Marc_Jacobsen@hp.com.
103 total_sent_thistime = MIN(total_sent_thistime, useable_space+
104 alignment_offset + data_alignment_offset);
106 set_message(outbuf, 10, total_sent_thistime, True);
108 /* Set total params and data to be sent */
109 SSVAL(outbuf,smb_tprcnt,paramsize);
110 SSVAL(outbuf,smb_tdrcnt,datasize);
112 /* Calculate how many parameters and data we can fit into
113 this packet. Parameters get precedence */
115 params_sent_thistime = MIN(params_to_send,useable_space);
116 data_sent_thistime = useable_space - params_sent_thistime;
117 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
119 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
121 /* smb_proff is the offset from the start of the SMB header to the
122 parameter bytes, however the first 4 bytes of outbuf are
123 the Netbios over TCP header. Thus use smb_base() to subtract
124 them from the calculation */
126 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
128 if(params_sent_thistime == 0)
129 SSVAL(outbuf,smb_prdisp,0);
131 /* Absolute displacement of param bytes sent in this packet */
132 SSVAL(outbuf,smb_prdisp,pp - params);
134 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
135 if(data_sent_thistime == 0)
137 SSVAL(outbuf,smb_droff,0);
138 SSVAL(outbuf,smb_drdisp, 0);
142 /* The offset of the data bytes is the offset of the
143 parameter bytes plus the number of parameters being sent this time */
144 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
145 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
146 SSVAL(outbuf,smb_drdisp, pd - pdata);
149 /* Copy the param bytes into the packet */
150 if(params_sent_thistime)
151 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
152 /* Copy in the data bytes */
153 if(data_sent_thistime)
154 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
155 data_alignment_offset,pd,data_sent_thistime);
157 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
158 params_sent_thistime, data_sent_thistime, useable_space));
159 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
160 params_to_send, data_to_send, paramsize, datasize));
162 /* Send the packet */
163 if (!send_smb(smbd_server_fd(),outbuf))
164 exit_server("send_trans2_replies: send_smb failed.");
166 pp += params_sent_thistime;
167 pd += data_sent_thistime;
169 params_to_send -= params_sent_thistime;
170 data_to_send -= data_sent_thistime;
173 if(params_to_send < 0 || data_to_send < 0)
175 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
176 params_to_send, data_to_send));
184 /****************************************************************************
185 Reply to a TRANSACT2_OPEN.
186 ****************************************************************************/
188 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
190 char **pparams, char **ppdata)
192 char *params = *pparams;
193 int16 open_mode = SVAL(params, 2);
194 int16 open_attr = SVAL(params,6);
195 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
197 BOOL return_additional_info = BITSETW(params,0);
198 int16 open_sattr = SVAL(params, 4);
199 time_t open_time = make_unix_date3(params+8);
201 int16 open_ofun = SVAL(params,12);
202 int32 open_size = IVAL(params,14);
203 char *pname = ¶ms[28];
207 int fmode=0,mtime=0,rmode;
209 SMB_STRUCT_STAT sbuf;
211 BOOL bad_path = False;
214 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
216 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
217 fname,open_mode, open_attr, open_ofun, open_size));
220 return(ERROR_DOS(ERRSRV,ERRaccess));
223 /* XXXX we need to handle passed times, sattr and flags */
225 unix_convert(fname,conn,0,&bad_path,&sbuf);
227 if (!check_name(fname,conn))
229 if((errno == ENOENT) && bad_path)
231 unix_ERR_class = ERRDOS;
232 unix_ERR_code = ERRbadpath;
234 return(UNIXERROR(ERRDOS,ERRnoaccess));
237 unixmode = unix_mode(conn,open_attr | aARCH, fname);
239 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
240 oplock_request, &rmode,&smb_action);
244 if((errno == ENOENT) && bad_path)
246 unix_ERR_class = ERRDOS;
247 unix_ERR_code = ERRbadpath;
249 return(UNIXERROR(ERRDOS,ERRnoaccess));
253 fmode = dos_mode(conn,fname,&sbuf);
254 mtime = sbuf.st_mtime;
257 close_file(fsp,False);
258 return(ERROR_DOS(ERRDOS,ERRnoaccess));
261 /* Realloc the size of parameters and data we will return */
262 params = Realloc(*pparams, 28);
263 if( params == NULL ) {
264 return(ERROR_DOS(ERRDOS,ERRnomem));
268 memset((char *)params,'\0',28);
269 SSVAL(params,0,fsp->fnum);
270 SSVAL(params,2,fmode);
271 put_dos_date2(params,4, mtime);
272 SIVAL(params,8, (uint32)size);
273 SSVAL(params,12,rmode);
275 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
276 smb_action |= EXTENDED_OPLOCK_GRANTED;
279 SSVAL(params,18,smb_action);
281 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
283 SIVAL(params,20,inode);
285 /* Send the required number of replies */
286 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
291 /*********************************************************
292 Routine to check if a given string matches exactly.
293 as a special case a mask of "." does NOT match. That
294 is required for correct wildcard semantics
295 Case can be significant or not.
296 **********************************************************/
298 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
300 if (mask[0] == '.' && mask[1] == 0)
303 return strcmp(str,mask)==0;
304 return strcasecmp(str,mask) == 0;
309 Not finished yet - jra.
311 /****************************************************************************
312 Return the filetype for UNIX extensions.
313 ****************************************************************************/
315 static uint32 unix_filetype(mode_t mode)
318 return UNIX_TYPE_FILE;
319 else if(S_ISDIR(mode))
320 return UNIX_TYPE_DIR;
322 else if(S_ISLNK(mode))
323 return UNIX_TYPE_SYMLINK;
326 else if(S_ISCHR(mode))
327 return UNIX_TYPE_CHARDEV;
330 else if(S_ISBLK(mode))
331 return UNIX_TYPE_BLKDEV;
334 else if(S_ISFIFO(mode))
335 return UNIX_TYPE_FIFO;
338 else if(S_ISSOCK(mode))
339 return UNIX_TYPE_SOCKET;
342 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
343 return UNIX_TYPE_UNKNOWN;
346 /****************************************************************************
347 Return the major devicenumber for UNIX extensions.
348 ****************************************************************************/
350 static uint32 unix_dev_major(SMB_DEV_T dev)
352 #if defined(HAVE_DEVICE_MAJOR_FN)
353 return (uint32)major(dev);
355 return (uint32)(dev >> 8);
359 /****************************************************************************
360 Return the minor devicenumber for UNIX extensions.
361 ****************************************************************************/
363 static uint32 unix_dev_minor(SMB_DEV_T dev)
365 #if defined(HAVE_DEVICE_MINOR_FN)
366 return (uint32)minor(dev);
368 return (uint32)(dev & 0xff);
372 /****************************************************************************
373 Map standard UNIX permissions onto wire representations.
374 ****************************************************************************/
376 static uint32 unix_perms_to_wire(mode_t perms)
380 ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0);
381 ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0);
382 ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0);
383 ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0);
384 ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0);
385 ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0);
386 ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0);
387 ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0);
388 ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0);
390 ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0);
393 ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0);
396 ret |= ((perms & S_ISVTX) ? UNIX_SET_UID : 0);
403 /****************************************************************************
404 Get a level dependent lanman2 dir entry.
405 ****************************************************************************/
407 static BOOL get_lanman2_dir_entry(connection_struct *conn,
408 void *inbuf, void *outbuf,
409 char *path_mask,int dirtype,int info_level,
410 int requires_resume_key,
411 BOOL dont_descend,char **ppdata,
412 char *base_data, int space_remaining,
413 BOOL *out_of_space, BOOL *got_exact_match,
418 SMB_STRUCT_STAT sbuf;
422 char *p, *q, *pdata = *ppdata;
427 SMB_OFF_T allocation_size = 0;
429 time_t mdate=0, adate=0, cdate=0;
432 int nt_extmode; /* Used for NT connections instead of mode */
433 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
436 *out_of_space = False;
437 *got_exact_match = False;
442 p = strrchr_m(path_mask,'/');
449 pstrcpy(mask, path_mask);
454 /* Needed if we run out of space */
455 prev_dirpos = TellDir(conn->dirptr);
456 dname = ReadDirName(conn->dirptr);
459 * Due to bugs in NT client redirectors we are not using
460 * resume keys any more - set them to zero.
461 * Check out the related comments in findfirst/findnext.
467 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
468 (long)conn->dirptr,TellDir(conn->dirptr)));
473 pstrcpy(fname,dname);
475 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
476 got_match = mask_match(fname, mask, case_sensitive);
478 if(!got_match && !is_8_3(fname, False)) {
481 * It turns out that NT matches wildcards against
482 * both long *and* short names. This may explain some
483 * of the wildcard wierdness from old DOS clients
484 * that some people have been seeing.... JRA.
488 pstrcpy( newname, fname);
489 name_map_mangle( newname, True, False, SNUM(conn));
490 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
491 got_match = mask_match(newname, mask, case_sensitive);
495 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
496 if (dont_descend && !isdots)
499 pstrcpy(pathreal,conn->dirpath);
501 pstrcat(pathreal,"/");
502 pstrcat(pathreal,dname);
504 if (INFO_LEVEL_IS_UNIX(info_level)) {
505 if (vfs_lstat(conn,pathreal,&sbuf) != 0) {
506 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
507 pathreal,strerror(errno)));
510 } else if (vfs_stat(conn,pathreal,&sbuf) != 0) {
511 /* Needed to show the msdfs symlinks as directories */
512 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
513 || !is_msdfs_link(conn, pathreal)) {
514 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
515 pathreal,strerror(errno)));
518 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n",
520 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
524 mode = dos_mode(conn,pathreal,&sbuf);
526 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
527 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
532 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
533 mdate = sbuf.st_mtime;
534 adate = sbuf.st_atime;
535 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
537 if (lp_dos_filetime_resolution(SNUM(conn))) {
546 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
552 name_map_mangle(fname,False,True,SNUM(conn));
557 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
559 switch (info_level) {
561 if(requires_resume_key) {
565 put_dos_date2(p,l1_fdateCreation,cdate);
566 put_dos_date2(p,l1_fdateLastAccess,adate);
567 put_dos_date2(p,l1_fdateLastWrite,mdate);
568 SIVAL(p,l1_cbFile,(uint32)size);
569 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
570 SSVAL(p,l1_attrFile,mode);
573 p += align_string(outbuf, p, 0);
574 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
575 SCVAL(nameptr, -1, len);
580 if(requires_resume_key) {
584 put_dos_date2(p,l2_fdateCreation,cdate);
585 put_dos_date2(p,l2_fdateLastAccess,adate);
586 put_dos_date2(p,l2_fdateLastWrite,mdate);
587 SIVAL(p,l2_cbFile,(uint32)size);
588 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
589 SSVAL(p,l2_attrFile,mode);
590 SIVAL(p,l2_cbList,0); /* No extended attributes */
593 len = srvstr_push(outbuf, p, fname, -1, STR_NOALIGN);
596 *p++ = 0; /* craig from unisys pointed out we need this */
599 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
600 was_8_3 = is_8_3(fname, True);
602 SIVAL(p,0,reskey); p += 4;
603 put_long_date(p,cdate); p += 8;
604 put_long_date(p,adate); p += 8;
605 put_long_date(p,mdate); p += 8;
606 put_long_date(p,mdate); p += 8;
608 SOFF_T(p,8,allocation_size);
610 SIVAL(p,0,nt_extmode); p += 4;
612 SIVAL(p,0,0); p += 4;
614 pstring mangled_name;
615 pstrcpy(mangled_name, fname);
616 name_map_mangle(mangled_name,True,True,SNUM(conn));
617 mangled_name[12] = 0;
618 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
625 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
628 len = PTR_DIFF(p, pdata);
629 len = (len + 3) & ~3;
634 case SMB_FIND_FILE_DIRECTORY_INFO:
636 SIVAL(p,0,reskey); p += 4;
637 put_long_date(p,cdate); p += 8;
638 put_long_date(p,adate); p += 8;
639 put_long_date(p,mdate); p += 8;
640 put_long_date(p,mdate); p += 8;
642 SOFF_T(p,8,allocation_size);
644 SIVAL(p,0,nt_extmode); p += 4;
646 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
649 len = PTR_DIFF(p, pdata);
650 len = (len + 3) & ~3;
655 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
657 SIVAL(p,0,reskey); p += 4;
658 put_long_date(p,cdate); p += 8;
659 put_long_date(p,adate); p += 8;
660 put_long_date(p,mdate); p += 8;
661 put_long_date(p,mdate); p += 8;
663 SOFF_T(p,8,allocation_size);
665 SIVAL(p,0,nt_extmode); p += 4;
667 SIVAL(p,0,0); p += 4;
669 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
673 len = PTR_DIFF(p, pdata);
674 len = (len + 3) & ~3;
679 case SMB_FIND_FILE_NAMES_INFO:
681 SIVAL(p,0,reskey); p += 4;
683 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
686 len = PTR_DIFF(p, pdata);
687 len = (len + 3) & ~3;
692 /* CIFS UNIX Extension. */
694 #if 0 /* JRA - FIXME - NEEDS UNICODE CONVERSION !!! */
695 case SMB_FIND_FILE_UNIX:
697 len = 108+strlen(fname)+1; /* (length of SMB_QUERY_FILE_UNIX_BASIC = 100)+4+4+strlen(fname)*/
698 /* +1 to be sure to transmit the termination of fname */
699 len = (len + 3) & ~3;
701 SIVAL(p,0,len); p+= 4; /* Offset from this structure to the beginning of the next one */
702 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
704 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
705 SOFF_T(p,0,sbuf.st_size); /* File size 64 Bit */
708 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
709 SOFF_T(p,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
711 /* Can't get the value - fake it using size. */
712 SOFF_T(p,0,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
716 put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
717 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
718 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
721 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
725 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
729 SIVAL(p,0,unix_filetype(sbuf.st_mode));
732 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
736 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
740 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
743 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
747 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
751 /* End of SMB_QUERY_FILE_UNIX_BASIC */
763 if (PTR_DIFF(p,pdata) > space_remaining) {
764 /* Move the dirptr back to prev_dirpos */
765 SeekDir(conn->dirptr, prev_dirpos);
766 *out_of_space = True;
767 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
768 return False; /* Not finished - just out of space */
771 /* Setup the last_filename pointer, as an offset from base_data */
772 *last_name_off = PTR_DIFF(nameptr,base_data);
773 /* Advance the data pointer to the next slot */
779 /****************************************************************************
780 Reply to a TRANS2_FINDFIRST.
781 ****************************************************************************/
783 static int call_trans2findfirst(connection_struct *conn,
784 char *inbuf, char *outbuf, int bufsize,
785 char **pparams, char **ppdata)
787 /* We must be careful here that we don't return more than the
788 allowed number of data bytes. If this means returning fewer than
789 maxentries then so be it. We assume that the redirector has
790 enough room for the fixed number of parameter bytes it has
792 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
793 char *params = *pparams;
794 char *pdata = *ppdata;
795 int dirtype = SVAL(params,0);
796 int maxentries = SVAL(params,2);
797 BOOL close_after_first = BITSETW(params+4,0);
798 BOOL close_if_end = BITSETW(params+4,1);
799 BOOL requires_resume_key = BITSETW(params+4,2);
800 int info_level = SVAL(params,6);
808 BOOL finished = False;
809 BOOL dont_descend = False;
810 BOOL out_of_space = False;
812 BOOL bad_path = False;
813 SMB_STRUCT_STAT sbuf;
815 *directory = *mask = 0;
817 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
818 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
819 info_level, max_data_bytes));
827 case SMB_FIND_FILE_DIRECTORY_INFO:
828 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
829 case SMB_FIND_FILE_NAMES_INFO:
830 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
833 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
836 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
838 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
840 unix_convert(directory,conn,0,&bad_path,&sbuf);
841 if(!check_name(directory,conn)) {
842 if((errno == ENOENT) && bad_path)
844 unix_ERR_class = ERRDOS;
845 unix_ERR_code = ERRbadpath;
849 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
850 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
851 (get_remote_arch() == RA_WINNT))
853 unix_ERR_class = ERRDOS;
854 unix_ERR_code = ERRbaddirectory;
858 return(UNIXERROR(ERRDOS,ERRbadpath));
861 p = strrchr_m(directory,'/');
863 pstrcpy(mask,directory);
864 pstrcpy(directory,"./");
870 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
872 pdata = Realloc(*ppdata, max_data_bytes + 1024);
873 if( pdata == NULL ) {
874 return(ERROR_DOS(ERRDOS,ERRnomem));
877 memset((char *)pdata,'\0',max_data_bytes + 1024);
879 /* Realloc the params space */
880 params = Realloc(*pparams, 10);
881 if (params == NULL) {
882 return ERROR_DOS(ERRDOS,ERRnomem);
886 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
888 return(UNIXERROR(ERRDOS,ERRbadfile));
890 /* Save the wildcard match and attribs we are using on this directory -
891 needed as lanman2 assumes these are being saved between calls */
893 if(!(wcard = strdup(mask))) {
894 dptr_close(&dptr_num);
895 return ERROR_DOS(ERRDOS,ERRnomem);
898 dptr_set_wcard(dptr_num, wcard);
899 dptr_set_attr(dptr_num, dirtype);
901 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
903 /* We don't need to check for VOL here as this is returned by
904 a different TRANS2 call. */
906 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
907 conn->dirpath,lp_dontdescend(SNUM(conn))));
908 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
912 space_remaining = max_data_bytes;
913 out_of_space = False;
915 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
917 BOOL got_exact_match = False;
919 /* this is a heuristic to avoid seeking the dirptr except when
920 absolutely necessary. It allows for a filename of about 40 chars */
921 if (space_remaining < DIRLEN_GUESS && numentries > 0)
928 finished = !get_lanman2_dir_entry(conn,
930 mask,dirtype,info_level,
931 requires_resume_key,dont_descend,
932 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
936 if (finished && out_of_space)
939 if (!finished && !out_of_space)
943 * As an optimisation if we know we aren't looking
944 * for a wildcard name (ie. the name matches the wildcard exactly)
945 * then we can finish on any (first) match.
946 * This speeds up large directory searches. JRA.
952 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
955 /* Check if we can close the dirptr */
956 if(close_after_first || (finished && close_if_end))
958 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
959 dptr_close(&dptr_num);
963 * If there are no matching entries we must return ERRDOS/ERRbadfile -
964 * from observation of NT.
967 if(numentries == 0) {
968 dptr_close(&dptr_num);
969 return ERROR_DOS(ERRDOS,ERRbadfile);
972 /* At this point pdata points to numentries directory entries. */
974 /* Set up the return parameter block */
975 SSVAL(params,0,dptr_num);
976 SSVAL(params,2,numentries);
977 SSVAL(params,4,finished);
978 SSVAL(params,6,0); /* Never an EA error */
979 SSVAL(params,8,last_name_off);
981 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
983 if ((! *directory) && dptr_path(dptr_num))
984 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
986 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
987 smb_fn_name(CVAL(inbuf,smb_com)),
988 mask, directory, dirtype, numentries ) );
991 * Force a name mangle here to ensure that the
992 * mask as an 8.3 name is top of the mangled cache.
993 * The reasons for this are subtle. Don't remove
994 * this code unless you know what you are doing
995 * (see PR#13758). JRA.
998 if(!is_8_3( mask, False))
999 name_map_mangle(mask, True, True, SNUM(conn));
1004 /****************************************************************************
1005 Reply to a TRANS2_FINDNEXT.
1006 ****************************************************************************/
1008 static int call_trans2findnext(connection_struct *conn,
1009 char *inbuf, char *outbuf,
1010 int length, int bufsize,
1011 char **pparams, char **ppdata)
1013 /* We must be careful here that we don't return more than the
1014 allowed number of data bytes. If this means returning fewer than
1015 maxentries then so be it. We assume that the redirector has
1016 enough room for the fixed number of parameter bytes it has
1018 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1019 char *params = *pparams;
1020 char *pdata = *ppdata;
1021 int dptr_num = SVAL(params,0);
1022 int maxentries = SVAL(params,2);
1023 uint16 info_level = SVAL(params,4);
1024 uint32 resume_key = IVAL(params,6);
1025 BOOL close_after_request = BITSETW(params+10,0);
1026 BOOL close_if_end = BITSETW(params+10,1);
1027 BOOL requires_resume_key = BITSETW(params+10,2);
1028 BOOL continue_bit = BITSETW(params+10,3);
1029 pstring resume_name;
1035 int i, last_name_off=0;
1036 BOOL finished = False;
1037 BOOL dont_descend = False;
1038 BOOL out_of_space = False;
1039 int space_remaining;
1041 *mask = *directory = *resume_name = 0;
1043 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
1045 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1046 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1047 resume_key = %d resume name = %s continue=%d level = %d\n",
1048 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1049 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1057 case SMB_FIND_FILE_DIRECTORY_INFO:
1058 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1059 case SMB_FIND_FILE_NAMES_INFO:
1060 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1063 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1066 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1068 return ERROR_DOS(ERRDOS,ERRnomem);
1071 memset((char *)pdata,'\0',max_data_bytes + 1024);
1073 /* Realloc the params space */
1074 params = Realloc(*pparams, 6*SIZEOFWORD);
1075 if( params == NULL ) {
1076 return ERROR_DOS(ERRDOS,ERRnomem);
1080 /* Check that the dptr is valid */
1081 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1082 return ERROR_DOS(ERRDOS,ERRnofiles);
1084 string_set(&conn->dirpath,dptr_path(dptr_num));
1086 /* Get the wildcard mask from the dptr */
1087 if((p = dptr_wcard(dptr_num))== NULL) {
1088 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1089 return ERROR_DOS(ERRDOS,ERRnofiles);
1092 pstrcpy(directory,conn->dirpath);
1094 /* Get the attr mask from the dptr */
1095 dirtype = dptr_attr(dptr_num);
1097 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1098 dptr_num, mask, dirtype,
1100 TellDir(conn->dirptr)));
1102 /* We don't need to check for VOL here as this is returned by
1103 a different TRANS2 call. */
1105 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1106 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1107 dont_descend = True;
1110 space_remaining = max_data_bytes;
1111 out_of_space = False;
1114 * Seek to the correct position. We no longer use the resume key but
1115 * depend on the last file name instead.
1117 if(requires_resume_key && *resume_name && !continue_bit)
1120 * Fix for NT redirector problem triggered by resume key indexes
1121 * changing between directory scans. We now return a resume key of 0
1122 * and instead look for the filename to continue from (also given
1123 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1124 * findfirst/findnext (as is usual) then the directory pointer
1125 * should already be at the correct place. Check this by scanning
1126 * backwards looking for an exact (ie. case sensitive) filename match.
1127 * If we get to the beginning of the directory and haven't found it then scan
1128 * forwards again looking for a match. JRA.
1131 int current_pos, start_pos;
1133 void *dirptr = conn->dirptr;
1134 start_pos = TellDir(dirptr);
1135 for(current_pos = start_pos; current_pos >= 0; current_pos--)
1137 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1139 SeekDir(dirptr, current_pos);
1140 dname = ReadDirName(dirptr);
1143 * Remember, name_map_mangle is called by
1144 * get_lanman2_dir_entry(), so the resume name
1145 * could be mangled. Ensure we do the same
1150 name_map_mangle( dname, False, True, SNUM(conn));
1152 if(dname && strcsequal( resume_name, dname))
1154 SeekDir(dirptr, current_pos+1);
1155 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1161 * Scan forward from start if not found going backwards.
1166 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1167 SeekDir(dirptr, start_pos);
1168 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1171 * Remember, name_map_mangle is called by
1172 * get_lanman2_dir_entry(), so the resume name
1173 * could be mangled. Ensure we do the same
1178 name_map_mangle( dname, False, True, SNUM(conn));
1180 if(dname && strcsequal( resume_name, dname))
1182 SeekDir(dirptr, current_pos+1);
1183 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1187 } /* end if current_pos */
1188 } /* end if requires_resume_key && !continue_bit */
1190 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1192 BOOL got_exact_match = False;
1194 /* this is a heuristic to avoid seeking the dirptr except when
1195 absolutely necessary. It allows for a filename of about 40 chars */
1196 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1198 out_of_space = True;
1203 finished = !get_lanman2_dir_entry(conn,
1205 mask,dirtype,info_level,
1206 requires_resume_key,dont_descend,
1207 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1211 if (finished && out_of_space)
1214 if (!finished && !out_of_space)
1218 * As an optimisation if we know we aren't looking
1219 * for a wildcard name (ie. the name matches the wildcard exactly)
1220 * then we can finish on any (first) match.
1221 * This speeds up large directory searches. JRA.
1227 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1230 /* Check if we can close the dirptr */
1231 if(close_after_request || (finished && close_if_end))
1233 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1234 dptr_close(&dptr_num); /* This frees up the saved mask */
1238 /* Set up the return parameter block */
1239 SSVAL(params,0,numentries);
1240 SSVAL(params,2,finished);
1241 SSVAL(params,4,0); /* Never an EA error */
1242 SSVAL(params,6,last_name_off);
1244 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1246 if ((! *directory) && dptr_path(dptr_num))
1247 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1249 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1250 smb_fn_name(CVAL(inbuf,smb_com)),
1251 mask, directory, dirtype, numentries ) );
1256 /****************************************************************************
1257 Reply to a TRANS2_QFSINFO (query filesystem info).
1258 ****************************************************************************/
1260 static int call_trans2qfsinfo(connection_struct *conn,
1261 char *inbuf, char *outbuf,
1262 int length, int bufsize,
1263 char **pparams, char **ppdata)
1265 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1266 char *pdata = *ppdata;
1267 char *params = *pparams;
1268 uint16 info_level = SVAL(params,0);
1271 char *vname = volume_label(SNUM(conn));
1272 int snum = SNUM(conn);
1273 char *fstype = lp_fstype(SNUM(conn));
1275 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1277 if(vfs_stat(conn,".",&st)!=0) {
1278 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1279 return ERROR_DOS(ERRSRV,ERRinvdevice);
1282 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1283 if ( pdata == NULL ) {
1284 return ERROR_DOS(ERRDOS,ERRnomem);
1287 memset((char *)pdata,'\0',max_data_bytes + 1024);
1293 SMB_BIG_UINT dfree,dsize,bsize;
1295 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1296 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1297 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1298 SIVAL(pdata,l1_cUnit,dsize);
1299 SIVAL(pdata,l1_cUnitAvail,dfree);
1300 SSVAL(pdata,l1_cbSector,512);
1301 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1302 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1303 (unsigned int)dfree, 512));
1307 /* Return volume name */
1309 * Add volume serial number - hash of a combination of
1310 * the called hostname and the service name.
1312 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1313 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1315 SCVAL(pdata,l2_vol_cch,len);
1316 data_len = l2_vol_szVolLabel + len;
1317 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1318 (unsigned)st.st_ctime, len, vname));
1321 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1322 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1323 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1324 SIVAL(pdata,4,255); /* Max filename component length */
1325 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1326 and will think we can't do long filenames */
1327 len = srvstr_push(outbuf, pdata+12, fstype, -1, 0);
1329 data_len = 12 + len;
1332 case SMB_QUERY_FS_LABEL_INFO:
1333 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1337 case SMB_QUERY_FS_VOLUME_INFO:
1339 * Add volume serial number - hash of a combination of
1340 * the called hostname and the service name.
1342 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1343 (str_checksum(local_machine)<<16));
1345 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1346 SIVAL(pdata,12,len);
1348 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1349 (int)strlen(vname),vname, lp_servicename(snum)));
1351 case SMB_QUERY_FS_SIZE_INFO:
1353 SMB_BIG_UINT dfree,dsize,bsize;
1355 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1356 SBIG_UINT(pdata,0,dsize);
1357 SBIG_UINT(pdata,8,dfree);
1358 SIVAL(pdata,16,bsize/512);
1359 SIVAL(pdata,20,512);
1362 case SMB_QUERY_FS_DEVICE_INFO:
1364 SIVAL(pdata,0,0); /* dev type */
1365 SIVAL(pdata,4,0); /* characteristics */
1367 case SMB_MAC_QUERY_FS_INFO:
1369 * Thursby MAC extension... ONLY on NTFS filesystems
1370 * once we do streams then we don't need this
1372 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1374 SIVAL(pdata,84,0x100); /* Don't support mac... */
1379 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1383 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1385 DEBUG( 4, ( "%s info_level = %d\n",
1386 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1391 /****************************************************************************
1392 Reply to a TRANS2_SETFSINFO (set filesystem info).
1393 ****************************************************************************/
1395 static int call_trans2setfsinfo(connection_struct *conn,
1396 char *inbuf, char *outbuf, int length,
1398 char **pparams, char **ppdata)
1400 /* Just say yes we did it - there is nothing that
1401 can be set here so it doesn't matter. */
1403 DEBUG(3,("call_trans2setfsinfo\n"));
1405 if (!CAN_WRITE(conn))
1406 return ERROR_DOS(ERRSRV,ERRaccess);
1408 outsize = set_message(outbuf,10,0,True);
1413 /****************************************************************************
1414 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1415 file name or file id).
1416 ****************************************************************************/
1418 static int call_trans2qfilepathinfo(connection_struct *conn,
1419 char *inbuf, char *outbuf, int length,
1421 char **pparams,char **ppdata,
1424 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1425 char *params = *pparams;
1426 char *pdata = *ppdata;
1427 uint16 tran_call = SVAL(inbuf, smb_setup0);
1431 SMB_OFF_T allocation_size=0;
1432 unsigned int data_size;
1433 SMB_STRUCT_STAT sbuf;
1438 BOOL bad_path = False;
1439 BOOL delete_pending = False;
1443 if (tran_call == TRANSACT2_QFILEINFO) {
1444 files_struct *fsp = file_fsp(params,0);
1445 info_level = SVAL(params,2);
1447 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1449 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1451 * This is actually a QFILEINFO on a directory
1452 * handle (returned from an NT SMB). NT5.0 seems
1453 * to do this call. JRA.
1455 pstrcpy(fname, fsp->fsp_name);
1456 unix_convert(fname,conn,0,&bad_path,&sbuf);
1457 if (!check_name(fname,conn) ||
1458 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1459 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1460 if((errno == ENOENT) && bad_path) {
1461 unix_ERR_class = ERRDOS;
1462 unix_ERR_code = ERRbadpath;
1464 return(UNIXERROR(ERRDOS,ERRbadpath));
1467 delete_pending = fsp->directory_delete_on_close;
1470 * Original code - this is an open file.
1472 CHECK_FSP(fsp,conn);
1474 pstrcpy(fname, fsp->fsp_name);
1475 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1476 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1477 return(UNIXERROR(ERRDOS,ERRbadfid));
1479 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1480 return(UNIXERROR(ERRDOS,ERRnoaccess));
1482 delete_pending = fsp->delete_on_close;
1486 info_level = SVAL(params,0);
1488 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1490 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1492 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1494 unix_convert(fname,conn,0,&bad_path,&sbuf);
1495 if (!check_name(fname,conn) ||
1496 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1497 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1498 if((errno == ENOENT) && bad_path) {
1499 unix_ERR_class = ERRDOS;
1500 unix_ERR_code = ERRbadpath;
1502 return(UNIXERROR(ERRDOS,ERRbadpath));
1507 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1508 fname,info_level,tran_call,total_data));
1510 p = strrchr_m(fname,'/');
1516 mode = dos_mode(conn,fname,&sbuf);
1517 size = sbuf.st_size;
1518 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
1523 params = Realloc(*pparams,2);
1525 return ERROR_DOS(ERRDOS,ERRnomem);
1527 memset((char *)params,'\0',2);
1528 data_size = max_data_bytes + 1024;
1529 pdata = Realloc(*ppdata, data_size);
1530 if ( pdata == NULL )
1531 return ERROR_DOS(ERRDOS,ERRnomem);
1534 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1535 /* uggh, EAs for OS2 */
1536 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1537 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1540 memset((char *)pdata,'\0',data_size);
1542 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1544 if (lp_dos_filetime_resolution(SNUM(conn))) {
1546 sbuf.st_atime &= ~1;
1547 sbuf.st_mtime &= ~1;
1548 sbuf.st_mtime &= ~1;
1551 switch (info_level) {
1552 case SMB_INFO_STANDARD:
1553 case SMB_INFO_QUERY_EA_SIZE:
1554 data_size = (info_level==1?22:26);
1555 put_dos_date2(pdata,l1_fdateCreation,c_time);
1556 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1557 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1558 SIVAL(pdata,l1_cbFile,(uint32)size);
1559 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1560 SSVAL(pdata,l1_attrFile,mode);
1561 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1564 case SMB_INFO_QUERY_EAS_FROM_LIST:
1566 put_dos_date2(pdata,0,c_time);
1567 put_dos_date2(pdata,4,sbuf.st_atime);
1568 put_dos_date2(pdata,8,sbuf.st_mtime);
1569 SIVAL(pdata,12,(uint32)size);
1570 SIVAL(pdata,16,(uint32)allocation_size);
1571 SIVAL(pdata,20,mode);
1574 case SMB_INFO_QUERY_ALL_EAS:
1576 SIVAL(pdata,0,data_size);
1580 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1582 case SMB_FILE_BASIC_INFORMATION:
1583 case SMB_QUERY_FILE_BASIC_INFO:
1585 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1586 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1591 put_long_date(pdata,c_time);
1592 put_long_date(pdata+8,sbuf.st_atime);
1593 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1594 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1595 SIVAL(pdata,32,mode);
1597 DEBUG(5,("SMB_QFBI - "));
1599 time_t create_time = c_time;
1600 DEBUG(5,("create: %s ", ctime(&create_time)));
1602 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1603 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1604 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1605 DEBUG(5,("mode: %x\n", mode));
1609 case SMB_FILE_STANDARD_INFORMATION:
1610 case SMB_QUERY_FILE_STANDARD_INFO:
1612 /* Fake up allocation size. */
1613 SOFF_T(pdata,0,allocation_size);
1614 SOFF_T(pdata,8,size);
1615 SIVAL(pdata,16,sbuf.st_nlink);
1617 SCVAL(pdata,21,(mode&aDIR)?1:0);
1620 case SMB_FILE_EA_INFORMATION:
1621 case SMB_QUERY_FILE_EA_INFO:
1625 /* Get the 8.3 name - used if NT SMB was negotiated. */
1626 case SMB_QUERY_FILE_ALT_NAME_INFO:
1630 pstrcpy(short_name,base_name);
1631 /* Mangle if not already 8.3 */
1632 if(!is_8_3(short_name, True)) {
1633 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1636 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
1637 data_size = 4 + len;
1642 case SMB_QUERY_FILE_NAME_INFO:
1644 * The first part of this code is essential
1645 * to get security descriptors to work on mapped
1646 * drives. Don't ask how I discovered this unless
1647 * you like hearing about me suffering.... :-). JRA.
1649 if(strequal(".", fname)) {
1650 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1652 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1654 data_size = 4 + len;
1658 case SMB_FILE_END_OF_FILE_INFORMATION:
1659 case SMB_QUERY_FILE_END_OF_FILEINFO:
1661 SOFF_T(pdata,0,size);
1664 case SMB_FILE_ALLOCATION_INFORMATION:
1665 case SMB_QUERY_FILE_ALLOCATION_INFO:
1667 SOFF_T(pdata,0,allocation_size);
1670 case SMB_QUERY_FILE_ALL_INFO:
1671 put_long_date(pdata,c_time);
1672 put_long_date(pdata+8,sbuf.st_atime);
1673 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1674 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1675 SIVAL(pdata,32,mode);
1677 SOFF_T(pdata,0,allocation_size);
1678 SOFF_T(pdata,8,size);
1679 SIVAL(pdata,16,sbuf.st_nlink);
1680 SCVAL(pdata,20,delete_pending);
1681 SCVAL(pdata,21,(mode&aDIR)?1:0);
1683 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1684 pdata += 8; /* index number */
1685 pdata += 4; /* EA info */
1687 SIVAL(pdata,0,0xA9);
1689 SIVAL(pdata,0,0xd01BF);
1691 SOFF_T(pdata,0,pos); /* current offset */
1693 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1695 pdata += 4; /* alignment */
1696 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1699 data_size = PTR_DIFF(pdata,(*ppdata));
1702 case SMB_FILE_INTERNAL_INFORMATION:
1703 /* This should be an index number - looks like dev/ino to me :-) */
1704 SIVAL(pdata,0,sbuf.st_dev);
1705 SIVAL(pdata,4,sbuf.st_ino);
1709 case SMB_FILE_ACCESS_INFORMATION:
1710 SIVAL(pdata,0,0x12019F); /* ??? */
1714 case SMB_FILE_NAME_INFORMATION:
1715 /* Pathname with leading '\'. */
1720 pstrcpy(new_fname, "\\");
1721 pstrcat(new_fname, fname);
1722 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1723 SIVAL(pdata,0,byte_len);
1724 data_size = 4 + byte_len;
1728 case SMB_FILE_DISPOSITION_INFORMATION:
1730 SCVAL(pdata,0,delete_pending);
1733 case SMB_FILE_POSITION_INFORMATION:
1735 SOFF_T(pdata,0,pos);
1738 case SMB_FILE_MODE_INFORMATION:
1739 SIVAL(pdata,0,mode);
1743 case SMB_FILE_ALIGNMENT_INFORMATION:
1744 SIVAL(pdata,0,0); /* No alignment needed. */
1749 /* Not yet finished... JRA */
1755 put_long_date(pdata,c_time);
1756 put_long_date(pdata+8,sbuf.st_atime);
1757 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1758 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1759 SIVAL(pdata,32,mode);
1760 SIVAL(pdata,36,0); /* ??? */
1761 SIVAL(pdata,40,0x20); /* ??? */
1762 SIVAL(pdata,44,0); /* ??? */
1763 SOFF_T(pdata,48,size);
1764 SIVAL(pdata,56,0x1); /* ??? */
1765 SIVAL(pdata,60,0); /* ??? */
1766 SIVAL(pdata,64,0); /* ??? */
1767 SIVAL(pdata,68,length); /* Following string length in bytes. */
1768 dos_PutUniCode(pdata+72,,False);
1773 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1774 /* Last component of pathname. */
1776 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1777 SIVAL(pdata,0,byte_len);
1778 data_size = 4 + byte_len;
1782 case SMB_FILE_STREAM_INFORMATION:
1786 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1787 SIVAL(pdata,0,0); /* ??? */
1788 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1789 SOFF_T(pdata,8,size);
1790 SIVAL(pdata,16,allocation_size);
1791 SIVAL(pdata,20,0); /* ??? */
1792 data_size = 24 + byte_len;
1796 case SMB_FILE_COMPRESSION_INFORMATION:
1797 SOFF_T(pdata,0,size);
1798 SIVAL(pdata,8,0); /* ??? */
1799 SIVAL(pdata,12,0); /* ??? */
1803 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1804 put_long_date(pdata,c_time);
1805 put_long_date(pdata+8,sbuf.st_atime);
1806 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1807 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1808 SIVAL(pdata,32,allocation_size);
1809 SOFF_T(pdata,40,size);
1810 SIVAL(pdata,48,mode);
1811 SIVAL(pdata,52,0); /* ??? */
1815 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1816 SIVAL(pdata,0,mode);
1822 /* NT4 server just returns "invalid query" to this - if we try to answer
1823 it then NTws gets a BSOD! (tridge) */
1824 case SMB_QUERY_FILE_STREAM_INFO:
1826 SIVAL(pdata,4,(uint32)size);
1827 SIVAL(pdata,12,(uint32)allocation_size);
1828 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1829 SIVAL(pdata,20,len);
1830 data_size = 24 + len;
1835 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1838 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1843 /****************************************************************************
1844 Deal with the internal needs of setting the delete on close flag. Note that
1845 as the tdb locking is recursive, it is safe to call this from within
1846 open_file_shared. JRA.
1847 ****************************************************************************/
1849 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
1852 * Only allow delete on close for writable shares.
1855 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
1856 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
1858 return NT_STATUS_ACCESS_DENIED;
1861 * Only allow delete on close for files/directories opened with delete intent.
1864 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1865 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
1867 return NT_STATUS_ACCESS_DENIED;
1870 if(fsp->is_directory) {
1871 fsp->directory_delete_on_close = delete_on_close;
1872 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
1873 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1874 } else if(fsp->stat_open) {
1876 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %s\n",
1877 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1881 files_struct *iterate_fsp;
1884 * Modify the share mode entry for all files open
1885 * on this device and inode to tell other smbds we have
1886 * changed the delete on close flag. This will be noticed
1887 * in the close code, the last closer will delete the file
1891 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1892 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1894 if (lock_share_entry_fsp(fsp) == False)
1895 return NT_STATUS_ACCESS_DENIED;
1897 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1898 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
1900 unlock_share_entry_fsp(fsp);
1901 return NT_STATUS_ACCESS_DENIED;
1908 unlock_share_entry_fsp(fsp);
1911 * Go through all files we have open on the same device and
1912 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1913 * Other smbd's that have this file open will look in the share_mode on close.
1914 * take care of this (rare) case in close_file(). See the comment there.
1915 * NB. JRA. We don't really need to do this anymore - all should be taken
1916 * care of in the share_mode changes in the tdb.
1919 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1920 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1921 fsp->delete_on_close = delete_on_close;
1924 * Set the delete on close flag in the fsp.
1926 fsp->delete_on_close = delete_on_close;
1928 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1929 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1933 return NT_STATUS_OK;
1936 /****************************************************************************
1937 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
1938 ****************************************************************************/
1940 static int call_trans2setfilepathinfo(connection_struct *conn,
1941 char *inbuf, char *outbuf, int length,
1942 int bufsize, char **pparams,
1943 char **ppdata, int total_data)
1945 char *params = *pparams;
1946 char *pdata = *ppdata;
1947 uint16 tran_call = SVAL(inbuf, smb_setup0);
1952 SMB_STRUCT_STAT sbuf;
1955 BOOL bad_path = False;
1956 files_struct *fsp = NULL;
1958 if (tran_call == TRANSACT2_SETFILEINFO) {
1959 fsp = file_fsp(params,0);
1960 info_level = SVAL(params,2);
1962 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1964 * This is actually a SETFILEINFO on a directory
1965 * handle (returned from an NT SMB). NT5.0 seems
1966 * to do this call. JRA.
1968 pstrcpy(fname, fsp->fsp_name);
1969 unix_convert(fname,conn,0,&bad_path,&sbuf);
1970 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1971 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1972 if((errno == ENOENT) && bad_path) {
1973 unix_ERR_class = ERRDOS;
1974 unix_ERR_code = ERRbadpath;
1976 return(UNIXERROR(ERRDOS,ERRbadpath));
1978 } else if (fsp && fsp->print_file) {
1980 * Doing a DELETE_ON_CLOSE should cancel a print job.
1982 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1983 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1985 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
1988 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1993 * Original code - this is an open file.
1995 CHECK_FSP(fsp,conn);
1997 pstrcpy(fname, fsp->fsp_name);
2000 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
2001 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2002 return(UNIXERROR(ERRDOS,ERRbadfid));
2007 info_level = SVAL(params,0);
2008 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2009 unix_convert(fname,conn,0,&bad_path,&sbuf);
2010 if(!check_name(fname, conn)) {
2011 if((errno == ENOENT) && bad_path) {
2012 unix_ERR_class = ERRDOS;
2013 unix_ERR_code = ERRbadpath;
2015 return(UNIXERROR(ERRDOS,ERRbadpath));
2018 if(!VALID_STAT(sbuf)) {
2019 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
2020 if((errno == ENOENT) && bad_path) {
2021 unix_ERR_class = ERRDOS;
2022 unix_ERR_code = ERRbadpath;
2024 return(UNIXERROR(ERRDOS,ERRbadpath));
2028 if (!CAN_WRITE(conn))
2029 return ERROR_DOS(ERRSRV,ERRaccess);
2031 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2032 tran_call,fname,info_level,total_data));
2034 /* Realloc the parameter and data sizes */
2035 params = Realloc(*pparams,2);
2037 return ERROR_DOS(ERRDOS,ERRnomem);
2042 size = sbuf.st_size;
2043 tvs.modtime = sbuf.st_mtime;
2044 tvs.actime = sbuf.st_atime;
2045 mode = dos_mode(conn,fname,&sbuf);
2047 if (total_data > 4 && IVAL(pdata,0) == total_data) {
2048 /* uggh, EAs for OS2 */
2049 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2050 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2053 switch (info_level) {
2054 case SMB_INFO_STANDARD:
2055 case SMB_INFO_QUERY_EA_SIZE:
2058 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2061 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2063 mode = SVAL(pdata,l1_attrFile);
2064 size = IVAL(pdata,l1_cbFile);
2068 /* XXXX um, i don't think this is right.
2069 it's also not in the cifs6.txt spec.
2071 case SMB_INFO_QUERY_EAS_FROM_LIST:
2072 tvs.actime = make_unix_date2(pdata+8);
2073 tvs.modtime = make_unix_date2(pdata+12);
2074 size = IVAL(pdata,16);
2075 mode = IVAL(pdata,24);
2078 /* XXXX nor this. not in cifs6.txt, either. */
2079 case SMB_INFO_QUERY_ALL_EAS:
2080 tvs.actime = make_unix_date2(pdata+8);
2081 tvs.modtime = make_unix_date2(pdata+12);
2082 size = IVAL(pdata,16);
2083 mode = IVAL(pdata,24);
2086 case SMB_SET_FILE_BASIC_INFO:
2087 case SMB_FILE_BASIC_INFORMATION:
2089 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2091 time_t changed_time;
2093 /* Ignore create time at offset pdata. */
2096 tvs.actime = interpret_long_date(pdata+8);
2098 write_time = interpret_long_date(pdata+16);
2099 changed_time = interpret_long_date(pdata+24);
2101 tvs.modtime = MIN(write_time, changed_time);
2103 /* Prefer a defined time to an undefined one. */
2104 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2105 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2106 ? changed_time : write_time);
2109 mode = IVAL(pdata,32);
2113 case SMB_FILE_ALLOCATION_INFORMATION:
2114 case SMB_SET_FILE_ALLOCATION_INFO:
2117 SMB_OFF_T allocation_size = IVAL(pdata,0);
2118 #ifdef LARGE_SMB_OFF_T
2119 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2120 #else /* LARGE_SMB_OFF_T */
2121 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2122 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2123 #endif /* LARGE_SMB_OFF_T */
2124 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2125 fname, (double)allocation_size ));
2127 if(allocation_size != sbuf.st_size) {
2128 SMB_STRUCT_STAT new_sbuf;
2130 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2131 fname, (double)allocation_size ));
2134 files_struct *new_fsp = NULL;
2135 int access_mode = 0;
2138 if(global_oplock_break) {
2139 /* Queue this file modify as we are the process of an oplock break. */
2141 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2142 DEBUGADD(2,( "in oplock break state.\n"));
2144 push_oplock_pending_smb_message(inbuf, length);
2148 new_fsp = open_file_shared(conn, fname, &sbuf,
2149 SET_OPEN_MODE(DOS_OPEN_RDWR),
2150 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2151 0, 0, &access_mode, &action);
2153 if (new_fsp == NULL)
2154 return(UNIXERROR(ERRDOS,ERRbadpath));
2155 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2156 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2157 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
2160 close_file(new_fsp,True);
2162 ret = vfs_allocate_file_space(fsp, size);
2163 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
2164 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2169 return ERROR_NT(NT_STATUS_DISK_FULL);
2171 /* Allocate can trucate size... */
2172 size = new_sbuf.st_size;
2178 case SMB_FILE_END_OF_FILE_INFORMATION:
2179 case SMB_SET_FILE_END_OF_FILE_INFO:
2181 size = IVAL(pdata,0);
2182 #ifdef LARGE_SMB_OFF_T
2183 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2184 #else /* LARGE_SMB_OFF_T */
2185 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2186 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2187 #endif /* LARGE_SMB_OFF_T */
2188 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2192 case SMB_FILE_DISPOSITION_INFORMATION:
2193 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2195 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2198 if (tran_call != TRANSACT2_SETFILEINFO)
2199 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2202 return(UNIXERROR(ERRDOS,ERRbadfid));
2204 status = set_delete_on_close_internal(fsp, delete_on_close);
2206 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2207 return ERROR_NT(status);
2213 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2216 /* get some defaults (no modifications) if any info is zero or -1. */
2217 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2218 tvs.actime = sbuf.st_atime;
2220 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2221 tvs.modtime = sbuf.st_mtime;
2223 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2224 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2225 DEBUG(6,("size: %.0f ", (double)size));
2226 DEBUG(6,("mode: %x\n" , mode));
2228 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2229 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2230 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2231 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2234 * Only do this test if we are not explicitly
2235 * changing the size of a file.
2238 size = sbuf.st_size;
2242 * Try and set the times, size and mode of this file -
2243 * if they are different from the current values
2245 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2248 * This was a setfileinfo on an open file.
2249 * NT does this a lot. It's actually pointless
2250 * setting the time here, as it will be overwritten
2251 * on the next write, so we save the request
2252 * away and will set it on file code. JRA.
2255 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2256 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2257 fsp->pending_modtime = tvs.modtime;
2262 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2264 if(file_utime(conn, fname, &tvs)!=0)
2265 return(UNIXERROR(ERRDOS,ERRnoaccess));
2269 /* check the mode isn't different, before changing it */
2270 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2272 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
2274 if(file_chmod(conn, fname, mode, NULL)) {
2275 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2276 return(UNIXERROR(ERRDOS,ERRnoaccess));
2280 if(size != sbuf.st_size) {
2282 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2283 fname, (double)size ));
2286 files_struct *new_fsp = NULL;
2287 int access_mode = 0;
2290 if(global_oplock_break) {
2291 /* Queue this file modify as we are the process of an oplock break. */
2293 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2294 DEBUGADD(2,( "in oplock break state.\n"));
2296 push_oplock_pending_smb_message(inbuf, length);
2300 new_fsp = open_file_shared(conn, fname, &sbuf,
2301 SET_OPEN_MODE(DOS_OPEN_RDWR),
2302 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2303 0, 0, &access_mode, &action);
2305 if (new_fsp == NULL)
2306 return(UNIXERROR(ERRDOS,ERRbadpath));
2307 vfs_set_filelen(new_fsp, size);
2308 close_file(new_fsp,True);
2310 vfs_set_filelen(fsp, size);
2316 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2321 /****************************************************************************
2322 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2323 ****************************************************************************/
2325 static int call_trans2mkdir(connection_struct *conn,
2326 char *inbuf, char *outbuf, int length, int bufsize,
2327 char **pparams, char **ppdata)
2329 char *params = *pparams;
2332 SMB_STRUCT_STAT sbuf;
2333 BOOL bad_path = False;
2335 if (!CAN_WRITE(conn))
2336 return ERROR_DOS(ERRSRV,ERRaccess);
2338 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2340 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2342 unix_convert(directory,conn,0,&bad_path,&sbuf);
2343 if (check_name(directory,conn))
2344 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2348 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2349 if((errno == ENOENT) && bad_path)
2351 unix_ERR_class = ERRDOS;
2352 unix_ERR_code = ERRbadpath;
2354 return(UNIXERROR(ERRDOS,ERRnoaccess));
2357 /* Realloc the parameter and data sizes */
2358 params = Realloc(*pparams,2);
2359 if(params == NULL) {
2360 return ERROR_DOS(ERRDOS,ERRnomem);
2366 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2371 /****************************************************************************
2372 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2373 We don't actually do this - we just send a null response.
2374 ****************************************************************************/
2376 static int call_trans2findnotifyfirst(connection_struct *conn,
2377 char *inbuf, char *outbuf,
2378 int length, int bufsize,
2379 char **pparams, char **ppdata)
2381 static uint16 fnf_handle = 257;
2382 char *params = *pparams;
2383 uint16 info_level = SVAL(params,4);
2385 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2393 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2396 /* Realloc the parameter and data sizes */
2397 params = Realloc(*pparams,6);
2398 if(params == NULL) {
2399 return ERROR_DOS(ERRDOS,ERRnomem);
2403 SSVAL(params,0,fnf_handle);
2404 SSVAL(params,2,0); /* No changes */
2405 SSVAL(params,4,0); /* No EA errors */
2412 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2417 /****************************************************************************
2418 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2419 changes). Currently this does nothing.
2420 ****************************************************************************/
2422 static int call_trans2findnotifynext(connection_struct *conn,
2423 char *inbuf, char *outbuf,
2424 int length, int bufsize,
2425 char **pparams, char **ppdata)
2427 char *params = *pparams;
2429 DEBUG(3,("call_trans2findnotifynext\n"));
2431 /* Realloc the parameter and data sizes */
2432 params = Realloc(*pparams,4);
2433 if(params == NULL) {
2434 return ERROR_DOS(ERRDOS,ERRnomem);
2438 SSVAL(params,0,0); /* No changes */
2439 SSVAL(params,2,0); /* No EA errors */
2441 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2446 /****************************************************************************
2447 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2448 ****************************************************************************/
2450 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2451 char* outbuf, int length, int bufsize,
2452 char** pparams, char** ppdata)
2454 char *params = *pparams;
2457 int max_referral_level = SVAL(params,0);
2460 DEBUG(10,("call_trans2getdfsreferral\n"));
2462 if(!lp_host_msdfs())
2463 return ERROR_DOS(ERRDOS,ERRbadfunc);
2465 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2467 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2468 return ERROR_DOS(ERRDOS,ERRbadfile);
2470 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2471 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2476 #define LMCAT_SPL 0x53
2477 #define LMFUNC_GETJOBID 0x60
2479 /****************************************************************************
2480 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2481 ****************************************************************************/
2483 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2484 char* outbuf, int length, int bufsize,
2485 char** pparams, char** ppdata)
2487 char *pdata = *ppdata;
2488 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2490 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2491 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2492 pdata = Realloc(*ppdata, 32);
2494 return ERROR_DOS(ERRDOS,ERRnomem);
2498 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2499 CAN ACCEPT THIS IN UNICODE. JRA. */
2501 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2502 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2503 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2504 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2507 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2508 return ERROR_DOS(ERRSRV,ERRerror);
2512 /****************************************************************************
2513 Reply to a SMBfindclose (stop trans2 directory search).
2514 ****************************************************************************/
2516 int reply_findclose(connection_struct *conn,
2517 char *inbuf,char *outbuf,int length,int bufsize)
2520 int dptr_num=SVALS(inbuf,smb_vwv0);
2521 START_PROFILE(SMBfindclose);
2523 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2525 dptr_close(&dptr_num);
2527 outsize = set_message(outbuf,0,0,True);
2529 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2531 END_PROFILE(SMBfindclose);
2535 /****************************************************************************
2536 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
2537 ****************************************************************************/
2539 int reply_findnclose(connection_struct *conn,
2540 char *inbuf,char *outbuf,int length,int bufsize)
2544 START_PROFILE(SMBfindnclose);
2546 dptr_num = SVAL(inbuf,smb_vwv0);
2548 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2550 /* We never give out valid handles for a
2551 findnotifyfirst - so any dptr_num is ok here.
2554 outsize = set_message(outbuf,0,0,True);
2556 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2558 END_PROFILE(SMBfindnclose);
2562 /****************************************************************************
2563 Reply to a SMBtranss2 - just ignore it!
2564 ****************************************************************************/
2566 int reply_transs2(connection_struct *conn,
2567 char *inbuf,char *outbuf,int length,int bufsize)
2569 START_PROFILE(SMBtranss2);
2570 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2571 END_PROFILE(SMBtranss2);
2575 /****************************************************************************
2576 Reply to a SMBtrans2.
2577 ****************************************************************************/
2579 int reply_trans2(connection_struct *conn,
2580 char *inbuf,char *outbuf,int length,int bufsize)
2583 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2584 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2586 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2587 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2588 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2589 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2590 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2591 int32 timeout = IVALS(inbuf,smb_timeout);
2593 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2594 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2595 char *params = NULL, *data = NULL;
2596 int num_params, num_params_sofar, num_data, num_data_sofar;
2597 START_PROFILE(SMBtrans2);
2599 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2600 /* Queue this open message as we are the process of an
2603 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2604 DEBUGADD(2,( "in oplock break state.\n"));
2606 push_oplock_pending_smb_message(inbuf, length);
2607 END_PROFILE(SMBtrans2);
2611 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2612 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2613 END_PROFILE(SMBtrans2);
2614 return ERROR_DOS(ERRSRV,ERRaccess);
2617 outsize = set_message(outbuf,0,0,True);
2619 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2620 is so as a sanity check */
2623 * Need to have rc=0 for ioctl to get job id for OS/2.
2624 * Network printing will fail if function is not successful.
2625 * Similar function in reply.c will be used if protocol
2626 * is LANMAN1.0 instead of LM1.2X002.
2627 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2628 * outbuf doesn't have to be set(only job id is used).
2630 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2631 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2632 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2633 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2635 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2636 DEBUG(2,("Transaction is %d\n",tran_call));
2637 END_PROFILE(SMBtrans2);
2638 return ERROR_DOS(ERRSRV,ERRerror);
2642 /* Allocate the space for the maximum needed parameters and data */
2643 if (total_params > 0)
2644 params = (char *)malloc(total_params);
2646 data = (char *)malloc(total_data);
2648 if ((total_params && !params) || (total_data && !data)) {
2649 DEBUG(2,("Out of memory in reply_trans2\n"));
2652 END_PROFILE(SMBtrans2);
2653 return ERROR_DOS(ERRDOS,ERRnomem);
2656 /* Copy the param and data bytes sent with this request into
2657 the params buffer */
2658 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2659 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2661 if (num_params > total_params || num_data > total_data)
2662 exit_server("invalid params in reply_trans2");
2665 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2667 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2669 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2670 /* We need to send an interim response then receive the rest
2671 of the parameter/data bytes */
2672 outsize = set_message(outbuf,0,0,True);
2673 if (!send_smb(smbd_server_fd(),outbuf))
2674 exit_server("reply_trans2: send_smb failed.");
2676 while (num_data_sofar < total_data ||
2677 num_params_sofar < total_params) {
2680 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2683 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2684 outsize = set_message(outbuf,0,0,True);
2686 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2688 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2689 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2692 END_PROFILE(SMBtrans2);
2693 return ERROR_DOS(ERRSRV,ERRerror);
2696 /* Revise total_params and total_data in case
2697 they have changed downwards */
2698 total_params = SVAL(inbuf, smb_tpscnt);
2699 total_data = SVAL(inbuf, smb_tdscnt);
2700 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2701 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2702 if (num_params_sofar > total_params || num_data_sofar > total_data)
2703 exit_server("data overflow in trans2");
2705 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2706 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2707 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2708 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2712 if (Protocol >= PROTOCOL_NT1) {
2713 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2716 /* Now we must call the relevant TRANS2 function */
2718 case TRANSACT2_OPEN:
2719 START_PROFILE_NESTED(Trans2_open);
2720 outsize = call_trans2open(conn,
2721 inbuf, outbuf, bufsize,
2723 END_PROFILE_NESTED(Trans2_open);
2726 case TRANSACT2_FINDFIRST:
2727 START_PROFILE_NESTED(Trans2_findfirst);
2728 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2729 bufsize, ¶ms, &data);
2730 END_PROFILE_NESTED(Trans2_findfirst);
2733 case TRANSACT2_FINDNEXT:
2734 START_PROFILE_NESTED(Trans2_findnext);
2735 outsize = call_trans2findnext(conn, inbuf, outbuf,
2738 END_PROFILE_NESTED(Trans2_findnext);
2741 case TRANSACT2_QFSINFO:
2742 START_PROFILE_NESTED(Trans2_qfsinfo);
2743 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2744 length, bufsize, ¶ms,
2746 END_PROFILE_NESTED(Trans2_qfsinfo);
2749 case TRANSACT2_SETFSINFO:
2750 START_PROFILE_NESTED(Trans2_setfsinfo);
2751 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2754 END_PROFILE_NESTED(Trans2_setfsinfo);
2757 case TRANSACT2_QPATHINFO:
2758 case TRANSACT2_QFILEINFO:
2759 START_PROFILE_NESTED(Trans2_qpathinfo);
2760 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2762 ¶ms, &data, total_data);
2763 END_PROFILE_NESTED(Trans2_qpathinfo);
2765 case TRANSACT2_SETPATHINFO:
2766 case TRANSACT2_SETFILEINFO:
2767 START_PROFILE_NESTED(Trans2_setpathinfo);
2768 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2772 END_PROFILE_NESTED(Trans2_setpathinfo);
2775 case TRANSACT2_FINDNOTIFYFIRST:
2776 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2777 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2780 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2783 case TRANSACT2_FINDNOTIFYNEXT:
2784 START_PROFILE_NESTED(Trans2_findnotifynext);
2785 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2788 END_PROFILE_NESTED(Trans2_findnotifynext);
2790 case TRANSACT2_MKDIR:
2791 START_PROFILE_NESTED(Trans2_mkdir);
2792 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2793 bufsize, ¶ms, &data);
2794 END_PROFILE_NESTED(Trans2_mkdir);
2797 case TRANSACT2_GET_DFS_REFERRAL:
2798 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2799 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2800 bufsize, ¶ms, &data);
2801 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2803 case TRANSACT2_IOCTL:
2804 START_PROFILE_NESTED(Trans2_ioctl);
2805 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2806 bufsize,¶ms,&data);
2807 END_PROFILE_NESTED(Trans2_ioctl);
2810 /* Error in request */
2811 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2814 END_PROFILE(SMBtrans2);
2815 return ERROR_DOS(ERRSRV,ERRerror);
2818 /* As we do not know how many data packets will need to be
2819 returned here the various call_trans2xxxx calls
2820 must send their own. Thus a call_trans2xxx routine only
2821 returns a value other than -1 when it wants to send
2827 END_PROFILE(SMBtrans2);
2828 return outsize; /* If a correct response was needed the
2829 call_trans2xxx calls have already sent
2830 it. If outsize != -1 then it is returning */