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, 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(!is_8_3( mask, False))
1001 name_map_mangle(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, name_map_mangle is called by
1146 * get_lanman2_dir_entry(), so the resume name
1147 * could be mangled. Ensure we do the same
1152 name_map_mangle( 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, name_map_mangle is called by
1174 * get_lanman2_dir_entry(), so the resume name
1175 * could be mangled. Ensure we do the same
1180 name_map_mangle( 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 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1417 file name or file id).
1418 ****************************************************************************/
1420 static int call_trans2qfilepathinfo(connection_struct *conn,
1421 char *inbuf, char *outbuf, int length,
1423 char **pparams,char **ppdata,
1426 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1427 char *params = *pparams;
1428 char *pdata = *ppdata;
1429 uint16 tran_call = SVAL(inbuf, smb_setup0);
1433 SMB_OFF_T allocation_size=0;
1434 unsigned int data_size;
1435 SMB_STRUCT_STAT sbuf;
1436 pstring fname, dos_fname;
1440 BOOL bad_path = False;
1441 BOOL delete_pending = False;
1446 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1449 if (tran_call == TRANSACT2_QFILEINFO) {
1450 files_struct *fsp = file_fsp(params,0);
1451 info_level = SVAL(params,2);
1453 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1455 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1457 * This is actually a QFILEINFO on a directory
1458 * handle (returned from an NT SMB). NT5.0 seems
1459 * to do this call. JRA.
1461 pstrcpy(fname, fsp->fsp_name);
1462 unix_convert(fname,conn,0,&bad_path,&sbuf);
1463 if (!check_name(fname,conn) ||
1464 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1465 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1466 if((errno == ENOENT) && bad_path) {
1467 unix_ERR_class = ERRDOS;
1468 unix_ERR_code = ERRbadpath;
1470 return(UNIXERROR(ERRDOS,ERRbadpath));
1473 delete_pending = fsp->directory_delete_on_close;
1476 * Original code - this is an open file.
1478 CHECK_FSP(fsp,conn);
1480 pstrcpy(fname, fsp->fsp_name);
1481 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1482 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1483 return(UNIXERROR(ERRDOS,ERRbadfid));
1485 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1486 return(UNIXERROR(ERRDOS,ERRnoaccess));
1488 delete_pending = fsp->delete_on_close;
1492 info_level = SVAL(params,0);
1494 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1496 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1498 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1500 unix_convert(fname,conn,0,&bad_path,&sbuf);
1501 if (!check_name(fname,conn) ||
1502 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1503 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1504 if((errno == ENOENT) && bad_path) {
1505 unix_ERR_class = ERRDOS;
1506 unix_ERR_code = ERRbadpath;
1508 return(UNIXERROR(ERRDOS,ERRbadpath));
1513 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1514 fname,info_level,tran_call,total_data));
1516 p = strrchr_m(fname,'/');
1522 mode = dos_mode(conn,fname,&sbuf);
1523 size = sbuf.st_size;
1524 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
1529 params = Realloc(*pparams,2);
1531 return ERROR_DOS(ERRDOS,ERRnomem);
1533 memset((char *)params,'\0',2);
1534 data_size = max_data_bytes + 1024;
1535 pdata = Realloc(*ppdata, data_size);
1536 if ( pdata == NULL )
1537 return ERROR_DOS(ERRDOS,ERRnomem);
1540 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1541 /* uggh, EAs for OS2 */
1542 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1543 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1546 memset((char *)pdata,'\0',data_size);
1548 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1550 if (lp_dos_filetime_resolution(SNUM(conn))) {
1552 sbuf.st_atime &= ~1;
1553 sbuf.st_mtime &= ~1;
1554 sbuf.st_mtime &= ~1;
1557 /* NT expects the name to be in an exact form */
1558 if (strequal(fname,".")) {
1559 pstrcpy(dos_fname, "\\");
1561 snprintf(dos_fname, sizeof(dos_fname), "\\%s", fname);
1562 string_replace( dos_fname, '/', '\\');
1565 switch (info_level) {
1566 case SMB_INFO_STANDARD:
1567 case SMB_INFO_QUERY_EA_SIZE:
1568 data_size = (info_level==1?22:26);
1569 put_dos_date2(pdata,l1_fdateCreation,c_time);
1570 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1571 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1572 SIVAL(pdata,l1_cbFile,(uint32)size);
1573 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1574 SSVAL(pdata,l1_attrFile,mode);
1575 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1578 case SMB_INFO_QUERY_EAS_FROM_LIST:
1580 put_dos_date2(pdata,0,c_time);
1581 put_dos_date2(pdata,4,sbuf.st_atime);
1582 put_dos_date2(pdata,8,sbuf.st_mtime);
1583 SIVAL(pdata,12,(uint32)size);
1584 SIVAL(pdata,16,(uint32)allocation_size);
1585 SIVAL(pdata,20,mode);
1588 case SMB_INFO_QUERY_ALL_EAS:
1590 SIVAL(pdata,0,data_size);
1594 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1596 case SMB_FILE_BASIC_INFORMATION:
1597 case SMB_QUERY_FILE_BASIC_INFO:
1599 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1600 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1605 put_long_date(pdata,c_time);
1606 put_long_date(pdata+8,sbuf.st_atime);
1607 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1608 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1609 SIVAL(pdata,32,mode);
1611 DEBUG(5,("SMB_QFBI - "));
1613 time_t create_time = c_time;
1614 DEBUG(5,("create: %s ", ctime(&create_time)));
1616 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1617 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1618 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1619 DEBUG(5,("mode: %x\n", mode));
1623 case SMB_FILE_STANDARD_INFORMATION:
1624 case SMB_QUERY_FILE_STANDARD_INFO:
1626 /* Fake up allocation size. */
1627 SOFF_T(pdata,0,allocation_size);
1628 SOFF_T(pdata,8,size);
1629 SIVAL(pdata,16,sbuf.st_nlink);
1631 SCVAL(pdata,21,(mode&aDIR)?1:0);
1634 case SMB_FILE_EA_INFORMATION:
1635 case SMB_QUERY_FILE_EA_INFO:
1639 /* Get the 8.3 name - used if NT SMB was negotiated. */
1640 case SMB_QUERY_FILE_ALT_NAME_INFO:
1644 pstrcpy(short_name,base_name);
1645 /* Mangle if not already 8.3 */
1646 if(!is_8_3(short_name, True)) {
1647 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1650 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
1651 data_size = 4 + len;
1656 case SMB_QUERY_FILE_NAME_INFO:
1658 this must be *exactly* right for ACLs on mapped drives to work
1660 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
1661 data_size = 4 + len;
1665 case SMB_FILE_END_OF_FILE_INFORMATION:
1666 case SMB_QUERY_FILE_END_OF_FILEINFO:
1668 SOFF_T(pdata,0,size);
1671 case SMB_FILE_ALLOCATION_INFORMATION:
1672 case SMB_QUERY_FILE_ALLOCATION_INFO:
1674 SOFF_T(pdata,0,allocation_size);
1677 case SMB_QUERY_FILE_ALL_INFO:
1678 put_long_date(pdata,c_time);
1679 put_long_date(pdata+8,sbuf.st_atime);
1680 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1681 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1682 SIVAL(pdata,32,mode);
1684 SOFF_T(pdata,0,allocation_size);
1685 SOFF_T(pdata,8,size);
1686 SIVAL(pdata,16,sbuf.st_nlink);
1687 SCVAL(pdata,20,delete_pending);
1688 SCVAL(pdata,21,(mode&aDIR)?1:0);
1690 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1691 pdata += 8; /* index number */
1692 pdata += 4; /* EA info */
1694 SIVAL(pdata,0,0xA9);
1696 SIVAL(pdata,0,0xd01BF);
1698 SOFF_T(pdata,0,pos); /* current offset */
1700 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1702 pdata += 4; /* alignment */
1703 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_TERMINATE);
1706 data_size = PTR_DIFF(pdata,(*ppdata));
1709 case SMB_FILE_INTERNAL_INFORMATION:
1710 /* This should be an index number - looks like dev/ino to me :-) */
1711 SIVAL(pdata,0,sbuf.st_dev);
1712 SIVAL(pdata,4,sbuf.st_ino);
1716 case SMB_FILE_ACCESS_INFORMATION:
1717 SIVAL(pdata,0,0x12019F); /* ??? */
1721 case SMB_FILE_NAME_INFORMATION:
1722 /* Pathname with leading '\'. */
1725 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
1726 SIVAL(pdata,0,byte_len);
1727 data_size = 4 + byte_len;
1731 case SMB_FILE_DISPOSITION_INFORMATION:
1733 SCVAL(pdata,0,delete_pending);
1736 case SMB_FILE_POSITION_INFORMATION:
1738 SOFF_T(pdata,0,pos);
1741 case SMB_FILE_MODE_INFORMATION:
1742 SIVAL(pdata,0,mode);
1746 case SMB_FILE_ALIGNMENT_INFORMATION:
1747 SIVAL(pdata,0,0); /* No alignment needed. */
1752 /* Not yet finished... JRA */
1755 put_long_date(pdata,c_time);
1756 put_long_date(pdata+8,sbuf.st_atime);
1757 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1758 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1759 SIVAL(pdata,32,mode);
1760 SIVAL(pdata,36,0); /* ??? */
1761 SIVAL(pdata,40,0x20); /* ??? */
1762 SIVAL(pdata,44,0); /* ??? */
1763 SOFF_T(pdata,48,size);
1764 SIVAL(pdata,56,0x1); /* ??? */
1765 SIVAL(pdata,60,0); /* ??? */
1766 SIVAL(pdata,64,0); /* ??? */
1767 SIVAL(pdata,68,length); /* Following string length in bytes. */
1768 dos_PutUniCode(pdata+72,,False);
1773 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1774 /* Last component of pathname. */
1776 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1777 SIVAL(pdata,0,byte_len);
1778 data_size = 4 + byte_len;
1782 case SMB_FILE_STREAM_INFORMATION:
1786 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1787 SIVAL(pdata,0,0); /* ??? */
1788 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1789 SOFF_T(pdata,8,size);
1790 SIVAL(pdata,16,allocation_size);
1791 SIVAL(pdata,20,0); /* ??? */
1792 data_size = 24 + byte_len;
1796 case SMB_FILE_COMPRESSION_INFORMATION:
1797 SOFF_T(pdata,0,size);
1798 SIVAL(pdata,8,0); /* ??? */
1799 SIVAL(pdata,12,0); /* ??? */
1803 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1804 put_long_date(pdata,c_time);
1805 put_long_date(pdata+8,sbuf.st_atime);
1806 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1807 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1808 SIVAL(pdata,32,allocation_size);
1809 SOFF_T(pdata,40,size);
1810 SIVAL(pdata,48,mode);
1811 SIVAL(pdata,52,0); /* ??? */
1815 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1816 SIVAL(pdata,0,mode);
1822 /* NT4 server just returns "invalid query" to this - if we try to answer
1823 it then NTws gets a BSOD! (tridge) */
1824 case SMB_QUERY_FILE_STREAM_INFO:
1826 SIVAL(pdata,4,(uint32)size);
1827 SIVAL(pdata,12,(uint32)allocation_size);
1828 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1829 SIVAL(pdata,20,len);
1830 data_size = 24 + len;
1835 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1838 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1843 /****************************************************************************
1844 Deal with the internal needs of setting the delete on close flag. Note that
1845 as the tdb locking is recursive, it is safe to call this from within
1846 open_file_shared. JRA.
1847 ****************************************************************************/
1849 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
1852 * Only allow delete on close for writable shares.
1855 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
1856 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
1858 return NT_STATUS_ACCESS_DENIED;
1861 * Only allow delete on close for files/directories opened with delete intent.
1864 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1865 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
1867 return NT_STATUS_ACCESS_DENIED;
1870 if(fsp->is_directory) {
1871 fsp->directory_delete_on_close = delete_on_close;
1872 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
1873 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1876 files_struct *iterate_fsp;
1879 * Modify the share mode entry for all files open
1880 * on this device and inode to tell other smbds we have
1881 * changed the delete on close flag. This will be noticed
1882 * in the close code, the last closer will delete the file
1886 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1887 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1889 if (lock_share_entry_fsp(fsp) == False)
1890 return NT_STATUS_ACCESS_DENIED;
1892 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1893 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
1895 unlock_share_entry_fsp(fsp);
1896 return NT_STATUS_ACCESS_DENIED;
1903 unlock_share_entry_fsp(fsp);
1906 * Go through all files we have open on the same device and
1907 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1908 * Other smbd's that have this file open will look in the share_mode on close.
1909 * take care of this (rare) case in close_file(). See the comment there.
1910 * NB. JRA. We don't really need to do this anymore - all should be taken
1911 * care of in the share_mode changes in the tdb.
1914 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1915 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1916 fsp->delete_on_close = delete_on_close;
1919 * Set the delete on close flag in the fsp.
1921 fsp->delete_on_close = delete_on_close;
1923 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1924 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1928 return NT_STATUS_OK;
1931 /****************************************************************************
1932 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
1933 ****************************************************************************/
1935 static int call_trans2setfilepathinfo(connection_struct *conn,
1936 char *inbuf, char *outbuf, int length,
1937 int bufsize, char **pparams,
1938 char **ppdata, int total_data)
1940 char *params = *pparams;
1941 char *pdata = *ppdata;
1942 uint16 tran_call = SVAL(inbuf, smb_setup0);
1947 SMB_STRUCT_STAT sbuf;
1950 BOOL bad_path = False;
1951 files_struct *fsp = NULL;
1953 if (tran_call == TRANSACT2_SETFILEINFO) {
1954 fsp = file_fsp(params,0);
1955 info_level = SVAL(params,2);
1957 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1959 * This is actually a SETFILEINFO on a directory
1960 * handle (returned from an NT SMB). NT5.0 seems
1961 * to do this call. JRA.
1963 pstrcpy(fname, fsp->fsp_name);
1964 unix_convert(fname,conn,0,&bad_path,&sbuf);
1965 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1966 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1967 if((errno == ENOENT) && bad_path) {
1968 unix_ERR_class = ERRDOS;
1969 unix_ERR_code = ERRbadpath;
1971 return(UNIXERROR(ERRDOS,ERRbadpath));
1973 } else if (fsp && fsp->print_file) {
1975 * Doing a DELETE_ON_CLOSE should cancel a print job.
1977 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1978 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1980 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
1983 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1988 * Original code - this is an open file.
1990 CHECK_FSP(fsp,conn);
1992 pstrcpy(fname, fsp->fsp_name);
1995 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1996 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1997 return(UNIXERROR(ERRDOS,ERRbadfid));
2002 info_level = SVAL(params,0);
2003 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2004 unix_convert(fname,conn,0,&bad_path,&sbuf);
2005 if(!check_name(fname, conn)) {
2006 if((errno == ENOENT) && bad_path) {
2007 unix_ERR_class = ERRDOS;
2008 unix_ERR_code = ERRbadpath;
2010 return(UNIXERROR(ERRDOS,ERRbadpath));
2013 if(!VALID_STAT(sbuf)) {
2014 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
2015 if((errno == ENOENT) && bad_path) {
2016 unix_ERR_class = ERRDOS;
2017 unix_ERR_code = ERRbadpath;
2019 return(UNIXERROR(ERRDOS,ERRbadpath));
2023 if (!CAN_WRITE(conn))
2024 return ERROR_DOS(ERRSRV,ERRaccess);
2026 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2027 tran_call,fname,info_level,total_data));
2029 /* Realloc the parameter and data sizes */
2030 params = Realloc(*pparams,2);
2032 return ERROR_DOS(ERRDOS,ERRnomem);
2037 size = sbuf.st_size;
2038 tvs.modtime = sbuf.st_mtime;
2039 tvs.actime = sbuf.st_atime;
2040 mode = dos_mode(conn,fname,&sbuf);
2042 if (total_data > 4 && IVAL(pdata,0) == total_data) {
2043 /* uggh, EAs for OS2 */
2044 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2045 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2048 switch (info_level) {
2049 case SMB_INFO_STANDARD:
2050 case SMB_INFO_QUERY_EA_SIZE:
2053 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2056 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2058 mode = SVAL(pdata,l1_attrFile);
2059 size = IVAL(pdata,l1_cbFile);
2063 /* XXXX um, i don't think this is right.
2064 it's also not in the cifs6.txt spec.
2066 case SMB_INFO_QUERY_EAS_FROM_LIST:
2067 tvs.actime = make_unix_date2(pdata+8);
2068 tvs.modtime = make_unix_date2(pdata+12);
2069 size = IVAL(pdata,16);
2070 mode = IVAL(pdata,24);
2073 /* XXXX nor this. not in cifs6.txt, either. */
2074 case SMB_INFO_QUERY_ALL_EAS:
2075 tvs.actime = make_unix_date2(pdata+8);
2076 tvs.modtime = make_unix_date2(pdata+12);
2077 size = IVAL(pdata,16);
2078 mode = IVAL(pdata,24);
2081 case SMB_SET_FILE_BASIC_INFO:
2082 case SMB_FILE_BASIC_INFORMATION:
2084 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2086 time_t changed_time;
2088 /* Ignore create time at offset pdata. */
2091 tvs.actime = interpret_long_date(pdata+8);
2093 write_time = interpret_long_date(pdata+16);
2094 changed_time = interpret_long_date(pdata+24);
2096 tvs.modtime = MIN(write_time, changed_time);
2098 /* Prefer a defined time to an undefined one. */
2099 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2100 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2101 ? changed_time : write_time);
2104 mode = IVAL(pdata,32);
2108 case SMB_FILE_ALLOCATION_INFORMATION:
2109 case SMB_SET_FILE_ALLOCATION_INFO:
2112 SMB_OFF_T allocation_size = IVAL(pdata,0);
2113 #ifdef LARGE_SMB_OFF_T
2114 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2115 #else /* LARGE_SMB_OFF_T */
2116 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2117 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2118 #endif /* LARGE_SMB_OFF_T */
2119 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2120 fname, (double)allocation_size ));
2122 if(allocation_size != sbuf.st_size) {
2123 SMB_STRUCT_STAT new_sbuf;
2125 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2126 fname, (double)allocation_size ));
2129 files_struct *new_fsp = NULL;
2130 int access_mode = 0;
2133 if(global_oplock_break) {
2134 /* Queue this file modify as we are the process of an oplock break. */
2136 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2137 DEBUGADD(2,( "in oplock break state.\n"));
2139 push_oplock_pending_smb_message(inbuf, length);
2143 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
2144 SET_OPEN_MODE(DOS_OPEN_RDWR),
2145 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2146 0, 0, &access_mode, &action);
2148 if (new_fsp == NULL)
2149 return(UNIXERROR(ERRDOS,ERRbadpath));
2150 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2151 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2152 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
2155 close_file(new_fsp,True);
2157 ret = vfs_allocate_file_space(fsp, size);
2158 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
2159 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2164 return ERROR_NT(NT_STATUS_DISK_FULL);
2166 /* Allocate can trucate size... */
2167 size = new_sbuf.st_size;
2173 case SMB_FILE_END_OF_FILE_INFORMATION:
2174 case SMB_SET_FILE_END_OF_FILE_INFO:
2176 size = IVAL(pdata,0);
2177 #ifdef LARGE_SMB_OFF_T
2178 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2179 #else /* LARGE_SMB_OFF_T */
2180 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2181 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2182 #endif /* LARGE_SMB_OFF_T */
2183 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2187 case SMB_FILE_DISPOSITION_INFORMATION:
2188 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2190 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2193 if (tran_call != TRANSACT2_SETFILEINFO)
2194 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2197 return(UNIXERROR(ERRDOS,ERRbadfid));
2199 status = set_delete_on_close_internal(fsp, delete_on_close);
2201 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2202 return ERROR_NT(status);
2208 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2211 /* get some defaults (no modifications) if any info is zero or -1. */
2212 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2213 tvs.actime = sbuf.st_atime;
2215 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2216 tvs.modtime = sbuf.st_mtime;
2218 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2219 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2220 DEBUG(6,("size: %.0f ", (double)size));
2221 DEBUG(6,("mode: %x\n" , mode));
2223 if (S_ISDIR(sbuf.st_mode))
2228 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2229 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2230 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2231 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2234 * Only do this test if we are not explicitly
2235 * changing the size of a file.
2238 size = sbuf.st_size;
2242 * Try and set the times, size and mode of this file -
2243 * if they are different from the current values
2245 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2248 * This was a setfileinfo on an open file.
2249 * NT does this a lot. It's actually pointless
2250 * setting the time here, as it will be overwritten
2251 * on the next write, so we save the request
2252 * away and will set it on file code. JRA.
2255 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2256 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2257 fsp->pending_modtime = tvs.modtime;
2262 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2264 if(file_utime(conn, fname, &tvs)!=0)
2265 return(UNIXERROR(ERRDOS,ERRnoaccess));
2269 /* check the mode isn't different, before changing it */
2270 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2272 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
2274 if(file_chmod(conn, fname, mode, NULL)) {
2275 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2276 return(UNIXERROR(ERRDOS,ERRnoaccess));
2280 if(size != sbuf.st_size) {
2282 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2283 fname, (double)size ));
2286 files_struct *new_fsp = NULL;
2287 int access_mode = 0;
2290 if(global_oplock_break) {
2291 /* Queue this file modify as we are the process of an oplock break. */
2293 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2294 DEBUGADD(2,( "in oplock break state.\n"));
2296 push_oplock_pending_smb_message(inbuf, length);
2300 new_fsp = open_file_shared(conn, fname, &sbuf,
2301 SET_OPEN_MODE(DOS_OPEN_RDWR),
2302 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2303 0, 0, &access_mode, &action);
2305 if (new_fsp == NULL)
2306 return(UNIXERROR(ERRDOS,ERRbadpath));
2307 vfs_set_filelen(new_fsp, size);
2308 close_file(new_fsp,True);
2310 vfs_set_filelen(fsp, size);
2316 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2321 /****************************************************************************
2322 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2323 ****************************************************************************/
2325 static int call_trans2mkdir(connection_struct *conn,
2326 char *inbuf, char *outbuf, int length, int bufsize,
2327 char **pparams, char **ppdata)
2329 char *params = *pparams;
2332 SMB_STRUCT_STAT sbuf;
2333 BOOL bad_path = False;
2335 if (!CAN_WRITE(conn))
2336 return ERROR_DOS(ERRSRV,ERRaccess);
2338 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2340 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2342 unix_convert(directory,conn,0,&bad_path,&sbuf);
2343 if (check_name(directory,conn))
2344 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2348 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2349 if((errno == ENOENT) && bad_path)
2351 unix_ERR_class = ERRDOS;
2352 unix_ERR_code = ERRbadpath;
2354 return(UNIXERROR(ERRDOS,ERRnoaccess));
2357 /* Realloc the parameter and data sizes */
2358 params = Realloc(*pparams,2);
2359 if(params == NULL) {
2360 return ERROR_DOS(ERRDOS,ERRnomem);
2366 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2371 /****************************************************************************
2372 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2373 We don't actually do this - we just send a null response.
2374 ****************************************************************************/
2376 static int call_trans2findnotifyfirst(connection_struct *conn,
2377 char *inbuf, char *outbuf,
2378 int length, int bufsize,
2379 char **pparams, char **ppdata)
2381 static uint16 fnf_handle = 257;
2382 char *params = *pparams;
2383 uint16 info_level = SVAL(params,4);
2385 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2393 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2396 /* Realloc the parameter and data sizes */
2397 params = Realloc(*pparams,6);
2398 if(params == NULL) {
2399 return ERROR_DOS(ERRDOS,ERRnomem);
2403 SSVAL(params,0,fnf_handle);
2404 SSVAL(params,2,0); /* No changes */
2405 SSVAL(params,4,0); /* No EA errors */
2412 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2417 /****************************************************************************
2418 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2419 changes). Currently this does nothing.
2420 ****************************************************************************/
2422 static int call_trans2findnotifynext(connection_struct *conn,
2423 char *inbuf, char *outbuf,
2424 int length, int bufsize,
2425 char **pparams, char **ppdata)
2427 char *params = *pparams;
2429 DEBUG(3,("call_trans2findnotifynext\n"));
2431 /* Realloc the parameter and data sizes */
2432 params = Realloc(*pparams,4);
2433 if(params == NULL) {
2434 return ERROR_DOS(ERRDOS,ERRnomem);
2438 SSVAL(params,0,0); /* No changes */
2439 SSVAL(params,2,0); /* No EA errors */
2441 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2446 /****************************************************************************
2447 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2448 ****************************************************************************/
2450 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2451 char* outbuf, int length, int bufsize,
2452 char** pparams, char** ppdata)
2454 char *params = *pparams;
2457 int max_referral_level = SVAL(params,0);
2460 DEBUG(10,("call_trans2getdfsreferral\n"));
2462 if(!lp_host_msdfs())
2463 return ERROR_DOS(ERRDOS,ERRbadfunc);
2465 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2467 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2468 return ERROR_DOS(ERRDOS,ERRbadfile);
2470 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2471 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2476 #define LMCAT_SPL 0x53
2477 #define LMFUNC_GETJOBID 0x60
2479 /****************************************************************************
2480 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2481 ****************************************************************************/
2483 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2484 char* outbuf, int length, int bufsize,
2485 char** pparams, char** ppdata)
2487 char *pdata = *ppdata;
2488 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2490 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2491 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2492 pdata = Realloc(*ppdata, 32);
2494 return ERROR_DOS(ERRDOS,ERRnomem);
2498 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2499 CAN ACCEPT THIS IN UNICODE. JRA. */
2501 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2502 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2503 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2504 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2507 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2508 return ERROR_DOS(ERRSRV,ERRerror);
2512 /****************************************************************************
2513 Reply to a SMBfindclose (stop trans2 directory search).
2514 ****************************************************************************/
2516 int reply_findclose(connection_struct *conn,
2517 char *inbuf,char *outbuf,int length,int bufsize)
2520 int dptr_num=SVALS(inbuf,smb_vwv0);
2521 START_PROFILE(SMBfindclose);
2523 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2525 dptr_close(&dptr_num);
2527 outsize = set_message(outbuf,0,0,True);
2529 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2531 END_PROFILE(SMBfindclose);
2535 /****************************************************************************
2536 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
2537 ****************************************************************************/
2539 int reply_findnclose(connection_struct *conn,
2540 char *inbuf,char *outbuf,int length,int bufsize)
2544 START_PROFILE(SMBfindnclose);
2546 dptr_num = SVAL(inbuf,smb_vwv0);
2548 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2550 /* We never give out valid handles for a
2551 findnotifyfirst - so any dptr_num is ok here.
2554 outsize = set_message(outbuf,0,0,True);
2556 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2558 END_PROFILE(SMBfindnclose);
2562 /****************************************************************************
2563 Reply to a SMBtranss2 - just ignore it!
2564 ****************************************************************************/
2566 int reply_transs2(connection_struct *conn,
2567 char *inbuf,char *outbuf,int length,int bufsize)
2569 START_PROFILE(SMBtranss2);
2570 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2571 END_PROFILE(SMBtranss2);
2575 /****************************************************************************
2576 Reply to a SMBtrans2.
2577 ****************************************************************************/
2579 int reply_trans2(connection_struct *conn,
2580 char *inbuf,char *outbuf,int length,int bufsize)
2583 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2584 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2586 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2587 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2588 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2589 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2590 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2591 int32 timeout = IVALS(inbuf,smb_timeout);
2593 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2594 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2595 char *params = NULL, *data = NULL;
2596 int num_params, num_params_sofar, num_data, num_data_sofar;
2597 START_PROFILE(SMBtrans2);
2599 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2600 /* Queue this open message as we are the process of an
2603 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2604 DEBUGADD(2,( "in oplock break state.\n"));
2606 push_oplock_pending_smb_message(inbuf, length);
2607 END_PROFILE(SMBtrans2);
2611 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2612 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2613 END_PROFILE(SMBtrans2);
2614 return ERROR_DOS(ERRSRV,ERRaccess);
2617 outsize = set_message(outbuf,0,0,True);
2619 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2620 is so as a sanity check */
2623 * Need to have rc=0 for ioctl to get job id for OS/2.
2624 * Network printing will fail if function is not successful.
2625 * Similar function in reply.c will be used if protocol
2626 * is LANMAN1.0 instead of LM1.2X002.
2627 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2628 * outbuf doesn't have to be set(only job id is used).
2630 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2631 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2632 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2633 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2635 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2636 DEBUG(2,("Transaction is %d\n",tran_call));
2637 END_PROFILE(SMBtrans2);
2638 return ERROR_DOS(ERRSRV,ERRerror);
2642 /* Allocate the space for the maximum needed parameters and data */
2643 if (total_params > 0)
2644 params = (char *)malloc(total_params);
2646 data = (char *)malloc(total_data);
2648 if ((total_params && !params) || (total_data && !data)) {
2649 DEBUG(2,("Out of memory in reply_trans2\n"));
2652 END_PROFILE(SMBtrans2);
2653 return ERROR_DOS(ERRDOS,ERRnomem);
2656 /* Copy the param and data bytes sent with this request into
2657 the params buffer */
2658 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2659 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2661 if (num_params > total_params || num_data > total_data)
2662 exit_server("invalid params in reply_trans2");
2665 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2667 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2669 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2670 /* We need to send an interim response then receive the rest
2671 of the parameter/data bytes */
2672 outsize = set_message(outbuf,0,0,True);
2673 if (!send_smb(smbd_server_fd(),outbuf))
2674 exit_server("reply_trans2: send_smb failed.");
2676 while (num_data_sofar < total_data ||
2677 num_params_sofar < total_params) {
2680 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2683 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2684 outsize = set_message(outbuf,0,0,True);
2686 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2688 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2689 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2692 END_PROFILE(SMBtrans2);
2693 return ERROR_DOS(ERRSRV,ERRerror);
2696 /* Revise total_params and total_data in case
2697 they have changed downwards */
2698 total_params = SVAL(inbuf, smb_tpscnt);
2699 total_data = SVAL(inbuf, smb_tdscnt);
2700 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2701 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2702 if (num_params_sofar > total_params || num_data_sofar > total_data)
2703 exit_server("data overflow in trans2");
2705 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2706 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2707 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2708 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2712 if (Protocol >= PROTOCOL_NT1) {
2713 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2716 /* Now we must call the relevant TRANS2 function */
2718 case TRANSACT2_OPEN:
2719 START_PROFILE_NESTED(Trans2_open);
2720 outsize = call_trans2open(conn,
2721 inbuf, outbuf, bufsize,
2723 END_PROFILE_NESTED(Trans2_open);
2726 case TRANSACT2_FINDFIRST:
2727 START_PROFILE_NESTED(Trans2_findfirst);
2728 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2729 bufsize, ¶ms, &data);
2730 END_PROFILE_NESTED(Trans2_findfirst);
2733 case TRANSACT2_FINDNEXT:
2734 START_PROFILE_NESTED(Trans2_findnext);
2735 outsize = call_trans2findnext(conn, inbuf, outbuf,
2738 END_PROFILE_NESTED(Trans2_findnext);
2741 case TRANSACT2_QFSINFO:
2742 START_PROFILE_NESTED(Trans2_qfsinfo);
2743 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2744 length, bufsize, ¶ms,
2746 END_PROFILE_NESTED(Trans2_qfsinfo);
2749 case TRANSACT2_SETFSINFO:
2750 START_PROFILE_NESTED(Trans2_setfsinfo);
2751 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2754 END_PROFILE_NESTED(Trans2_setfsinfo);
2757 case TRANSACT2_QPATHINFO:
2758 case TRANSACT2_QFILEINFO:
2759 START_PROFILE_NESTED(Trans2_qpathinfo);
2760 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2762 ¶ms, &data, total_data);
2763 END_PROFILE_NESTED(Trans2_qpathinfo);
2765 case TRANSACT2_SETPATHINFO:
2766 case TRANSACT2_SETFILEINFO:
2767 START_PROFILE_NESTED(Trans2_setpathinfo);
2768 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2772 END_PROFILE_NESTED(Trans2_setpathinfo);
2775 case TRANSACT2_FINDNOTIFYFIRST:
2776 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2777 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2780 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2783 case TRANSACT2_FINDNOTIFYNEXT:
2784 START_PROFILE_NESTED(Trans2_findnotifynext);
2785 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2788 END_PROFILE_NESTED(Trans2_findnotifynext);
2790 case TRANSACT2_MKDIR:
2791 START_PROFILE_NESTED(Trans2_mkdir);
2792 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2793 bufsize, ¶ms, &data);
2794 END_PROFILE_NESTED(Trans2_mkdir);
2797 case TRANSACT2_GET_DFS_REFERRAL:
2798 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2799 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2800 bufsize, ¶ms, &data);
2801 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2803 case TRANSACT2_IOCTL:
2804 START_PROFILE_NESTED(Trans2_ioctl);
2805 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2806 bufsize,¶ms,&data);
2807 END_PROFILE_NESTED(Trans2_ioctl);
2810 /* Error in request */
2811 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2814 END_PROFILE(SMBtrans2);
2815 return ERROR_DOS(ERRSRV,ERRerror);
2818 /* As we do not know how many data packets will need to be
2819 returned here the various call_trans2xxxx calls
2820 must send their own. Thus a call_trans2xxx routine only
2821 returns a value other than -1 when it wants to send
2827 END_PROFILE(SMBtrans2);
2828 return outsize; /* If a correct response was needed the
2829 call_trans2xxx calls have already sent
2830 it. If outsize != -1 then it is returning */