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 && !mangle_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 mangle_map( 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 mangle_map(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 = mangle_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 mangle_map(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, 0);
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, 0);
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, 0);
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 /* this must *not* be null terminated or w2k gets in a loop trying to set an
684 acl on a dir (tridge) */
685 len = srvstr_push(outbuf, p, fname, -1, 0);
688 len = PTR_DIFF(p, pdata);
689 len = (len + 3) & ~3;
694 /* CIFS UNIX Extension. */
696 #if 0 /* JRA - FIXME - NEEDS UNICODE CONVERSION !!! */
697 case SMB_FIND_FILE_UNIX:
699 len = 108+strlen(fname)+1; /* (length of SMB_QUERY_FILE_UNIX_BASIC = 100)+4+4+strlen(fname)*/
700 /* +1 to be sure to transmit the termination of fname */
701 len = (len + 3) & ~3;
703 SIVAL(p,0,len); p+= 4; /* Offset from this structure to the beginning of the next one */
704 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
706 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
707 SOFF_T(p,0,sbuf.st_size); /* File size 64 Bit */
710 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
711 SOFF_T(p,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
713 /* Can't get the value - fake it using size. */
714 SOFF_T(p,0,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
718 put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
719 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
720 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
723 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
727 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
731 SIVAL(p,0,unix_filetype(sbuf.st_mode));
734 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
738 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
742 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
745 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
749 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
753 /* End of SMB_QUERY_FILE_UNIX_BASIC */
765 if (PTR_DIFF(p,pdata) > space_remaining) {
766 /* Move the dirptr back to prev_dirpos */
767 SeekDir(conn->dirptr, prev_dirpos);
768 *out_of_space = True;
769 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
770 return False; /* Not finished - just out of space */
773 /* Setup the last_filename pointer, as an offset from base_data */
774 *last_name_off = PTR_DIFF(nameptr,base_data);
775 /* Advance the data pointer to the next slot */
781 /****************************************************************************
782 Reply to a TRANS2_FINDFIRST.
783 ****************************************************************************/
785 static int call_trans2findfirst(connection_struct *conn,
786 char *inbuf, char *outbuf, int bufsize,
787 char **pparams, char **ppdata)
789 /* We must be careful here that we don't return more than the
790 allowed number of data bytes. If this means returning fewer than
791 maxentries then so be it. We assume that the redirector has
792 enough room for the fixed number of parameter bytes it has
794 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
795 char *params = *pparams;
796 char *pdata = *ppdata;
797 int dirtype = SVAL(params,0);
798 int maxentries = SVAL(params,2);
799 BOOL close_after_first = BITSETW(params+4,0);
800 BOOL close_if_end = BITSETW(params+4,1);
801 BOOL requires_resume_key = BITSETW(params+4,2);
802 int info_level = SVAL(params,6);
810 BOOL finished = False;
811 BOOL dont_descend = False;
812 BOOL out_of_space = False;
814 BOOL bad_path = False;
815 SMB_STRUCT_STAT sbuf;
817 *directory = *mask = 0;
819 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",
820 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
821 info_level, max_data_bytes));
829 case SMB_FIND_FILE_DIRECTORY_INFO:
830 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
831 case SMB_FIND_FILE_NAMES_INFO:
832 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
835 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
838 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
840 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
842 unix_convert(directory,conn,0,&bad_path,&sbuf);
843 if(!check_name(directory,conn)) {
844 if((errno == ENOENT) && bad_path)
846 unix_ERR_class = ERRDOS;
847 unix_ERR_code = ERRbadpath;
851 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
852 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
853 (get_remote_arch() == RA_WINNT))
855 unix_ERR_class = ERRDOS;
856 unix_ERR_code = ERRbaddirectory;
860 return(UNIXERROR(ERRDOS,ERRbadpath));
863 p = strrchr_m(directory,'/');
865 pstrcpy(mask,directory);
866 pstrcpy(directory,"./");
872 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
874 pdata = Realloc(*ppdata, max_data_bytes + 1024);
875 if( pdata == NULL ) {
876 return(ERROR_DOS(ERRDOS,ERRnomem));
879 memset((char *)pdata,'\0',max_data_bytes + 1024);
881 /* Realloc the params space */
882 params = Realloc(*pparams, 10);
883 if (params == NULL) {
884 return ERROR_DOS(ERRDOS,ERRnomem);
888 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
890 return(UNIXERROR(ERRDOS,ERRbadfile));
892 /* Save the wildcard match and attribs we are using on this directory -
893 needed as lanman2 assumes these are being saved between calls */
895 if(!(wcard = strdup(mask))) {
896 dptr_close(&dptr_num);
897 return ERROR_DOS(ERRDOS,ERRnomem);
900 dptr_set_wcard(dptr_num, wcard);
901 dptr_set_attr(dptr_num, dirtype);
903 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
905 /* We don't need to check for VOL here as this is returned by
906 a different TRANS2 call. */
908 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
909 conn->dirpath,lp_dontdescend(SNUM(conn))));
910 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
914 space_remaining = max_data_bytes;
915 out_of_space = False;
917 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
919 BOOL got_exact_match = False;
921 /* this is a heuristic to avoid seeking the dirptr except when
922 absolutely necessary. It allows for a filename of about 40 chars */
923 if (space_remaining < DIRLEN_GUESS && numentries > 0)
930 finished = !get_lanman2_dir_entry(conn,
932 mask,dirtype,info_level,
933 requires_resume_key,dont_descend,
934 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
938 if (finished && out_of_space)
941 if (!finished && !out_of_space)
945 * As an optimisation if we know we aren't looking
946 * for a wildcard name (ie. the name matches the wildcard exactly)
947 * then we can finish on any (first) match.
948 * This speeds up large directory searches. JRA.
954 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
957 /* Check if we can close the dirptr */
958 if(close_after_first || (finished && close_if_end))
960 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
961 dptr_close(&dptr_num);
965 * If there are no matching entries we must return ERRDOS/ERRbadfile -
966 * from observation of NT.
969 if(numentries == 0) {
970 dptr_close(&dptr_num);
971 return ERROR_DOS(ERRDOS,ERRbadfile);
974 /* At this point pdata points to numentries directory entries. */
976 /* Set up the return parameter block */
977 SSVAL(params,0,dptr_num);
978 SSVAL(params,2,numentries);
979 SSVAL(params,4,finished);
980 SSVAL(params,6,0); /* Never an EA error */
981 SSVAL(params,8,last_name_off);
983 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
985 if ((! *directory) && dptr_path(dptr_num))
986 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
988 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
989 smb_fn_name(CVAL(inbuf,smb_com)),
990 mask, directory, dirtype, numentries ) );
993 * Force a name mangle here to ensure that the
994 * mask as an 8.3 name is top of the mangled cache.
995 * The reasons for this are subtle. Don't remove
996 * this code unless you know what you are doing
997 * (see PR#13758). JRA.
1000 if(!mangle_is_8_3( mask, False))
1001 mangle_map(mask, True, True, SNUM(conn));
1006 /****************************************************************************
1007 Reply to a TRANS2_FINDNEXT.
1008 ****************************************************************************/
1010 static int call_trans2findnext(connection_struct *conn,
1011 char *inbuf, char *outbuf,
1012 int length, int bufsize,
1013 char **pparams, char **ppdata)
1015 /* We must be careful here that we don't return more than the
1016 allowed number of data bytes. If this means returning fewer than
1017 maxentries then so be it. We assume that the redirector has
1018 enough room for the fixed number of parameter bytes it has
1020 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1021 char *params = *pparams;
1022 char *pdata = *ppdata;
1023 int dptr_num = SVAL(params,0);
1024 int maxentries = SVAL(params,2);
1025 uint16 info_level = SVAL(params,4);
1026 uint32 resume_key = IVAL(params,6);
1027 BOOL close_after_request = BITSETW(params+10,0);
1028 BOOL close_if_end = BITSETW(params+10,1);
1029 BOOL requires_resume_key = BITSETW(params+10,2);
1030 BOOL continue_bit = BITSETW(params+10,3);
1031 pstring resume_name;
1037 int i, last_name_off=0;
1038 BOOL finished = False;
1039 BOOL dont_descend = False;
1040 BOOL out_of_space = False;
1041 int space_remaining;
1043 *mask = *directory = *resume_name = 0;
1045 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
1047 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1048 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1049 resume_key = %d resume name = %s continue=%d level = %d\n",
1050 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1051 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1059 case SMB_FIND_FILE_DIRECTORY_INFO:
1060 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1061 case SMB_FIND_FILE_NAMES_INFO:
1062 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1065 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1068 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1070 return ERROR_DOS(ERRDOS,ERRnomem);
1073 memset((char *)pdata,'\0',max_data_bytes + 1024);
1075 /* Realloc the params space */
1076 params = Realloc(*pparams, 6*SIZEOFWORD);
1077 if( params == NULL ) {
1078 return ERROR_DOS(ERRDOS,ERRnomem);
1082 /* Check that the dptr is valid */
1083 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1084 return ERROR_DOS(ERRDOS,ERRnofiles);
1086 string_set(&conn->dirpath,dptr_path(dptr_num));
1088 /* Get the wildcard mask from the dptr */
1089 if((p = dptr_wcard(dptr_num))== NULL) {
1090 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1091 return ERROR_DOS(ERRDOS,ERRnofiles);
1094 pstrcpy(directory,conn->dirpath);
1096 /* Get the attr mask from the dptr */
1097 dirtype = dptr_attr(dptr_num);
1099 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1100 dptr_num, mask, dirtype,
1102 TellDir(conn->dirptr)));
1104 /* We don't need to check for VOL here as this is returned by
1105 a different TRANS2 call. */
1107 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1108 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1109 dont_descend = True;
1112 space_remaining = max_data_bytes;
1113 out_of_space = False;
1116 * Seek to the correct position. We no longer use the resume key but
1117 * depend on the last file name instead.
1119 if(requires_resume_key && *resume_name && !continue_bit)
1122 * Fix for NT redirector problem triggered by resume key indexes
1123 * changing between directory scans. We now return a resume key of 0
1124 * and instead look for the filename to continue from (also given
1125 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1126 * findfirst/findnext (as is usual) then the directory pointer
1127 * should already be at the correct place. Check this by scanning
1128 * backwards looking for an exact (ie. case sensitive) filename match.
1129 * If we get to the beginning of the directory and haven't found it then scan
1130 * forwards again looking for a match. JRA.
1133 int current_pos, start_pos;
1135 void *dirptr = conn->dirptr;
1136 start_pos = TellDir(dirptr);
1137 for(current_pos = start_pos; current_pos >= 0; current_pos--)
1139 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1141 SeekDir(dirptr, current_pos);
1142 dname = ReadDirName(dirptr);
1145 * Remember, mangle_map is called by
1146 * get_lanman2_dir_entry(), so the resume name
1147 * could be mangled. Ensure we do the same
1152 mangle_map( dname, False, True, SNUM(conn));
1154 if(dname && strcsequal( resume_name, dname))
1156 SeekDir(dirptr, current_pos+1);
1157 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1163 * Scan forward from start if not found going backwards.
1168 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1169 SeekDir(dirptr, start_pos);
1170 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1173 * Remember, mangle_map is called by
1174 * get_lanman2_dir_entry(), so the resume name
1175 * could be mangled. Ensure we do the same
1180 mangle_map( dname, False, True, SNUM(conn));
1182 if(dname && strcsequal( resume_name, dname))
1184 SeekDir(dirptr, current_pos+1);
1185 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1189 } /* end if current_pos */
1190 } /* end if requires_resume_key && !continue_bit */
1192 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1194 BOOL got_exact_match = False;
1196 /* this is a heuristic to avoid seeking the dirptr except when
1197 absolutely necessary. It allows for a filename of about 40 chars */
1198 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1200 out_of_space = True;
1205 finished = !get_lanman2_dir_entry(conn,
1207 mask,dirtype,info_level,
1208 requires_resume_key,dont_descend,
1209 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1213 if (finished && out_of_space)
1216 if (!finished && !out_of_space)
1220 * As an optimisation if we know we aren't looking
1221 * for a wildcard name (ie. the name matches the wildcard exactly)
1222 * then we can finish on any (first) match.
1223 * This speeds up large directory searches. JRA.
1229 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1232 /* Check if we can close the dirptr */
1233 if(close_after_request || (finished && close_if_end))
1235 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1236 dptr_close(&dptr_num); /* This frees up the saved mask */
1240 /* Set up the return parameter block */
1241 SSVAL(params,0,numentries);
1242 SSVAL(params,2,finished);
1243 SSVAL(params,4,0); /* Never an EA error */
1244 SSVAL(params,6,last_name_off);
1246 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1248 if ((! *directory) && dptr_path(dptr_num))
1249 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1251 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1252 smb_fn_name(CVAL(inbuf,smb_com)),
1253 mask, directory, dirtype, numentries ) );
1258 /****************************************************************************
1259 Reply to a TRANS2_QFSINFO (query filesystem info).
1260 ****************************************************************************/
1262 static int call_trans2qfsinfo(connection_struct *conn,
1263 char *inbuf, char *outbuf,
1264 int length, int bufsize,
1265 char **pparams, char **ppdata)
1267 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1268 char *pdata = *ppdata;
1269 char *params = *pparams;
1270 uint16 info_level = SVAL(params,0);
1273 char *vname = volume_label(SNUM(conn));
1274 int snum = SNUM(conn);
1275 char *fstype = lp_fstype(SNUM(conn));
1277 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1279 if(vfs_stat(conn,".",&st)!=0) {
1280 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1281 return ERROR_DOS(ERRSRV,ERRinvdevice);
1284 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1285 if ( pdata == NULL ) {
1286 return ERROR_DOS(ERRDOS,ERRnomem);
1289 memset((char *)pdata,'\0',max_data_bytes + 1024);
1295 SMB_BIG_UINT dfree,dsize,bsize;
1297 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1298 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1299 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1300 SIVAL(pdata,l1_cUnit,dsize);
1301 SIVAL(pdata,l1_cUnitAvail,dfree);
1302 SSVAL(pdata,l1_cbSector,512);
1303 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1304 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1305 (unsigned int)dfree, 512));
1309 /* Return volume name */
1311 * Add volume serial number - hash of a combination of
1312 * the called hostname and the service name.
1314 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1315 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1317 SCVAL(pdata,l2_vol_cch,len);
1318 data_len = l2_vol_szVolLabel + len;
1319 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1320 (unsigned)st.st_ctime, len, vname));
1323 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1324 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1325 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1326 SIVAL(pdata,4,255); /* Max filename component length */
1327 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1328 and will think we can't do long filenames */
1329 len = srvstr_push(outbuf, pdata+12, fstype, -1, 0);
1331 data_len = 12 + len;
1334 case SMB_QUERY_FS_LABEL_INFO:
1335 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1339 case SMB_QUERY_FS_VOLUME_INFO:
1341 * Add volume serial number - hash of a combination of
1342 * the called hostname and the service name.
1344 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1345 (str_checksum(local_machine)<<16));
1347 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1348 SIVAL(pdata,12,len);
1350 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1351 (int)strlen(vname),vname, lp_servicename(snum)));
1353 case SMB_QUERY_FS_SIZE_INFO:
1355 SMB_BIG_UINT dfree,dsize,bsize;
1357 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1358 SBIG_UINT(pdata,0,dsize);
1359 SBIG_UINT(pdata,8,dfree);
1360 SIVAL(pdata,16,bsize/512);
1361 SIVAL(pdata,20,512);
1364 case SMB_QUERY_FS_DEVICE_INFO:
1366 SIVAL(pdata,0,0); /* dev type */
1367 SIVAL(pdata,4,0); /* characteristics */
1369 case SMB_MAC_QUERY_FS_INFO:
1371 * Thursby MAC extension... ONLY on NTFS filesystems
1372 * once we do streams then we don't need this
1374 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1376 SIVAL(pdata,84,0x100); /* Don't support mac... */
1381 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1385 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1387 DEBUG( 4, ( "%s info_level = %d\n",
1388 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1393 /****************************************************************************
1394 Reply to a TRANS2_SETFSINFO (set filesystem info).
1395 ****************************************************************************/
1397 static int call_trans2setfsinfo(connection_struct *conn,
1398 char *inbuf, char *outbuf, int length,
1400 char **pparams, char **ppdata)
1402 /* Just say yes we did it - there is nothing that
1403 can be set here so it doesn't matter. */
1405 DEBUG(3,("call_trans2setfsinfo\n"));
1407 if (!CAN_WRITE(conn))
1408 return ERROR_DOS(ERRSRV,ERRaccess);
1410 outsize = set_message(outbuf,10,0,True);
1415 /****************************************************************************
1416 * Utility function to set bad path error.
1417 ****************************************************************************/
1419 NTSTATUS set_bad_path_error(int err, BOOL bad_path)
1421 if((err == ENOENT) && bad_path) {
1422 unix_ERR_class = ERRDOS;
1423 unix_ERR_code = ERRbadpath;
1424 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1426 return NT_STATUS_OK;
1429 /****************************************************************************
1430 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1431 file name or file id).
1432 ****************************************************************************/
1434 static int call_trans2qfilepathinfo(connection_struct *conn,
1435 char *inbuf, char *outbuf, int length,
1437 char **pparams,char **ppdata,
1440 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1441 char *params = *pparams;
1442 char *pdata = *ppdata;
1443 uint16 tran_call = SVAL(inbuf, smb_setup0);
1447 SMB_OFF_T allocation_size=0;
1448 unsigned int data_size;
1449 SMB_STRUCT_STAT sbuf;
1450 pstring fname, dos_fname;
1454 BOOL bad_path = False;
1455 BOOL delete_pending = False;
1460 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1463 if (tran_call == TRANSACT2_QFILEINFO) {
1464 files_struct *fsp = file_fsp(params,0);
1465 info_level = SVAL(params,2);
1467 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1469 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1471 * This is actually a QFILEINFO on a directory
1472 * handle (returned from an NT SMB). NT5.0 seems
1473 * to do this call. JRA.
1475 pstrcpy(fname, fsp->fsp_name);
1476 unix_convert(fname,conn,0,&bad_path,&sbuf);
1477 if (!check_name(fname,conn) ||
1478 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1479 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1480 if((errno == ENOENT) && bad_path) {
1481 unix_ERR_class = ERRDOS;
1482 unix_ERR_code = ERRbadpath;
1484 return(UNIXERROR(ERRDOS,ERRbadpath));
1487 delete_pending = fsp->directory_delete_on_close;
1490 * Original code - this is an open file.
1492 CHECK_FSP(fsp,conn);
1494 pstrcpy(fname, fsp->fsp_name);
1495 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1496 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1497 return(UNIXERROR(ERRDOS,ERRbadfid));
1499 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1500 return(UNIXERROR(ERRDOS,ERRnoaccess));
1502 delete_pending = fsp->delete_on_close;
1506 info_level = SVAL(params,0);
1508 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1510 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1512 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1514 unix_convert(fname,conn,0,&bad_path,&sbuf);
1515 if (!check_name(fname,conn) ||
1516 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1517 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1518 if((errno == ENOENT) && bad_path) {
1519 unix_ERR_class = ERRDOS;
1520 unix_ERR_code = ERRbadpath;
1522 return(UNIXERROR(ERRDOS,ERRbadpath));
1527 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1528 fname,info_level,tran_call,total_data));
1530 p = strrchr_m(fname,'/');
1536 mode = dos_mode(conn,fname,&sbuf);
1537 size = sbuf.st_size;
1538 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
1543 params = Realloc(*pparams,2);
1545 return ERROR_DOS(ERRDOS,ERRnomem);
1547 memset((char *)params,'\0',2);
1548 data_size = max_data_bytes + 1024;
1549 pdata = Realloc(*ppdata, data_size);
1550 if ( pdata == NULL )
1551 return ERROR_DOS(ERRDOS,ERRnomem);
1554 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1555 /* uggh, EAs for OS2 */
1556 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1557 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1560 memset((char *)pdata,'\0',data_size);
1562 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1564 if (lp_dos_filetime_resolution(SNUM(conn))) {
1566 sbuf.st_atime &= ~1;
1567 sbuf.st_mtime &= ~1;
1568 sbuf.st_mtime &= ~1;
1571 /* NT expects the name to be in an exact form */
1572 if (strequal(fname,".")) {
1573 pstrcpy(dos_fname, "\\");
1575 snprintf(dos_fname, sizeof(dos_fname), "\\%s", fname);
1576 string_replace( dos_fname, '/', '\\');
1579 switch (info_level) {
1580 case SMB_INFO_STANDARD:
1581 case SMB_INFO_QUERY_EA_SIZE:
1582 data_size = (info_level==1?22:26);
1583 put_dos_date2(pdata,l1_fdateCreation,c_time);
1584 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1585 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1586 SIVAL(pdata,l1_cbFile,(uint32)size);
1587 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1588 SSVAL(pdata,l1_attrFile,mode);
1589 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1592 case SMB_INFO_QUERY_EAS_FROM_LIST:
1594 put_dos_date2(pdata,0,c_time);
1595 put_dos_date2(pdata,4,sbuf.st_atime);
1596 put_dos_date2(pdata,8,sbuf.st_mtime);
1597 SIVAL(pdata,12,(uint32)size);
1598 SIVAL(pdata,16,(uint32)allocation_size);
1599 SIVAL(pdata,20,mode);
1602 case SMB_INFO_QUERY_ALL_EAS:
1604 SIVAL(pdata,0,data_size);
1608 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1610 case SMB_FILE_BASIC_INFORMATION:
1611 case SMB_QUERY_FILE_BASIC_INFO:
1613 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1614 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1619 put_long_date(pdata,c_time);
1620 put_long_date(pdata+8,sbuf.st_atime);
1621 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1622 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1623 SIVAL(pdata,32,mode);
1625 DEBUG(5,("SMB_QFBI - "));
1627 time_t create_time = c_time;
1628 DEBUG(5,("create: %s ", ctime(&create_time)));
1630 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1631 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1632 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1633 DEBUG(5,("mode: %x\n", mode));
1637 case SMB_FILE_STANDARD_INFORMATION:
1638 case SMB_QUERY_FILE_STANDARD_INFO:
1640 /* Fake up allocation size. */
1641 SOFF_T(pdata,0,allocation_size);
1642 SOFF_T(pdata,8,size);
1643 SIVAL(pdata,16,sbuf.st_nlink);
1645 SCVAL(pdata,21,(mode&aDIR)?1:0);
1648 case SMB_FILE_EA_INFORMATION:
1649 case SMB_QUERY_FILE_EA_INFO:
1653 /* Get the 8.3 name - used if NT SMB was negotiated. */
1654 case SMB_QUERY_FILE_ALT_NAME_INFO:
1658 pstrcpy(short_name,base_name);
1659 /* Mangle if not already 8.3 */
1660 if(!mangle_is_8_3(short_name, True)) {
1661 if(!mangle_map(short_name,True,True,SNUM(conn)))
1664 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
1665 data_size = 4 + len;
1670 case SMB_QUERY_FILE_NAME_INFO:
1672 this must be *exactly* right for ACLs on mapped drives to work
1674 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
1675 data_size = 4 + len;
1679 case SMB_FILE_END_OF_FILE_INFORMATION:
1680 case SMB_QUERY_FILE_END_OF_FILEINFO:
1682 SOFF_T(pdata,0,size);
1685 case SMB_FILE_ALLOCATION_INFORMATION:
1686 case SMB_QUERY_FILE_ALLOCATION_INFO:
1688 SOFF_T(pdata,0,allocation_size);
1691 case SMB_QUERY_FILE_ALL_INFO:
1692 put_long_date(pdata,c_time);
1693 put_long_date(pdata+8,sbuf.st_atime);
1694 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1695 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1696 SIVAL(pdata,32,mode);
1698 SOFF_T(pdata,0,allocation_size);
1699 SOFF_T(pdata,8,size);
1700 SIVAL(pdata,16,sbuf.st_nlink);
1701 SCVAL(pdata,20,delete_pending);
1702 SCVAL(pdata,21,(mode&aDIR)?1:0);
1704 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1705 pdata += 8; /* index number */
1706 pdata += 4; /* EA info */
1708 SIVAL(pdata,0,0xA9);
1710 SIVAL(pdata,0,0xd01BF);
1712 SOFF_T(pdata,0,pos); /* current offset */
1714 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1716 pdata += 4; /* alignment */
1717 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_TERMINATE);
1720 data_size = PTR_DIFF(pdata,(*ppdata));
1723 case SMB_FILE_INTERNAL_INFORMATION:
1724 /* This should be an index number - looks like dev/ino to me :-) */
1725 SIVAL(pdata,0,sbuf.st_dev);
1726 SIVAL(pdata,4,sbuf.st_ino);
1730 case SMB_FILE_ACCESS_INFORMATION:
1731 SIVAL(pdata,0,0x12019F); /* ??? */
1735 case SMB_FILE_NAME_INFORMATION:
1736 /* Pathname with leading '\'. */
1739 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
1740 SIVAL(pdata,0,byte_len);
1741 data_size = 4 + byte_len;
1745 case SMB_FILE_DISPOSITION_INFORMATION:
1747 SCVAL(pdata,0,delete_pending);
1750 case SMB_FILE_POSITION_INFORMATION:
1752 SOFF_T(pdata,0,pos);
1755 case SMB_FILE_MODE_INFORMATION:
1756 SIVAL(pdata,0,mode);
1760 case SMB_FILE_ALIGNMENT_INFORMATION:
1761 SIVAL(pdata,0,0); /* No alignment needed. */
1766 /* Not yet finished... JRA */
1769 put_long_date(pdata,c_time);
1770 put_long_date(pdata+8,sbuf.st_atime);
1771 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1772 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1773 SIVAL(pdata,32,mode);
1774 SIVAL(pdata,36,0); /* ??? */
1775 SIVAL(pdata,40,0x20); /* ??? */
1776 SIVAL(pdata,44,0); /* ??? */
1777 SOFF_T(pdata,48,size);
1778 SIVAL(pdata,56,0x1); /* ??? */
1779 SIVAL(pdata,60,0); /* ??? */
1780 SIVAL(pdata,64,0); /* ??? */
1781 SIVAL(pdata,68,length); /* Following string length in bytes. */
1782 dos_PutUniCode(pdata+72,,False);
1787 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1788 /* Last component of pathname. */
1790 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1791 SIVAL(pdata,0,byte_len);
1792 data_size = 4 + byte_len;
1796 case SMB_FILE_STREAM_INFORMATION:
1800 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1801 SIVAL(pdata,0,0); /* ??? */
1802 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1803 SOFF_T(pdata,8,size);
1804 SIVAL(pdata,16,allocation_size);
1805 SIVAL(pdata,20,0); /* ??? */
1806 data_size = 24 + byte_len;
1810 case SMB_FILE_COMPRESSION_INFORMATION:
1811 SOFF_T(pdata,0,size);
1812 SIVAL(pdata,8,0); /* ??? */
1813 SIVAL(pdata,12,0); /* ??? */
1817 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1818 put_long_date(pdata,c_time);
1819 put_long_date(pdata+8,sbuf.st_atime);
1820 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1821 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1822 SIVAL(pdata,32,allocation_size);
1823 SOFF_T(pdata,40,size);
1824 SIVAL(pdata,48,mode);
1825 SIVAL(pdata,52,0); /* ??? */
1829 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1830 SIVAL(pdata,0,mode);
1836 /* NT4 server just returns "invalid query" to this - if we try to answer
1837 it then NTws gets a BSOD! (tridge) */
1838 case SMB_QUERY_FILE_STREAM_INFO:
1840 SIVAL(pdata,4,(uint32)size);
1841 SIVAL(pdata,12,(uint32)allocation_size);
1842 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1843 SIVAL(pdata,20,len);
1844 data_size = 24 + len;
1849 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1852 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1857 /****************************************************************************
1858 Deal with the internal needs of setting the delete on close flag. Note that
1859 as the tdb locking is recursive, it is safe to call this from within
1860 open_file_shared. JRA.
1861 ****************************************************************************/
1863 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
1866 * Only allow delete on close for writable shares.
1869 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
1870 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
1872 return NT_STATUS_ACCESS_DENIED;
1875 * Only allow delete on close for files/directories opened with delete intent.
1878 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
1879 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
1881 return NT_STATUS_ACCESS_DENIED;
1884 if(fsp->is_directory) {
1885 fsp->directory_delete_on_close = delete_on_close;
1886 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
1887 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1890 files_struct *iterate_fsp;
1893 * Modify the share mode entry for all files open
1894 * on this device and inode to tell other smbds we have
1895 * changed the delete on close flag. This will be noticed
1896 * in the close code, the last closer will delete the file
1900 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1901 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1903 if (lock_share_entry_fsp(fsp) == False)
1904 return NT_STATUS_ACCESS_DENIED;
1906 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1907 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
1909 unlock_share_entry_fsp(fsp);
1910 return NT_STATUS_ACCESS_DENIED;
1917 unlock_share_entry_fsp(fsp);
1920 * Go through all files we have open on the same device and
1921 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1922 * Other smbd's that have this file open will look in the share_mode on close.
1923 * take care of this (rare) case in close_file(). See the comment there.
1924 * NB. JRA. We don't really need to do this anymore - all should be taken
1925 * care of in the share_mode changes in the tdb.
1928 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1929 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1930 fsp->delete_on_close = delete_on_close;
1933 * Set the delete on close flag in the fsp.
1935 fsp->delete_on_close = delete_on_close;
1937 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1938 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1942 return NT_STATUS_OK;
1945 /****************************************************************************
1946 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
1947 ****************************************************************************/
1949 static int call_trans2setfilepathinfo(connection_struct *conn,
1950 char *inbuf, char *outbuf, int length,
1951 int bufsize, char **pparams,
1952 char **ppdata, int total_data)
1954 char *params = *pparams;
1955 char *pdata = *ppdata;
1956 uint16 tran_call = SVAL(inbuf, smb_setup0);
1961 SMB_STRUCT_STAT sbuf;
1964 BOOL bad_path = False;
1965 files_struct *fsp = NULL;
1967 if (tran_call == TRANSACT2_SETFILEINFO) {
1968 fsp = file_fsp(params,0);
1969 info_level = SVAL(params,2);
1971 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1973 * This is actually a SETFILEINFO on a directory
1974 * handle (returned from an NT SMB). NT5.0 seems
1975 * to do this call. JRA.
1977 pstrcpy(fname, fsp->fsp_name);
1978 unix_convert(fname,conn,0,&bad_path,&sbuf);
1979 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1980 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1981 if((errno == ENOENT) && bad_path) {
1982 unix_ERR_class = ERRDOS;
1983 unix_ERR_code = ERRbadpath;
1985 return(UNIXERROR(ERRDOS,ERRbadpath));
1987 } else if (fsp && fsp->print_file) {
1989 * Doing a DELETE_ON_CLOSE should cancel a print job.
1991 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1992 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1994 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
1997 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2002 * Original code - this is an open file.
2004 CHECK_FSP(fsp,conn);
2006 pstrcpy(fname, fsp->fsp_name);
2009 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
2010 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2011 return(UNIXERROR(ERRDOS,ERRbadfid));
2016 info_level = SVAL(params,0);
2017 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2018 unix_convert(fname,conn,0,&bad_path,&sbuf);
2019 if(!check_name(fname, conn)) {
2020 if((errno == ENOENT) && bad_path) {
2021 unix_ERR_class = ERRDOS;
2022 unix_ERR_code = ERRbadpath;
2024 return(UNIXERROR(ERRDOS,ERRbadpath));
2027 if(!VALID_STAT(sbuf)) {
2028 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
2029 if((errno == ENOENT) && bad_path) {
2030 unix_ERR_class = ERRDOS;
2031 unix_ERR_code = ERRbadpath;
2033 return(UNIXERROR(ERRDOS,ERRbadpath));
2037 if (!CAN_WRITE(conn))
2038 return ERROR_DOS(ERRSRV,ERRaccess);
2040 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2041 tran_call,fname,info_level,total_data));
2043 /* Realloc the parameter and data sizes */
2044 params = Realloc(*pparams,2);
2046 return ERROR_DOS(ERRDOS,ERRnomem);
2051 size = sbuf.st_size;
2052 tvs.modtime = sbuf.st_mtime;
2053 tvs.actime = sbuf.st_atime;
2054 mode = dos_mode(conn,fname,&sbuf);
2056 if (total_data > 4 && IVAL(pdata,0) == total_data) {
2057 /* uggh, EAs for OS2 */
2058 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2059 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2062 switch (info_level) {
2063 case SMB_INFO_STANDARD:
2064 case SMB_INFO_QUERY_EA_SIZE:
2067 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2070 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2072 mode = SVAL(pdata,l1_attrFile);
2073 size = IVAL(pdata,l1_cbFile);
2077 /* XXXX um, i don't think this is right.
2078 it's also not in the cifs6.txt spec.
2080 case SMB_INFO_QUERY_EAS_FROM_LIST:
2081 tvs.actime = make_unix_date2(pdata+8);
2082 tvs.modtime = make_unix_date2(pdata+12);
2083 size = IVAL(pdata,16);
2084 mode = IVAL(pdata,24);
2087 /* XXXX nor this. not in cifs6.txt, either. */
2088 case SMB_INFO_QUERY_ALL_EAS:
2089 tvs.actime = make_unix_date2(pdata+8);
2090 tvs.modtime = make_unix_date2(pdata+12);
2091 size = IVAL(pdata,16);
2092 mode = IVAL(pdata,24);
2095 case SMB_SET_FILE_BASIC_INFO:
2096 case SMB_FILE_BASIC_INFORMATION:
2098 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2100 time_t changed_time;
2102 /* Ignore create time at offset pdata. */
2105 tvs.actime = interpret_long_date(pdata+8);
2107 write_time = interpret_long_date(pdata+16);
2108 changed_time = interpret_long_date(pdata+24);
2110 tvs.modtime = MIN(write_time, changed_time);
2112 /* Prefer a defined time to an undefined one. */
2113 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2114 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2115 ? changed_time : write_time);
2118 mode = IVAL(pdata,32);
2122 case SMB_FILE_ALLOCATION_INFORMATION:
2123 case SMB_SET_FILE_ALLOCATION_INFO:
2126 SMB_OFF_T allocation_size = IVAL(pdata,0);
2127 #ifdef LARGE_SMB_OFF_T
2128 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2129 #else /* LARGE_SMB_OFF_T */
2130 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2131 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2132 #endif /* LARGE_SMB_OFF_T */
2133 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2134 fname, (double)allocation_size ));
2136 if(allocation_size != sbuf.st_size) {
2137 SMB_STRUCT_STAT new_sbuf;
2139 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2140 fname, (double)allocation_size ));
2143 files_struct *new_fsp = NULL;
2144 int access_mode = 0;
2147 if(global_oplock_break) {
2148 /* Queue this file modify as we are the process of an oplock break. */
2150 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2151 DEBUGADD(2,( "in oplock break state.\n"));
2153 push_oplock_pending_smb_message(inbuf, length);
2157 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
2158 SET_OPEN_MODE(DOS_OPEN_RDWR),
2159 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2160 0, 0, &access_mode, &action);
2162 if (new_fsp == NULL)
2163 return(UNIXERROR(ERRDOS,ERRbadpath));
2164 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2165 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2166 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
2169 close_file(new_fsp,True);
2171 ret = vfs_allocate_file_space(fsp, allocation_size);
2172 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
2173 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2178 return ERROR_NT(NT_STATUS_DISK_FULL);
2180 /* Allocate can trucate size... */
2181 size = new_sbuf.st_size;
2187 case SMB_FILE_END_OF_FILE_INFORMATION:
2188 case SMB_SET_FILE_END_OF_FILE_INFO:
2190 size = IVAL(pdata,0);
2191 #ifdef LARGE_SMB_OFF_T
2192 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2193 #else /* LARGE_SMB_OFF_T */
2194 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2195 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2196 #endif /* LARGE_SMB_OFF_T */
2197 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2201 case SMB_FILE_DISPOSITION_INFORMATION:
2202 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2204 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2207 if (tran_call != TRANSACT2_SETFILEINFO)
2208 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2211 return(UNIXERROR(ERRDOS,ERRbadfid));
2213 status = set_delete_on_close_internal(fsp, delete_on_close);
2215 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2216 return ERROR_NT(status);
2222 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2225 /* get some defaults (no modifications) if any info is zero or -1. */
2226 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2227 tvs.actime = sbuf.st_atime;
2229 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2230 tvs.modtime = sbuf.st_mtime;
2232 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2233 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2234 DEBUG(6,("size: %.0f ", (double)size));
2235 DEBUG(6,("mode: %x\n" , mode));
2237 if (S_ISDIR(sbuf.st_mode))
2242 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2243 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2244 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2245 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2248 * Only do this test if we are not explicitly
2249 * changing the size of a file.
2252 size = sbuf.st_size;
2256 * Try and set the times, size and mode of this file -
2257 * if they are different from the current values
2259 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2262 * This was a setfileinfo on an open file.
2263 * NT does this a lot. It's actually pointless
2264 * setting the time here, as it will be overwritten
2265 * on the next write, so we save the request
2266 * away and will set it on file code. JRA.
2269 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2270 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2271 fsp->pending_modtime = tvs.modtime;
2276 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2278 if(file_utime(conn, fname, &tvs)!=0)
2279 return(UNIXERROR(ERRDOS,ERRnoaccess));
2283 /* check the mode isn't different, before changing it */
2284 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2286 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
2288 if(file_chmod(conn, fname, mode, NULL)) {
2289 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2290 return(UNIXERROR(ERRDOS,ERRnoaccess));
2294 if(size != sbuf.st_size) {
2298 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2299 fname, (double)size ));
2302 files_struct *new_fsp = NULL;
2303 int access_mode = 0;
2306 if(global_oplock_break) {
2307 /* Queue this file modify as we are the process of an oplock break. */
2309 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2310 DEBUGADD(2,( "in oplock break state.\n"));
2312 push_oplock_pending_smb_message(inbuf, length);
2316 new_fsp = open_file_shared(conn, fname, &sbuf,
2317 SET_OPEN_MODE(DOS_OPEN_RDWR),
2318 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2319 0, 0, &access_mode, &action);
2321 if (new_fsp == NULL)
2322 return(UNIXERROR(ERRDOS,ERRbadpath));
2323 ret = vfs_set_filelen(new_fsp, size);
2324 close_file(new_fsp,True);
2326 ret = vfs_set_filelen(fsp, size);
2330 return (UNIXERROR(ERRHRD,ERRdiskfull));
2335 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2340 /****************************************************************************
2341 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2342 ****************************************************************************/
2344 static int call_trans2mkdir(connection_struct *conn,
2345 char *inbuf, char *outbuf, int length, int bufsize,
2346 char **pparams, char **ppdata)
2348 char *params = *pparams;
2351 SMB_STRUCT_STAT sbuf;
2352 BOOL bad_path = False;
2354 if (!CAN_WRITE(conn))
2355 return ERROR_DOS(ERRSRV,ERRaccess);
2357 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2359 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2361 unix_convert(directory,conn,0,&bad_path,&sbuf);
2362 if (check_name(directory,conn))
2363 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2367 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2368 if((errno == ENOENT) && bad_path)
2370 unix_ERR_class = ERRDOS;
2371 unix_ERR_code = ERRbadpath;
2373 return(UNIXERROR(ERRDOS,ERRnoaccess));
2376 /* Realloc the parameter and data sizes */
2377 params = Realloc(*pparams,2);
2378 if(params == NULL) {
2379 return ERROR_DOS(ERRDOS,ERRnomem);
2385 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2390 /****************************************************************************
2391 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2392 We don't actually do this - we just send a null response.
2393 ****************************************************************************/
2395 static int call_trans2findnotifyfirst(connection_struct *conn,
2396 char *inbuf, char *outbuf,
2397 int length, int bufsize,
2398 char **pparams, char **ppdata)
2400 static uint16 fnf_handle = 257;
2401 char *params = *pparams;
2402 uint16 info_level = SVAL(params,4);
2404 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2412 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2415 /* Realloc the parameter and data sizes */
2416 params = Realloc(*pparams,6);
2417 if(params == NULL) {
2418 return ERROR_DOS(ERRDOS,ERRnomem);
2422 SSVAL(params,0,fnf_handle);
2423 SSVAL(params,2,0); /* No changes */
2424 SSVAL(params,4,0); /* No EA errors */
2431 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2436 /****************************************************************************
2437 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2438 changes). Currently this does nothing.
2439 ****************************************************************************/
2441 static int call_trans2findnotifynext(connection_struct *conn,
2442 char *inbuf, char *outbuf,
2443 int length, int bufsize,
2444 char **pparams, char **ppdata)
2446 char *params = *pparams;
2448 DEBUG(3,("call_trans2findnotifynext\n"));
2450 /* Realloc the parameter and data sizes */
2451 params = Realloc(*pparams,4);
2452 if(params == NULL) {
2453 return ERROR_DOS(ERRDOS,ERRnomem);
2457 SSVAL(params,0,0); /* No changes */
2458 SSVAL(params,2,0); /* No EA errors */
2460 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2465 /****************************************************************************
2466 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2467 ****************************************************************************/
2469 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2470 char* outbuf, int length, int bufsize,
2471 char** pparams, char** ppdata)
2473 char *params = *pparams;
2476 int max_referral_level = SVAL(params,0);
2479 DEBUG(10,("call_trans2getdfsreferral\n"));
2481 if(!lp_host_msdfs())
2482 return ERROR_DOS(ERRDOS,ERRbadfunc);
2484 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2486 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2487 return ERROR_DOS(ERRDOS,ERRbadfile);
2489 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2490 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2495 #define LMCAT_SPL 0x53
2496 #define LMFUNC_GETJOBID 0x60
2498 /****************************************************************************
2499 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2500 ****************************************************************************/
2502 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2503 char* outbuf, int length, int bufsize,
2504 char** pparams, char** ppdata)
2506 char *pdata = *ppdata;
2507 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2509 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2510 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2511 pdata = Realloc(*ppdata, 32);
2513 return ERROR_DOS(ERRDOS,ERRnomem);
2517 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2518 CAN ACCEPT THIS IN UNICODE. JRA. */
2520 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2521 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2522 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2523 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2526 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2527 return ERROR_DOS(ERRSRV,ERRerror);
2531 /****************************************************************************
2532 Reply to a SMBfindclose (stop trans2 directory search).
2533 ****************************************************************************/
2535 int reply_findclose(connection_struct *conn,
2536 char *inbuf,char *outbuf,int length,int bufsize)
2539 int dptr_num=SVALS(inbuf,smb_vwv0);
2540 START_PROFILE(SMBfindclose);
2542 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2544 dptr_close(&dptr_num);
2546 outsize = set_message(outbuf,0,0,True);
2548 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2550 END_PROFILE(SMBfindclose);
2554 /****************************************************************************
2555 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
2556 ****************************************************************************/
2558 int reply_findnclose(connection_struct *conn,
2559 char *inbuf,char *outbuf,int length,int bufsize)
2563 START_PROFILE(SMBfindnclose);
2565 dptr_num = SVAL(inbuf,smb_vwv0);
2567 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2569 /* We never give out valid handles for a
2570 findnotifyfirst - so any dptr_num is ok here.
2573 outsize = set_message(outbuf,0,0,True);
2575 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2577 END_PROFILE(SMBfindnclose);
2581 /****************************************************************************
2582 Reply to a SMBtranss2 - just ignore it!
2583 ****************************************************************************/
2585 int reply_transs2(connection_struct *conn,
2586 char *inbuf,char *outbuf,int length,int bufsize)
2588 START_PROFILE(SMBtranss2);
2589 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2590 END_PROFILE(SMBtranss2);
2594 /****************************************************************************
2595 Reply to a SMBtrans2.
2596 ****************************************************************************/
2598 int reply_trans2(connection_struct *conn,
2599 char *inbuf,char *outbuf,int length,int bufsize)
2602 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2603 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2605 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2606 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2607 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2608 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2609 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2610 int32 timeout = IVALS(inbuf,smb_timeout);
2612 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2613 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2614 char *params = NULL, *data = NULL;
2615 int num_params, num_params_sofar, num_data, num_data_sofar;
2616 START_PROFILE(SMBtrans2);
2618 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2619 /* Queue this open message as we are the process of an
2622 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2623 DEBUGADD(2,( "in oplock break state.\n"));
2625 push_oplock_pending_smb_message(inbuf, length);
2626 END_PROFILE(SMBtrans2);
2630 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2631 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2632 END_PROFILE(SMBtrans2);
2633 return ERROR_DOS(ERRSRV,ERRaccess);
2636 outsize = set_message(outbuf,0,0,True);
2638 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2639 is so as a sanity check */
2642 * Need to have rc=0 for ioctl to get job id for OS/2.
2643 * Network printing will fail if function is not successful.
2644 * Similar function in reply.c will be used if protocol
2645 * is LANMAN1.0 instead of LM1.2X002.
2646 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2647 * outbuf doesn't have to be set(only job id is used).
2649 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2650 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2651 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2652 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2654 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2655 DEBUG(2,("Transaction is %d\n",tran_call));
2656 END_PROFILE(SMBtrans2);
2657 return ERROR_DOS(ERRSRV,ERRerror);
2661 /* Allocate the space for the maximum needed parameters and data */
2662 if (total_params > 0)
2663 params = (char *)malloc(total_params);
2665 data = (char *)malloc(total_data);
2667 if ((total_params && !params) || (total_data && !data)) {
2668 DEBUG(2,("Out of memory in reply_trans2\n"));
2671 END_PROFILE(SMBtrans2);
2672 return ERROR_DOS(ERRDOS,ERRnomem);
2675 /* Copy the param and data bytes sent with this request into
2676 the params buffer */
2677 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2678 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2680 if (num_params > total_params || num_data > total_data)
2681 exit_server("invalid params in reply_trans2");
2684 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2686 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2688 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2689 /* We need to send an interim response then receive the rest
2690 of the parameter/data bytes */
2691 outsize = set_message(outbuf,0,0,True);
2692 if (!send_smb(smbd_server_fd(),outbuf))
2693 exit_server("reply_trans2: send_smb failed.");
2695 while (num_data_sofar < total_data ||
2696 num_params_sofar < total_params) {
2699 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2702 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2703 outsize = set_message(outbuf,0,0,True);
2705 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2707 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2708 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2711 END_PROFILE(SMBtrans2);
2712 return ERROR_DOS(ERRSRV,ERRerror);
2715 /* Revise total_params and total_data in case
2716 they have changed downwards */
2717 total_params = SVAL(inbuf, smb_tpscnt);
2718 total_data = SVAL(inbuf, smb_tdscnt);
2719 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2720 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2721 if (num_params_sofar > total_params || num_data_sofar > total_data)
2722 exit_server("data overflow in trans2");
2724 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2725 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2726 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2727 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2731 if (Protocol >= PROTOCOL_NT1) {
2732 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2735 /* Now we must call the relevant TRANS2 function */
2737 case TRANSACT2_OPEN:
2738 START_PROFILE_NESTED(Trans2_open);
2739 outsize = call_trans2open(conn,
2740 inbuf, outbuf, bufsize,
2742 END_PROFILE_NESTED(Trans2_open);
2745 case TRANSACT2_FINDFIRST:
2746 START_PROFILE_NESTED(Trans2_findfirst);
2747 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2748 bufsize, ¶ms, &data);
2749 END_PROFILE_NESTED(Trans2_findfirst);
2752 case TRANSACT2_FINDNEXT:
2753 START_PROFILE_NESTED(Trans2_findnext);
2754 outsize = call_trans2findnext(conn, inbuf, outbuf,
2757 END_PROFILE_NESTED(Trans2_findnext);
2760 case TRANSACT2_QFSINFO:
2761 START_PROFILE_NESTED(Trans2_qfsinfo);
2762 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2763 length, bufsize, ¶ms,
2765 END_PROFILE_NESTED(Trans2_qfsinfo);
2768 case TRANSACT2_SETFSINFO:
2769 START_PROFILE_NESTED(Trans2_setfsinfo);
2770 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2773 END_PROFILE_NESTED(Trans2_setfsinfo);
2776 case TRANSACT2_QPATHINFO:
2777 case TRANSACT2_QFILEINFO:
2778 START_PROFILE_NESTED(Trans2_qpathinfo);
2779 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2781 ¶ms, &data, total_data);
2782 END_PROFILE_NESTED(Trans2_qpathinfo);
2784 case TRANSACT2_SETPATHINFO:
2785 case TRANSACT2_SETFILEINFO:
2786 START_PROFILE_NESTED(Trans2_setpathinfo);
2787 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2791 END_PROFILE_NESTED(Trans2_setpathinfo);
2794 case TRANSACT2_FINDNOTIFYFIRST:
2795 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2796 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2799 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2802 case TRANSACT2_FINDNOTIFYNEXT:
2803 START_PROFILE_NESTED(Trans2_findnotifynext);
2804 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2807 END_PROFILE_NESTED(Trans2_findnotifynext);
2809 case TRANSACT2_MKDIR:
2810 START_PROFILE_NESTED(Trans2_mkdir);
2811 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2812 bufsize, ¶ms, &data);
2813 END_PROFILE_NESTED(Trans2_mkdir);
2816 case TRANSACT2_GET_DFS_REFERRAL:
2817 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2818 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2819 bufsize, ¶ms, &data);
2820 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2822 case TRANSACT2_IOCTL:
2823 START_PROFILE_NESTED(Trans2_ioctl);
2824 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2825 bufsize,¶ms,&data);
2826 END_PROFILE_NESTED(Trans2_ioctl);
2829 /* Error in request */
2830 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2833 END_PROFILE(SMBtrans2);
2834 return ERROR_DOS(ERRSRV,ERRerror);
2837 /* As we do not know how many data packets will need to be
2838 returned here the various call_trans2xxxx calls
2839 must send their own. Thus a call_trans2xxx routine only
2840 returns a value other than -1 when it wants to send
2846 END_PROFILE(SMBtrans2);
2847 return outsize; /* If a correct response was needed the
2848 call_trans2xxx calls have already sent
2849 it. If outsize != -1 then it is returning */