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;
1444 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1447 if (tran_call == TRANSACT2_QFILEINFO) {
1448 files_struct *fsp = file_fsp(params,0);
1449 info_level = SVAL(params,2);
1451 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1453 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1455 * This is actually a QFILEINFO on a directory
1456 * handle (returned from an NT SMB). NT5.0 seems
1457 * to do this call. JRA.
1459 pstrcpy(fname, fsp->fsp_name);
1460 unix_convert(fname,conn,0,&bad_path,&sbuf);
1461 if (!check_name(fname,conn) ||
1462 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1463 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1464 if((errno == ENOENT) && bad_path) {
1465 unix_ERR_class = ERRDOS;
1466 unix_ERR_code = ERRbadpath;
1468 return(UNIXERROR(ERRDOS,ERRbadpath));
1471 delete_pending = fsp->directory_delete_on_close;
1474 * Original code - this is an open file.
1476 CHECK_FSP(fsp,conn);
1478 pstrcpy(fname, fsp->fsp_name);
1479 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1480 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1481 return(UNIXERROR(ERRDOS,ERRbadfid));
1483 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1484 return(UNIXERROR(ERRDOS,ERRnoaccess));
1486 delete_pending = fsp->delete_on_close;
1490 info_level = SVAL(params,0);
1492 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1494 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1496 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1498 unix_convert(fname,conn,0,&bad_path,&sbuf);
1499 if (!check_name(fname,conn) ||
1500 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1501 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1502 if((errno == ENOENT) && bad_path) {
1503 unix_ERR_class = ERRDOS;
1504 unix_ERR_code = ERRbadpath;
1506 return(UNIXERROR(ERRDOS,ERRbadpath));
1511 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1512 fname,info_level,tran_call,total_data));
1514 p = strrchr_m(fname,'/');
1520 mode = dos_mode(conn,fname,&sbuf);
1521 size = sbuf.st_size;
1522 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
1527 params = Realloc(*pparams,2);
1529 return ERROR_DOS(ERRDOS,ERRnomem);
1531 memset((char *)params,'\0',2);
1532 data_size = max_data_bytes + 1024;
1533 pdata = Realloc(*ppdata, data_size);
1534 if ( pdata == NULL )
1535 return ERROR_DOS(ERRDOS,ERRnomem);
1538 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1539 /* uggh, EAs for OS2 */
1540 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1541 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1544 memset((char *)pdata,'\0',data_size);
1546 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1548 if (lp_dos_filetime_resolution(SNUM(conn))) {
1550 sbuf.st_atime &= ~1;
1551 sbuf.st_mtime &= ~1;
1552 sbuf.st_mtime &= ~1;
1555 switch (info_level) {
1556 case SMB_INFO_STANDARD:
1557 case SMB_INFO_QUERY_EA_SIZE:
1558 data_size = (info_level==1?22:26);
1559 put_dos_date2(pdata,l1_fdateCreation,c_time);
1560 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1561 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1562 SIVAL(pdata,l1_cbFile,(uint32)size);
1563 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1564 SSVAL(pdata,l1_attrFile,mode);
1565 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1568 case SMB_INFO_QUERY_EAS_FROM_LIST:
1570 put_dos_date2(pdata,0,c_time);
1571 put_dos_date2(pdata,4,sbuf.st_atime);
1572 put_dos_date2(pdata,8,sbuf.st_mtime);
1573 SIVAL(pdata,12,(uint32)size);
1574 SIVAL(pdata,16,(uint32)allocation_size);
1575 SIVAL(pdata,20,mode);
1578 case SMB_INFO_QUERY_ALL_EAS:
1580 SIVAL(pdata,0,data_size);
1584 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1586 case SMB_FILE_BASIC_INFORMATION:
1587 case SMB_QUERY_FILE_BASIC_INFO:
1589 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1590 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1595 put_long_date(pdata,c_time);
1596 put_long_date(pdata+8,sbuf.st_atime);
1597 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1598 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1599 SIVAL(pdata,32,mode);
1601 DEBUG(5,("SMB_QFBI - "));
1603 time_t create_time = c_time;
1604 DEBUG(5,("create: %s ", ctime(&create_time)));
1606 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1607 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1608 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1609 DEBUG(5,("mode: %x\n", mode));
1613 case SMB_FILE_STANDARD_INFORMATION:
1614 case SMB_QUERY_FILE_STANDARD_INFO:
1616 /* Fake up allocation size. */
1617 SOFF_T(pdata,0,allocation_size);
1618 SOFF_T(pdata,8,size);
1619 SIVAL(pdata,16,sbuf.st_nlink);
1621 SCVAL(pdata,21,(mode&aDIR)?1:0);
1624 case SMB_FILE_EA_INFORMATION:
1625 case SMB_QUERY_FILE_EA_INFO:
1629 /* Get the 8.3 name - used if NT SMB was negotiated. */
1630 case SMB_QUERY_FILE_ALT_NAME_INFO:
1634 pstrcpy(short_name,base_name);
1635 /* Mangle if not already 8.3 */
1636 if(!is_8_3(short_name, True)) {
1637 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1640 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
1641 data_size = 4 + len;
1646 case SMB_QUERY_FILE_NAME_INFO:
1648 * The first part of this code is essential
1649 * to get security descriptors to work on mapped
1650 * drives. Don't ask how I discovered this unless
1651 * you like hearing about me suffering.... :-). JRA.
1653 if(strequal(".", fname)) {
1654 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1656 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1658 data_size = 4 + len;
1662 case SMB_FILE_END_OF_FILE_INFORMATION:
1663 case SMB_QUERY_FILE_END_OF_FILEINFO:
1665 SOFF_T(pdata,0,size);
1668 case SMB_FILE_ALLOCATION_INFORMATION:
1669 case SMB_QUERY_FILE_ALLOCATION_INFO:
1671 SOFF_T(pdata,0,allocation_size);
1674 case SMB_QUERY_FILE_ALL_INFO:
1675 put_long_date(pdata,c_time);
1676 put_long_date(pdata+8,sbuf.st_atime);
1677 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1678 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1679 SIVAL(pdata,32,mode);
1681 SOFF_T(pdata,0,allocation_size);
1682 SOFF_T(pdata,8,size);
1683 SIVAL(pdata,16,sbuf.st_nlink);
1684 SCVAL(pdata,20,delete_pending);
1685 SCVAL(pdata,21,(mode&aDIR)?1:0);
1687 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1688 pdata += 8; /* index number */
1689 pdata += 4; /* EA info */
1691 SIVAL(pdata,0,0xA9);
1693 SIVAL(pdata,0,0xd01BF);
1695 SOFF_T(pdata,0,pos); /* current offset */
1697 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1699 pdata += 4; /* alignment */
1700 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1703 data_size = PTR_DIFF(pdata,(*ppdata));
1706 case SMB_FILE_INTERNAL_INFORMATION:
1707 /* This should be an index number - looks like dev/ino to me :-) */
1708 SIVAL(pdata,0,sbuf.st_dev);
1709 SIVAL(pdata,4,sbuf.st_ino);
1713 case SMB_FILE_ACCESS_INFORMATION:
1714 SIVAL(pdata,0,0x12019F); /* ??? */
1718 case SMB_FILE_NAME_INFORMATION:
1719 /* Pathname with leading '\'. */
1724 pstrcpy(new_fname, "\\");
1725 pstrcat(new_fname, fname);
1726 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1727 SIVAL(pdata,0,byte_len);
1728 data_size = 4 + byte_len;
1732 case SMB_FILE_DISPOSITION_INFORMATION:
1734 SCVAL(pdata,0,delete_pending);
1737 case SMB_FILE_POSITION_INFORMATION:
1739 SOFF_T(pdata,0,pos);
1742 case SMB_FILE_MODE_INFORMATION:
1743 SIVAL(pdata,0,mode);
1747 case SMB_FILE_ALIGNMENT_INFORMATION:
1748 SIVAL(pdata,0,0); /* No alignment needed. */
1753 /* Not yet finished... JRA */
1759 put_long_date(pdata,c_time);
1760 put_long_date(pdata+8,sbuf.st_atime);
1761 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1762 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1763 SIVAL(pdata,32,mode);
1764 SIVAL(pdata,36,0); /* ??? */
1765 SIVAL(pdata,40,0x20); /* ??? */
1766 SIVAL(pdata,44,0); /* ??? */
1767 SOFF_T(pdata,48,size);
1768 SIVAL(pdata,56,0x1); /* ??? */
1769 SIVAL(pdata,60,0); /* ??? */
1770 SIVAL(pdata,64,0); /* ??? */
1771 SIVAL(pdata,68,length); /* Following string length in bytes. */
1772 dos_PutUniCode(pdata+72,,False);
1777 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1778 /* Last component of pathname. */
1780 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1781 SIVAL(pdata,0,byte_len);
1782 data_size = 4 + byte_len;
1786 case SMB_FILE_STREAM_INFORMATION:
1790 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1791 SIVAL(pdata,0,0); /* ??? */
1792 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1793 SOFF_T(pdata,8,size);
1794 SIVAL(pdata,16,allocation_size);
1795 SIVAL(pdata,20,0); /* ??? */
1796 data_size = 24 + byte_len;
1800 case SMB_FILE_COMPRESSION_INFORMATION:
1801 SOFF_T(pdata,0,size);
1802 SIVAL(pdata,8,0); /* ??? */
1803 SIVAL(pdata,12,0); /* ??? */
1807 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1808 put_long_date(pdata,c_time);
1809 put_long_date(pdata+8,sbuf.st_atime);
1810 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1811 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1812 SIVAL(pdata,32,allocation_size);
1813 SOFF_T(pdata,40,size);
1814 SIVAL(pdata,48,mode);
1815 SIVAL(pdata,52,0); /* ??? */
1819 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1820 SIVAL(pdata,0,mode);
1826 /* NT4 server just returns "invalid query" to this - if we try to answer
1827 it then NTws gets a BSOD! (tridge) */
1828 case SMB_QUERY_FILE_STREAM_INFO:
1830 SIVAL(pdata,4,(uint32)size);
1831 SIVAL(pdata,12,(uint32)allocation_size);
1832 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1833 SIVAL(pdata,20,len);
1834 data_size = 24 + len;
1839 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1842 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1847 /****************************************************************************
1848 Deal with the internal needs of setting the delete on close flag. Note that
1849 as the tdb locking is recursive, it is safe to call this from within
1850 open_file_shared. JRA.
1851 ****************************************************************************/
1853 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
1856 * Only allow delete on close for writable shares.
1859 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
1860 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
1862 return NT_STATUS_ACCESS_DENIED;
1865 * Only allow delete on close for files/directories opened with delete intent.
1868 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1869 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
1871 return NT_STATUS_ACCESS_DENIED;
1874 if(fsp->is_directory) {
1875 fsp->directory_delete_on_close = delete_on_close;
1876 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
1877 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1878 } else if(fsp->stat_open) {
1880 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %s\n",
1881 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1885 files_struct *iterate_fsp;
1888 * Modify the share mode entry for all files open
1889 * on this device and inode to tell other smbds we have
1890 * changed the delete on close flag. This will be noticed
1891 * in the close code, the last closer will delete the file
1895 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1896 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1898 if (lock_share_entry_fsp(fsp) == False)
1899 return NT_STATUS_ACCESS_DENIED;
1901 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1902 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
1904 unlock_share_entry_fsp(fsp);
1905 return NT_STATUS_ACCESS_DENIED;
1912 unlock_share_entry_fsp(fsp);
1915 * Go through all files we have open on the same device and
1916 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1917 * Other smbd's that have this file open will look in the share_mode on close.
1918 * take care of this (rare) case in close_file(). See the comment there.
1919 * NB. JRA. We don't really need to do this anymore - all should be taken
1920 * care of in the share_mode changes in the tdb.
1923 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1924 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1925 fsp->delete_on_close = delete_on_close;
1928 * Set the delete on close flag in the fsp.
1930 fsp->delete_on_close = delete_on_close;
1932 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1933 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1937 return NT_STATUS_OK;
1940 /****************************************************************************
1941 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
1942 ****************************************************************************/
1944 static int call_trans2setfilepathinfo(connection_struct *conn,
1945 char *inbuf, char *outbuf, int length,
1946 int bufsize, char **pparams,
1947 char **ppdata, int total_data)
1949 char *params = *pparams;
1950 char *pdata = *ppdata;
1951 uint16 tran_call = SVAL(inbuf, smb_setup0);
1956 SMB_STRUCT_STAT sbuf;
1959 BOOL bad_path = False;
1960 files_struct *fsp = NULL;
1962 if (tran_call == TRANSACT2_SETFILEINFO) {
1963 fsp = file_fsp(params,0);
1964 info_level = SVAL(params,2);
1966 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1968 * This is actually a SETFILEINFO on a directory
1969 * handle (returned from an NT SMB). NT5.0 seems
1970 * to do this call. JRA.
1972 pstrcpy(fname, fsp->fsp_name);
1973 unix_convert(fname,conn,0,&bad_path,&sbuf);
1974 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1975 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1976 if((errno == ENOENT) && bad_path) {
1977 unix_ERR_class = ERRDOS;
1978 unix_ERR_code = ERRbadpath;
1980 return(UNIXERROR(ERRDOS,ERRbadpath));
1982 } else if (fsp && fsp->print_file) {
1984 * Doing a DELETE_ON_CLOSE should cancel a print job.
1986 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1987 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1989 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
1992 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1997 * Original code - this is an open file.
1999 CHECK_FSP(fsp,conn);
2001 pstrcpy(fname, fsp->fsp_name);
2004 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
2005 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2006 return(UNIXERROR(ERRDOS,ERRbadfid));
2011 info_level = SVAL(params,0);
2012 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2013 unix_convert(fname,conn,0,&bad_path,&sbuf);
2014 if(!check_name(fname, conn)) {
2015 if((errno == ENOENT) && bad_path) {
2016 unix_ERR_class = ERRDOS;
2017 unix_ERR_code = ERRbadpath;
2019 return(UNIXERROR(ERRDOS,ERRbadpath));
2022 if(!VALID_STAT(sbuf)) {
2023 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
2024 if((errno == ENOENT) && bad_path) {
2025 unix_ERR_class = ERRDOS;
2026 unix_ERR_code = ERRbadpath;
2028 return(UNIXERROR(ERRDOS,ERRbadpath));
2032 if (!CAN_WRITE(conn))
2033 return ERROR_DOS(ERRSRV,ERRaccess);
2035 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2036 tran_call,fname,info_level,total_data));
2038 /* Realloc the parameter and data sizes */
2039 params = Realloc(*pparams,2);
2041 return ERROR_DOS(ERRDOS,ERRnomem);
2046 size = sbuf.st_size;
2047 tvs.modtime = sbuf.st_mtime;
2048 tvs.actime = sbuf.st_atime;
2049 mode = dos_mode(conn,fname,&sbuf);
2051 if (total_data > 4 && IVAL(pdata,0) == total_data) {
2052 /* uggh, EAs for OS2 */
2053 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2054 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2057 switch (info_level) {
2058 case SMB_INFO_STANDARD:
2059 case SMB_INFO_QUERY_EA_SIZE:
2062 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2065 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2067 mode = SVAL(pdata,l1_attrFile);
2068 size = IVAL(pdata,l1_cbFile);
2072 /* XXXX um, i don't think this is right.
2073 it's also not in the cifs6.txt spec.
2075 case SMB_INFO_QUERY_EAS_FROM_LIST:
2076 tvs.actime = make_unix_date2(pdata+8);
2077 tvs.modtime = make_unix_date2(pdata+12);
2078 size = IVAL(pdata,16);
2079 mode = IVAL(pdata,24);
2082 /* XXXX nor this. not in cifs6.txt, either. */
2083 case SMB_INFO_QUERY_ALL_EAS:
2084 tvs.actime = make_unix_date2(pdata+8);
2085 tvs.modtime = make_unix_date2(pdata+12);
2086 size = IVAL(pdata,16);
2087 mode = IVAL(pdata,24);
2090 case SMB_SET_FILE_BASIC_INFO:
2091 case SMB_FILE_BASIC_INFORMATION:
2093 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2095 time_t changed_time;
2097 /* Ignore create time at offset pdata. */
2100 tvs.actime = interpret_long_date(pdata+8);
2102 write_time = interpret_long_date(pdata+16);
2103 changed_time = interpret_long_date(pdata+24);
2105 tvs.modtime = MIN(write_time, changed_time);
2107 /* Prefer a defined time to an undefined one. */
2108 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2109 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2110 ? changed_time : write_time);
2113 mode = IVAL(pdata,32);
2117 case SMB_FILE_ALLOCATION_INFORMATION:
2118 case SMB_SET_FILE_ALLOCATION_INFO:
2121 SMB_OFF_T allocation_size = IVAL(pdata,0);
2122 #ifdef LARGE_SMB_OFF_T
2123 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2124 #else /* LARGE_SMB_OFF_T */
2125 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2126 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2127 #endif /* LARGE_SMB_OFF_T */
2128 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2129 fname, (double)allocation_size ));
2131 if(allocation_size != sbuf.st_size) {
2132 SMB_STRUCT_STAT new_sbuf;
2134 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2135 fname, (double)allocation_size ));
2138 files_struct *new_fsp = NULL;
2139 int access_mode = 0;
2142 if(global_oplock_break) {
2143 /* Queue this file modify as we are the process of an oplock break. */
2145 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2146 DEBUGADD(2,( "in oplock break state.\n"));
2148 push_oplock_pending_smb_message(inbuf, length);
2152 new_fsp = open_file_shared(conn, fname, &sbuf,
2153 SET_OPEN_MODE(DOS_OPEN_RDWR),
2154 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2155 0, 0, &access_mode, &action);
2157 if (new_fsp == NULL)
2158 return(UNIXERROR(ERRDOS,ERRbadpath));
2159 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2160 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2161 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
2164 close_file(new_fsp,True);
2166 ret = vfs_allocate_file_space(fsp, size);
2167 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
2168 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2173 return ERROR_NT(NT_STATUS_DISK_FULL);
2175 /* Allocate can trucate size... */
2176 size = new_sbuf.st_size;
2182 case SMB_FILE_END_OF_FILE_INFORMATION:
2183 case SMB_SET_FILE_END_OF_FILE_INFO:
2185 size = IVAL(pdata,0);
2186 #ifdef LARGE_SMB_OFF_T
2187 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2188 #else /* LARGE_SMB_OFF_T */
2189 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2190 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2191 #endif /* LARGE_SMB_OFF_T */
2192 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2196 case SMB_FILE_DISPOSITION_INFORMATION:
2197 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2199 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2202 if (tran_call != TRANSACT2_SETFILEINFO)
2203 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2206 return(UNIXERROR(ERRDOS,ERRbadfid));
2208 status = set_delete_on_close_internal(fsp, delete_on_close);
2210 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2211 return ERROR_NT(status);
2217 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2220 /* get some defaults (no modifications) if any info is zero or -1. */
2221 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2222 tvs.actime = sbuf.st_atime;
2224 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2225 tvs.modtime = sbuf.st_mtime;
2227 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2228 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2229 DEBUG(6,("size: %.0f ", (double)size));
2230 DEBUG(6,("mode: %x\n" , mode));
2232 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2233 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2234 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2235 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2238 * Only do this test if we are not explicitly
2239 * changing the size of a file.
2242 size = sbuf.st_size;
2246 * Try and set the times, size and mode of this file -
2247 * if they are different from the current values
2249 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2252 * This was a setfileinfo on an open file.
2253 * NT does this a lot. It's actually pointless
2254 * setting the time here, as it will be overwritten
2255 * on the next write, so we save the request
2256 * away and will set it on file code. JRA.
2259 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2260 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2261 fsp->pending_modtime = tvs.modtime;
2266 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2268 if(file_utime(conn, fname, &tvs)!=0)
2269 return(UNIXERROR(ERRDOS,ERRnoaccess));
2273 /* check the mode isn't different, before changing it */
2274 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2276 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
2278 if(file_chmod(conn, fname, mode, NULL)) {
2279 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2280 return(UNIXERROR(ERRDOS,ERRnoaccess));
2284 if(size != sbuf.st_size) {
2286 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2287 fname, (double)size ));
2290 files_struct *new_fsp = NULL;
2291 int access_mode = 0;
2294 if(global_oplock_break) {
2295 /* Queue this file modify as we are the process of an oplock break. */
2297 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2298 DEBUGADD(2,( "in oplock break state.\n"));
2300 push_oplock_pending_smb_message(inbuf, length);
2304 new_fsp = open_file_shared(conn, fname, &sbuf,
2305 SET_OPEN_MODE(DOS_OPEN_RDWR),
2306 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2307 0, 0, &access_mode, &action);
2309 if (new_fsp == NULL)
2310 return(UNIXERROR(ERRDOS,ERRbadpath));
2311 vfs_set_filelen(new_fsp, size);
2312 close_file(new_fsp,True);
2314 vfs_set_filelen(fsp, size);
2320 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2325 /****************************************************************************
2326 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2327 ****************************************************************************/
2329 static int call_trans2mkdir(connection_struct *conn,
2330 char *inbuf, char *outbuf, int length, int bufsize,
2331 char **pparams, char **ppdata)
2333 char *params = *pparams;
2336 SMB_STRUCT_STAT sbuf;
2337 BOOL bad_path = False;
2339 if (!CAN_WRITE(conn))
2340 return ERROR_DOS(ERRSRV,ERRaccess);
2342 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2344 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2346 unix_convert(directory,conn,0,&bad_path,&sbuf);
2347 if (check_name(directory,conn))
2348 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2352 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2353 if((errno == ENOENT) && bad_path)
2355 unix_ERR_class = ERRDOS;
2356 unix_ERR_code = ERRbadpath;
2358 return(UNIXERROR(ERRDOS,ERRnoaccess));
2361 /* Realloc the parameter and data sizes */
2362 params = Realloc(*pparams,2);
2363 if(params == NULL) {
2364 return ERROR_DOS(ERRDOS,ERRnomem);
2370 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2375 /****************************************************************************
2376 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2377 We don't actually do this - we just send a null response.
2378 ****************************************************************************/
2380 static int call_trans2findnotifyfirst(connection_struct *conn,
2381 char *inbuf, char *outbuf,
2382 int length, int bufsize,
2383 char **pparams, char **ppdata)
2385 static uint16 fnf_handle = 257;
2386 char *params = *pparams;
2387 uint16 info_level = SVAL(params,4);
2389 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2397 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2400 /* Realloc the parameter and data sizes */
2401 params = Realloc(*pparams,6);
2402 if(params == NULL) {
2403 return ERROR_DOS(ERRDOS,ERRnomem);
2407 SSVAL(params,0,fnf_handle);
2408 SSVAL(params,2,0); /* No changes */
2409 SSVAL(params,4,0); /* No EA errors */
2416 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2421 /****************************************************************************
2422 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2423 changes). Currently this does nothing.
2424 ****************************************************************************/
2426 static int call_trans2findnotifynext(connection_struct *conn,
2427 char *inbuf, char *outbuf,
2428 int length, int bufsize,
2429 char **pparams, char **ppdata)
2431 char *params = *pparams;
2433 DEBUG(3,("call_trans2findnotifynext\n"));
2435 /* Realloc the parameter and data sizes */
2436 params = Realloc(*pparams,4);
2437 if(params == NULL) {
2438 return ERROR_DOS(ERRDOS,ERRnomem);
2442 SSVAL(params,0,0); /* No changes */
2443 SSVAL(params,2,0); /* No EA errors */
2445 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2450 /****************************************************************************
2451 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2452 ****************************************************************************/
2454 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2455 char* outbuf, int length, int bufsize,
2456 char** pparams, char** ppdata)
2458 char *params = *pparams;
2461 int max_referral_level = SVAL(params,0);
2464 DEBUG(10,("call_trans2getdfsreferral\n"));
2466 if(!lp_host_msdfs())
2467 return ERROR_DOS(ERRDOS,ERRbadfunc);
2469 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2471 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2472 return ERROR_DOS(ERRDOS,ERRbadfile);
2474 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2475 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2480 #define LMCAT_SPL 0x53
2481 #define LMFUNC_GETJOBID 0x60
2483 /****************************************************************************
2484 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2485 ****************************************************************************/
2487 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2488 char* outbuf, int length, int bufsize,
2489 char** pparams, char** ppdata)
2491 char *pdata = *ppdata;
2492 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2494 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2495 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2496 pdata = Realloc(*ppdata, 32);
2498 return ERROR_DOS(ERRDOS,ERRnomem);
2502 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2503 CAN ACCEPT THIS IN UNICODE. JRA. */
2505 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2506 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2507 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2508 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2511 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2512 return ERROR_DOS(ERRSRV,ERRerror);
2516 /****************************************************************************
2517 Reply to a SMBfindclose (stop trans2 directory search).
2518 ****************************************************************************/
2520 int reply_findclose(connection_struct *conn,
2521 char *inbuf,char *outbuf,int length,int bufsize)
2524 int dptr_num=SVALS(inbuf,smb_vwv0);
2525 START_PROFILE(SMBfindclose);
2527 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2529 dptr_close(&dptr_num);
2531 outsize = set_message(outbuf,0,0,True);
2533 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2535 END_PROFILE(SMBfindclose);
2539 /****************************************************************************
2540 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
2541 ****************************************************************************/
2543 int reply_findnclose(connection_struct *conn,
2544 char *inbuf,char *outbuf,int length,int bufsize)
2548 START_PROFILE(SMBfindnclose);
2550 dptr_num = SVAL(inbuf,smb_vwv0);
2552 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2554 /* We never give out valid handles for a
2555 findnotifyfirst - so any dptr_num is ok here.
2558 outsize = set_message(outbuf,0,0,True);
2560 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2562 END_PROFILE(SMBfindnclose);
2566 /****************************************************************************
2567 Reply to a SMBtranss2 - just ignore it!
2568 ****************************************************************************/
2570 int reply_transs2(connection_struct *conn,
2571 char *inbuf,char *outbuf,int length,int bufsize)
2573 START_PROFILE(SMBtranss2);
2574 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2575 END_PROFILE(SMBtranss2);
2579 /****************************************************************************
2580 Reply to a SMBtrans2.
2581 ****************************************************************************/
2583 int reply_trans2(connection_struct *conn,
2584 char *inbuf,char *outbuf,int length,int bufsize)
2587 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2588 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2590 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2591 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2592 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2593 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2594 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2595 int32 timeout = IVALS(inbuf,smb_timeout);
2597 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2598 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2599 char *params = NULL, *data = NULL;
2600 int num_params, num_params_sofar, num_data, num_data_sofar;
2601 START_PROFILE(SMBtrans2);
2603 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2604 /* Queue this open message as we are the process of an
2607 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2608 DEBUGADD(2,( "in oplock break state.\n"));
2610 push_oplock_pending_smb_message(inbuf, length);
2611 END_PROFILE(SMBtrans2);
2615 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2616 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2617 END_PROFILE(SMBtrans2);
2618 return ERROR_DOS(ERRSRV,ERRaccess);
2621 outsize = set_message(outbuf,0,0,True);
2623 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2624 is so as a sanity check */
2627 * Need to have rc=0 for ioctl to get job id for OS/2.
2628 * Network printing will fail if function is not successful.
2629 * Similar function in reply.c will be used if protocol
2630 * is LANMAN1.0 instead of LM1.2X002.
2631 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2632 * outbuf doesn't have to be set(only job id is used).
2634 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2635 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2636 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2637 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2639 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2640 DEBUG(2,("Transaction is %d\n",tran_call));
2641 END_PROFILE(SMBtrans2);
2642 return ERROR_DOS(ERRSRV,ERRerror);
2646 /* Allocate the space for the maximum needed parameters and data */
2647 if (total_params > 0)
2648 params = (char *)malloc(total_params);
2650 data = (char *)malloc(total_data);
2652 if ((total_params && !params) || (total_data && !data)) {
2653 DEBUG(2,("Out of memory in reply_trans2\n"));
2656 END_PROFILE(SMBtrans2);
2657 return ERROR_DOS(ERRDOS,ERRnomem);
2660 /* Copy the param and data bytes sent with this request into
2661 the params buffer */
2662 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2663 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2665 if (num_params > total_params || num_data > total_data)
2666 exit_server("invalid params in reply_trans2");
2669 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2671 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2673 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2674 /* We need to send an interim response then receive the rest
2675 of the parameter/data bytes */
2676 outsize = set_message(outbuf,0,0,True);
2677 if (!send_smb(smbd_server_fd(),outbuf))
2678 exit_server("reply_trans2: send_smb failed.");
2680 while (num_data_sofar < total_data ||
2681 num_params_sofar < total_params) {
2684 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2687 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2688 outsize = set_message(outbuf,0,0,True);
2690 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2692 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2693 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2696 END_PROFILE(SMBtrans2);
2697 return ERROR_DOS(ERRSRV,ERRerror);
2700 /* Revise total_params and total_data in case
2701 they have changed downwards */
2702 total_params = SVAL(inbuf, smb_tpscnt);
2703 total_data = SVAL(inbuf, smb_tdscnt);
2704 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2705 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2706 if (num_params_sofar > total_params || num_data_sofar > total_data)
2707 exit_server("data overflow in trans2");
2709 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2710 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2711 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2712 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2716 if (Protocol >= PROTOCOL_NT1) {
2717 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2720 /* Now we must call the relevant TRANS2 function */
2722 case TRANSACT2_OPEN:
2723 START_PROFILE_NESTED(Trans2_open);
2724 outsize = call_trans2open(conn,
2725 inbuf, outbuf, bufsize,
2727 END_PROFILE_NESTED(Trans2_open);
2730 case TRANSACT2_FINDFIRST:
2731 START_PROFILE_NESTED(Trans2_findfirst);
2732 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2733 bufsize, ¶ms, &data);
2734 END_PROFILE_NESTED(Trans2_findfirst);
2737 case TRANSACT2_FINDNEXT:
2738 START_PROFILE_NESTED(Trans2_findnext);
2739 outsize = call_trans2findnext(conn, inbuf, outbuf,
2742 END_PROFILE_NESTED(Trans2_findnext);
2745 case TRANSACT2_QFSINFO:
2746 START_PROFILE_NESTED(Trans2_qfsinfo);
2747 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2748 length, bufsize, ¶ms,
2750 END_PROFILE_NESTED(Trans2_qfsinfo);
2753 case TRANSACT2_SETFSINFO:
2754 START_PROFILE_NESTED(Trans2_setfsinfo);
2755 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2758 END_PROFILE_NESTED(Trans2_setfsinfo);
2761 case TRANSACT2_QPATHINFO:
2762 case TRANSACT2_QFILEINFO:
2763 START_PROFILE_NESTED(Trans2_qpathinfo);
2764 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2766 ¶ms, &data, total_data);
2767 END_PROFILE_NESTED(Trans2_qpathinfo);
2769 case TRANSACT2_SETPATHINFO:
2770 case TRANSACT2_SETFILEINFO:
2771 START_PROFILE_NESTED(Trans2_setpathinfo);
2772 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2776 END_PROFILE_NESTED(Trans2_setpathinfo);
2779 case TRANSACT2_FINDNOTIFYFIRST:
2780 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2781 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2784 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2787 case TRANSACT2_FINDNOTIFYNEXT:
2788 START_PROFILE_NESTED(Trans2_findnotifynext);
2789 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2792 END_PROFILE_NESTED(Trans2_findnotifynext);
2794 case TRANSACT2_MKDIR:
2795 START_PROFILE_NESTED(Trans2_mkdir);
2796 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2797 bufsize, ¶ms, &data);
2798 END_PROFILE_NESTED(Trans2_mkdir);
2801 case TRANSACT2_GET_DFS_REFERRAL:
2802 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2803 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2804 bufsize, ¶ms, &data);
2805 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2807 case TRANSACT2_IOCTL:
2808 START_PROFILE_NESTED(Trans2_ioctl);
2809 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2810 bufsize,¶ms,&data);
2811 END_PROFILE_NESTED(Trans2_ioctl);
2814 /* Error in request */
2815 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2818 END_PROFILE(SMBtrans2);
2819 return ERROR_DOS(ERRSRV,ERRerror);
2822 /* As we do not know how many data packets will need to be
2823 returned here the various call_trans2xxxx calls
2824 must send their own. Thus a call_trans2xxx routine only
2825 returns a value other than -1 when it wants to send
2831 END_PROFILE(SMBtrans2);
2832 return outsize; /* If a correct response was needed the
2833 call_trans2xxx calls have already sent
2834 it. If outsize != -1 then it is returning */